Importing rustc-1.40.0
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4daaa98..37a217d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -15,7 +15,7 @@
 * [Helpful Links and Information](#helpful-links-and-information)
 
 If you have questions, please make a post on [internals.rust-lang.org][internals] or
-hop on the [Rust Discord server][rust-discord], [Rust Zulip server][rust-zulip] or [#rust-internals][pound-rust-internals].
+hop on the [Rust Discord server][rust-discord] or [Rust Zulip server][rust-zulip].
 
 As a reminder, all contributors are expected to follow our [Code of Conduct][coc].
 
@@ -25,7 +25,6 @@
 If this is your first time contributing, the [walkthrough] chapter of the guide
 can give you a good example of how a typical contribution would go.
 
-[pound-rust-internals]: https://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-internals
 [internals]: https://internals.rust-lang.org
 [rust-discord]: http://discord.gg/rust-lang
 [rust-zulip]: https://rust-lang.zulipchat.com
@@ -129,6 +128,14 @@
 Also, please make sure that fixup commits are squashed into other related
 commits with meaningful commit messages.
 
+GitHub allows [closing issues using keywords][closing-keywords]. This feature
+should be used to keep the issue tracker tidy. However, it is generally preferred
+to put the "closes #123" text in the PR description rather than the issue commit;
+particularly during rebasing, citing the issue number in the commit can "spam"
+the issue in question.
+
+[closing-keywords]: https://help.github.com/en/articles/closing-issues-using-keywords
+
 Please make sure your pull request is in compliance with Rust's style
 guidelines by running
 
@@ -404,7 +411,7 @@
 There are a number of other ways to contribute to Rust that don't deal with
 this repository.
 
-Answer questions in [#rust][pound-rust], or on [users.rust-lang.org][users],
+Answer questions in the _Get Help!_ channels from the [Rust Discord server][rust-discord], on [users.rust-lang.org][users],
 or on [StackOverflow][so].
 
 Participate in the [RFC process](https://github.com/rust-lang/rfcs).
@@ -413,7 +420,7 @@
 it to [Crates.io](http://crates.io). Easier said than done, but very, very
 valuable!
 
-[pound-rust]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust
+[rust-discord]: https://discord.gg/rust-lang
 [users]: https://users.rust-lang.org/
 [so]: http://stackoverflow.com/questions/tagged/rust
 [community-library]: https://github.com/rust-lang/rfcs/labels/A-community-library
diff --git a/Cargo.lock b/Cargo.lock
index 5bc1938..f44ed3d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -27,16 +27,16 @@
 
 [[package]]
 name = "ammonia"
-version = "2.1.2"
+version = "3.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "384d704f242a0a9faf793fff775a0be6ab9aa27edabffa097331d73779142520"
+checksum = "9e266e1f4be5ffa05309f650e2586fe1d3ae6034eb24025a7ae1dfecc330823a"
 dependencies = [
  "html5ever",
  "lazy_static 1.3.0",
  "maplit",
  "matches",
  "tendril",
- "url 1.7.2",
+ "url 2.1.0",
 ]
 
 [[package]]
@@ -108,10 +108,16 @@
 ]
 
 [[package]]
-name = "backtrace"
-version = "0.3.37"
+name = "autocfg"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5180c5a20655b14a819b652fd2378fa5f1697b6c9ddad3e695c2f9cedf6df4e2"
+checksum = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875"
+
+[[package]]
+name = "backtrace"
+version = "0.3.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea"
 dependencies = [
  "backtrace-sys",
  "cfg-if",
@@ -123,9 +129,9 @@
 
 [[package]]
 name = "backtrace-sys"
-version = "0.1.30"
+version = "0.1.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b3a000b9c543553af61bc01cbfc403b04b5caa9e421033866f2e98061eb3e61"
+checksum = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491"
 dependencies = [
  "cc",
  "compiler_builtins",
@@ -134,19 +140,10 @@
 ]
 
 [[package]]
-name = "base64"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
-dependencies = [
- "byteorder",
-]
-
-[[package]]
 name = "bitflags"
-version = "1.1.0"
+version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
+checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
 
 [[package]]
 name = "blake2-rfc"
@@ -243,7 +240,6 @@
 checksum = "40ade3d27603c2cb345eb0912aec461a6dec7e06a4ae48589904e808335c7afa"
 dependencies = [
  "byteorder",
- "either",
  "iovec",
 ]
 
@@ -265,10 +261,11 @@
 
 [[package]]
 name = "cargo"
-version = "0.40.0"
+version = "0.41.0"
 dependencies = [
  "atty",
  "bytesize",
+ "cargo-platform",
  "cargo-test-macro",
  "cargo-test-support",
  "clap",
@@ -278,7 +275,7 @@
  "crypto-hash",
  "curl",
  "curl-sys",
- "env_logger",
+ "env_logger 0.7.1",
  "failure",
  "filetime",
  "flate2",
@@ -326,6 +323,13 @@
 ]
 
 [[package]]
+name = "cargo-platform"
+version = "0.1.0"
+dependencies = [
+ "serde",
+]
+
+[[package]]
 name = "cargo-test-macro"
 version = "0.1.0"
 
@@ -360,14 +364,26 @@
 ]
 
 [[package]]
+name = "cargo_metadata"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d2d1617e838936c0d2323a65cc151e03ae19a7678dd24f72bccf27119b90a5d"
+dependencies = [
+ "semver",
+ "serde",
+ "serde_derive",
+ "serde_json",
+]
+
+[[package]]
 name = "cargotest2"
 version = "0.1.0"
 
 [[package]]
 name = "cc"
-version = "1.0.35"
+version = "1.0.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e5f3fee5eeb60324c2781f1e41286bdee933850fff9b3c672587fed5ec58c83"
+checksum = "39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d"
 
 [[package]]
 name = "cfg-if"
@@ -429,7 +445,7 @@
 name = "clippy"
 version = "0.0.212"
 dependencies = [
- "cargo_metadata",
+ "cargo_metadata 0.9.0",
  "clippy-mini-macro-test",
  "clippy_lints",
  "compiletest_rs",
@@ -450,12 +466,12 @@
 name = "clippy_lints"
 version = "0.0.212"
 dependencies = [
- "cargo_metadata",
+ "cargo_metadata 0.9.0",
  "if_chain",
  "itertools 0.8.0",
  "lazy_static 1.3.0",
  "matches",
- "pulldown-cmark 0.6.0",
+ "pulldown-cmark 0.6.1",
  "quine-mc_cluskey",
  "regex-syntax",
  "semver",
@@ -526,7 +542,7 @@
 version = "0.0.0"
 dependencies = [
  "diff",
- "env_logger",
+ "env_logger 0.7.1",
  "getopts",
  "lazy_static 1.3.0",
  "libc",
@@ -542,9 +558,9 @@
 
 [[package]]
 name = "compiletest_rs"
-version = "0.3.22"
+version = "0.3.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f40ecc9332b68270998995c00f8051ee856121764a0d3230e64c9efd059d27b6"
+checksum = "f75b10a18fb53549fdd090846eb01c7f8593914494d1faabc4d3005c436e417a"
 dependencies = [
  "diff",
  "filetime",
@@ -558,7 +574,6 @@
  "serde_derive",
  "serde_json",
  "tempfile",
- "tester",
  "winapi 0.3.6",
 ]
 
@@ -593,7 +608,7 @@
 
 [[package]]
 name = "crates-io"
-version = "0.28.0"
+version = "0.29.0"
 dependencies = [
  "curl",
  "failure",
@@ -653,6 +668,16 @@
 ]
 
 [[package]]
+name = "crossbeam-deque"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71"
+dependencies = [
+ "crossbeam-epoch 0.7.2",
+ "crossbeam-utils 0.6.5",
+]
+
+[[package]]
 name = "crossbeam-epoch"
 version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -723,25 +748,24 @@
 
 [[package]]
 name = "curl"
-version = "0.4.21"
+version = "0.4.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a85f2f95f2bd277d316d1aa8a477687ab4a6942258c7db7c89c187534669979c"
+checksum = "d08ad3cb89d076a36b0ce5749eec2c9964f70c0c58480ab6b75a91ec4fc206d8"
 dependencies = [
  "curl-sys",
- "kernel32-sys",
  "libc",
  "openssl-probe",
  "openssl-sys",
  "schannel",
  "socket2",
- "winapi 0.2.8",
+ "winapi 0.3.6",
 ]
 
 [[package]]
 name = "curl-sys"
-version = "0.4.18"
+version = "0.4.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d91a0052d5b982887d8e829bee0faffc7218ea3c6ebd3d6c2c8f678a93c9a42"
+checksum = "2e9a9a4e417722876332136a00cacf92c2ceb331fab4b52b6a1ad16c6cd79255"
 dependencies = [
  "cc",
  "libc",
@@ -881,12 +905,6 @@
 ]
 
 [[package]]
-name = "dtoa"
-version = "0.4.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e"
-
-[[package]]
 name = "either"
 version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -909,23 +927,14 @@
 
 [[package]]
 name = "ena"
-version = "0.13.0"
+version = "0.13.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3dc01d68e08ca384955a3aeba9217102ca1aa85b6e168639bf27739f1d749d87"
+checksum = "8944dc8fa28ce4a38f778bd46bf7d923fe73eed5a439398507246c8e017e6f36"
 dependencies = [
  "log",
 ]
 
 [[package]]
-name = "encoding_rs"
-version = "0.8.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4155785c79f2f6701f185eb2e6b4caf0555ec03477cb4c70db67b465311620ed"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
 name = "env_logger"
 version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -939,6 +948,19 @@
 ]
 
 [[package]]
+name = "env_logger"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
+dependencies = [
+ "atty",
+ "humantime",
+ "log",
+ "regex",
+ "termcolor",
+]
+
+[[package]]
 name = "error-chain"
 version = "0.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -974,7 +996,7 @@
  "proc-macro2 0.4.30",
  "quote 0.6.12",
  "syn 0.15.35",
- "synstructure",
+ "synstructure 0.10.2",
 ]
 
 [[package]]
@@ -1116,16 +1138,6 @@
 checksum = "45dc39533a6cae6da2b56da48edae506bb767ec07370f86f70fc062e9d435869"
 
 [[package]]
-name = "futures-cpupool"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
-dependencies = [
- "futures",
- "num_cpus",
-]
-
-[[package]]
 name = "fwdansi"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1217,30 +1229,12 @@
 version = "0.0.0"
 
 [[package]]
-name = "h2"
-version = "0.1.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a539b63339fbbb00e081e84b6e11bd1d9634a82d91da2984a18ac74a8823f392"
-dependencies = [
- "byteorder",
- "bytes",
- "fnv",
- "futures",
- "http",
- "indexmap",
- "log",
- "slab",
- "string",
- "tokio-io",
-]
-
-[[package]]
 name = "handlebars"
 version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "df044dd42cdb7e32f28557b661406fc0f2494be75199779998810dbc35030e0d"
 dependencies = [
- "hashbrown",
+ "hashbrown 0.5.0",
  "lazy_static 1.3.0",
  "log",
  "pest",
@@ -1257,10 +1251,19 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e1de41fb8dba9714efd92241565cdff73f78508c95697dd56787d3cba27e2353"
 dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3cd9867f119b19fecb08cd5c326ad4488d7a1da4bf75b4d95d71db742525aaab"
+dependencies = [
+ "autocfg",
  "compiler_builtins",
  "rustc-std-workspace-alloc",
  "rustc-std-workspace-core",
- "serde",
 ]
 
 [[package]]
@@ -1273,6 +1276,17 @@
 ]
 
 [[package]]
+name = "hermit-abi"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f22b8f315b98f415780ddbe9163c7dbbc5a07225b6d102ace1d8aeef85775140"
+dependencies = [
+ "compiler_builtins",
+ "libc",
+ "rustc-std-workspace-core",
+]
+
+[[package]]
 name = "hex"
 version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1286,9 +1300,9 @@
 
 [[package]]
 name = "home"
-version = "0.5.0"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c07c315e106bd6f83f026a20ddaeef2706782e490db1dcdd37caad38a0e895b3"
+checksum = "a3753954f7bd71f0e671afb8b5a992d1724cf43b7f95a563cd4a0bde94659ca8"
 dependencies = [
  "scopeguard 1.0.0",
  "winapi 0.3.6",
@@ -1296,100 +1310,28 @@
 
 [[package]]
 name = "html5ever"
-version = "0.23.0"
+version = "0.24.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ce65ac8028cf5a287a7dbf6c4e0a6cf2dcf022ed5b167a81bae66ebf599a8b7"
+checksum = "025483b0a1e4577bb28578318c886ee5f817dda6eb62473269349044406644cb"
 dependencies = [
  "log",
  "mac",
  "markup5ever",
- "proc-macro2 0.4.30",
- "quote 0.6.12",
- "syn 0.15.35",
+ "proc-macro2 1.0.3",
+ "quote 1.0.2",
+ "syn 1.0.5",
 ]
 
 [[package]]
-name = "http"
-version = "0.1.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fe67e3678f2827030e89cc4b9e7ecd16d52f132c0b940ab5005f88e821500f6a"
-dependencies = [
- "bytes",
- "fnv",
- "itoa",
-]
-
-[[package]]
-name = "http-body"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d"
-dependencies = [
- "bytes",
- "futures",
- "http",
- "tokio-buf",
-]
-
-[[package]]
-name = "httparse"
-version = "1.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
-
-[[package]]
 name = "humantime"
-version = "1.2.0"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114"
+checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
 dependencies = [
  "quick-error",
 ]
 
 [[package]]
-name = "hyper"
-version = "0.12.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6481fff8269772d4463253ca83c788104a7305cb3fb9136bc651a6211e46e03f"
-dependencies = [
- "bytes",
- "futures",
- "futures-cpupool",
- "h2",
- "http",
- "http-body",
- "httparse",
- "iovec",
- "itoa",
- "log",
- "net2",
- "rustc_version",
- "time",
- "tokio",
- "tokio-buf",
- "tokio-executor",
- "tokio-io",
- "tokio-reactor",
- "tokio-tcp",
- "tokio-threadpool",
- "tokio-timer",
- "want",
-]
-
-[[package]]
-name = "hyper-tls"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f"
-dependencies = [
- "bytes",
- "futures",
- "hyper",
- "native-tls",
- "tokio-io",
-]
-
-[[package]]
 name = "ident_case"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1564,9 +1506,9 @@
 
 [[package]]
 name = "jsonrpc-core"
-version = "13.1.0"
+version = "13.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd42951eb35079520ee29b7efbac654d85821b397ef88c8151600ef7e2d00217"
+checksum = "91d767c183a7e58618a609499d359ce3820700b3ebb4823a18c343b4a2a41a0d"
 dependencies = [
  "futures",
  "log",
@@ -1636,7 +1578,7 @@
  "num_cpus",
  "tokio",
  "tokio-codec",
- "unicase 2.5.1",
+ "unicase",
 ]
 
 [[package]]
@@ -1669,27 +1611,14 @@
 
 [[package]]
 name = "libc"
-version = "0.2.62"
+version = "0.2.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
+checksum = "74dfca3d9957906e8d1e6a0b641dc9a59848e793f1da2165889fd4f62d10d79c"
 dependencies = [
  "rustc-std-workspace-core",
 ]
 
 [[package]]
-name = "libflate"
-version = "0.1.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90c6f86f4b0caa347206f916f8b687b51d77c6ef8ff18d52dd007491fd580529"
-dependencies = [
- "adler32",
- "byteorder",
- "crc32fast",
- "rle-decode-fast",
- "take_mut",
-]
-
-[[package]]
 name = "libgit2-sys"
 version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1835,9 +1764,9 @@
 
 [[package]]
 name = "markup5ever"
-version = "0.8.1"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1af46a727284117e09780d05038b1ce6fc9c76cc6df183c3dae5a8955a25e21"
+checksum = "65381d9d47506b8592b97c4efd936afcf673b09b059f2bef39c7211ee78b9d03"
 dependencies = [
  "log",
  "phf",
@@ -1858,15 +1787,15 @@
 
 [[package]]
 name = "mdbook"
-version = "0.3.1"
+version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "949bb2acb2cff9fa5c375cf9c43e70b3dba0a974d9fe01c31285d7a84d2a0fa2"
+checksum = "031bdd9d4893c983e2f69ebc4b59070feee8276a584c4aabdcb351235ea28016"
 dependencies = [
  "ammonia",
  "chrono",
  "clap",
  "elasticlunr-rs",
- "env_logger",
+ "env_logger 0.6.2",
  "error-chain",
  "handlebars",
  "itertools 0.8.0",
@@ -1874,7 +1803,7 @@
  "log",
  "memchr",
  "open",
- "pulldown-cmark 0.5.3",
+ "pulldown-cmark 0.6.1",
  "regex",
  "serde",
  "serde_derive",
@@ -1886,33 +1815,10 @@
 ]
 
 [[package]]
-name = "mdbook-linkcheck"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77d1f0ba4d1e6b86fa18e8853d026d7d76a97eb7eb5eb052ed80901e43b7fc10"
-dependencies = [
- "env_logger",
- "failure",
- "log",
- "mdbook",
- "memchr",
- "pulldown-cmark 0.5.3",
- "rayon",
- "regex",
- "reqwest",
- "semver",
- "serde",
- "serde_derive",
- "serde_json",
- "structopt 0.2.18",
- "url 1.7.2",
-]
-
-[[package]]
 name = "measureme"
-version = "0.3.0"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d09de7dafa3aa334bc806447c7e4de69419723312f4b88b80b561dea66601ce8"
+checksum = "cd21b0e6e1af976b269ce062038fe5e1b9ca2f817ab7a3af09ec4210aebf0d30"
 dependencies = [
  "byteorder",
  "memmap",
@@ -1951,27 +1857,6 @@
 ]
 
 [[package]]
-name = "mime"
-version = "0.3.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e27ca21f40a310bd06d9031785f4801710d566c184a6e15bad4f1d9b65f9425"
-dependencies = [
- "unicase 2.5.1",
-]
-
-[[package]]
-name = "mime_guess"
-version = "2.0.0-alpha.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30de2e4613efcba1ec63d8133f344076952090c122992a903359be5a4f99c3ed"
-dependencies = [
- "mime",
- "phf",
- "phf_codegen",
- "unicase 1.4.2",
-]
-
-[[package]]
 name = "minifier"
 version = "0.0.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2080,13 +1965,13 @@
 version = "0.1.0"
 dependencies = [
  "byteorder",
- "cargo_metadata",
+ "cargo_metadata 0.9.0",
  "colored",
  "compiletest_rs",
  "directories",
- "env_logger",
+ "env_logger 0.7.1",
  "getrandom",
- "hex 0.3.2",
+ "hex 0.4.0",
  "log",
  "num-traits",
  "rand 0.7.0",
@@ -2097,24 +1982,6 @@
 ]
 
 [[package]]
-name = "native-tls"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e"
-dependencies = [
- "lazy_static 1.3.0",
- "libc",
- "log",
- "openssl",
- "openssl-probe",
- "openssl-sys",
- "schannel",
- "security-framework",
- "security-framework-sys",
- "tempfile",
-]
-
-[[package]]
 name = "net2"
 version = "0.2.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2444,7 +2311,6 @@
 checksum = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0"
 dependencies = [
  "siphasher",
- "unicase 1.4.2",
 ]
 
 [[package]]
@@ -2493,7 +2359,7 @@
 checksum = "df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61"
 dependencies = [
  "chrono",
- "env_logger",
+ "env_logger 0.6.2",
  "log",
 ]
 
@@ -2558,21 +2424,20 @@
 checksum = "77043da1282374688ee212dc44b3f37ff929431de9c9adc3053bd3cee5630357"
 dependencies = [
  "bitflags",
- "getopts",
  "memchr",
- "unicase 2.5.1",
+ "unicase",
 ]
 
 [[package]]
 name = "pulldown-cmark"
-version = "0.6.0"
+version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85b0ad0d4c1702965ee6bb5b4ff5e71f83850b497d497e9444302987bf9e26a4"
+checksum = "1c205cc82214f3594e2d50686730314f817c67ffa80fe800cf0db78c3c2b9d9e"
 dependencies = [
  "bitflags",
  "getopts",
  "memchr",
- "unicase 2.5.1",
+ "unicase",
 ]
 
 [[package]]
@@ -2613,14 +2478,14 @@
 
 [[package]]
 name = "racer"
-version = "2.1.27"
+version = "2.1.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dde22b84ab75220015cbd91240222402bf885cbe3a5dc856475771abb82533ae"
+checksum = "acc70369054bad4ad0c16a3f45cd73e0695361a3af35c7b465e619ac2674f064"
 dependencies = [
  "bitflags",
  "clap",
  "derive_more",
- "env_logger",
+ "env_logger 0.6.2",
  "humantime",
  "lazy_static 1.3.0",
  "log",
@@ -2772,22 +2637,22 @@
 
 [[package]]
 name = "rayon"
-version = "1.1.0"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4b0186e22767d5b9738a05eab7c6ac90b15db17e5b5f9bd87976dd7d89a10a4"
+checksum = "83a27732a533a1be0a0035a111fe76db89ad312f6f0347004c220c57f209a123"
 dependencies = [
- "crossbeam-deque 0.6.3",
+ "crossbeam-deque 0.7.1",
  "either",
  "rayon-core",
 ]
 
 [[package]]
 name = "rayon-core"
-version = "1.5.0"
+version = "1.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebbe0df8435ac0c397d467b6cad6d25543d06e8a019ef3f6af3c384597515bd2"
+checksum = "98dcf634205083b17d0861252431eb2acbfb698ab7478a2d20de07954f47ec7b"
 dependencies = [
- "crossbeam-deque 0.6.3",
+ "crossbeam-deque 0.7.1",
  "crossbeam-queue",
  "crossbeam-utils 0.6.5",
  "lazy_static 1.3.0",
@@ -2870,51 +2735,15 @@
 ]
 
 [[package]]
-name = "reqwest"
-version = "0.9.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e542d9f077c126af32536b6aacc75bb7325400eab8cd0743543be5d91660780d"
-dependencies = [
- "base64",
- "bytes",
- "encoding_rs",
- "futures",
- "http",
- "hyper",
- "hyper-tls",
- "libflate",
- "log",
- "mime",
- "mime_guess",
- "native-tls",
- "serde",
- "serde_json",
- "serde_urlencoded",
- "tokio",
- "tokio-executor",
- "tokio-io",
- "tokio-threadpool",
- "tokio-timer",
- "url 1.7.2",
- "uuid",
-]
-
-[[package]]
-name = "rle-decode-fast"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac"
-
-[[package]]
 name = "rls"
-version = "1.39.0"
+version = "1.40.0"
 dependencies = [
  "cargo",
- "cargo_metadata",
+ "cargo_metadata 0.8.0",
  "clippy_lints",
  "crossbeam-channel",
  "difference",
- "env_logger",
+ "env_logger 0.7.1",
  "failure",
  "futures",
  "heck",
@@ -2928,7 +2757,7 @@
  "num_cpus",
  "ordslice",
  "racer",
- "rand 0.6.1",
+ "rand 0.7.0",
  "rayon",
  "regex",
  "rls-analysis",
@@ -2937,7 +2766,6 @@
  "rls-rustc",
  "rls-span",
  "rls-vfs",
- "rustc-serialize",
  "rustc-workspace-hack",
  "rustc_tools_util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustfmt-nightly",
@@ -2998,11 +2826,11 @@
 version = "0.6.0"
 dependencies = [
  "clippy_lints",
- "env_logger",
+ "env_logger 0.7.1",
  "failure",
  "futures",
  "log",
- "rand 0.6.1",
+ "rand 0.7.0",
  "rls-data",
  "rls-ipc",
  "serde",
@@ -3035,7 +2863,7 @@
  "clap",
  "failure",
  "mdbook",
- "mdbook-linkcheck",
+ "rustc-workspace-hack",
 ]
 
 [[package]]
@@ -3046,6 +2874,7 @@
  "backtrace",
  "bitflags",
  "byteorder",
+ "cc",
  "chalk-engine",
  "fmt_macros",
  "graphviz",
@@ -3055,12 +2884,13 @@
  "num_cpus",
  "parking_lot 0.9.0",
  "polonius-engine",
- "rustc-rayon",
- "rustc-rayon-core",
+ "rustc-rayon 0.3.0",
+ "rustc-rayon-core 0.3.0",
  "rustc_apfloat",
  "rustc_data_structures",
  "rustc_errors",
  "rustc_fs_util",
+ "rustc_index",
  "rustc_macros",
  "rustc_target",
  "scoped-tls",
@@ -3072,9 +2902,9 @@
 
 [[package]]
 name = "rustc-ap-arena"
-version = "583.0.0"
+version = "606.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f59b76d334bd533f3fdc5c651c27678c5e80fac67c6f7da22ba21a58878c55f5"
+checksum = "a623fd4805842e9bd0bb6e6dace63efede0ee22de4522a0b03b7c3d15a22f009"
 dependencies = [
  "rustc-ap-rustc_data_structures",
  "smallvec",
@@ -3082,15 +2912,15 @@
 
 [[package]]
 name = "rustc-ap-graphviz"
-version = "583.0.0"
+version = "606.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e632ef08ca17458acfd46d2ead3d541a1c249586cd5329f5fe333dacfab6142"
+checksum = "ee549ade784b444ef10c0240c3487ed785aa65d711071f7984246b15329a17b6"
 
 [[package]]
 name = "rustc-ap-rustc_data_structures"
-version = "583.0.0"
+version = "606.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e89e2c7be68185418f3cd56af3df8b29007a59a1cebefa63612d055f9bcb1a36"
+checksum = "ca545744a5a9b42e3d0410d6290d40de96dd567253fe77f310c1de4afd213dd4"
 dependencies = [
  "cfg-if",
  "crossbeam-utils 0.6.5",
@@ -3099,21 +2929,22 @@
  "jobserver",
  "lazy_static 1.3.0",
  "log",
- "parking_lot 0.7.1",
+ "parking_lot 0.9.0",
  "rustc-ap-graphviz",
+ "rustc-ap-rustc_index",
  "rustc-ap-serialize",
  "rustc-hash",
- "rustc-rayon",
- "rustc-rayon-core",
+ "rustc-rayon 0.2.0",
+ "rustc-rayon-core 0.2.0",
  "smallvec",
  "stable_deref_trait",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_errors"
-version = "583.0.0"
+version = "606.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e47cb380abeb72b01e42b2342d592f7eeea7d536c2f1f0d0e550dc509e46333"
+checksum = "a6967a41ed38ef4bce0f559fe9a4801d8ba12ac032f40a12a55e72f79d52c9bb"
 dependencies = [
  "annotate-snippets",
  "atty",
@@ -3127,45 +2958,56 @@
 ]
 
 [[package]]
-name = "rustc-ap-rustc_lexer"
-version = "583.0.0"
+name = "rustc-ap-rustc_index"
+version = "606.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "494cfaf67f49217d67d0774eeecbba61ac89acf478db97ef11f113ed8a959305"
+checksum = "457a5c204ae2fdaa5bdb5b196e58ca59896870d80445fe423063c9453496e3ea"
+dependencies = [
+ "rustc-ap-serialize",
+ "smallvec",
+]
+
+[[package]]
+name = "rustc-ap-rustc_lexer"
+version = "606.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed0c064676f8a08e42a36b0d4e4a102465fb0f4b75e11436cb7f66d2c3fa7139"
 dependencies = [
  "unicode-xid 0.2.0",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_macros"
-version = "583.0.0"
+version = "606.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2e5d36becc59b4497f9cbd3ae0610081de0207a1d0e95c066369167b14f486f"
+checksum = "b2d77e46159c5288c585decbcdc9d742889c65e307c31e104c7a36d63fe1f5d0"
 dependencies = [
  "itertools 0.8.0",
  "proc-macro2 0.4.30",
  "quote 0.6.12",
  "syn 0.15.35",
- "synstructure",
+ "synstructure 0.10.2",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_target"
-version = "583.0.0"
+version = "606.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7bfc5f96dfc3b9f8d5b57884f7f37467ecff6776cd4b8b491a7daece6fdd7c2"
+checksum = "86ca895350b0de14d064b499168c93fa183958d5462eb042c927d93623e41ec1"
 dependencies = [
  "bitflags",
  "log",
  "rustc-ap-rustc_data_structures",
+ "rustc-ap-rustc_index",
  "rustc-ap-serialize",
  "rustc-ap-syntax_pos",
 ]
 
 [[package]]
 name = "rustc-ap-serialize"
-version = "583.0.0"
+version = "606.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bb9ee231cf79eded39c56647499f83d6136ff5c8c0baaa9e21b6febee00f4f6"
+checksum = "92679240e86f4583cc05f8dcf6439bdab87bac9e6555718469176de9bd52ba20"
 dependencies = [
  "indexmap",
  "smallvec",
@@ -3173,17 +3015,17 @@
 
 [[package]]
 name = "rustc-ap-syntax"
-version = "583.0.0"
+version = "606.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3827fc208814efbde82d613e31d11b4250ce9e8cf8afe4a4d47bbbd099632c9"
+checksum = "0a0c30f8e38c847dbfd9e2f1e472ab06d0bd0a23ab53ae4c5a44912842ce834e"
 dependencies = [
  "bitflags",
  "lazy_static 1.3.0",
  "log",
  "rustc-ap-rustc_data_structures",
  "rustc-ap-rustc_errors",
+ "rustc-ap-rustc_index",
  "rustc-ap-rustc_lexer",
- "rustc-ap-rustc_macros",
  "rustc-ap-rustc_target",
  "rustc-ap-serialize",
  "rustc-ap-syntax_pos",
@@ -3193,13 +3035,14 @@
 
 [[package]]
 name = "rustc-ap-syntax_pos"
-version = "583.0.0"
+version = "606.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "930ed81c34f325e512cc315c04d676fa84a373879d5c43bb54054a0522b05213"
+checksum = "2bdaa0fb40143b4b878256ac4e2b498885daafc269502504d91929eab4744bf4"
 dependencies = [
  "cfg-if",
  "rustc-ap-arena",
  "rustc-ap-rustc_data_structures",
+ "rustc-ap-rustc_index",
  "rustc-ap-rustc_macros",
  "rustc-ap-serialize",
  "scoped-tls",
@@ -3243,7 +3086,18 @@
 dependencies = [
  "crossbeam-deque 0.2.0",
  "either",
- "rustc-rayon-core",
+ "rustc-rayon-core 0.2.0",
+]
+
+[[package]]
+name = "rustc-rayon"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f32767f90d938f1b7199a174ef249ae1924f6e5bbdb9d112fea141e016f25b3a"
+dependencies = [
+ "crossbeam-deque 0.7.1",
+ "either",
+ "rustc-rayon-core 0.3.0",
 ]
 
 [[package]]
@@ -3259,10 +3113,17 @@
 ]
 
 [[package]]
-name = "rustc-serialize"
-version = "0.3.24"
+name = "rustc-rayon-core"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
+checksum = "ea2427831f0053ea3ea73559c8eabd893133a51b251d142bacee53c62a288cb3"
+dependencies = [
+ "crossbeam-deque 0.7.1",
+ "crossbeam-queue",
+ "crossbeam-utils 0.6.5",
+ "lazy_static 1.3.0",
+ "num_cpus",
+]
 
 [[package]]
 name = "rustc-std-workspace-alloc"
@@ -3293,6 +3154,7 @@
  "serde",
  "serde_json",
  "smallvec",
+ "syn 0.15.35",
  "url 2.1.0",
  "winapi 0.3.6",
 ]
@@ -3317,19 +3179,6 @@
 ]
 
 [[package]]
-name = "rustc_ast_borrowck"
-version = "0.0.0"
-dependencies = [
- "graphviz",
- "log",
- "rustc",
- "rustc_data_structures",
- "rustc_errors",
- "syntax",
- "syntax_pos",
-]
-
-[[package]]
 name = "rustc_codegen_llvm"
 version = "0.0.0"
 dependencies = [
@@ -3347,7 +3196,6 @@
  "log",
  "memmap",
  "num_cpus",
- "parking_lot 0.9.0",
  "rustc",
  "rustc_apfloat",
  "rustc_codegen_utils",
@@ -3355,6 +3203,7 @@
  "rustc_errors",
  "rustc_fs_util",
  "rustc_incremental",
+ "rustc_index",
  "rustc_target",
  "serialize",
  "syntax",
@@ -3366,7 +3215,6 @@
 name = "rustc_codegen_utils"
 version = "0.0.0"
 dependencies = [
- "flate2",
  "log",
  "punycode",
  "rustc",
@@ -3392,8 +3240,9 @@
  "log",
  "parking_lot 0.9.0",
  "rustc-hash",
- "rustc-rayon",
- "rustc-rayon-core",
+ "rustc-rayon 0.3.0",
+ "rustc-rayon-core 0.3.0",
+ "rustc_index",
  "serialize",
  "smallvec",
  "stable_deref_trait",
@@ -3403,16 +3252,16 @@
 name = "rustc_driver"
 version = "0.0.0"
 dependencies = [
- "env_logger",
+ "env_logger 0.7.1",
  "graphviz",
  "lazy_static 1.3.0",
  "log",
  "rustc",
- "rustc_ast_borrowck",
  "rustc_codegen_utils",
  "rustc_data_structures",
  "rustc_errors",
  "rustc_interface",
+ "rustc_lint",
  "rustc_metadata",
  "rustc_mir",
  "rustc_plugin",
@@ -3459,14 +3308,21 @@
 ]
 
 [[package]]
+name = "rustc_index"
+version = "0.0.0"
+dependencies = [
+ "serialize",
+ "smallvec",
+]
+
+[[package]]
 name = "rustc_interface"
 version = "0.0.0"
 dependencies = [
  "log",
  "once_cell",
  "rustc",
- "rustc-rayon",
- "rustc_ast_borrowck",
+ "rustc-rayon 0.3.0",
  "rustc_codegen_ssa",
  "rustc_codegen_utils",
  "rustc_data_structures",
@@ -3479,11 +3335,13 @@
  "rustc_plugin_impl",
  "rustc_privacy",
  "rustc_resolve",
+ "rustc_target",
  "rustc_traits",
  "rustc_typeck",
  "serialize",
  "smallvec",
  "syntax",
+ "syntax_expand",
  "syntax_ext",
  "syntax_pos",
  "tempfile",
@@ -3503,6 +3361,7 @@
  "log",
  "rustc",
  "rustc_data_structures",
+ "rustc_index",
  "rustc_target",
  "syntax",
  "syntax_pos",
@@ -3532,10 +3391,10 @@
 version = "0.1.0"
 dependencies = [
  "itertools 0.8.0",
- "proc-macro2 0.4.30",
- "quote 0.6.12",
- "syn 0.15.35",
- "synstructure",
+ "proc-macro2 1.0.3",
+ "quote 1.0.2",
+ "syn 1.0.5",
+ "synstructure 0.12.1",
 ]
 
 [[package]]
@@ -3548,11 +3407,13 @@
  "rustc",
  "rustc_data_structures",
  "rustc_errors",
+ "rustc_index",
  "rustc_target",
  "serialize",
  "smallvec",
  "stable_deref_trait",
  "syntax",
+ "syntax_expand",
  "syntax_pos",
 ]
 
@@ -3561,7 +3422,6 @@
 version = "0.0.0"
 dependencies = [
  "arena",
- "byteorder",
  "either",
  "graphviz",
  "log",
@@ -3571,6 +3431,7 @@
  "rustc_apfloat",
  "rustc_data_structures",
  "rustc_errors",
+ "rustc_index",
  "rustc_lexer",
  "rustc_target",
  "serialize",
@@ -3598,6 +3459,8 @@
  "rustc",
  "rustc_data_structures",
  "rustc_errors",
+ "rustc_index",
+ "rustc_target",
  "syntax",
  "syntax_pos",
 ]
@@ -3614,9 +3477,9 @@
 version = "0.0.0"
 dependencies = [
  "rustc",
- "rustc_errors",
  "rustc_metadata",
  "syntax",
+ "syntax_expand",
  "syntax_pos",
 ]
 
@@ -3638,7 +3501,6 @@
 dependencies = [
  "arena",
  "bitflags",
- "indexmap",
  "log",
  "rustc",
  "rustc_data_structures",
@@ -3646,6 +3508,7 @@
  "rustc_metadata",
  "smallvec",
  "syntax",
+ "syntax_expand",
  "syntax_pos",
 ]
 
@@ -3660,7 +3523,6 @@
  "rustc_codegen_utils",
  "rustc_data_structures",
  "rustc_target",
- "rustc_typeck",
  "serde_json",
  "syntax",
  "syntax_pos",
@@ -3673,6 +3535,7 @@
  "bitflags",
  "log",
  "rustc_data_structures",
+ "rustc_index",
  "serialize",
  "syntax_pos",
 ]
@@ -3691,9 +3554,7 @@
 name = "rustc_traits"
 version = "0.0.0"
 dependencies = [
- "bitflags",
  "chalk-engine",
- "graphviz",
  "log",
  "rustc",
  "rustc_data_structures",
@@ -3723,6 +3584,7 @@
  "rustc",
  "rustc_data_structures",
  "rustc_errors",
+ "rustc_index",
  "rustc_target",
  "smallvec",
  "syntax",
@@ -3744,7 +3606,7 @@
 dependencies = [
  "minifier",
  "pulldown-cmark 0.5.3",
- "rustc-rayon",
+ "rustc-rayon 0.3.0",
  "tempfile",
 ]
 
@@ -3783,15 +3645,15 @@
 
 [[package]]
 name = "rustfmt-nightly"
-version = "1.4.8"
+version = "1.4.9"
 dependencies = [
  "annotate-snippets",
  "bytecount",
- "cargo_metadata",
+ "cargo_metadata 0.8.0",
  "derive-new",
  "diff",
  "dirs",
- "env_logger",
+ "env_logger 0.6.2",
  "failure",
  "getopts",
  "ignore",
@@ -3806,7 +3668,7 @@
  "rustfmt-config_proc_macro",
  "serde",
  "serde_json",
- "structopt 0.3.1",
+ "structopt",
  "term 0.6.0",
  "toml",
  "unicode-segmentation",
@@ -3864,27 +3726,6 @@
 checksum = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
 
 [[package]]
-name = "security-framework"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eee63d0f4a9ec776eeb30e220f0bc1e092c3ad744b2a379e3993070364d3adc2"
-dependencies = [
- "core-foundation",
- "core-foundation-sys",
- "libc",
- "security-framework-sys",
-]
-
-[[package]]
-name = "security-framework-sys"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9636f8989cbf61385ae4824b98c1aaa54c994d7d8b41f11c601ed799f0549a56"
-dependencies = [
- "core-foundation-sys",
-]
-
-[[package]]
 name = "semver"
 version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3952,18 +3793,6 @@
 ]
 
 [[package]]
-name = "serde_urlencoded"
-version = "0.5.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a"
-dependencies = [
- "dtoa",
- "itoa",
- "serde",
- "url 1.7.2",
-]
-
-[[package]]
 name = "serialize"
 version = "0.0.0"
 dependencies = [
@@ -4056,13 +3885,13 @@
 dependencies = [
  "alloc",
  "backtrace",
- "cc",
  "cfg-if",
  "compiler_builtins",
  "core",
  "dlmalloc",
  "fortanix-sgx-abi",
- "hashbrown",
+ "hashbrown 0.6.2",
+ "hermit-abi",
  "libc",
  "panic_abort",
  "panic_unwind",
@@ -4077,15 +3906,6 @@
 ]
 
 [[package]]
-name = "string"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d"
-dependencies = [
- "bytes",
-]
-
-[[package]]
 name = "string_cache"
 version = "0.7.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4136,34 +3956,12 @@
 
 [[package]]
 name = "structopt"
-version = "0.2.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7"
-dependencies = [
- "clap",
- "structopt-derive 0.2.18",
-]
-
-[[package]]
-name = "structopt"
 version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2ac9d6e93dd792b217bf89cda5c14566e3043960c6f9da890c2ba5d09d07804c"
 dependencies = [
  "clap",
- "structopt-derive 0.3.1",
-]
-
-[[package]]
-name = "structopt-derive"
-version = "0.2.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107"
-dependencies = [
- "heck",
- "proc-macro2 0.4.30",
- "quote 0.6.12",
- "syn 0.15.35",
+ "structopt-derive",
 ]
 
 [[package]]
@@ -4232,6 +4030,18 @@
 ]
 
 [[package]]
+name = "synstructure"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f085a5855930c0441ca1288cf044ea4aecf4f43a91668abdb870b4ba546a203"
+dependencies = [
+ "proc-macro2 1.0.3",
+ "quote 1.0.2",
+ "syn 1.0.5",
+ "unicode-xid 0.2.0",
+]
+
+[[package]]
 name = "syntax"
 version = "0.0.0"
 dependencies = [
@@ -4240,8 +4050,8 @@
  "log",
  "rustc_data_structures",
  "rustc_errors",
+ "rustc_index",
  "rustc_lexer",
- "rustc_macros",
  "rustc_target",
  "scoped-tls",
  "serialize",
@@ -4250,6 +4060,25 @@
 ]
 
 [[package]]
+name = "syntax_expand"
+version = "0.0.0"
+dependencies = [
+ "bitflags",
+ "lazy_static 1.3.0",
+ "log",
+ "rustc_data_structures",
+ "rustc_errors",
+ "rustc_index",
+ "rustc_lexer",
+ "rustc_target",
+ "scoped-tls",
+ "serialize",
+ "smallvec",
+ "syntax",
+ "syntax_pos",
+]
+
+[[package]]
 name = "syntax_ext"
 version = "0.0.0"
 dependencies = [
@@ -4257,10 +4086,10 @@
  "log",
  "rustc_data_structures",
  "rustc_errors",
- "rustc_lexer",
  "rustc_target",
  "smallvec",
  "syntax",
+ "syntax_expand",
  "syntax_pos",
 ]
 
@@ -4271,6 +4100,7 @@
  "arena",
  "cfg-if",
  "rustc_data_structures",
+ "rustc_index",
  "rustc_macros",
  "scoped-tls",
  "serialize",
@@ -4278,12 +4108,6 @@
 ]
 
 [[package]]
-name = "take_mut"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60"
-
-[[package]]
 name = "tar"
 version = "0.4.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4330,16 +4154,6 @@
 
 [[package]]
 name = "term"
-version = "0.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
-dependencies = [
- "kernel32-sys",
- "winapi 0.2.8",
-]
-
-[[package]]
-name = "term"
 version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0dd90505d5006a4422d3520b30c781d480b3f36768c2fa2187c3e950bc110464"
@@ -4395,17 +4209,6 @@
 ]
 
 [[package]]
-name = "tester"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e812cb26c597f86a49b26dbb58b878bd2a2b4b93fc069dc39499228fe556ff6"
-dependencies = [
- "getopts",
- "libc",
- "term 0.4.6",
-]
-
-[[package]]
 name = "textwrap"
 version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4469,17 +4272,6 @@
 ]
 
 [[package]]
-name = "tokio-buf"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46"
-dependencies = [
- "bytes",
- "either",
- "futures",
-]
-
-[[package]]
 name = "tokio-codec"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4716,12 +4508,6 @@
 ]
 
 [[package]]
-name = "try-lock"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
-
-[[package]]
 name = "typenum"
 version = "1.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4741,15 +4527,6 @@
 
 [[package]]
 name = "unicase"
-version = "1.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
-dependencies = [
- "version_check",
-]
-
-[[package]]
-name = "unicase"
 version = "2.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2e2e6bd1e59e56598518beb94fd6db628ded570326f0a98c679a304bd9f00150"
@@ -4868,15 +4645,6 @@
 checksum = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d"
 
 [[package]]
-name = "uuid"
-version = "0.7.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a"
-dependencies = [
- "rand 0.6.1",
-]
-
-[[package]]
 name = "vcpkg"
 version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4926,17 +4694,6 @@
 ]
 
 [[package]]
-name = "want"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230"
-dependencies = [
- "futures",
- "log",
- "try-lock",
-]
-
-[[package]]
 name = "wasi"
 version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/README.md b/README.md
index 96d7e93..c5468a2 100644
--- a/README.md
+++ b/README.md
@@ -33,6 +33,7 @@
    * `curl`
    * `git`
    * `ssl` which comes in `libssl-dev` or `openssl-devel`
+   * `pkg-config` if you are compiling on Linux and targeting Linux
 
 2. Clone the [source] with `git`:
 
@@ -243,19 +244,17 @@
 
 To contribute to Rust, please see [CONTRIBUTING](CONTRIBUTING.md).
 
-Rust has an [IRC] culture and most real-time collaboration happens in a
-variety of channels on Mozilla's IRC network, irc.mozilla.org. The
-most popular channel is [#rust], a venue for general discussion about
-Rust. And a good place to ask for help would be [#rust-beginners].
+Most real-time collaboration happens in a variety of channels on the
+[Rust Discord server][rust-discord], with channels dedicated for getting help,
+community, documentation, and all major contribution areas in the Rust ecosystem.
+A good place to ask for help would be the #help channel.
 
 The [rustc guide] might be a good place to start if you want to find out how
 various parts of the compiler work.
 
 Also, you may find the [rustdocs for the compiler itself][rustdocs] useful.
 
-[IRC]: https://en.wikipedia.org/wiki/Internet_Relay_Chat
-[#rust]: irc://irc.mozilla.org/rust
-[#rust-beginners]: irc://irc.mozilla.org/rust-beginners
+[rust-discord]: https://discord.gg/rust-lang
 [rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html
 [rustdocs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/
 
diff --git a/config.toml.example b/config.toml.example
index 848147c..e832570 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -258,10 +258,9 @@
 [rust]
 
 # Whether or not to optimize the compiler and standard library.
-#
-# Note: the slowness of the non optimized compiler compiling itself usually
-#       outweighs the time gains in not doing optimizations, therefore a
-#       full bootstrap takes much more time with `optimize` set to false.
+# WARNING: Building with optimize = false is NOT SUPPORTED. Due to bootstrapping,
+# building without optimizations takes much longer than optimizing. Further, some platforms
+# fail to build without this optimization (c.f. #65352).
 #optimize = true
 
 # Indicates that the build should be configured for debugging Rust. A
@@ -341,6 +340,9 @@
 # nightly features
 #channel = "dev"
 
+# The root location of the MUSL installation directory.
+#musl-root = "..."
+
 # By default the `rustc` executable is built with `-Wl,-rpath` flags on Unix
 # platforms to ensure that the compiler is usable by default from the build
 # directory (as it links to a number of dynamic libraries). This may not be
@@ -374,9 +376,7 @@
 
 # This is an array of the codegen backends that will be compiled for the rustc
 # that's being compiled. The default is to only build the LLVM codegen backend,
-# but you can also optionally enable the "emscripten" backend for asm.js or
-# make this an empty array (but that probably won't get too far in the
-# bootstrap)
+# and currently the only standard option supported is `"llvm"`
 #codegen-backends = ["llvm"]
 
 # This is the name of the directory in which codegen backends will get installed
diff --git a/git-commit-hash b/git-commit-hash
index c702c5c..7047962 100644
--- a/git-commit-hash
+++ b/git-commit-hash
@@ -1 +1 @@
-4560ea788cb760f0a34127156c78e2552949f734
\ No newline at end of file
+73528e339aae0f17a15ffa49a8ac608f50c6cf14
\ No newline at end of file
diff --git a/src/README.md b/src/README.md
index 32ca4a1..2f7cf90 100644
--- a/src/README.md
+++ b/src/README.md
@@ -5,7 +5,4 @@
 
 For more information on how various parts of the compiler work, see the [rustc guide].
 
-There is also useful content in this README:
-https://github.com/rust-lang/rust/tree/master/src/librustc/infer/lexical_region_resolve.
-
 [rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html
diff --git a/src/bootstrap/README.md b/src/bootstrap/README.md
index 3e877fc..c501378 100644
--- a/src/bootstrap/README.md
+++ b/src/bootstrap/README.md
@@ -328,6 +328,8 @@
   `Config` struct.
 * Adding a sanity check? Take a look at `bootstrap/sanity.rs`.
 
-If you have any questions feel free to reach out on `#rust-infra` on IRC or ask on
-internals.rust-lang.org. When you encounter bugs, please file issues on the
-rust-lang/rust issue tracker.
+If you have any questions feel free to reach out on `#infra` channel in the
+[Rust Discord server][rust-discord] or ask on internals.rust-lang.org. When
+you encounter bugs, please file issues on the rust-lang/rust issue tracker.
+
+[rust-discord]: https://discord.gg/rust-lang
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 65129ee..4caf36a 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -734,10 +734,6 @@
             if module.endswith("llvm-project"):
                 if self.get_toml('llvm-config') and self.get_toml('lld') != 'true':
                     continue
-            if module.endswith("llvm-emscripten"):
-                backends = self.get_toml('codegen-backends')
-                if backends is None or not 'emscripten' in backends:
-                    continue
             check = self.check_submodule(module, slow_submodules)
             filtered_submodules.append((module, check))
             submodules_names.append(module)
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 5d586f0..2edcef2 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -443,6 +443,7 @@
                 dist::Rustc,
                 dist::DebuggerScripts,
                 dist::Std,
+                dist::RustcDev,
                 dist::Analysis,
                 dist::Src,
                 dist::PlainSourceTarball,
@@ -817,12 +818,22 @@
 
         let mut rustflags = Rustflags::new(&target);
         if stage != 0 {
+            if let Ok(s) = env::var("CARGOFLAGS_NOT_BOOTSTRAP") {
+                cargo.args(s.split_whitespace());
+            }
             rustflags.env("RUSTFLAGS_NOT_BOOTSTRAP");
         } else {
+            if let Ok(s) = env::var("CARGOFLAGS_BOOTSTRAP") {
+                cargo.args(s.split_whitespace());
+            }
             rustflags.env("RUSTFLAGS_BOOTSTRAP");
             rustflags.arg("--cfg=bootstrap");
         }
 
+        if let Ok(s) = env::var("CARGOFLAGS") {
+            cargo.args(s.split_whitespace());
+        }
+
         match mode {
             Mode::Std | Mode::ToolBootstrap | Mode::ToolStd => {},
             Mode::Rustc | Mode::Codegen | Mode::ToolRustc => {
@@ -875,7 +886,18 @@
         // things still build right, please do!
         match mode {
             Mode::Std => metadata.push_str("std"),
-            _ => {},
+            // When we're building rustc tools, they're built with a search path
+            // that contains things built during the rustc build. For example,
+            // bitflags is built during the rustc build, and is a dependency of
+            // rustdoc as well. We're building rustdoc in a different target
+            // directory, though, which means that Cargo will rebuild the
+            // dependency. When we go on to build rustdoc, we'll look for
+            // bitflags, and find two different copies: one built during the
+            // rustc step and one that we just built. This isn't always a
+            // problem, somehow -- not really clear why -- but we know that this
+            // fixes things.
+            Mode::ToolRustc => metadata.push_str("tool-rustc"),
+            _ => {}
         }
         cargo.env("__CARGO_DEFAULT_LIB_METADATA", &metadata);
 
@@ -970,6 +992,7 @@
                 Some("-Wl,-rpath,@loader_path/../lib")
             } else if !target.contains("windows") &&
                       !target.contains("wasm32") &&
+                      !target.contains("emscripten") &&
                       !target.contains("fuchsia") {
                 Some("-Wl,-rpath,$ORIGIN/../lib")
             } else {
diff --git a/src/bootstrap/cache.rs b/src/bootstrap/cache.rs
index 53071df..4310f2c 100644
--- a/src/bootstrap/cache.rs
+++ b/src/bootstrap/cache.rs
@@ -161,7 +161,7 @@
     }
 }
 
-struct TyIntern<T: Hash + Clone + Eq> {
+struct TyIntern<T: Clone + Eq> {
     items: Vec<T>,
     set: HashMap<T, Interned<T>>,
 }
diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs
index caa4843..ef1b6e2 100644
--- a/src/bootstrap/channel.rs
+++ b/src/bootstrap/channel.rs
@@ -13,7 +13,7 @@
 use crate::Build;
 
 // The version number
-pub const CFG_RELEASE_NUM: &str = "1.39.0";
+pub const CFG_RELEASE_NUM: &str = "1.40.0";
 
 pub struct GitInfo {
     inner: Option<Info>,
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index cadb9a7..df1c725 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -55,6 +55,7 @@
                   cargo,
                   args(builder.kind),
                   &libstd_stamp(builder, compiler, target),
+                  vec![],
                   true);
 
         let libdir = builder.sysroot_libdir(compiler, target);
@@ -103,6 +104,7 @@
                   cargo,
                   args(builder.kind),
                   &librustc_stamp(builder, compiler, target),
+                  vec![],
                   true);
 
         let libdir = builder.sysroot_libdir(compiler, target);
@@ -155,6 +157,7 @@
                   cargo,
                   args(builder.kind),
                   &codegen_backend_stamp(builder, compiler, target, backend),
+                  vec![],
                   true);
     }
 }
@@ -199,6 +202,7 @@
                   cargo,
                   args(builder.kind),
                   &rustdoc_stamp(builder, compiler, target),
+                  vec![],
                   true);
 
         let libdir = builder.sysroot_libdir(compiler, target);
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 6ea32ed..8e5fe25 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -69,7 +69,7 @@
             return;
         }
 
-        builder.ensure(StartupObjects { compiler, target });
+        let mut target_deps = builder.ensure(StartupObjects { compiler, target });
 
         let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
         if compiler_to_use != compiler {
@@ -91,7 +91,7 @@
             return;
         }
 
-        copy_third_party_objects(builder, &compiler, target);
+        target_deps.extend(copy_third_party_objects(builder, &compiler, target).into_iter());
 
         let mut cargo = builder.cargo(compiler, Mode::Std, target, "build");
         std_cargo(builder, &compiler, target, &mut cargo);
@@ -102,6 +102,7 @@
                   cargo,
                   vec![],
                   &libstd_stamp(builder, compiler, target),
+                  target_deps,
                   false);
 
         builder.ensure(StdLink {
@@ -113,9 +114,22 @@
 }
 
 /// Copies third pary objects needed by various targets.
-fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target: Interned<String>) {
+fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target: Interned<String>)
+    -> Vec<PathBuf>
+{
     let libdir = builder.sysroot_libdir(*compiler, target);
 
+    let mut target_deps = vec![];
+
+    let mut copy_and_stamp = |sourcedir: &Path, name: &str| {
+        let target = libdir.join(name);
+        builder.copy(
+            &sourcedir.join(name),
+            &target,
+        );
+        target_deps.push(target);
+    };
+
     // Copies the crt(1,i,n).o startup objects
     //
     // Since musl supports fully static linking, we can cross link for it even
@@ -123,19 +137,13 @@
     // files. As those shipped with glibc won't work, copy the ones provided by
     // musl so we have them on linux-gnu hosts.
     if target.contains("musl") {
+        let srcdir = builder.musl_root(target).unwrap().join("lib");
         for &obj in &["crt1.o", "crti.o", "crtn.o"] {
-            builder.copy(
-                &builder.musl_root(target).unwrap().join("lib").join(obj),
-                &libdir.join(obj),
-            );
+            copy_and_stamp(&srcdir, obj);
         }
     } else if target.ends_with("-wasi") {
-        for &obj in &["crt1.o"] {
-            builder.copy(
-                &builder.wasi_root(target).unwrap().join("lib/wasm32-wasi").join(obj),
-                &libdir.join(obj),
-            );
-        }
+        let srcdir = builder.wasi_root(target).unwrap().join("lib/wasm32-wasi");
+        copy_and_stamp(&srcdir, "crt1.o");
     }
 
     // Copies libunwind.a compiled to be linked wit x86_64-fortanix-unknown-sgx.
@@ -145,11 +153,11 @@
     // which is provided by std for this target.
     if target == "x86_64-fortanix-unknown-sgx" {
         let src_path_env = "X86_FORTANIX_SGX_LIBS";
-        let obj = "libunwind.a";
         let src = env::var(src_path_env).expect(&format!("{} not found in env", src_path_env));
-        let src = Path::new(&src).join(obj);
-        builder.copy(&src, &libdir.join(obj));
+        copy_and_stamp(Path::new(&src), "libunwind.a");
     }
+
+    target_deps
 }
 
 /// Configure cargo to compile the standard library, adding appropriate env vars
@@ -210,7 +218,6 @@
             // config.toml equivalent) is used
             let llvm_config = builder.ensure(native::Llvm {
                 target: builder.config.build,
-                emscripten: false,
             });
             cargo.env("LLVM_CONFIG", llvm_config);
             cargo.env("RUSTC_BUILD_SANITIZERS", "1");
@@ -307,7 +314,7 @@
 }
 
 impl Step for StartupObjects {
-    type Output = ();
+    type Output = Vec<PathBuf>;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
         run.path("src/rtstartup")
@@ -326,13 +333,15 @@
     /// They don't require any library support as they're just plain old object
     /// files, so we just use the nightly snapshot compiler to always build them (as
     /// no other compilers are guaranteed to be available).
-    fn run(self, builder: &Builder<'_>) {
+    fn run(self, builder: &Builder<'_>) -> Vec<PathBuf> {
         let for_compiler = self.compiler;
         let target = self.target;
         if !target.contains("windows-gnu") {
-            return
+            return vec![]
         }
 
+        let mut target_deps = vec![];
+
         let src_dir = &builder.src.join("src/rtstartup");
         let dst_dir = &builder.native_dir(target).join("rtstartup");
         let sysroot_dir = &builder.sysroot_libdir(for_compiler, target);
@@ -351,7 +360,9 @@
                             .arg(src_file));
             }
 
-            builder.copy(dst_file, &sysroot_dir.join(file.to_string() + ".o"));
+            let target = sysroot_dir.join(file.to_string() + ".o");
+            builder.copy(dst_file, &target);
+            target_deps.push(target);
         }
 
         for obj in ["crt2.o", "dllcrt2.o"].iter() {
@@ -359,8 +370,12 @@
                                     builder.cc(target),
                                     target,
                                     obj);
-            builder.copy(&src, &sysroot_dir.join(obj));
+            let target = sysroot_dir.join(obj);
+            builder.copy(&src, &target);
+            target_deps.push(target);
         }
+
+        target_deps
     }
 }
 
@@ -438,6 +453,7 @@
                   cargo,
                   vec![],
                   &librustc_stamp(builder, compiler, target),
+                  vec![],
                   false);
 
         builder.ensure(RustcLink {
@@ -586,7 +602,7 @@
 
         let tmp_stamp = out_dir.join(".tmp.stamp");
 
-        let files = run_cargo(builder, cargo, vec![], &tmp_stamp, false);
+        let files = run_cargo(builder, cargo, vec![], &tmp_stamp, vec![], false);
         if builder.config.dry_run {
             return;
         }
@@ -615,46 +631,37 @@
                              compiler: &Compiler,
                              target: Interned<String>,
                              backend: Interned<String>) -> String {
-    let mut features = String::new();
-
     match &*backend {
-        "llvm" | "emscripten" => {
+        "llvm" => {
             // Build LLVM for our target. This will implicitly build the
             // host LLVM if necessary.
             let llvm_config = builder.ensure(native::Llvm {
                 target,
-                emscripten: backend == "emscripten",
             });
 
-            if backend == "emscripten" {
-                features.push_str(" emscripten");
-            }
-
             builder.info(&format!("Building stage{} codegen artifacts ({} -> {}, {})",
                      compiler.stage, &compiler.host, target, backend));
 
             // Pass down configuration from the LLVM build into the build of
             // librustc_llvm and librustc_codegen_llvm.
-            if builder.is_rust_llvm(target) && backend != "emscripten" {
+            if builder.is_rust_llvm(target) {
                 cargo.env("LLVM_RUSTLLVM", "1");
             }
 
             cargo.env("LLVM_CONFIG", &llvm_config);
-            if backend != "emscripten" {
-                let target_config = builder.config.target_config.get(&target);
-                if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
-                    cargo.env("CFG_LLVM_ROOT", s);
-                }
+            let target_config = builder.config.target_config.get(&target);
+            if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
+                cargo.env("CFG_LLVM_ROOT", s);
             }
             // Some LLVM linker flags (-L and -l) may be needed to link librustc_llvm.
             if let Some(ref s) = builder.config.llvm_ldflags {
                 cargo.env("LLVM_LINKER_FLAGS", s);
             }
-            // Building with a static libstdc++ is only supported on linux right now,
+            // Building with a static libstdc++ is only supported on linux and mingw right now,
             // not for MSVC or macOS
             if builder.config.llvm_static_stdcpp &&
                !target.contains("freebsd") &&
-               !target.contains("windows") &&
+               !target.contains("msvc") &&
                !target.contains("apple") {
                 let file = compiler_file(builder,
                                          builder.cxx(target).unwrap(),
@@ -662,9 +669,7 @@
                                          "libstdc++.a");
                 cargo.env("LLVM_STATIC_STDCPP", file);
             }
-            if builder.config.llvm_link_shared ||
-                (builder.config.llvm_thin_lto && backend != "emscripten")
-            {
+            if builder.config.llvm_link_shared || builder.config.llvm_thin_lto {
                 cargo.env("LLVM_LINK_SHARED", "1");
             }
             if builder.config.llvm_use_libcxx {
@@ -676,8 +681,7 @@
         }
         _ => panic!("unknown backend: {}", backend),
     }
-
-    features
+    String::new()
 }
 
 /// Creates the `codegen-backends` folder for a compiler that's about to be
@@ -954,6 +958,7 @@
                  cargo: Cargo,
                  tail_args: Vec<String>,
                  stamp: &Path,
+                 additional_target_deps: Vec<PathBuf>,
                  is_check: bool)
     -> Vec<PathBuf>
 {
@@ -1070,6 +1075,7 @@
         deps.push((path_to_add.into(), false));
     }
 
+    deps.extend(additional_target_deps.into_iter().map(|d| (d, false)));
     deps.sort();
     let mut new_contents = Vec::new();
     for (dep, proc_macro) in deps.iter() {
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 52b5cd8..d1bdfa0 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -200,16 +200,15 @@
     target: Vec<String>,
     cargo: Option<String>,
     rustc: Option<String>,
-    low_priority: Option<bool>,
-    compiler_docs: Option<bool>,
     docs: Option<bool>,
+    compiler_docs: Option<bool>,
     submodules: Option<bool>,
     fast_submodules: Option<bool>,
     gdb: Option<String>,
-    locked_deps: Option<bool>,
-    vendor: Option<bool>,
     nodejs: Option<String>,
     python: Option<String>,
+    locked_deps: Option<bool>,
+    vendor: Option<bool>,
     full_bootstrap: Option<bool>,
     extended: Option<bool>,
     tools: Option<HashSet<String>>,
@@ -217,6 +216,7 @@
     sanitizers: Option<bool>,
     profiler: Option<bool>,
     cargo_native_static: Option<bool>,
+    low_priority: Option<bool>,
     configure_args: Option<Vec<String>>,
     local_rebuild: Option<bool>,
     print_step_timings: Option<bool>,
@@ -228,11 +228,11 @@
 struct Install {
     prefix: Option<String>,
     sysconfdir: Option<String>,
-    datadir: Option<String>,
     docdir: Option<String>,
     bindir: Option<String>,
     libdir: Option<String>,
     mandir: Option<String>,
+    datadir: Option<String>,
 
     // standard paths, currently unused
     infodir: Option<String>,
@@ -243,14 +243,14 @@
 #[derive(Deserialize, Default)]
 #[serde(deny_unknown_fields, rename_all = "kebab-case")]
 struct Llvm {
-    ccache: Option<StringOrBool>,
-    ninja: Option<bool>,
-    assertions: Option<bool>,
     optimize: Option<bool>,
     thin_lto: Option<bool>,
     release_debuginfo: Option<bool>,
+    assertions: Option<bool>,
+    ccache: Option<StringOrBool>,
     version_check: Option<bool>,
     static_libstdcpp: Option<bool>,
+    ninja: Option<bool>,
     targets: Option<String>,
     experimental_targets: Option<String>,
     link_jobs: Option<u32>,
@@ -293,6 +293,7 @@
 #[serde(deny_unknown_fields, rename_all = "kebab-case")]
 struct Rust {
     optimize: Option<bool>,
+    debug: Option<bool>,
     codegen_units: Option<u32>,
     codegen_units_std: Option<u32>,
     debug_assertions: Option<bool>,
@@ -301,25 +302,24 @@
     debuginfo_level_std: Option<u32>,
     debuginfo_level_tools: Option<u32>,
     debuginfo_level_tests: Option<u32>,
-    parallel_compiler: Option<bool>,
     backtrace: Option<bool>,
+    incremental: Option<bool>,
+    parallel_compiler: Option<bool>,
     default_linker: Option<String>,
     channel: Option<String>,
     musl_root: Option<String>,
     rpath: Option<bool>,
+    verbose_tests: Option<bool>,
     optimize_tests: Option<bool>,
     codegen_tests: Option<bool>,
     ignore_git: Option<bool>,
-    debug: Option<bool>,
     dist_src: Option<bool>,
-    verbose_tests: Option<bool>,
-    incremental: Option<bool>,
     save_toolstates: Option<String>,
     codegen_backends: Option<Vec<String>>,
     codegen_backends_dir: Option<String>,
     lld: Option<bool>,
-    lldb: Option<bool>,
     llvm_tools: Option<bool>,
+    lldb: Option<bool>,
     deny_warnings: Option<bool>,
     backtrace_on_ice: Option<bool>,
     verify_llvm_ir: Option<bool>,
@@ -333,13 +333,13 @@
 #[derive(Deserialize, Default)]
 #[serde(deny_unknown_fields, rename_all = "kebab-case")]
 struct TomlTarget {
-    llvm_config: Option<String>,
-    llvm_filecheck: Option<String>,
     cc: Option<String>,
     cxx: Option<String>,
     ar: Option<String>,
     ranlib: Option<String>,
     linker: Option<String>,
+    llvm_config: Option<String>,
+    llvm_filecheck: Option<String>,
     android_ndk: Option<String>,
     crt_static: Option<bool>,
     musl_root: Option<String>,
@@ -668,7 +668,6 @@
 
     pub fn llvm_enabled(&self) -> bool {
         self.rust_codegen_backends.contains(&INTERNER.intern_str("llvm"))
-        || self.rust_codegen_backends.contains(&INTERNER.intern_str("emscripten"))
     }
 }
 
diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py
index 346f0cb..bb6041d 100755
--- a/src/bootstrap/configure.py
+++ b/src/bootstrap/configure.py
@@ -55,7 +55,6 @@
 o("dist-src", "rust.dist-src", "when building tarballs enables building a source tarball")
 o("cargo-native-static", "build.cargo-native-static", "static native libraries in cargo")
 o("profiler", "build.profiler", "build the profiler runtime")
-o("emscripten", None, "compile the emscripten backend as well as LLVM")
 o("full-tools", None, "enable all tools")
 o("lld", "rust.lld", "build lld")
 o("lldb", "rust.lldb", "build lldb")
@@ -134,6 +133,10 @@
   "mips-unknown-linux-musl install directory")
 v("musl-root-mipsel", "target.mipsel-unknown-linux-musl.musl-root",
   "mipsel-unknown-linux-musl install directory")
+v("musl-root-mips64", "target.mips64-unknown-linux-muslabi64.musl-root",
+  "mips64-unknown-linux-muslabi64 install directory")
+v("musl-root-mips64el", "target.mips64el-unknown-linux-muslabi64.musl-root",
+  "mips64el-unknown-linux-muslabi64 install directory")
 v("qemu-armhf-rootfs", "target.arm-unknown-linux-gnueabihf.qemu-rootfs",
   "rootfs in qemu testing, you probably don't want to use this")
 v("qemu-aarch64-rootfs", "target.aarch64-unknown-linux-gnu.qemu-rootfs",
@@ -335,10 +338,8 @@
         set('build.host', value.split(','))
     elif option.name == 'target':
         set('build.target', value.split(','))
-    elif option.name == 'emscripten':
-        set('rust.codegen-backends', ['llvm', 'emscripten'])
     elif option.name == 'full-tools':
-        set('rust.codegen-backends', ['llvm', 'emscripten'])
+        set('rust.codegen-backends', ['llvm'])
         set('rust.lld', True)
         set('rust.llvm-tools', True)
         set('build.extended', True)
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index d9dff77..67907bc 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -236,7 +236,7 @@
     }
 
     let target_tools = ["gcc.exe", "ld.exe", "dlltool.exe", "libwinpthread-1.dll"];
-    let mut rustc_dlls = vec!["libstdc++-6.dll", "libwinpthread-1.dll"];
+    let mut rustc_dlls = vec!["libwinpthread-1.dll"];
     if target_triple.starts_with("i686-") {
         rustc_dlls.push("libgcc_s_dw2-1.dll");
     } else {
@@ -637,6 +637,28 @@
     }
 }
 
+fn skip_host_target_lib(builder: &Builder<'_>, compiler: Compiler) -> bool {
+    // The only true set of target libraries came from the build triple, so
+    // let's reduce redundant work by only producing archives from that host.
+    if compiler.host != builder.config.build {
+        builder.info("\tskipping, not a build host");
+        true
+    } else {
+        false
+    }
+}
+
+/// Copy stamped files into an image's `target/lib` directory.
+fn copy_target_libs(builder: &Builder<'_>, target: &str, image: &Path, stamp: &Path) {
+    let dst = image.join("lib/rustlib").join(target).join("lib");
+    t!(fs::create_dir_all(&dst));
+    for (path, host) in builder.read_stamp_file(stamp) {
+        if !host || builder.config.build == target {
+            builder.copy(&path, &dst.join(path.file_name().unwrap()));
+        }
+    }
+}
+
 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct Std {
     pub compiler: Compiler,
@@ -667,44 +689,19 @@
         let target = self.target;
 
         let name = pkgname(builder, "rust-std");
-
-        // The only true set of target libraries came from the build triple, so
-        // let's reduce redundant work by only producing archives from that host.
-        if compiler.host != builder.config.build {
-            builder.info("\tskipping, not a build host");
-            return distdir(builder).join(format!("{}-{}.tar.gz", name, target));
+        let archive = distdir(builder).join(format!("{}-{}.tar.gz", name, target));
+        if skip_host_target_lib(builder, compiler) {
+            return archive;
         }
 
-        // We want to package up as many target libraries as possible
-        // for the `rust-std` package, so if this is a host target we
-        // depend on librustc and otherwise we just depend on libtest.
-        if builder.hosts.iter().any(|t| t == target) {
-            builder.ensure(compile::Rustc { compiler, target });
-        } else {
-            builder.ensure(compile::Std { compiler, target });
-        }
+        builder.ensure(compile::Std { compiler, target });
 
         let image = tmpdir(builder).join(format!("{}-{}-image", name, target));
         let _ = fs::remove_dir_all(&image);
 
-        let dst = image.join("lib/rustlib").join(target);
-        t!(fs::create_dir_all(&dst));
-        let mut src = builder.sysroot_libdir(compiler, target).to_path_buf();
-        src.pop(); // Remove the trailing /lib folder from the sysroot_libdir
-        builder.cp_filtered(&src, &dst, &|path| {
-            if let Some(name) = path.file_name().and_then(|s| s.to_str()) {
-                if name == builder.config.rust_codegen_backends_dir.as_str() {
-                    return false
-                }
-                if name == "bin" {
-                    return false
-                }
-                if name.contains("LLVM") {
-                    return false
-                }
-            }
-            true
-        });
+        let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
+        let stamp = compile::libstd_stamp(builder, compiler_to_use, target);
+        copy_target_libs(builder, &target, &image, &stamp);
 
         let mut cmd = rust_installer(builder);
         cmd.arg("generate")
@@ -723,7 +720,73 @@
         let _time = timeit(builder);
         builder.run(&mut cmd);
         builder.remove_dir(&image);
-        distdir(builder).join(format!("{}-{}.tar.gz", name, target))
+        archive
+    }
+}
+
+#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct RustcDev {
+    pub compiler: Compiler,
+    pub target: Interned<String>,
+}
+
+impl Step for RustcDev {
+    type Output = PathBuf;
+    const DEFAULT: bool = true;
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.path("rustc-dev")
+    }
+
+    fn make_run(run: RunConfig<'_>) {
+        run.builder.ensure(RustcDev {
+            compiler: run.builder.compiler_for(
+                run.builder.top_stage,
+                run.builder.config.build,
+                run.target,
+            ),
+            target: run.target,
+        });
+    }
+
+    fn run(self, builder: &Builder<'_>) -> PathBuf {
+        let compiler = self.compiler;
+        let target = self.target;
+
+        let name = pkgname(builder, "rustc-dev");
+        let archive = distdir(builder).join(format!("{}-{}.tar.gz", name, target));
+        if skip_host_target_lib(builder, compiler) {
+            return archive;
+        }
+
+        builder.ensure(compile::Rustc { compiler, target });
+
+        let image = tmpdir(builder).join(format!("{}-{}-image", name, target));
+        let _ = fs::remove_dir_all(&image);
+
+        let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
+        let stamp = compile::librustc_stamp(builder, compiler_to_use, target);
+        copy_target_libs(builder, &target, &image, &stamp);
+
+        let mut cmd = rust_installer(builder);
+        cmd.arg("generate")
+           .arg("--product-name=Rust")
+           .arg("--rel-manifest-dir=rustlib")
+           .arg("--success-message=Rust-is-ready-to-develop.")
+           .arg("--image-dir").arg(&image)
+           .arg("--work-dir").arg(&tmpdir(builder))
+           .arg("--output-dir").arg(&distdir(builder))
+           .arg(format!("--package-name={}-{}", name, target))
+           .arg(format!("--component-name=rustc-dev-{}", target))
+           .arg("--legacy-manifest-dirs=rustlib,cargo");
+
+        builder.info(&format!("Dist rustc-dev stage{} ({} -> {})",
+            compiler.stage, &compiler.host, target));
+        let _time = timeit(builder);
+        builder.run(&mut cmd);
+        builder.remove_dir(&image);
+        archive
     }
 }
 
@@ -826,7 +889,6 @@
 
         const LLVM_TEST: &[&str] = &[
             "llvm-project/llvm/test", "llvm-project\\llvm\\test",
-            "llvm-emscripten/test", "llvm-emscripten\\test",
         ];
         if LLVM_TEST.iter().any(|path| spath.contains(path)) &&
             (spath.ends_with(".ll") ||
@@ -834,9 +896,6 @@
              spath.ends_with(".s")) {
             return false
         }
-        if spath.contains("test/emscripten") || spath.contains("test\\emscripten") {
-            return false
-        }
 
         let full_path = Path::new(dir).join(path);
         if exclude_dirs.iter().any(|excl| full_path == Path::new(excl)) {
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 9203a55..39d7ea9 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -160,7 +160,7 @@
     }
 }
 
-#[cfg(any(target_os = "haiku", not(any(unix, windows))))]
+#[cfg(any(target_os = "haiku", target_os = "hermit", not(any(unix, windows))))]
 mod job {
     pub unsafe fn setup(_build: &mut crate::Build) {
     }
@@ -232,7 +232,6 @@
     miri_info: channel::GitInfo,
     rustfmt_info: channel::GitInfo,
     in_tree_llvm_info: channel::GitInfo,
-    emscripten_llvm_info: channel::GitInfo,
     local_rebuild: bool,
     fail_fast: bool,
     doc_tests: DocTests,
@@ -351,7 +350,6 @@
 
         // we always try to use git for LLVM builds
         let in_tree_llvm_info = channel::GitInfo::new(false, &src.join("src/llvm-project"));
-        let emscripten_llvm_info = channel::GitInfo::new(false, &src.join("src/llvm-emscripten"));
 
         let mut build = Build {
             initial_rustc: config.initial_rustc.clone(),
@@ -376,7 +374,6 @@
             miri_info,
             rustfmt_info,
             in_tree_llvm_info,
-            emscripten_llvm_info,
             cc: HashMap::new(),
             cxx: HashMap::new(),
             ar: HashMap::new(),
@@ -553,10 +550,6 @@
         self.out.join(&*target).join("llvm")
     }
 
-    fn emscripten_llvm_out(&self, target: Interned<String>) -> PathBuf {
-        self.out.join(&*target).join("llvm-emscripten")
-    }
-
     fn lld_out(&self, target: Interned<String>) -> PathBuf {
         self.out.join(&*target).join("lld")
     }
@@ -1087,6 +1080,10 @@
     /// done. The file is updated immediately after this function completes.
     pub fn save_toolstate(&self, tool: &str, state: ToolState) {
         if let Some(ref path) = self.config.save_toolstates {
+            if let Some(parent) = path.parent() {
+                // Ensure the parent directory always exists
+                t!(std::fs::create_dir_all(parent));
+            }
             let mut file = t!(fs::OpenOptions::new()
                 .create(true)
                 .read(true)
@@ -1126,7 +1123,7 @@
         }
 
         let mut paths = Vec::new();
-        let contents = t!(fs::read(stamp));
+        let contents = t!(fs::read(stamp), &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) {
@@ -1144,6 +1141,7 @@
     pub fn copy(&self, src: &Path, dst: &Path) {
         if self.config.dry_run { return; }
         self.verbose_than(1, &format!("Copy {:?} to {:?}", src, dst));
+        if src == dst { return; }
         let _ = fs::remove_file(&dst);
         let metadata = t!(src.symlink_metadata());
         if metadata.file_type().is_symlink() {
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index 7bf9ea2..2e89fd5 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -28,7 +28,6 @@
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct Llvm {
     pub target: Interned<String>,
-    pub emscripten: bool,
 }
 
 impl Step for Llvm {
@@ -40,46 +39,35 @@
         run.path("src/llvm-project")
             .path("src/llvm-project/llvm")
             .path("src/llvm")
-            .path("src/llvm-emscripten")
     }
 
     fn make_run(run: RunConfig<'_>) {
-        let emscripten = run.path.ends_with("llvm-emscripten");
         run.builder.ensure(Llvm {
             target: run.target,
-            emscripten,
         });
     }
 
     /// Compile LLVM for `target`.
     fn run(self, builder: &Builder<'_>) -> PathBuf {
         let target = self.target;
-        let emscripten = self.emscripten;
 
         // If we're using a custom LLVM bail out here, but we can only use a
         // custom LLVM for the build triple.
-        if !self.emscripten {
-            if let Some(config) = builder.config.target_config.get(&target) {
-                if let Some(ref s) = config.llvm_config {
-                    check_llvm_version(builder, s);
-                    return s.to_path_buf()
-                }
+        if let Some(config) = builder.config.target_config.get(&target) {
+            if let Some(ref s) = config.llvm_config {
+                check_llvm_version(builder, s);
+                return s.to_path_buf()
             }
         }
 
-        let (llvm_info, root, out_dir, llvm_config_ret_dir) = if emscripten {
-            let info = &builder.emscripten_llvm_info;
-            let dir = builder.emscripten_llvm_out(target);
-            let config_dir = dir.join("bin");
-            (info, "src/llvm-emscripten", dir, config_dir)
-        } else {
-            let info = &builder.in_tree_llvm_info;
-            let mut dir = builder.llvm_out(builder.config.build);
-            if !builder.config.build.contains("msvc") || builder.config.ninja {
-                dir.push("build");
-            }
-            (info, "src/llvm-project/llvm", builder.llvm_out(target), dir.join("bin"))
-        };
+        let llvm_info = &builder.in_tree_llvm_info;
+        let root = "src/llvm-project/llvm";
+        let out_dir = builder.llvm_out(target);
+        let mut llvm_config_ret_dir = builder.llvm_out(builder.config.build);
+        if !builder.config.build.contains("msvc") || builder.config.ninja {
+            llvm_config_ret_dir.push("build");
+        }
+        llvm_config_ret_dir.push("bin");
 
         let build_llvm_config = llvm_config_ret_dir
             .join(exe("llvm-config", &*builder.config.build));
@@ -107,8 +95,7 @@
             }
         }
 
-        let descriptor = if emscripten { "Emscripten " } else { "" };
-        builder.info(&format!("Building {}LLVM for {}", descriptor, target));
+        builder.info(&format!("Building LLVM for {}", target));
         let _time = util::timeit(&builder);
         t!(fs::create_dir_all(&out_dir));
 
@@ -123,23 +110,15 @@
 
         // NOTE: remember to also update `config.toml.example` when changing the
         // defaults!
-        let llvm_targets = if self.emscripten {
-            "JSBackend"
-        } else {
-            match builder.config.llvm_targets {
-                Some(ref s) => s,
-                None => "AArch64;ARM;Hexagon;MSP430;Mips;NVPTX;PowerPC;RISCV;\
-                         Sparc;SystemZ;WebAssembly;X86",
-            }
+        let llvm_targets = match &builder.config.llvm_targets {
+            Some(s) => s,
+            None => "AArch64;ARM;Hexagon;MSP430;Mips;NVPTX;PowerPC;RISCV;\
+                     Sparc;SystemZ;WebAssembly;X86",
         };
 
-        let llvm_exp_targets = if self.emscripten {
-            ""
-        } else {
-            match builder.config.llvm_experimental_targets {
-                Some(ref s) => s,
-                None => "",
-            }
+        let llvm_exp_targets = match builder.config.llvm_experimental_targets {
+            Some(ref s) => s,
+            None => "",
         };
 
         let assertions = if builder.config.llvm_assertions {"ON"} else {"OFF"};
@@ -157,40 +136,30 @@
            .define("WITH_POLLY", "OFF")
            .define("LLVM_ENABLE_TERMINFO", "OFF")
            .define("LLVM_ENABLE_LIBEDIT", "OFF")
+           .define("LLVM_ENABLE_BINDINGS", "OFF")
            .define("LLVM_ENABLE_Z3_SOLVER", "OFF")
            .define("LLVM_PARALLEL_COMPILE_JOBS", builder.jobs().to_string())
            .define("LLVM_TARGET_ARCH", target.split('-').next().unwrap())
            .define("LLVM_DEFAULT_TARGET_TRIPLE", target);
 
-        if builder.config.llvm_thin_lto && !emscripten {
+        if builder.config.llvm_thin_lto {
             cfg.define("LLVM_ENABLE_LTO", "Thin");
             if !target.contains("apple") {
                cfg.define("LLVM_ENABLE_LLD", "ON");
             }
         }
 
-        // By default, LLVM will automatically find OCaml and, if it finds it,
-        // install the LLVM bindings in LLVM_OCAML_INSTALL_PATH, which defaults
-        // to /usr/bin/ocaml.
-        // This causes problem for non-root builds of Rust. Side-step the issue
-        // by setting LLVM_OCAML_INSTALL_PATH to a relative path, so it installs
-        // in the prefix.
-        cfg.define("LLVM_OCAML_INSTALL_PATH",
-            env::var_os("LLVM_OCAML_INSTALL_PATH").unwrap_or_else(|| "usr/lib/ocaml".into()));
-
-        let want_lldb = builder.config.lldb_enabled && !self.emscripten;
-
         // This setting makes the LLVM tools link to the dynamic LLVM library,
         // which saves both memory during parallel links and overall disk space
         // for the tools. We don't do this on every platform as it doesn't work
         // equally well everywhere.
-        if builder.llvm_link_tools_dynamically(target) && !emscripten {
+        if builder.llvm_link_tools_dynamically(target) {
             cfg.define("LLVM_LINK_LLVM_DYLIB", "ON");
         }
 
         // For distribution we want the LLVM tools to be *statically* linked to libstdc++
-        if builder.config.llvm_tools_enabled || want_lldb {
-            if !target.contains("windows") {
+        if builder.config.llvm_tools_enabled || builder.config.lldb_enabled {
+            if !target.contains("msvc") {
                 if target.contains("apple") {
                     cfg.define("CMAKE_EXE_LINKER_FLAGS", "-static-libstdc++");
                 } else {
@@ -217,7 +186,7 @@
             enabled_llvm_projects.push("compiler-rt");
         }
 
-        if want_lldb {
+        if builder.config.lldb_enabled {
             enabled_llvm_projects.push("clang");
             enabled_llvm_projects.push("lldb");
             // For the time being, disable code signing.
@@ -242,10 +211,9 @@
         }
 
         // http://llvm.org/docs/HowToCrossCompileLLVM.html
-        if target != builder.config.build && !emscripten {
+        if target != builder.config.build {
             builder.ensure(Llvm {
                 target: builder.config.build,
-                emscripten: false,
             });
             // FIXME: if the llvm root for the build triple is overridden then we
             //        should use llvm-tblgen from there, also should verify that it
@@ -427,7 +395,7 @@
     cfg.define("CMAKE_C_FLAGS", cflags);
     let mut cxxflags = builder.cflags(target, GitRepo::Llvm).join(" ");
     if builder.config.llvm_static_stdcpp &&
-        !target.contains("windows") &&
+        !target.contains("msvc") &&
         !target.contains("netbsd")
     {
         cxxflags.push_str(" -static-libstdc++");
@@ -489,7 +457,6 @@
 
         let llvm_config = builder.ensure(Llvm {
             target: self.target,
-            emscripten: false,
         });
 
         let out_dir = builder.lld_out(target);
@@ -567,6 +534,10 @@
         builder.info("Building test helpers");
         t!(fs::create_dir_all(&dst));
         let mut cfg = cc::Build::new();
+        // FIXME: Workaround for https://github.com/emscripten-core/emscripten/issues/9013
+        if target.contains("emscripten") {
+            cfg.pic(false);
+        }
 
         // We may have found various cross-compilers a little differently due to our
         // extra configuration, so inform gcc of these compilers. Note, though, that
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index b7ce9c7..60f0dcc 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -386,8 +386,17 @@
             extra_features: Vec::new(),
         });
         if let Some(miri) = miri {
+            let mut cargo = builder.cargo(compiler, Mode::ToolRustc, host, "install");
+            cargo.arg("xargo");
+            // Configure `cargo install` path. cargo adds a `bin/`.
+            cargo.env("CARGO_INSTALL_ROOT", &builder.out);
+
+            let mut cargo = Command::from(cargo);
+            if !try_run(builder, &mut cargo) {
+                return;
+            }
+
             // # Run `cargo miri setup`.
-            // As a side-effect, this will install xargo.
             let mut cargo = tool::prepare_tool_cargo(
                 builder,
                 compiler,
@@ -412,9 +421,7 @@
             cargo.env("XARGO_RUST_SRC", builder.src.join("src"));
             // Debug things.
             cargo.env("RUST_BACKTRACE", "1");
-            // Configure `cargo install` path, and let cargo-miri know that that's where
-            // xargo ends up.
-            cargo.env("CARGO_INSTALL_ROOT", &builder.out); // cargo adds a `bin/`
+            // Let cargo-miri know where xargo ended up.
             cargo.env("XARGO", builder.out.join("bin").join("xargo"));
 
             let mut cargo = Command::from(cargo);
@@ -427,7 +434,7 @@
             // (We do this separately from the above so that when the setup actually
             // happens we get some output.)
             // We re-use the `cargo` from above.
-            cargo.arg("--env");
+            cargo.arg("--print-sysroot");
 
             // FIXME: Is there a way in which we can re-use the usual `run` helpers?
             let miri_sysroot = if builder.config.dry_run {
@@ -437,13 +444,11 @@
                 let out = cargo.output()
                     .expect("We already ran `cargo miri setup` before and that worked");
                 assert!(out.status.success(), "`cargo miri setup` returned with non-0 exit code");
-                // Output is "MIRI_SYSROOT=<str>\n".
+                // Output is "<sysroot>\n".
                 let stdout = String::from_utf8(out.stdout)
                     .expect("`cargo miri setup` stdout is not valid UTF-8");
-                let stdout = stdout.trim();
-                builder.verbose(&format!("`cargo miri setup --env` returned: {:?}", stdout));
-                let sysroot = stdout.splitn(2, '=')
-                    .nth(1).expect("`cargo miri setup` stdout did not contain '='");
+                let sysroot = stdout.trim_end();
+                builder.verbose(&format!("`cargo miri setup --print-sysroot` said: {:?}", sysroot));
                 sysroot.to_owned()
             };
 
@@ -1047,10 +1052,11 @@
         // Also provide `rust_test_helpers` for the host.
         builder.ensure(native::TestHelpers { target: compiler.host });
 
-        // wasm32 can't build the test helpers
-        if !target.contains("wasm32") {
+        // As well as the target, except for plain wasm32, which can't build it
+        if !target.contains("wasm32") || target.contains("emscripten") {
             builder.ensure(native::TestHelpers { target });
         }
+
         builder.ensure(RemoteCopyLibs { compiler, target });
 
         let mut cmd = builder.tool_cmd(Tool::Compiletest);
@@ -1164,7 +1170,7 @@
                     }).to_string()
             })
         };
-        let lldb_exe = if builder.config.lldb_enabled && !target.contains("emscripten") {
+        let lldb_exe = if builder.config.lldb_enabled {
             // Test against the lldb that was just built.
             builder.llvm_out(target).join("bin").join("lldb")
         } else {
@@ -1233,7 +1239,6 @@
         if builder.config.llvm_enabled() {
             let llvm_config = builder.ensure(native::Llvm {
                 target: builder.config.build,
-                emscripten: false,
             });
             if !builder.config.dry_run {
                 let llvm_version = output(Command::new(&llvm_config).arg("--version"));
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index f1baeaf..8154980 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -244,6 +244,7 @@
             path.ends_with("rls") ||
             path.ends_with("clippy") ||
             path.ends_with("miri") ||
+            path.ends_with("rustbook") ||
             path.ends_with("rustfmt")
         {
             cargo.env("LIBZ_SYS_STATIC", "1");
diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs
index f035a71..bb94fb2 100644
--- a/src/build_helper/lib.rs
+++ b/src/build_helper/lib.rs
@@ -21,6 +21,13 @@
             Err(e) => panic!("{} failed with {}", stringify!($e), e),
         }
     };
+    // it can show extra info in the second parameter
+    ($e:expr, $extra:expr) => {
+        match $e {
+            Ok(e) => e,
+            Err(e) => panic!("{} failed with {} ({:?})", stringify!($e), e, $extra),
+        }
+    };
 }
 
 // Because Cargo adds the compiler's dylib path to our library search path, llvm-config may
diff --git a/src/ci/azure-pipelines/auto.yml b/src/ci/azure-pipelines/auto.yml
index e81b7ef..271c325 100644
--- a/src/ci/azure-pipelines/auto.yml
+++ b/src/ci/azure-pipelines/auto.yml
@@ -130,6 +130,8 @@
         IMAGE: i686-gnu-nopt
       test-various:
         IMAGE: test-various
+      wasm32:
+        IMAGE: wasm32
       x86_64-gnu:
         IMAGE: x86_64-gnu
       x86_64-gnu-full-bootstrap:
@@ -138,6 +140,7 @@
         IMAGE: x86_64-gnu-aux
       x86_64-gnu-tools:
         IMAGE: x86_64-gnu-tools
+        DEPLOY_TOOLSTATES_JSON: toolstates-linux.json
       x86_64-gnu-debug:
         IMAGE: x86_64-gnu-debug
       x86_64-gnu-nopt:
@@ -260,8 +263,9 @@
       # MSVC tools tests
       x86_64-msvc-tools:
         MSYS_BITS: 64
-        SCRIPT: src/ci/docker/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstates.json windows
-        RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstates.json
+        SCRIPT: src/ci/docker/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstate/toolstates.json windows
+        RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstate/toolstates.json
+        DEPLOY_TOOLSTATES_JSON: toolstates-windows.json
 
       # 32/64-bit MinGW builds.
       #
@@ -313,6 +317,7 @@
 
       # 32/64 bit MSVC and GNU deployment
       dist-x86_64-msvc:
+        MSYS_BITS: 64
         RUST_CONFIGURE_ARGS: >
           --build=x86_64-pc-windows-msvc
           --target=x86_64-pc-windows-msvc,aarch64-pc-windows-msvc
@@ -322,6 +327,7 @@
         DIST_REQUIRE_ALL_TOOLS: 1
         DEPLOY: 1
       dist-i686-msvc:
+        MSYS_BITS: 32
         RUST_CONFIGURE_ARGS: >
           --build=i686-pc-windows-msvc
           --target=i586-pc-windows-msvc
diff --git a/src/ci/azure-pipelines/pr.yml b/src/ci/azure-pipelines/pr.yml
index 62e23ef..566e654 100644
--- a/src/ci/azure-pipelines/pr.yml
+++ b/src/ci/azure-pipelines/pr.yml
@@ -22,14 +22,6 @@
         IMAGE: x86_64-gnu-llvm-6.0
       mingw-check:
         IMAGE: mingw-check
-
-- job: LinuxTools
-  timeoutInMinutes: 600
-  pool:
-    vmImage: ubuntu-16.04
-  steps:
-    - template: steps/run.yml
-      parameters:
-        only_on_updated_submodules: 'yes'
-  variables:
-    IMAGE: x86_64-gnu-tools
+      x86_64-gnu-tools:
+        IMAGE: x86_64-gnu-tools
+        CI_ONLY_WHEN_SUBMODULES_CHANGED: 1
diff --git a/src/ci/azure-pipelines/steps/install-clang.yml b/src/ci/azure-pipelines/steps/install-clang.yml
deleted file mode 100644
index 14daf81..0000000
--- a/src/ci/azure-pipelines/steps/install-clang.yml
+++ /dev/null
@@ -1,46 +0,0 @@
-steps:
-
-- bash: |
-    set -e
-    curl -f http://releases.llvm.org/7.0.0/clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz | tar xJf -
-
-    export CC=`pwd`/clang+llvm-7.0.0-x86_64-apple-darwin/bin/clang
-    echo "##vso[task.setvariable variable=CC]$CC"
-
-    export CXX=`pwd`/clang+llvm-7.0.0-x86_64-apple-darwin/bin/clang++
-    echo "##vso[task.setvariable variable=CXX]$CXX"
-
-    # Configure `AR` specifically so rustbuild doesn't try to infer it as
-    # `clang-ar` by accident.
-    echo "##vso[task.setvariable variable=AR]ar"
-  displayName: Install clang (OSX)
-  condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin'))
-
-# If we're compiling for MSVC then we, like most other distribution builders,
-# switch to clang as the compiler. This'll allow us eventually to enable LTO
-# amongst LLVM and rustc. Note that we only do this on MSVC as I don't think
-# clang has an output mode compatible with MinGW that we need. If it does we
-# should switch to clang for MinGW as well!
-#
-# Note that the LLVM installer is an NSIS installer
-#
-# Original downloaded here came from
-# http://releases.llvm.org/7.0.0/LLVM-7.0.0-win64.exe
-# That installer was run through `wine` on Linux and then the resulting
-# installation directory (found in `$HOME/.wine/drive_c/Program Files/LLVM`) was
-# packaged up into a tarball. We've had issues otherwise that the installer will
-# randomly hang, provide not a lot of useful information, pollute global state,
-# etc. In general the tarball is just more confined and easier to deal with when
-# working with various CI environments.
-- bash: |
-    set -e
-    mkdir -p citools
-    cd citools
-    curl -f https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/LLVM-7.0.0-win64.tar.gz | tar xzf -
-    echo "##vso[task.setvariable variable=RUST_CONFIGURE_ARGS]$RUST_CONFIGURE_ARGS --set llvm.clang-cl=`pwd`/clang-rust/bin/clang-cl.exe"
-  condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), eq(variables['MINGW_URL'],''))
-  displayName: Install clang (Windows)
-
-# Note that we don't install clang on Linux since its compiler story is just so
-# different. Each container has its own toolchain configured appropriately
-# already.
diff --git a/src/ci/azure-pipelines/steps/install-sccache.yml b/src/ci/azure-pipelines/steps/install-sccache.yml
deleted file mode 100644
index d4679c1..0000000
--- a/src/ci/azure-pipelines/steps/install-sccache.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-steps:
-
-- bash: |
-    set -e
-    curl -fo /usr/local/bin/sccache https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2018-04-02-sccache-x86_64-apple-darwin
-    chmod +x /usr/local/bin/sccache
-  displayName: Install sccache (OSX)
-  condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin'))
-
-- script: |
-    md sccache
-    powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf sccache\sccache.exe https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2018-04-26-sccache-x86_64-pc-windows-msvc"
-    echo ##vso[task.prependpath]%CD%\sccache
-  displayName: Install sccache (Windows)
-  condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
-
-# Note that we don't install sccache on Linux since it's installed elsewhere
-# through all the containers.
-#
-# FIXME: we should probably install sccache outside the containers and then
-# mount it inside the containers so we can centralize all installation here.
diff --git a/src/ci/azure-pipelines/steps/install-windows-build-deps.yml b/src/ci/azure-pipelines/steps/install-windows-build-deps.yml
deleted file mode 100644
index bd4f1ed..0000000
--- a/src/ci/azure-pipelines/steps/install-windows-build-deps.yml
+++ /dev/null
@@ -1,120 +0,0 @@
-steps:
-# We use the WIX toolset to create combined installers for Windows, and these
-# binaries are downloaded from
-# https://github.com/wixtoolset/wix3 originally
-- bash: |
-    set -e
-    curl -O https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/wix311-binaries.zip
-    echo "##vso[task.setvariable variable=WIX]`pwd`/wix"
-    mkdir -p wix/bin
-    cd wix/bin
-    7z x ../../wix311-binaries.zip
-  displayName: Install wix
-  condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
-
-# We use InnoSetup and its `iscc` program to also create combined installers.
-# Honestly at this point WIX above and `iscc` are just holdovers from
-# oh-so-long-ago and are required for creating installers on Windows. I think
-# one is MSI installers and one is EXE, but they're not used so frequently at
-# this point anyway so perhaps it's a wash!
-- script: |
-    echo ##vso[task.prependpath]C:\Program Files (x86)\Inno Setup 5
-    curl.exe -o is-install.exe https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2017-08-22-is.exe
-    is-install.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-
-  displayName: Install InnoSetup
-  condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
-
-# We've had issues with the default drive in use running out of space during a
-# build, and it looks like the `C:` drive has more space than the default `D:`
-# drive. We should probably confirm this with the azure pipelines team at some
-# point, but this seems to fix our "disk space full" problems.
-- script: |
-    mkdir c:\MORE_SPACE
-    mklink /J build c:\MORE_SPACE
-  displayName: "Ensure build happens on C:/ instead of D:/"
-  condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
-
-- bash: git config --replace-all --global core.autocrlf false
-  displayName: "Disable git automatic line ending conversion (on C:/)"
-
-# Download and install MSYS2, needed primarily for the test suite (run-make) but
-# also used by the MinGW toolchain for assembling things.
-#
-# FIXME: we should probe the default azure image and see if we can use the MSYS2
-# toolchain there. (if there's even one there). For now though this gets the job
-# done.
-- bash: |
-    set -e
-    choco install msys2 --params="/InstallDir:$(System.Workfolder)/msys2 /NoPath" -y --no-progress
-    echo "##vso[task.prependpath]$(System.Workfolder)/msys2/usr/bin"
-    mkdir -p "$(System.Workfolder)/msys2/home/$USERNAME"
-  displayName: Install msys2
-  condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
-
-- bash: pacman -S --noconfirm --needed base-devel ca-certificates make diffutils tar
-  displayName: Install msys2 base deps
-  condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
-
-# If we need to download a custom MinGW, do so here and set the path
-# appropriately.
-#
-# Here we also do a pretty heinous thing which is to mangle the MinGW
-# installation we just downloaded. Currently, as of this writing, we're using
-# MinGW-w64 builds of gcc, and that's currently at 6.3.0. We use 6.3.0 as it
-# appears to be the first version which contains a fix for #40546, builds
-# randomly failing during LLVM due to ar.exe/ranlib.exe failures.
-#
-# Unfortunately, though, 6.3.0 *also* is the first version of MinGW-w64 builds
-# to contain a regression in gdb (#40184). As a result if we were to use the
-# gdb provided (7.11.1) then we would fail all debuginfo tests.
-#
-# In order to fix spurious failures (pretty high priority) we use 6.3.0. To
-# avoid disabling gdb tests we download an *old* version of gdb, specifically
-# that found inside the 6.2.0 distribution. We then overwrite the 6.3.0 gdb
-# with the 6.2.0 gdb to get tests passing.
-#
-# Note that we don't literally overwrite the gdb.exe binary because it appears
-# to just use gdborig.exe, so that's the binary we deal with instead.
-- bash: |
-    set -e
-    curl -o mingw.7z $MINGW_URL/$MINGW_ARCHIVE
-    7z x -y mingw.7z > /dev/null
-    curl -o $MINGW_DIR/bin/gdborig.exe $MINGW_URL/2017-04-20-${MSYS_BITS}bit-gdborig.exe
-    echo "##vso[task.prependpath]`pwd`/$MINGW_DIR/bin"
-  condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), ne(variables['MINGW_URL'],''))
-  displayName: Download custom MinGW
-
-# Otherwise install MinGW through `pacman`
-- bash: |
-    set -e
-    arch=i686
-    if [ "$MSYS_BITS" = "64" ]; then
-      arch=x86_64
-    fi
-    pacman -S --noconfirm --needed mingw-w64-$arch-toolchain mingw-w64-$arch-cmake mingw-w64-$arch-gcc mingw-w64-$arch-python2
-    echo "##vso[task.prependpath]$(System.Workfolder)/msys2/mingw$MSYS_BITS/bin"
-  condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), eq(variables['MINGW_URL'],''))
-  displayName: Download standard MinGW
-
-# Make sure we use the native python interpreter instead of some msys equivalent
-# one way or another. The msys interpreters seem to have weird path conversions
-# baked in which break LLVM's build system one way or another, so let's use the
-# native version which keeps everything as native as possible.
-- bash: |
-    set -e
-    cp C:/Python27amd64/python.exe C:/Python27amd64/python2.7.exe
-    echo "##vso[task.prependpath]C:/Python27amd64"
-  displayName: Prefer the "native" Python as LLVM has trouble building with MSYS sometimes
-  condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
-
-# Note that this is originally from the github releases patch of Ninja
-- bash: |
-    set -e
-    mkdir ninja
-    curl -o ninja.zip https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2017-03-15-ninja-win.zip
-    7z x -oninja ninja.zip
-    rm ninja.zip
-    echo "##vso[task.setvariable variable=RUST_CONFIGURE_ARGS]$RUST_CONFIGURE_ARGS --enable-ninja"
-    echo "##vso[task.prependpath]`pwd`/ninja"
-  displayName: Download and install ninja
-  condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
diff --git a/src/ci/azure-pipelines/steps/run.yml b/src/ci/azure-pipelines/steps/run.yml
index 15a2499..cef2d23 100644
--- a/src/ci/azure-pipelines/steps/run.yml
+++ b/src/ci/azure-pipelines/steps/run.yml
@@ -6,11 +6,6 @@
 #
 # Check travis config for `gdb --batch` command to print all crash logs
 
-parameters:
-  # When this parameter is set to anything other than an empty string the tests
-  # will only be executed when the commit updates submodules
-  only_on_updated_submodules: ''
-
 steps:
 
 # Disable automatic line ending conversion, which is enabled by default on
@@ -26,21 +21,8 @@
 - checkout: self
   fetchDepth: 2
 
-# Set the SKIP_JOB environment variable if this job is supposed to only run
-# when submodules are updated and they were not. The following time consuming
-# tasks will be skipped when the environment variable is present.
-- ${{ if parameters.only_on_updated_submodules }}:
-  - bash: |
-      set -e
-      # Submodules pseudo-files inside git have the 160000 permissions, so when
-      # those files are present in the diff a submodule was updated.
-      if git diff HEAD^ | grep "^index .* 160000" >/dev/null 2>&1; then
-          echo "Executing the job since submodules are updated"
-      else
-          echo "Not executing this job since no submodules were updated"
-          echo "##vso[task.setvariable variable=SKIP_JOB;]1"
-      fi
-    displayName: Decide whether to run this job
+- bash: src/ci/scripts/should-skip-this.sh
+  displayName: Decide whether to run this job
 
 # Spawn a background process to collect CPU usage statistics which we'll upload
 # at the end of the build. See the comments in the script here for more
@@ -48,86 +30,106 @@
 - bash: python src/ci/cpu-usage-over-time.py &> cpu-usage.csv &
   displayName: "Collect CPU-usage statistics in the background"
 
-- bash: printenv | sort
-  displayName: Show environment variables
+- bash: src/ci/scripts/dump-environment.sh
+  displayName: Show the current environment
 
-- bash: |
-    set -e
-    df -h
-    du . | sort -nr | head -n100
-  displayName: Show disk usage
-  # FIXME: this hasn't been tested, but maybe it works on Windows? Should test!
-  condition: and(succeeded(), ne(variables['Agent.OS'], 'Windows_NT'))
+- bash: src/ci/scripts/install-sccache.sh
+  env:
+    AGENT_OS: $(Agent.OS)
+  displayName: Install sccache
+  condition: and(succeeded(), not(variables.SKIP_JOB))
 
-- template: install-sccache.yml
-- template: install-clang.yml
+- bash: src/ci/scripts/install-clang.sh
+  env:
+    AGENT_OS: $(Agent.OS)
+  displayName: Install clang
+  condition: and(succeeded(), not(variables.SKIP_JOB))
 
-# Switch to XCode 9.3 on OSX since it seems to be the last version that supports
-# i686-apple-darwin. We'll eventually want to upgrade this and it will probably
-# force us to drop i686-apple-darwin, but let's keep the wheels turning for now.
-- bash: |
-    set -e
-    sudo xcode-select --switch /Applications/Xcode_9.3.app
-  displayName: Switch to Xcode 9.3 (OSX)
-  condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin'))
+- bash: src/ci/scripts/switch-xcode.sh
+  env:
+    AGENT_OS: $(Agent.OS)
+  displayName: Switch to Xcode 9.3
+  condition: and(succeeded(), not(variables.SKIP_JOB))
 
-- template: install-windows-build-deps.yml
+- bash: src/ci/scripts/install-wix.sh
+  env:
+    AGENT_OS: $(Agent.OS)
+  displayName: Install wix
+  condition: and(succeeded(), not(variables.SKIP_JOB))
 
-# Looks like docker containers have IPv6 disabled by default, so let's turn it
-# on since libstd tests require it
-- bash: |
-    set -e
-    sudo mkdir -p /etc/docker
-    echo '{"ipv6":true,"fixed-cidr-v6":"fd9a:8454:6789:13f7::/64"}' | sudo tee /etc/docker/daemon.json
-    sudo service docker restart
-  displayName: Enable IPv6
-  condition: and(succeeded(), not(variables.SKIP_JOB), eq(variables['Agent.OS'], 'Linux'))
+- bash: src/ci/scripts/install-innosetup.sh
+  env:
+    AGENT_OS: $(Agent.OS)
+  displayName: Install InnoSetup
+  condition: and(succeeded(), not(variables.SKIP_JOB))
+
+- bash: src/ci/scripts/windows-symlink-build-dir.sh
+  env:
+    AGENT_OS: $(Agent.OS)
+  displayName: Ensure the build happens on C:\ instead of D:\
+  condition: and(succeeded(), not(variables.SKIP_JOB))
+
+- bash: src/ci/scripts/disable-git-crlf-conversion.sh
+  displayName: "Disable git automatic line ending conversion (on C:/)"
+  condition: and(succeeded(), not(variables.SKIP_JOB))
+
+- bash: src/ci/scripts/install-msys2.sh
+  env:
+    AGENT_OS: $(Agent.OS)
+    SYSTEM_WORKFOLDER: $(System.Workfolder)
+  displayName: Install msys2
+  condition: and(succeeded(), not(variables.SKIP_JOB))
+
+- bash: src/ci/scripts/install-msys2-packages.sh
+  env:
+    AGENT_OS: $(Agent.OS)
+    SYSTEM_WORKFOLDER: $(System.Workfolder)
+  displayName: Install msys2 packages
+  condition: and(succeeded(), not(variables.SKIP_JOB))
+
+- bash: src/ci/scripts/install-mingw.sh
+  env:
+    AGENT_OS: $(Agent.OS)
+    SYSTEM_WORKFOLDER: $(System.Workfolder)
+  displayName: Install MinGW
+  condition: and(succeeded(), not(variables.SKIP_JOB))
+
+- bash: src/ci/scripts/install-ninja.sh
+  env:
+    AGENT_OS: $(Agent.OS)
+  displayName: Install ninja
+  condition: and(succeeded(), not(variables.SKIP_JOB))
+
+- bash: src/ci/scripts/enable-docker-ipv6.sh
+  env:
+    AGENT_OS: $(Agent.OS)
+  displayName: Enable IPv6 on Docker
+  condition: and(succeeded(), not(variables.SKIP_JOB))
 
 # Disable automatic line ending conversion (again). On Windows, when we're
 # installing dependencies, something switches the git configuration directory or
 # re-enables autocrlf. We've not tracked down the exact cause -- and there may
 # be multiple -- but this should ensure submodules are checked out with the
 # appropriate line endings.
-- bash: git config --replace-all --global core.autocrlf false
-  displayName: "Disable git automatic line ending conversion"
+- bash: src/ci/scripts/disable-git-crlf-conversion.sh
+  displayName: Disable git automatic line ending conversion
+  condition: and(succeeded(), not(variables.SKIP_JOB))
 
-# Check out all our submodules, but more quickly than using git by using one of
-# our custom scripts
-- bash: |
-    set -e
-    mkdir -p $HOME/rustsrc
-    $BUILD_SOURCESDIRECTORY/src/ci/init_repo.sh . $HOME/rustsrc
-  condition: and(succeeded(), not(variables.SKIP_JOB), ne(variables['Agent.OS'], 'Windows_NT'))
-  displayName: Check out submodules (Unix)
-- script: |
-    if not exist C:\cache\rustsrc\NUL mkdir C:\cache\rustsrc
-    sh src/ci/init_repo.sh . /c/cache/rustsrc
-  condition: and(succeeded(), not(variables.SKIP_JOB), eq(variables['Agent.OS'], 'Windows_NT'))
-  displayName: Check out submodules (Windows)
+- bash: src/ci/scripts/checkout-submodules.sh
+  env:
+    AGENT_OS: $(Agent.OS)
+  displayName: Checkout submodules
+  condition: and(succeeded(), not(variables.SKIP_JOB))
 
-# See also the disable for autocrlf above, this just checks that it worked
-#
-# We check both in rust-lang/rust and in a submodule to make sure both are
-# accurate. Submodules are checked out significantly later than the main
-# repository in this script, so settings can (and do!) change between then.
-#
-# Linux (and maybe macOS) builders don't currently have dos2unix so just only
-# run this step on Windows.
-- bash: |
-    set -x
-    # print out the git configuration so we can better investigate failures in
-    # the following
-    git config --list --show-origin
-    dos2unix -ih Cargo.lock src/tools/rust-installer/install-template.sh
-    endings=$(dos2unix -ic Cargo.lock src/tools/rust-installer/install-template.sh)
-    # if endings has non-zero length, error out
-    if [ -n "$endings" ]; then exit 1 ; fi
-  condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
-  displayName: Verify line endings are LF
+- bash: src/ci/scripts/verify-line-endings.sh
+  env:
+    AGENT_OS: $(Agent.OS)
+  displayName: Verify line endings
+  condition: and(succeeded(), not(variables.SKIP_JOB))
 
 # Ensure the `aws` CLI is installed so we can deploy later on, cache docker
 # images, etc.
-- bash: src/ci/install-awscli.sh
+- bash: src/ci/scripts/install-awscli.sh
   env:
     AGENT_OS: $(Agent.OS)
   condition: and(succeeded(), not(variables.SKIP_JOB))
@@ -181,37 +183,21 @@
   condition: and(succeeded(), not(variables.SKIP_JOB))
   displayName: Run build
 
-# If we're a deploy builder, use the `aws` command to publish everything to our
-# bucket.
-- bash: |
-    set -e
-    source src/ci/shared.sh
-    if [ "$AGENT_OS" = "Linux" ]; then
-        rm -rf obj/build/dist/doc
-        upload_dir=obj/build/dist
-    else
-        rm -rf build/dist/doc
-        upload_dir=build/dist
-    fi
-    ls -la $upload_dir
-    deploy_dir=rustc-builds
-    if [ "$DEPLOY_ALT" == "1" ]; then
-        deploy_dir=rustc-builds-alt
-    fi
-    retry aws s3 cp --no-progress --recursive --acl public-read ./$upload_dir s3://$DEPLOY_BUCKET/$deploy_dir/$BUILD_SOURCEVERSION
+- bash: src/ci/scripts/upload-artifacts.sh
   env:
     AWS_ACCESS_KEY_ID: $(UPLOAD_AWS_ACCESS_KEY_ID)
     AWS_SECRET_ACCESS_KEY: $(UPLOAD_AWS_SECRET_ACCESS_KEY)
-  condition: and(succeeded(), not(variables.SKIP_JOB), or(eq(variables.DEPLOY, '1'), eq(variables.DEPLOY_ALT, '1')))
   displayName: Upload artifacts
-
-# Upload CPU usage statistics that we've been gathering this whole time. Always
-# execute this step in case we want to inspect failed builds, but don't let
-# errors here ever fail the build since this is just informational.
-- bash: aws s3 cp --acl public-read cpu-usage.csv s3://$DEPLOY_BUCKET/rustc-builds/$BUILD_SOURCEVERSION/cpu-$CI_JOB_NAME.csv
-  env:
-    AWS_ACCESS_KEY_ID: $(UPLOAD_AWS_ACCESS_KEY_ID)
-    AWS_SECRET_ACCESS_KEY: $(UPLOAD_AWS_SECRET_ACCESS_KEY)
-  condition: variables['UPLOAD_AWS_SECRET_ACCESS_KEY']
-  continueOnError: true
-  displayName: Upload CPU usage statistics
+  # Adding a condition on DEPLOY=1 or DEPLOY_ALT=1 is not needed as all deploy
+  # builders *should* have the AWS credentials available. Still, explicitly
+  # adding the condition is helpful as this way CI will not silently skip
+  # deploying artifacts from a dist builder if the variables are misconfigured,
+  # erroring about invalid credentials instead.
+  condition: |
+    and(
+      succeeded(), not(variables.SKIP_JOB),
+      or(
+        variables.UPLOAD_AWS_SECRET_ACCESS_KEY,
+        eq(variables.DEPLOY, '1'), eq(variables.DEPLOY_ALT, '1')
+      )
+    )
diff --git a/src/ci/docker/asmjs/Dockerfile b/src/ci/docker/asmjs/Dockerfile
deleted file mode 100644
index 3abaab6..0000000
--- a/src/ci/docker/asmjs/Dockerfile
+++ /dev/null
@@ -1,47 +0,0 @@
-FROM ubuntu:16.04
-
-RUN apt-get update && apt-get install -y --no-install-recommends \
-  g++ \
-  make \
-  file \
-  curl \
-  ca-certificates \
-  python \
-  git \
-  cmake \
-  sudo \
-  gdb \
-  xz-utils
-
-COPY scripts/emscripten.sh /scripts/
-RUN bash /scripts/emscripten.sh
-
-COPY scripts/sccache.sh /scripts/
-RUN sh /scripts/sccache.sh
-
-ENV PATH=$PATH:/emsdk-portable
-ENV PATH=$PATH:/emsdk-portable/clang/e1.38.15_64bit/
-ENV PATH=$PATH:/emsdk-portable/emscripten/1.38.15/
-ENV PATH=$PATH:/emsdk-portable/node/8.9.1_64bit/bin/
-ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.38.15/
-ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.38.15_64bit/binaryen/
-ENV EM_CONFIG=/emsdk-portable/.emscripten
-
-ENV TARGETS=asmjs-unknown-emscripten
-
-ENV RUST_CONFIGURE_ARGS --enable-emscripten --disable-optimize-tests
-
-ENV SCRIPT python2.7 ../x.py test --target $TARGETS \
-  src/test/ui \
-  src/test/run-fail \
-  src/libstd \
-  src/liballoc \
-  src/libcore
-
-# Debug assertions in rustc are largely covered by other builders, and LLVM
-# assertions cause this builder to slow down by quite a large amount and don't
-# buy us a huge amount over other builders (not sure if we've ever seen an
-# asmjs-specific backend assertion trip), so disable assertions for these
-# tests.
-ENV NO_LLVM_ASSERTIONS=1
-ENV NO_DEBUG_ASSERTIONS=1
diff --git a/src/ci/docker/disabled/asmjs/Dockerfile b/src/ci/docker/disabled/asmjs/Dockerfile
new file mode 100644
index 0000000..e27a2a5
--- /dev/null
+++ b/src/ci/docker/disabled/asmjs/Dockerfile
@@ -0,0 +1,41 @@
+FROM ubuntu:16.04
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+  g++ \
+  make \
+  file \
+  curl \
+  ca-certificates \
+  python \
+  git \
+  cmake \
+  sudo \
+  gdb \
+  xz-utils \
+  bzip2
+
+COPY scripts/emscripten.sh /scripts/
+RUN bash /scripts/emscripten.sh
+
+COPY scripts/sccache.sh /scripts/
+RUN sh /scripts/sccache.sh
+
+ENV PATH=$PATH:/emsdk-portable
+ENV PATH=$PATH:/emsdk-portable/upstream/emscripten/
+ENV PATH=$PATH:/emsdk-portable/node/12.9.1_64bit/bin/
+ENV BINARYEN_ROOT=/emsdk-portable/upstream/
+
+ENV TARGETS=asmjs-unknown-emscripten
+
+# Use -O1 optimizations in the link step to reduce time spent optimizing JS.
+ENV EMCC_CFLAGS=-O1
+
+# Emscripten installation is user-specific
+ENV NO_CHANGE_USER=1
+
+ENV SCRIPT python2.7 ../x.py test --target $TARGETS
+
+# This is almost identical to the wasm32-unknown-emscripten target, so
+# running with assertions again is not useful
+ENV NO_DEBUG_ASSERTIONS=1
+ENV NO_LLVM_ASSERTIONS=1
diff --git a/src/ci/docker/disabled/wasm32-exp/Dockerfile b/src/ci/docker/disabled/wasm32-exp/Dockerfile
deleted file mode 100644
index 420d47b..0000000
--- a/src/ci/docker/disabled/wasm32-exp/Dockerfile
+++ /dev/null
@@ -1,35 +0,0 @@
-FROM ubuntu:16.04
-
-RUN apt-get update && apt-get install -y --no-install-recommends \
-  g++ \
-  make \
-  file \
-  curl \
-  ca-certificates \
-  python \
-  git \
-  cmake \
-  sudo \
-  gdb \
-  xz-utils \
-  jq \
-  bzip2
-
-# emscripten
-COPY scripts/emscripten-wasm.sh /scripts/
-COPY wasm32-exp/node.sh /usr/local/bin/node
-RUN bash /scripts/emscripten-wasm.sh
-
-# cache
-COPY scripts/sccache.sh /scripts/
-RUN sh /scripts/sccache.sh
-
-# env
-ENV PATH=/wasm-install/emscripten:/wasm-install/bin:$PATH
-ENV EM_CONFIG=/root/.emscripten
-
-ENV TARGETS=wasm32-experimental-emscripten
-
-ENV RUST_CONFIGURE_ARGS --experimental-targets=WebAssembly
-
-ENV SCRIPT python2.7 ../x.py test --target $TARGETS
diff --git a/src/ci/docker/disabled/wasm32-exp/node.sh b/src/ci/docker/disabled/wasm32-exp/node.sh
deleted file mode 100755
index aa93897..0000000
--- a/src/ci/docker/disabled/wasm32-exp/node.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/env bash
-
-path="$(dirname $1)"
-file="$(basename $1)"
-
-shift
-
-cd "$path"
-exec /node-v8.0.0-linux-x64/bin/node "$file" "$@"
diff --git a/src/ci/docker/disabled/wasm32/Dockerfile b/src/ci/docker/disabled/wasm32/Dockerfile
deleted file mode 100644
index 0d2bd39..0000000
--- a/src/ci/docker/disabled/wasm32/Dockerfile
+++ /dev/null
@@ -1,32 +0,0 @@
-FROM ubuntu:16.04
-
-RUN apt-get update && apt-get install -y --no-install-recommends \
-  g++ \
-  make \
-  file \
-  curl \
-  ca-certificates \
-  python \
-  git \
-  cmake \
-  sudo \
-  gdb \
-  xz-utils
-
-# emscripten
-COPY scripts/emscripten.sh /scripts/
-RUN bash /scripts/emscripten.sh
-
-COPY scripts/sccache.sh /scripts/
-RUN sh /scripts/sccache.sh
-
-ENV PATH=$PATH:/emsdk-portable
-ENV PATH=$PATH:/emsdk-portable/clang/e1.38.15_64bit/
-ENV PATH=$PATH:/emsdk-portable/emscripten/1.38.15/
-ENV PATH=$PATH:/emsdk-portable/node/8.9.1_64bit/bin/
-ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.38.15/
-ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.38.15_64bit/binaryen/
-ENV EM_CONFIG=/emsdk-portable/.emscripten
-
-ENV TARGETS=wasm32-unknown-emscripten
-ENV SCRIPT python2.7 ../x.py test --target $TARGETS
diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile
index 1057911..816bdb3 100644
--- a/src/ci/docker/dist-various-1/Dockerfile
+++ b/src/ci/docker/dist-various-1/Dockerfile
@@ -15,6 +15,8 @@
   g++-arm-linux-gnueabi \
   g++-arm-linux-gnueabihf \
   g++-aarch64-linux-gnu \
+  g++-mips64-linux-gnuabi64 \
+  g++-mips64el-linux-gnuabi64 \
   gcc-sparc64-linux-gnu \
   libc6-dev-sparc64-cross \
   bzip2 \
@@ -77,6 +79,14 @@
     CC=mipsel-openwrt-linux-gcc \
     CXX=mipsel-openwrt-linux-g++ \
     bash musl.sh mipsel && \
+    env \
+    CC=mips64-linux-gnuabi64-gcc \
+    CXX=mips64-linux-gnuabi64-g++ \
+    bash musl.sh mips64 && \
+    env \
+    CC=mips64el-linux-gnuabi64-gcc \
+    CXX=mips64el-linux-gnuabi64-g++ \
+    bash musl.sh mips64el && \
     rm -rf /build/*
 
 # FIXME(mozilla/sccache#235) this shouldn't be necessary but is currently
@@ -97,6 +107,8 @@
 ENV TARGETS=$TARGETS,x86_64-rumprun-netbsd
 ENV TARGETS=$TARGETS,mips-unknown-linux-musl
 ENV TARGETS=$TARGETS,mipsel-unknown-linux-musl
+ENV TARGETS=$TARGETS,mips64-unknown-linux-muslabi64
+ENV TARGETS=$TARGETS,mips64el-unknown-linux-muslabi64
 ENV TARGETS=$TARGETS,arm-unknown-linux-musleabi
 ENV TARGETS=$TARGETS,arm-unknown-linux-musleabihf
 ENV TARGETS=$TARGETS,armv5te-unknown-linux-gnueabi
@@ -125,6 +137,8 @@
 
 ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \
     CC_mips_unknown_linux_musl=mips-openwrt-linux-gcc \
+    CC_mips64el_unknown_linux_muslabi64=mips64el-linux-gnuabi64-gcc \
+    CC_mips64_unknown_linux_muslabi64=mips64-linux-gnuabi64-gcc \
     CC_sparc64_unknown_linux_gnu=sparc64-linux-gnu-gcc \
     CC_x86_64_unknown_redox=x86_64-unknown-redox-gcc \
     CC_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc \
@@ -139,7 +153,8 @@
       --musl-root-aarch64=/musl-aarch64 \
       --musl-root-mips=/musl-mips \
       --musl-root-mipsel=/musl-mipsel \
-      --enable-emscripten \
+      --musl-root-mips64=/musl-mips64 \
+      --musl-root-mips64el=/musl-mips64el \
       --disable-docs
 
 ENV SCRIPT \
diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh
index 415d6b6..cdafcba 100755
--- a/src/ci/docker/run.sh
+++ b/src/ci/docker/run.sh
@@ -106,6 +106,7 @@
 mkdir -p $HOME/.cargo
 mkdir -p $objdir/tmp
 mkdir -p $objdir/cores
+mkdir -p /tmp/toolstate
 
 args=
 if [ "$SCCACHE_BUCKET" != "" ]; then
@@ -156,6 +157,7 @@
   args="$args --volume $objdir:/checkout/obj"
   args="$args --volume $HOME/.cargo:/cargo"
   args="$args --volume $HOME/rustsrc:$HOME/rustsrc"
+  args="$args --volume /tmp/toolstate:/tmp/toolstate"
   args="$args --env LOCAL_USER_ID=`id -u`"
 fi
 
diff --git a/src/ci/docker/scripts/emscripten-wasm.sh b/src/ci/docker/scripts/emscripten-wasm.sh
deleted file mode 100644
index e4a93d7..0000000
--- a/src/ci/docker/scripts/emscripten-wasm.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-set -ex
-
-hide_output() {
-  set +x
-  on_err="
-echo ERROR: An error was encountered with the build.
-cat /tmp/build.log
-exit 1
-"
-  trap "$on_err" ERR
-  bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
-  PING_LOOP_PID=$!
-  $@ &> /tmp/build.log
-  trap - ERR
-  kill $PING_LOOP_PID
-  rm -f /tmp/build.log
-  set -x
-}
-
-# Download last known good emscripten from WebAssembly waterfall
-BUILD=$(curl -fL https://storage.googleapis.com/wasm-llvm/builds/linux/lkgr.json | \
-    jq '.build | tonumber')
-curl -sL https://storage.googleapis.com/wasm-llvm/builds/linux/$BUILD/wasm-binaries.tbz2 | \
-    hide_output tar xvkj
-
-# node 8 is required to run wasm
-cd /
-curl -sL https://nodejs.org/dist/v8.0.0/node-v8.0.0-linux-x64.tar.xz | \
-    tar -xJ
-
-# Make emscripten use wasm-ready node and LLVM tools
-echo "EMSCRIPTEN_ROOT = '/wasm-install/emscripten'" >> /root/.emscripten
-echo "NODE_JS='/usr/local/bin/node'" >> /root/.emscripten
-echo "LLVM_ROOT='/wasm-install/bin'" >> /root/.emscripten
-echo "BINARYEN_ROOT = '/wasm-install'" >> /root/.emscripten
-echo "COMPILER_ENGINE = NODE_JS" >> /root/.emscripten
-echo "JS_ENGINES = [NODE_JS]" >> /root/.emscripten
diff --git a/src/ci/docker/scripts/emscripten.sh b/src/ci/docker/scripts/emscripten.sh
index 47196e8..1be8074 100644
--- a/src/ci/docker/scripts/emscripten.sh
+++ b/src/ci/docker/scripts/emscripten.sh
@@ -17,22 +17,7 @@
   set -x
 }
 
-cd /
-curl -fL https://mozilla-games.s3.amazonaws.com/emscripten/releases/emsdk-portable.tar.gz | \
-    tar -xz
-
+git clone https://github.com/emscripten-core/emsdk.git /emsdk-portable
 cd /emsdk-portable
-./emsdk update
-hide_output ./emsdk install sdk-1.38.15-64bit
-./emsdk activate sdk-1.38.15-64bit
-
-# Compile and cache libc
-source ./emsdk_env.sh
-echo "main(){}" > a.c
-HOME=/emsdk-portable/ emcc a.c
-HOME=/emsdk-portable/ emcc -s BINARYEN=1 a.c
-rm -f a.*
-
-# Make emsdk usable by any user
-cp /root/.emscripten /emsdk-portable
-chmod a+rxw -R /emsdk-portable
+hide_output ./emsdk install 1.38.46-upstream
+./emsdk activate 1.38.46-upstream
diff --git a/src/ci/docker/wasm32/Dockerfile b/src/ci/docker/wasm32/Dockerfile
new file mode 100644
index 0000000..a0f35af
--- /dev/null
+++ b/src/ci/docker/wasm32/Dockerfile
@@ -0,0 +1,44 @@
+FROM ubuntu:16.04
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+  g++ \
+  make \
+  file \
+  curl \
+  ca-certificates \
+  python \
+  git \
+  cmake \
+  sudo \
+  gdb \
+  xz-utils \
+  bzip2
+
+COPY scripts/emscripten.sh /scripts/
+RUN bash /scripts/emscripten.sh
+
+COPY scripts/sccache.sh /scripts/
+RUN sh /scripts/sccache.sh
+
+ENV PATH=$PATH:/emsdk-portable
+ENV PATH=$PATH:/emsdk-portable/upstream/emscripten/
+ENV PATH=$PATH:/emsdk-portable/node/12.9.1_64bit/bin/
+ENV BINARYEN_ROOT=/emsdk-portable/upstream/
+
+ENV TARGETS=wasm32-unknown-emscripten
+
+# Use -O1 optimizations in the link step to reduce time spent optimizing.
+ENV EMCC_CFLAGS=-O1
+
+# Emscripten installation is user-specific
+ENV NO_CHANGE_USER=1
+
+# FIXME: Re-enable these tests once https://github.com/rust-lang/cargo/pull/7476
+# is picked up by CI
+ENV SCRIPT python2.7 ../x.py test --target $TARGETS \
+    --exclude src/libcore \
+    --exclude src/liballoc \
+    --exclude src/libproc_macro \
+    --exclude src/libstd \
+    --exclude src/libterm \
+    --exclude src/libtest
diff --git a/src/ci/docker/x86_64-gnu-tools/Dockerfile b/src/ci/docker/x86_64-gnu-tools/Dockerfile
index 8035195..7687a6c 100644
--- a/src/ci/docker/x86_64-gnu-tools/Dockerfile
+++ b/src/ci/docker/x86_64-gnu-tools/Dockerfile
@@ -26,5 +26,5 @@
 
 ENV RUST_CONFIGURE_ARGS \
   --build=x86_64-unknown-linux-gnu \
-  --save-toolstates=/tmp/toolstates.json
-ENV SCRIPT /tmp/checktools.sh ../x.py /tmp/toolstates.json linux
+  --save-toolstates=/tmp/toolstate/toolstates.json
+ENV SCRIPT /tmp/checktools.sh ../x.py /tmp/toolstate/toolstates.json linux
diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh
index 4243eff..ebb8c0b 100755
--- a/src/ci/docker/x86_64-gnu-tools/checktools.sh
+++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh
@@ -3,7 +3,7 @@
 set -eu
 
 X_PY="$1"
-TOOLSTATE_FILE="$(realpath $2)"
+TOOLSTATE_FILE="$(realpath -m $2)"
 OS="$3"
 COMMIT="$(git rev-parse HEAD)"
 CHANGED_FILES="$(git diff --name-status HEAD HEAD^)"
@@ -13,6 +13,7 @@
 #   The Wednesday after this has value 0.
 #   We track this value to prevent regressing tools in the last week of the 6-week cycle.
 
+mkdir -p "$(dirname $TOOLSTATE_FILE)"
 touch "$TOOLSTATE_FILE"
 
 # Try to test all the tools and store the build/test success in the TOOLSTATE_FILE
diff --git a/src/ci/init_repo.sh b/src/ci/init_repo.sh
index c7c3b0a..92c6e54 100755
--- a/src/ci/init_repo.sh
+++ b/src/ci/init_repo.sh
@@ -47,7 +47,7 @@
     rm $cached
 }
 
-included="src/llvm-project src/llvm-emscripten src/doc/book src/doc/rust-by-example"
+included="src/llvm-project src/doc/book src/doc/rust-by-example"
 modules="$(git config --file .gitmodules --get-regexp '\.path$' | cut -d' ' -f2)"
 modules=($modules)
 use_git=""
diff --git a/src/ci/install-awscli.sh b/src/ci/install-awscli.sh
deleted file mode 100755
index 69c8d2e..0000000
--- a/src/ci/install-awscli.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-# This script downloads and installs awscli from the packages mirrored in our
-# own S3 bucket. This follows the recommendations at:
-#
-#    https://packaging.python.org/guides/index-mirrors-and-caches/#caching-with-pip
-#
-# To create a new mirrored copy you can run the command:
-#
-#    pip wheel awscli
-#
-# Before compressing please make sure all the wheels end with `-none-any.whl`.
-# If that's not the case you'll need to remove the non-cross-platform ones and
-# replace them with the .tar.gz downloaded from https://pypi.org. Also make
-# sure it's possible to call this script with both Python 2 and Python 3.
-
-set -euo pipefail
-IFS=$'\n\t'
-
-MIRROR="https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2019-07-27-awscli.tar"
-DEPS_DIR="/tmp/awscli-deps"
-
-pip="pip"
-pipflags=""
-if [[ "${AGENT_OS}" == "Linux" ]]; then
-    pip="pip3"
-    pipflags="--user"
-
-    sudo apt-get install -y python3-setuptools
-    echo "##vso[task.prependpath]$HOME/.local/bin"
-fi
-
-mkdir -p "${DEPS_DIR}"
-curl "${MIRROR}" | tar xf - -C "${DEPS_DIR}"
-"${pip}" install ${pipflags} --no-index "--find-links=${DEPS_DIR}" awscli
-rm -rf "${DEPS_DIR}"
diff --git a/src/ci/run.sh b/src/ci/run.sh
index c3f8e4c..7c5df63 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -55,6 +55,9 @@
   if [ "$NO_LLVM_ASSERTIONS" = "1" ]; then
     RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-assertions"
   elif [ "$DEPLOY_ALT" != "" ]; then
+    if [ "$NO_PARALLEL_COMPILER" = "" ]; then
+      RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.parallel-compiler"
+    fi
     RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-assertions"
     RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.verify-llvm-ir"
   fi
@@ -114,7 +117,7 @@
 
 # Display the CPU and memory information. This helps us know why the CI timing
 # is fluctuating.
-if isOSX; then
+if isMacOS; then
     system_profiler SPHardwareDataType || true
     sysctl hw || true
     ncpus=$(sysctl -n hw.ncpu)
diff --git a/src/ci/scripts/checkout-submodules.sh b/src/ci/scripts/checkout-submodules.sh
new file mode 100755
index 0000000..0b44ea3
--- /dev/null
+++ b/src/ci/scripts/checkout-submodules.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Check out all our submodules, but more quickly than using git by using one of
+# our custom scripts
+
+set -euo pipefail
+IFS=$'\n\t'
+
+source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
+
+if isWindows; then
+    path="/c/cache/rustsrc"
+else
+    path="${HOME}/rustsrc"
+fi
+
+mkdir -p "${path}"
+"$(cd "$(dirname "$0")" && pwd)/../init_repo.sh" . "${path}"
diff --git a/src/ci/scripts/disable-git-crlf-conversion.sh b/src/ci/scripts/disable-git-crlf-conversion.sh
new file mode 100755
index 0000000..836145f
--- /dev/null
+++ b/src/ci/scripts/disable-git-crlf-conversion.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Disable automatic line ending conversion, which is enabled by default on
+# Azure's Windows image. Having the conversion enabled caused regressions both
+# in our test suite (it broke miri tests) and in the ecosystem, since we
+# started shipping install scripts with CRLF endings instead of the old LF.
+#
+# Note that we do this a couple times during the build as the PATH and current
+# user/directory change, e.g. when mingw is enabled.
+
+set -euo pipefail
+IFS=$'\n\t'
+
+git config --replace-all --global core.autocrlf false
diff --git a/src/ci/scripts/dump-environment.sh b/src/ci/scripts/dump-environment.sh
new file mode 100755
index 0000000..c6774b5
--- /dev/null
+++ b/src/ci/scripts/dump-environment.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# This script dumps information about the build environment to stdout.
+
+set -euo pipefail
+IFS=$'\n\t'
+
+echo "environment variables:"
+printenv | sort
+echo
+
+echo "disk usage:"
+df -h
+echo
+
+echo "biggest files in the working dir:"
+set +o pipefail
+du . | sort -nr | head -n100
+set -o pipefail
+echo
diff --git a/src/ci/scripts/enable-docker-ipv6.sh b/src/ci/scripts/enable-docker-ipv6.sh
new file mode 100755
index 0000000..03d5a75
--- /dev/null
+++ b/src/ci/scripts/enable-docker-ipv6.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+# Looks like docker containers have IPv6 disabled by default, so let's turn it
+# on since libstd tests require it
+
+set -euo pipefail
+IFS=$'\n\t'
+
+source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
+
+if isLinux; then
+    sudo mkdir -p /etc/docker
+    echo '{"ipv6":true,"fixed-cidr-v6":"fd9a:8454:6789:13f7::/64"}' \
+        | sudo tee /etc/docker/daemon.json
+    sudo service docker restart
+fi
diff --git a/src/ci/scripts/install-awscli.sh b/src/ci/scripts/install-awscli.sh
new file mode 100755
index 0000000..e211879
--- /dev/null
+++ b/src/ci/scripts/install-awscli.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# This script downloads and installs awscli from the packages mirrored in our
+# own S3 bucket. This follows the recommendations at:
+#
+#    https://packaging.python.org/guides/index-mirrors-and-caches/#caching-with-pip
+#
+# To create a new mirrored copy you can run the command:
+#
+#    pip wheel awscli
+#
+# Before compressing please make sure all the wheels end with `-none-any.whl`.
+# If that's not the case you'll need to remove the non-cross-platform ones and
+# replace them with the .tar.gz downloaded from https://pypi.org. Also make
+# sure it's possible to call this script with both Python 2 and Python 3.
+
+set -euo pipefail
+IFS=$'\n\t'
+
+source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
+
+MIRROR="${MIRRORS_BASE}/2019-07-27-awscli.tar"
+DEPS_DIR="/tmp/awscli-deps"
+
+pip="pip"
+pipflags=""
+if isLinux; then
+    pip="pip3"
+    pipflags="--user"
+
+    sudo apt-get install -y python3-setuptools
+    echo "##vso[task.prependpath]$HOME/.local/bin"
+fi
+
+mkdir -p "${DEPS_DIR}"
+curl "${MIRROR}" | tar xf - -C "${DEPS_DIR}"
+"${pip}" install ${pipflags} --no-index "--find-links=${DEPS_DIR}" awscli
+rm -rf "${DEPS_DIR}"
diff --git a/src/ci/scripts/install-clang.sh b/src/ci/scripts/install-clang.sh
new file mode 100755
index 0000000..e9b6857
--- /dev/null
+++ b/src/ci/scripts/install-clang.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+# This script installs clang on the local machine. Note that we don't install
+# clang on Linux since its compiler story is just so different. Each container
+# has its own toolchain configured appropriately already.
+
+set -euo pipefail
+IFS=$'\n\t'
+
+source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
+
+if isMacOS; then
+    curl -f "${MIRRORS_BASE}/clang%2Bllvm-7.0.0-x86_64-apple-darwin.tar.xz" | tar xJf -
+
+    ciCommandSetEnv CC "$(pwd)/clang+llvm-7.0.0-x86_64-apple-darwin/bin/clang"
+    ciCommandSetEnv CXX "$(pwd)/clang+llvm-7.0.0-x86_64-apple-darwin/bin/clang++"
+
+    # Configure `AR` specifically so rustbuild doesn't try to infer it as
+    # `clang-ar` by accident.
+    ciCommandSetEnv AR "ar"
+elif isWindows && [[ -z ${MINGW_URL+x} ]]; then
+    # If we're compiling for MSVC then we, like most other distribution builders,
+    # switch to clang as the compiler. This'll allow us eventually to enable LTO
+    # amongst LLVM and rustc. Note that we only do this on MSVC as I don't think
+    # clang has an output mode compatible with MinGW that we need. If it does we
+    # should switch to clang for MinGW as well!
+    #
+    # Note that the LLVM installer is an NSIS installer
+    #
+    # Original downloaded here came from
+    # http://releases.llvm.org/7.0.0/LLVM-7.0.0-win64.exe
+    # That installer was run through `wine` on Linux and then the resulting
+    # installation directory (found in `$HOME/.wine/drive_c/Program Files/LLVM`) was
+    # packaged up into a tarball. We've had issues otherwise that the installer will
+    # randomly hang, provide not a lot of useful information, pollute global state,
+    # etc. In general the tarball is just more confined and easier to deal with when
+    # working with various CI environments.
+
+    mkdir -p citools
+    cd citools
+    curl -f "${MIRRORS_BASE}/LLVM-7.0.0-win64.tar.gz" | tar xzf -
+    ciCommandSetEnv RUST_CONFIGURE_ARGS \
+        "${RUST_CONFIGURE_ARGS} --set llvm.clang-cl=$(pwd)/clang-rust/bin/clang-cl.exe"
+fi
diff --git a/src/ci/scripts/install-innosetup.sh b/src/ci/scripts/install-innosetup.sh
new file mode 100755
index 0000000..04ca249
--- /dev/null
+++ b/src/ci/scripts/install-innosetup.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+# We use InnoSetup and its `iscc` program to also create combined installers.
+# Honestly at this point WIX above and `iscc` are just holdovers from
+# oh-so-long-ago and are required for creating installers on Windows. I think
+# one is MSI installers and one is EXE, but they're not used so frequently at
+# this point anyway so perhaps it's a wash!
+
+set -euo pipefail
+IFS=$'\n\t'
+
+source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
+
+if isWindows; then
+    curl.exe -o is-install.exe "${MIRRORS_BASE}/2017-08-22-is.exe"
+    cmd.exe //c "is-install.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-"
+
+    ciCommandAddPath "C:\\Program Files (x86)\\Inno Setup 5"
+fi
diff --git a/src/ci/scripts/install-mingw.sh b/src/ci/scripts/install-mingw.sh
new file mode 100755
index 0000000..b4e8b88
--- /dev/null
+++ b/src/ci/scripts/install-mingw.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# If we need to download a custom MinGW, do so here and set the path
+# appropriately.
+#
+# Here we also do a pretty heinous thing which is to mangle the MinGW
+# installation we just downloaded. Currently, as of this writing, we're using
+# MinGW-w64 builds of gcc, and that's currently at 6.3.0. We use 6.3.0 as it
+# appears to be the first version which contains a fix for #40546, builds
+# randomly failing during LLVM due to ar.exe/ranlib.exe failures.
+#
+# Unfortunately, though, 6.3.0 *also* is the first version of MinGW-w64 builds
+# to contain a regression in gdb (#40184). As a result if we were to use the
+# gdb provided (7.11.1) then we would fail all debuginfo tests.
+#
+# In order to fix spurious failures (pretty high priority) we use 6.3.0. To
+# avoid disabling gdb tests we download an *old* version of gdb, specifically
+# that found inside the 6.2.0 distribution. We then overwrite the 6.3.0 gdb
+# with the 6.2.0 gdb to get tests passing.
+#
+# Note that we don't literally overwrite the gdb.exe binary because it appears
+# to just use gdborig.exe, so that's the binary we deal with instead.
+#
+# Otherwise install MinGW through `pacman`
+
+set -euo pipefail
+IFS=$'\n\t'
+
+source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
+
+if isWindows; then
+    if [[ -z "${MINGW_URL+x}" ]]; then
+        arch=i686
+        if [ "$MSYS_BITS" = "64" ]; then
+          arch=x86_64
+        fi
+        pacman -S --noconfirm --needed mingw-w64-$arch-toolchain mingw-w64-$arch-cmake \
+            mingw-w64-$arch-gcc mingw-w64-$arch-python2
+        ciCommandAddPath "${SYSTEM_WORKFOLDER}/msys2/mingw${MSYS_BITS}/bin"
+    else
+        curl -o mingw.7z "${MINGW_URL}/${MINGW_ARCHIVE}"
+        7z x -y mingw.7z > /dev/null
+        curl -o "${MINGW_DIR}/bin/gdborig.exe" "${MINGW_URL}/2017-04-20-${MSYS_BITS}bit-gdborig.exe"
+        ciCommandAddPath "$(pwd)/${MINGW_DIR}/bin"
+    fi
+fi
diff --git a/src/ci/scripts/install-msys2-packages.sh b/src/ci/scripts/install-msys2-packages.sh
new file mode 100755
index 0000000..36d9202
--- /dev/null
+++ b/src/ci/scripts/install-msys2-packages.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+set -euo pipefail
+IFS=$'\n\t'
+
+source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
+
+if isWindows; then
+    pacman -S --noconfirm --needed base-devel ca-certificates make diffutils tar
+
+    # Make sure we use the native python interpreter instead of some msys equivalent
+    # one way or another. The msys interpreters seem to have weird path conversions
+    # baked in which break LLVM's build system one way or another, so let's use the
+    # native version which keeps everything as native as possible.
+    cp C:/Python27amd64/python.exe C:/Python27amd64/python2.7.exe
+    ciCommandAddPath "C:\\Python27amd64"
+fi
diff --git a/src/ci/scripts/install-msys2.sh b/src/ci/scripts/install-msys2.sh
new file mode 100755
index 0000000..ce37c3b
--- /dev/null
+++ b/src/ci/scripts/install-msys2.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# Download and install MSYS2, needed primarily for the test suite (run-make) but
+# also used by the MinGW toolchain for assembling things.
+#
+# FIXME: we should probe the default azure image and see if we can use the MSYS2
+# toolchain there. (if there's even one there). For now though this gets the job
+# done.
+
+set -euo pipefail
+IFS=$'\n\t'
+
+source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
+
+if isWindows; then
+    choco install msys2 --params="/InstallDir:${SYSTEM_WORKFOLDER}/msys2 /NoPath" -y --no-progress
+    mkdir -p "${SYSTEM_WORKFOLDER}/msys2/home/${USERNAME}"
+
+    ciCommandAddPath "${SYSTEM_WORKFOLDER}/msys2/usr/bin"
+fi
diff --git a/src/ci/scripts/install-ninja.sh b/src/ci/scripts/install-ninja.sh
new file mode 100755
index 0000000..b8261d8
--- /dev/null
+++ b/src/ci/scripts/install-ninja.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# Note that this is originally from the github releases patch of Ninja
+
+set -euo pipefail
+IFS=$'\n\t'
+
+source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
+
+if isWindows; then
+    mkdir ninja
+    curl -o ninja.zip "${MIRRORS_BASE}/2017-03-15-ninja-win.zip"
+    7z x -oninja ninja.zip
+    rm ninja.zip
+    ciCommandSetEnv "RUST_CONFIGURE_ARGS" "${RUST_CONFIGURE_ARGS} --enable-ninja"
+    ciCommandAddPath "$(pwd)/ninja"
+fi
diff --git a/src/ci/scripts/install-sccache.sh b/src/ci/scripts/install-sccache.sh
new file mode 100755
index 0000000..d3c2989
--- /dev/null
+++ b/src/ci/scripts/install-sccache.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# This script installs sccache on the local machine. Note that we don't install
+# sccache on Linux since it's installed elsewhere through all the containers.
+
+set -euo pipefail
+IFS=$'\n\t'
+
+source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
+
+if isMacOS; then
+    curl -fo /usr/local/bin/sccache "${MIRRORS_BASE}/2018-04-02-sccache-x86_64-apple-darwin"
+    chmod +x /usr/local/bin/sccache
+elif isWindows; then
+    mkdir -p sccache
+    curl -fo sccache/sccache.exe "${MIRRORS_BASE}/2018-04-26-sccache-x86_64-pc-windows-msvc"
+    ciCommandAddPath "$(pwd)/sccache"
+fi
+
+# FIXME: we should probably install sccache outside the containers and then
+# mount it inside the containers so we can centralize all installation here.
diff --git a/src/ci/scripts/install-wix.sh b/src/ci/scripts/install-wix.sh
new file mode 100755
index 0000000..688f1a4
--- /dev/null
+++ b/src/ci/scripts/install-wix.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# We use the WIX toolset to create combined installers for Windows, and these
+# binaries are downloaded from https://github.com/wixtoolset/wix3 originally
+
+set -euo pipefail
+IFS=$'\n\t'
+
+source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
+
+if isWindows; then
+    ciCommandSetEnv WIX "$(pwd)/wix"
+
+    curl -O "${MIRRORS_BASE}/wix311-binaries.zip"
+    mkdir -p wix/bin
+    cd wix/bin
+    7z x ../../wix311-binaries.zip
+fi
diff --git a/src/ci/scripts/should-skip-this.sh b/src/ci/scripts/should-skip-this.sh
new file mode 100755
index 0000000..f945db0
--- /dev/null
+++ b/src/ci/scripts/should-skip-this.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# Set the SKIP_JOB environment variable if this job is supposed to only run
+# when submodules are updated and they were not. The following time consuming
+# tasks will be skipped when the environment variable is present.
+
+set -euo pipefail
+IFS=$'\n\t'
+
+source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
+
+if [[ -z "${CI_ONLY_WHEN_SUBMODULES_CHANGED+x}" ]]; then
+    echo "Executing the job since there is no skip rule in effect"
+elif git diff HEAD^ | grep --quiet "^index .* 160000"; then
+    # Submodules pseudo-files inside git have the 160000 permissions, so when
+    # those files are present in the diff a submodule was updated.
+    echo "Executing the job since submodules are updated"
+else
+    echo "Not executing this job since no submodules were updated"
+    ciCommandSetEnv SKIP_JOB 1
+fi
diff --git a/src/ci/scripts/switch-xcode.sh b/src/ci/scripts/switch-xcode.sh
new file mode 100755
index 0000000..2cbb2dd
--- /dev/null
+++ b/src/ci/scripts/switch-xcode.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Switch to XCode 9.3 on OSX since it seems to be the last version that supports
+# i686-apple-darwin. We'll eventually want to upgrade this and it will probably
+# force us to drop i686-apple-darwin, but let's keep the wheels turning for now.
+
+set -euo pipefail
+IFS=$'\n\t'
+
+source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
+
+if isMacOS; then
+    sudo xcode-select --switch /Applications/Xcode_9.3.app
+fi
diff --git a/src/ci/scripts/upload-artifacts.sh b/src/ci/scripts/upload-artifacts.sh
new file mode 100755
index 0000000..312ec9d
--- /dev/null
+++ b/src/ci/scripts/upload-artifacts.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# Upload all the artifacts to our S3 bucket. All the files inside ${upload_dir}
+# will be uploaded to the deploy bucket and eventually signed and released in
+# static.rust-lang.org.
+
+set -euo pipefail
+IFS=$'\n\t'
+
+source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
+
+upload_dir="$(mktemp -d)"
+
+# Release tarballs produced by a dist builder.
+if [[ "${DEPLOY-0}" -eq "1" ]] || [[ "${DEPLOY_ALT-0}" -eq "1" ]]; then
+    dist_dir=build/dist
+    if isLinux; then
+        dist_dir=obj/build/dist
+    fi
+    rm -rf "${dist_dir}/doc"
+    cp -r "${dist_dir}"/* "${upload_dir}"
+fi
+
+# CPU usage statistics.
+cp cpu-usage.csv "${upload_dir}/cpu-${CI_JOB_NAME}.csv"
+
+# Toolstate data.
+if [[ -n "${DEPLOY_TOOLSTATES_JSON+x}" ]]; then
+    cp /tmp/toolstate/toolstates.json "${upload_dir}/${DEPLOY_TOOLSTATES_JSON}"
+fi
+
+echo "Files that will be uploaded:"
+ls -lah "${upload_dir}"
+echo
+
+deploy_dir="rustc-builds"
+if [[ "${DEPLOY_ALT-0}" -eq "1" ]]; then
+    deploy_dir="rustc-builds-alt"
+fi
+deploy_url="s3://${DEPLOY_BUCKET}/${deploy_dir}/$(ciCommit)"
+
+retry aws s3 cp --no-progress --recursive --acl public-read "${upload_dir}" "${deploy_url}"
diff --git a/src/ci/scripts/verify-line-endings.sh b/src/ci/scripts/verify-line-endings.sh
new file mode 100755
index 0000000..f3cac13
--- /dev/null
+++ b/src/ci/scripts/verify-line-endings.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# See also the disable for autocrlf, this just checks that it worked.
+#
+# We check both in rust-lang/rust and in a submodule to make sure both are
+# accurate. Submodules are checked out significantly later than the main
+# repository in this script, so settings can (and do!) change between then.
+#
+# Linux (and maybe macOS) builders don't currently have dos2unix so just only
+# run this step on Windows.
+
+set -euo pipefail
+IFS=$'\n\t'
+
+source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
+
+if isWindows; then
+    # print out the git configuration so we can better investigate failures in
+    # the following
+    git config --list --show-origin
+    dos2unix -ih Cargo.lock src/tools/rust-installer/install-template.sh
+    endings=$(dos2unix -ic Cargo.lock src/tools/rust-installer/install-template.sh)
+    # if endings has non-zero length, error out
+    if [ -n "$endings" ]; then exit 1 ; fi
+fi
diff --git a/src/ci/scripts/windows-symlink-build-dir.sh b/src/ci/scripts/windows-symlink-build-dir.sh
new file mode 100755
index 0000000..e57128c
--- /dev/null
+++ b/src/ci/scripts/windows-symlink-build-dir.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+# We've had issues with the default drive in use running out of space during a
+# build, and it looks like the `C:` drive has more space than the default `D:`
+# drive. We should probably confirm this with the azure pipelines team at some
+# point, but this seems to fix our "disk space full" problems.
+
+set -euo pipefail
+IFS=$'\n\t'
+
+source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
+
+if isWindows; then
+    cmd //c "mkdir c:\\MORE_SPACE"
+    cmd //c "mklink /J build c:\\MORE_SPACE"
+fi
diff --git a/src/ci/shared.sh b/src/ci/shared.sh
index b093a07..718a537 100644
--- a/src/ci/shared.sh
+++ b/src/ci/shared.sh
@@ -4,6 +4,8 @@
 # `source shared.sh`, hence the invalid shebang and not being
 # marked as an executable file in git.
 
+export MIRRORS_BASE="https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc"
+
 # See http://unix.stackexchange.com/questions/82598
 # Duplicated in docker/dist-various-2/shared.sh
 function retry {
@@ -28,10 +30,43 @@
   [ "$CI" = "true" ] || [ "$TF_BUILD" = "True" ]
 }
 
-function isOSX {
+function isMacOS {
   [ "$AGENT_OS" = "Darwin" ]
 }
 
+function isWindows {
+  [ "$AGENT_OS" = "Windows_NT" ]
+}
+
+function isLinux {
+  [ "$AGENT_OS" = "Linux" ]
+}
+
 function getCIBranch {
   echo "$BUILD_SOURCEBRANCHNAME"
 }
+
+function ciCommit {
+  echo "${BUILD_SOURCEVERSION}"
+}
+
+function ciCommandAddPath {
+    if [[ $# -ne 1 ]]; then
+        echo "usage: $0 <path>"
+        exit 1
+    fi
+    path="$1"
+
+    echo "##vso[task.prependpath]${path}"
+}
+
+function ciCommandSetEnv {
+    if [[ $# -ne 2 ]]; then
+        echo "usage: $0 <name> <value>"
+        exit 1
+    fi
+    name="$1"
+    value="$2"
+
+    echo "##vso[task.setvariable variable=${name}]${value}"
+}
diff --git a/src/doc/book/Cargo.lock b/src/doc/book/Cargo.lock
index 928f6b1..dbf9557 100644
--- a/src/doc/book/Cargo.lock
+++ b/src/doc/book/Cargo.lock
@@ -1,3 +1,5 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
 [[package]]
 name = "aho-corasick"
 version = "0.5.3"
diff --git a/src/doc/book/ci/build.sh b/src/doc/book/ci/build.sh
old mode 100644
new mode 100755
index 9ad1781..13f4509
--- a/src/doc/book/ci/build.sh
+++ b/src/doc/book/ci/build.sh
@@ -4,13 +4,6 @@
 
 export PATH=$PATH:/home/travis/.cargo/bin;
 
-# Feature check
-cd ci/stable-check
-
-cargo run -- ../../src
-
-cd ../..
-
 echo 'Spellchecking...'
 bash ci/spellcheck.sh list
 echo 'Testing...'
@@ -19,3 +12,8 @@
 mdbook build
 echo 'Linting for local file paths...'
 cargo run --bin lfp src
+echo 'Validating references'
+for file in src/*.md ; do
+    echo Checking references in $file
+    cargo run --quiet --bin link2print < $file > /dev/null
+done
diff --git a/src/doc/book/ci/stable-check/Cargo.lock b/src/doc/book/ci/stable-check/Cargo.lock
deleted file mode 100644
index 9a3b307..0000000
--- a/src/doc/book/ci/stable-check/Cargo.lock
+++ /dev/null
@@ -1,4 +0,0 @@
-[root]
-name = "stable-check"
-version = "0.1.0"
-
diff --git a/src/doc/book/ci/stable-check/Cargo.toml b/src/doc/book/ci/stable-check/Cargo.toml
deleted file mode 100644
index 691722a..0000000
--- a/src/doc/book/ci/stable-check/Cargo.toml
+++ /dev/null
@@ -1,6 +0,0 @@
-[package]
-name = "stable-check"
-version = "0.1.0"
-authors = ["steveklabnik <steve@steveklabnik.com>"]
-
-[dependencies]
diff --git a/src/doc/book/ci/stable-check/src/main.rs b/src/doc/book/ci/stable-check/src/main.rs
deleted file mode 100644
index 167f1f8..0000000
--- a/src/doc/book/ci/stable-check/src/main.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-use std::error::Error;
-use std::env;
-use std::fs;
-use std::fs::File;
-use std::io::prelude::*;
-use std::path::Path;
-
-fn main() {
-    let arg = env::args().nth(1).unwrap_or_else(|| {
-        println!("Please pass a src directory as the first argument");
-        std::process::exit(1);
-    });
-
-    match check_directory(&Path::new(&arg)) {
-        Ok(()) => println!("passed!"),
-        Err(e) => {
-            println!("Error: {}", e);
-            std::process::exit(1);
-        }
-    }
-
-}
-
-fn check_directory(dir: &Path) -> Result<(), Box<Error>> {
-    for entry in fs::read_dir(dir)? {
-        let entry = entry?;
-        let path = entry.path();
-
-        if path.is_dir() {
-            continue;
-        }
-
-        let mut file = File::open(&path)?;
-        let mut contents = String::new();
-        file.read_to_string(&mut contents)?;
-
-        if contents.contains("#![feature") {
-            return Err(From::from(format!("Feature flag found in {:?}", path)));
-        }
-    }
-
-    Ok(())
-}
diff --git a/src/doc/book/rust-toolchain b/src/doc/book/rust-toolchain
new file mode 100644
index 0000000..bf50e91
--- /dev/null
+++ b/src/doc/book/rust-toolchain
@@ -0,0 +1 @@
+1.37.0
diff --git a/src/doc/book/src/appendix-04-useful-development-tools.md b/src/doc/book/src/appendix-04-useful-development-tools.md
index ec40d1c..33929bc 100644
--- a/src/doc/book/src/appendix-04-useful-development-tools.md
+++ b/src/doc/book/src/appendix-04-useful-development-tools.md
@@ -1,10 +1,10 @@
-# Appendix D - Useful Development Tools
+## Appendix D - Useful Development Tools
 
 In this appendix, we talk about some useful development tools that the Rust
 project provides. We’ll look at automatic formatting, quick ways to apply
 warning fixes, a linter, and integrating with IDEs.
 
-## Automatic Formatting with `rustfmt`
+### Automatic Formatting with `rustfmt`
 
 The `rustfmt` tool reformats your code according to the community code style.
 Many collaborative projects use `rustfmt` to prevent arguments about which
@@ -29,7 +29,7 @@
 
 [rustfmt]: https://github.com/rust-lang/rustfmt
 
-## Fix Your Code with `rustfix`
+### Fix Your Code with `rustfix`
 
 The rustfix tool is included with Rust installations and can automatically fix
 some compiler warnings. If you’ve written code in Rust, you’ve probably seen
@@ -96,7 +96,7 @@
 You can also use the `cargo fix` command to transition your code between
 different Rust editions. Editions are covered in Appendix E.
 
-## More Lints with Clippy
+### More Lints with Clippy
 
 The Clippy tool is a collection of lints to analyze your code so you can catch
 common mistakes and improve your Rust code.
@@ -158,7 +158,7 @@
 
 [clippy]: https://github.com/rust-lang/rust-clippy
 
-## IDE Integration Using the Rust Language Server
+### IDE Integration Using the Rust Language Server
 
 To help IDE integration, the Rust project distributes the *Rust Language
 Server* (`rls`). This tool speaks the [Language Server
diff --git a/src/doc/book/src/appendix-05-editions.md b/src/doc/book/src/appendix-05-editions.md
index ac75c41..db98ecc 100644
--- a/src/doc/book/src/appendix-05-editions.md
+++ b/src/doc/book/src/appendix-05-editions.md
@@ -1,4 +1,4 @@
-# Appendix E - Editions
+## Appendix E - Editions
 
 In Chapter 1, you saw that `cargo new` adds a bit of metadata to your
 *Cargo.toml* file about an edition. This appendix talks about what that means!
diff --git a/src/doc/book/src/appendix-07-nightly-rust.md b/src/doc/book/src/appendix-07-nightly-rust.md
index d8fd0da..bace82f 100644
--- a/src/doc/book/src/appendix-07-nightly-rust.md
+++ b/src/doc/book/src/appendix-07-nightly-rust.md
@@ -1,4 +1,4 @@
-# Appendix G - How Rust is Made and “Nightly Rust”
+## Appendix G - How Rust is Made and “Nightly Rust”
 
 This appendix is about how Rust is made and how that affects you as a Rust
 developer.
diff --git a/src/doc/book/src/ch00-00-introduction.md b/src/doc/book/src/ch00-00-introduction.md
index 7a37ee4..86fe469 100644
--- a/src/doc/book/src/ch00-00-introduction.md
+++ b/src/doc/book/src/ch00-00-introduction.md
@@ -104,7 +104,7 @@
 chapters, we’ll build small programs together, applying what you’ve learned so
 far. Chapters 2, 12, and 20 are project chapters; the rest are concept chapters.
 
-Chapter 1 explains how to install Rust, how to write a Hello, world! program,
+Chapter 1 explains how to install Rust, how to write a “Hello, world!” program,
 and how to use Cargo, Rust’s package manager and build tool. Chapter 2 is a
 hands-on introduction to the Rust language. Here we cover concepts at a high
 level, and later chapters will provide additional detail. If you want to get
diff --git a/src/doc/book/src/ch01-01-installation.md b/src/doc/book/src/ch01-01-installation.md
index 9061389..d7659eb 100644
--- a/src/doc/book/src/ch01-01-installation.md
+++ b/src/doc/book/src/ch01-01-installation.md
@@ -126,9 +126,9 @@
 
 ### Local Documentation
 
-The installer also includes a copy of the documentation locally, so you can
-read it offline. Run `rustup doc` to open the local documentation in your
-browser.
+The installation of Rust also includes a copy of the documentation locally, so
+you can read it offline. Run `rustup doc` to open the local documentation in
+your browser.
 
 Any time a type or function is provided by the standard library and you’re not
 sure what it does or how to use it, use the application programming interface
diff --git a/src/doc/book/src/ch01-02-hello-world.md b/src/doc/book/src/ch01-02-hello-world.md
index e82ba49..82a545a 100644
--- a/src/doc/book/src/ch01-02-hello-world.md
+++ b/src/doc/book/src/ch01-02-hello-world.md
@@ -20,7 +20,7 @@
 your projects there.
 
 Open a terminal and enter the following commands to make a *projects* directory
-and a directory for the Hello, world! project within the *projects* directory.
+and a directory for the “Hello, world!” project within the *projects* directory.
 
 For Linux, macOS, and PowerShell on Windows, enter this:
 
@@ -86,7 +86,7 @@
 
 ### Anatomy of a Rust Program
 
-Let’s review in detail what just happened in your Hello, world! program.
+Let’s review in detail what just happened in your “Hello, world!” program.
 Here’s the first piece of the puzzle:
 
 ```rust
@@ -178,7 +178,7 @@
 $ ./main # or .\main.exe on Windows
 ```
 
-If *main.rs* was your Hello, world! program, this line would print `Hello,
+If *main.rs* was your “Hello, world!” program, this line would print `Hello,
 world!` to your terminal.
 
 If you’re more familiar with a dynamic language, such as Ruby, Python, or
diff --git a/src/doc/book/src/ch01-03-hello-cargo.md b/src/doc/book/src/ch01-03-hello-cargo.md
index 34428e5..b40be39 100644
--- a/src/doc/book/src/ch01-03-hello-cargo.md
+++ b/src/doc/book/src/ch01-03-hello-cargo.md
@@ -6,9 +6,9 @@
 building those libraries. (We call libraries your code needs *dependencies*.)
 
 The simplest Rust programs, like the one we’ve written so far, don’t have any
-dependencies. So if we had built the Hello, world! project with Cargo, it would
-only use the part of Cargo that handles building your code. As you write more
-complex Rust programs, you’ll add dependencies, and if you start a project
+dependencies. So if we had built the “Hello, world!” project with Cargo, it
+would only use the part of Cargo that handles building your code. As you write
+more complex Rust programs, you’ll add dependencies, and if you start a project
 using Cargo, adding dependencies will be much easier to do.
 
 Because the vast majority of Rust projects use Cargo, the rest of this book
@@ -29,7 +29,7 @@
 ### Creating a Project with Cargo
 
 Let’s create a new project using Cargo and look at how it differs from our
-original Hello, world! project. Navigate back to your *projects* directory (or
+original “Hello, world!” project. Navigate back to your *projects* directory (or
 wherever you decided to store your code). Then, on any operating system, run
 the following:
 
@@ -99,10 +99,10 @@
 }
 ```
 
-Cargo has generated a Hello, world! program for you, just like the one we wrote
-in Listing 1-1! So far, the differences between our previous project and the
-project Cargo generates are that Cargo placed the code in the *src* directory,
-and we have a *Cargo.toml* configuration file in the top directory.
+Cargo has generated a “Hello, world!” program for you, just like the one we
+wrote in Listing 1-1! So far, the differences between our previous project and
+the project Cargo generates are that Cargo placed the code in the *src*
+directory, and we have a *Cargo.toml* configuration file in the top directory.
 
 Cargo expects your source files to live inside the *src* directory. The
 top-level project directory is just for README files, license information,
@@ -110,14 +110,14 @@
 helps you organize your projects. There’s a place for everything, and
 everything is in its place.
 
-If you started a project that doesn’t use Cargo, as we did with the Hello,
-world! project, you can convert it to a project that does use Cargo. Move the
+If you started a project that doesn’t use Cargo, as we did with the “Hello,
+world!” project, you can convert it to a project that does use Cargo. Move the
 project code into the *src* directory and create an appropriate *Cargo.toml*
 file.
 
 ### Building and Running a Cargo Project
 
-Now let’s look at what’s different when we build and run the Hello, world!
+Now let’s look at what’s different when we build and run the “Hello, world!”
 program with Cargo! From your *hello_cargo* directory, build your project by
 entering the following command:
 
@@ -237,7 +237,7 @@
 * Install the latest stable version of Rust using `rustup`
 * Update to a newer Rust version
 * Open locally installed documentation
-* Write and run a Hello, world! program using `rustc` directly
+* Write and run a “Hello, world!” program using `rustc` directly
 * Create and run a new project using the conventions of Cargo
 
 This is a great time to build a more substantial program to get used to reading
diff --git a/src/doc/book/src/ch02-00-guessing-game-tutorial.md b/src/doc/book/src/ch02-00-guessing-game-tutorial.md
index 5651b68..2ecc152 100644
--- a/src/doc/book/src/ch02-00-guessing-game-tutorial.md
+++ b/src/doc/book/src/ch02-00-guessing-game-tutorial.md
@@ -201,7 +201,7 @@
     .expect("Failed to read line");
 ```
 
-If we hadn’t listed the `use std::io` line at the beginning of the program, we
+If we hadn’t put the `use std::io` line at the beginning of the program, we
 could have written this function call as `std::io::stdin`. The `stdin` function
 returns an instance of [`std::io::Stdin`][iostdin]<!-- ignore -->, which is a
 type that represents a handle to the standard input for your terminal.
@@ -373,23 +373,28 @@
 the bottom beneath the `[dependencies]` section header that Cargo created for
 you:
 
+<!-- When updating the version of `rand` used, also update the version of
+`rand` used in these files so they all match:
+* ch07-04-bringing-paths-into-scope-with-the-use-keyword.md
+* ch14-03-cargo-workspaces.md
+-->
+
 <span class="filename">Filename: Cargo.toml</span>
 
 ```toml
 [dependencies]
-
-rand = "0.3.14"
+rand = "0.5.5"
 ```
 
 In the *Cargo.toml* file, everything that follows a header is part of a section
 that continues until another section starts. The `[dependencies]` section is
 where you tell Cargo which external crates your project depends on and which
 versions of those crates you require. In this case, we’ll specify the `rand`
-crate with the semantic version specifier `0.3.14`. Cargo understands [Semantic
+crate with the semantic version specifier `0.5.5`. Cargo understands [Semantic
 Versioning][semver]<!-- ignore --> (sometimes called *SemVer*), which is a
-standard for writing version numbers. The number `0.3.14` is actually shorthand
-for `^0.3.14`, which means “any version that has a public API compatible with
-version 0.3.14.”
+standard for writing version numbers. The number `0.5.5` is actually shorthand
+for `^0.5.5`, which means “any version that has a public API compatible with
+version 0.5.5.”
 
 [semver]: http://semver.org
 
@@ -398,13 +403,19 @@
 
 ```text
 $ cargo build
-    Updating registry `https://github.com/rust-lang/crates.io-index`
- Downloading rand v0.3.14
- Downloading libc v0.2.14
-   Compiling libc v0.2.14
-   Compiling rand v0.3.14
+    Updating crates.io index
+  Downloaded rand v0.5.5
+  Downloaded libc v0.2.62
+  Downloaded rand_core v0.2.2
+  Downloaded rand_core v0.3.1
+  Downloaded rand_core v0.4.2
+   Compiling rand_core v0.4.2
+   Compiling libc v0.2.62
+   Compiling rand_core v0.3.1
+   Compiling rand_core v0.2.2
+   Compiling rand v0.5.5
    Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
-    Finished dev [unoptimized + debuginfo] target(s) in 2.53 secs
+    Finished dev [unoptimized + debuginfo] target(s) in 2.53 s
 ```
 
 <span class="caption">Listing 2-2: The output from running `cargo build` after
@@ -422,8 +433,8 @@
 
 After updating the registry, Cargo checks the `[dependencies]` section and
 downloads any crates you don’t have yet. In this case, although we only listed
-`rand` as a dependency, Cargo also grabbed a copy of `libc`, because `rand`
-depends on `libc` to work. After downloading the crates, Rust compiles them and
+`rand` as a dependency, Cargo also grabbed `libc` and `rand_core`, because `rand`
+depends on those to work. After downloading the crates, Rust compiles them and
 then compiles the project with the dependencies available.
 
 If you immediately run `cargo build` again without making any changes, you
@@ -439,7 +450,7 @@
 ```text
 $ cargo build
    Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
-    Finished dev [unoptimized + debuginfo] target(s) in 2.53 secs
+    Finished dev [unoptimized + debuginfo] target(s) in 2.53s
 ```
 
 These lines show Cargo only updates the build with your tiny change to the
@@ -452,7 +463,7 @@
 Cargo has a mechanism that ensures you can rebuild the same artifact every time
 you or anyone else builds your code: Cargo will use only the versions of the
 dependencies you specified until you indicate otherwise. For example, what
-happens if next week version 0.3.15 of the `rand` crate comes out and
+happens if next week version 0.5.6 of the `rand` crate comes out and
 contains an important bug fix but also contains a regression that will break
 your code?
 
@@ -464,7 +475,7 @@
 see that the *Cargo.lock* file exists and use the versions specified there
 rather than doing all the work of figuring out versions again. This lets you
 have a reproducible build automatically. In other words, your project will
-remain at `0.3.14` until you explicitly upgrade, thanks to the *Cargo.lock*
+remain at `0.5.5` until you explicitly upgrade, thanks to the *Cargo.lock*
 file.
 
 #### Updating a Crate to Get a New Version
@@ -474,26 +485,25 @@
 that fit your specifications in *Cargo.toml*. If that works, Cargo will write
 those versions to the *Cargo.lock* file.
 
-But by default, Cargo will only look for versions greater than `0.3.0` and less
-than `0.4.0`. If the `rand` crate has released two new versions, `0.3.15` and
-`0.4.0`, you would see the following if you ran `cargo update`:
+But by default, Cargo will only look for versions greater than `0.5.5` and less
+than `0.6.0`. If the `rand` crate has released two new versions, `0.5.6` and
+`0.6.0`, you would see the following if you ran `cargo update`:
 
 ```text
 $ cargo update
-    Updating registry `https://github.com/rust-lang/crates.io-index`
-    Updating rand v0.3.14 -> v0.3.15
+    Updating crates.io index
+    Updating rand v0.5.5 -> v0.5.6
 ```
 
 At this point, you would also notice a change in your *Cargo.lock* file noting
-that the version of the `rand` crate you are now using is `0.3.15`.
+that the version of the `rand` crate you are now using is `0.5.6`.
 
-If you wanted to use `rand` version `0.4.0` or any version in the `0.4.x`
+If you wanted to use `rand` version `0.6.0` or any version in the `0.6.x`
 series, you’d have to update the *Cargo.toml* file to look like this instead:
 
 ```toml
 [dependencies]
-
-rand = "0.4.0"
+rand = "0.6.0"
 ```
 
 The next time you run `cargo build`, Cargo will update the registry of crates
diff --git a/src/doc/book/src/ch03-01-variables-and-mutability.md b/src/doc/book/src/ch03-01-variables-and-mutability.md
index b14bba5..d6a73a0 100644
--- a/src/doc/book/src/ch03-01-variables-and-mutability.md
+++ b/src/doc/book/src/ch03-01-variables-and-mutability.md
@@ -65,7 +65,7 @@
 you did in Chapter 2, you can make them mutable by adding `mut` in front of the
 variable name. In addition to allowing this value to change, `mut` conveys
 intent to future readers of the code by indicating that other parts of the code
-will be changing this variable's value.
+will be changing this variable’s value.
 
 For example, let’s change *src/main.rs* to the following:
 
diff --git a/src/doc/book/src/ch03-02-data-types.md b/src/doc/book/src/ch03-02-data-types.md
index 228e431..482e69f 100644
--- a/src/doc/book/src/ch03-02-data-types.md
+++ b/src/doc/book/src/ch03-02-data-types.md
@@ -228,9 +228,9 @@
 
 #### The Tuple Type
 
-A tuple is a general way of grouping together some number of other values
-with a variety of types into one compound type. Tuples have a fixed length:
-once declared, they cannot grow or shrink in size.
+A tuple is a general way of grouping together a number of values with a variety
+of types into one compound type. Tuples have a fixed length: once declared,
+they cannot grow or shrink in size.
 
 We create a tuple by writing a comma-separated list of values inside
 parentheses. Each position in the tuple has a type, and the types of the
@@ -286,8 +286,8 @@
 ```
 
 This program creates a tuple, `x`, and then makes new variables for each
-element by using their index. As with most programming languages, the first
-index in a tuple is 0.
+element by using their respective indices. As with most programming languages,
+the first index in a tuple is 0.
 
 #### The Array Type
 
@@ -318,7 +318,7 @@
 An example of when you might want to use an array rather than a vector is in a
 program that needs to know the names of the months of the year. It’s very
 unlikely that such a program will need to add or remove months, so you can use
-an array because you know it will always contain 12 items:
+an array because you know it will always contain 12 elements:
 
 ```rust
 let months = ["January", "February", "March", "April", "May", "June", "July",
@@ -334,7 +334,7 @@
 ```
 
 Here, `i32` is the type of each element. After the semicolon, the number `5`
-indicates the element contains five items.
+indicates the array contains five elements.
 
 Writing an array’s type this way looks similar to an alternative syntax for
 initializing an array: if you want to create an array that contains the same
diff --git a/src/doc/book/src/ch06-00-enums.md b/src/doc/book/src/ch06-00-enums.md
index 767f866..cf7ea67 100644
--- a/src/doc/book/src/ch06-00-enums.md
+++ b/src/doc/book/src/ch06-00-enums.md
@@ -1,7 +1,7 @@
 # Enums and Pattern Matching
 
 In this chapter we’ll look at *enumerations*, also referred to as *enums*.
-Enums allow you to define a type by enumerating its possible values. First,
+Enums allow you to define a type by enumerating its possible *variants*. First,
 we’ll define and use an enum to show how an enum can encode meaning along with
 data. Next, we’ll explore a particularly useful enum, called `Option`, which
 expresses that a value can be either something or nothing. Then we’ll look at
diff --git a/src/doc/book/src/ch06-01-defining-an-enum.md b/src/doc/book/src/ch06-01-defining-an-enum.md
index 9a56af7..0d25afb 100644
--- a/src/doc/book/src/ch06-01-defining-an-enum.md
+++ b/src/doc/book/src/ch06-01-defining-an-enum.md
@@ -5,18 +5,18 @@
 with IP addresses. Currently, two major standards are used for IP addresses:
 version four and version six. These are the only possibilities for an IP
 address that our program will come across: we can *enumerate* all possible
-values, which is where enumeration gets its name.
+variants, which is where enumeration gets its name.
 
 Any IP address can be either a version four or a version six address, but not
 both at the same time. That property of IP addresses makes the enum data
-structure appropriate, because enum values can only be one of the variants.
+structure appropriate, because enum values can only be one of its variants.
 Both version four and version six addresses are still fundamentally IP
 addresses, so they should be treated as the same type when the code is handling
 situations that apply to any kind of IP address.
 
 We can express this concept in code by defining an `IpAddrKind` enumeration and
-listing the possible kinds an IP address can be, `V4` and `V6`. These are known
-as the *variants* of the enum:
+listing the possible kinds an IP address can be, `V4` and `V6`. These are the
+variants of the enum:
 
 ```rust
 enum IpAddrKind {
diff --git a/src/doc/book/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md b/src/doc/book/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md
index ea6e517..05af46c 100644
--- a/src/doc/book/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md
+++ b/src/doc/book/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md
@@ -241,6 +241,12 @@
 package called `rand` to get random numbers. To use `rand` in our project, we
 added this line to *Cargo.toml*:
 
+<!-- When updating the version of `rand` used, also update the version of
+`rand` used in these files so they all match:
+* ch02-00-guessing-game-tutorial.md
+* ch14-03-cargo-workspaces.md
+-->
+
 <span class="filename">Filename: Cargo.toml</span>
 
 ```toml
diff --git a/src/doc/book/src/ch07-05-separating-modules-into-different-files.md b/src/doc/book/src/ch07-05-separating-modules-into-different-files.md
index 4a039fa..6b51859 100644
--- a/src/doc/book/src/ch07-05-separating-modules-into-different-files.md
+++ b/src/doc/book/src/ch07-05-separating-modules-into-different-files.md
@@ -76,7 +76,7 @@
 
 ## Summary
 
-Rust lets you organize your packages into crates and your crates into modules
+Rust lets you split a package into multiple crates and a crate into modules
 so you can refer to items defined in one module from another module. You can do
 this by specifying absolute or relative paths. These paths can be brought into
 scope with a `use` statement so you can use a shorter path for multiple uses of
diff --git a/src/doc/book/src/ch09-02-recoverable-errors-with-result.md b/src/doc/book/src/ch09-02-recoverable-errors-with-result.md
index 7de4528..8461e2b 100644
--- a/src/doc/book/src/ch09-02-recoverable-errors-with-result.md
+++ b/src/doc/book/src/ch09-02-recoverable-errors-with-result.md
@@ -470,13 +470,13 @@
 opportunity to explain all the error handling, so we did it the longer way
 first.
 
-#### The `?` Operator Can Only Be Used in Functions That Return `Result`
+#### The `?` Operator Can Be Used in Functions That Return `Result`
 
-The `?` operator can only be used in functions that have a return type of
+The `?` operator can be used in functions that have a return type of
 `Result`, because it is defined to work in the same way as the `match`
 expression we defined in Listing 9-6. The part of the `match` that requires a
 return type of `Result` is `return Err(e)`, so the return type of the function
-must be a `Result` to be compatible with this `return`.
+can be a `Result` to be compatible with this `return`.
 
 Let’s look at what happens if we use the `?` operator in the `main` function,
 which you’ll recall has a return type of `()`:
@@ -505,8 +505,9 @@
 ```
 
 This error points out that we’re only allowed to use the `?` operator in a
-function that returns `Result<T, E>`. When you’re writing code in a function
-that doesn’t return `Result<T, E>`, and you want to use `?` when you call other
+function that returns `Result` or `Option` or another type that implements
+`std::ops::Try`. When you’re writing code in a function
+that doesn’t return one of these types, and you want to use `?` when you call other
 functions that return `Result<T, E>`, you have two choices to fix this problem.
 One technique is to change the return type of your function to be `Result<T,
 E>` if you have no restrictions preventing that. The other technique is to use
diff --git a/src/doc/book/src/ch10-02-traits.md b/src/doc/book/src/ch10-02-traits.md
index 8fcf15d..19e873b 100644
--- a/src/doc/book/src/ch10-02-traits.md
+++ b/src/doc/book/src/ch10-02-traits.md
@@ -611,12 +611,12 @@
 type to have particular behavior. The compiler can then use the trait bound
 information to check that all the concrete types used with our code provide the
 correct behavior. In dynamically typed languages, we would get an error at
-runtime if we called a method on a type that the type didn’t implement. But
-Rust moves these errors to compile time so we’re forced to fix the problems
-before our code is even able to run. Additionally, we don’t have to write code
-that checks for behavior at runtime because we’ve already checked at compile
-time. Doing so improves performance without having to give up the flexibility
-of generics.
+runtime if we called a method on a type which didn’t implement the type which
+defines the method. But Rust moves these errors to compile time so we’re forced
+to fix the problems before our code is even able to run. Additionally, we don’t
+have to write code that checks for behavior at runtime because we’ve already
+checked at compile time. Doing so improves performance without having to give
+up the flexibility of generics.
 
 Another kind of generic that we’ve already been using is called *lifetimes*.
 Rather than ensuring that a type has the behavior we want, lifetimes ensure
diff --git a/src/doc/book/src/ch12-04-testing-the-librarys-functionality.md b/src/doc/book/src/ch12-04-testing-the-librarys-functionality.md
index 2d1eeb0..e8ed858 100644
--- a/src/doc/book/src/ch12-04-testing-the-librarys-functionality.md
+++ b/src/doc/book/src/ch12-04-testing-the-librarys-functionality.md
@@ -196,7 +196,7 @@
 </span>
 
 The `lines` method returns an iterator. We’ll talk about iterators in depth in
-[Chapter 13][ch13]<!-- ignore -->, but recall that you saw this way of using an
+[Chapter 13][ch13-iterators]<!-- ignore -->, but recall that you saw this way of using an
 iterator in [Listing 3-5][ch3-iter]<!-- ignore -->, where we used a `for` loop
 with an iterator to run some code on each item in a collection.
 
@@ -266,7 +266,7 @@
 implementation of the search function while keeping the tests passing to
 maintain the same functionality. The code in the search function isn’t too bad,
 but it doesn’t take advantage of some useful features of iterators. We’ll
-return to this example in [Chapter 13][ch13]<!-- ignore -->, where we’ll
+return to this example in [Chapter 13][ch13-iterators]<!-- ignore -->, where we’ll
 explore iterators in detail, and look at how to improve it.
 
 #### Using the `search` Function in the `run` Function
@@ -336,3 +336,4 @@
 [ch11-anatomy]: ch11-01-writing-tests.html#the-anatomy-of-a-test-function
 [ch10-lifetimes]: ch10-03-lifetime-syntax.html
 [ch3-iter]: ch03-05-control-flow.html#looping-through-a-collection-with-for
+[ch13-iterators]: ch13-02-iterators.html
diff --git a/src/doc/book/src/ch13-01-closures.md b/src/doc/book/src/ch13-01-closures.md
index f679c14..56f8ed4 100644
--- a/src/doc/book/src/ch13-01-closures.md
+++ b/src/doc/book/src/ch13-01-closures.md
@@ -133,11 +133,9 @@
 inside the outer `else` doesn’t call it at all, and the code inside the
 second `else` case calls it once.
 
-<!-- NEXT PARAGRAPH WRAPPED WEIRD INTENTIONALLY SEE #199 -->
-
 The desired behavior of the `generate_workout` function is to first check
-whether the user wants a low-intensity workout (indicated by a number less
-than 25) or a high-intensity workout (a number of 25 or greater).
+whether the user wants a low-intensity workout (indicated by a number less than
+25) or a high-intensity workout (a number of 25 or greater).
 
 Low-intensity workout plans will recommend a number of push-ups and sit-ups
 based on the complex algorithm we’re simulating.
diff --git a/src/doc/book/src/ch14-03-cargo-workspaces.md b/src/doc/book/src/ch14-03-cargo-workspaces.md
index 8b8c078..a662ac2 100644
--- a/src/doc/book/src/ch14-03-cargo-workspaces.md
+++ b/src/doc/book/src/ch14-03-cargo-workspaces.md
@@ -192,12 +192,17 @@
 *add-one/Cargo.toml* file to be able to use the `rand` crate in the `add-one`
 crate:
 
+<!-- When updating the version of `rand` used, also update the version of
+`rand` used in these files so they all match:
+* ch02-00-guessing-game-tutorial.md
+* ch07-04-bringing-paths-into-scope-with-the-use-keyword.md
+-->
+
 <span class="filename">Filename: add-one/Cargo.toml</span>
 
 ```toml
 [dependencies]
-
-rand = "0.3.14"
+rand = "0.5.5"
 ```
 
 We can now add `use rand;` to the *add-one/src/lib.rs* file, and building the
@@ -206,10 +211,10 @@
 
 ```text
 $ cargo build
-    Updating registry `https://github.com/rust-lang/crates.io-index`
- Downloading rand v0.3.14
+    Updating crates.io index
+  Downloaded rand v0.5.5
    --snip--
-   Compiling rand v0.3.14
+   Compiling rand v0.5.5
    Compiling add-one v0.1.0 (file:///projects/add/add-one)
    Compiling adder v0.1.0 (file:///projects/add/adder)
     Finished dev [unoptimized + debuginfo] target(s) in 10.18 secs
diff --git a/src/doc/book/src/ch15-03-drop.md b/src/doc/book/src/ch15-03-drop.md
index 800de36..333e4e2 100644
--- a/src/doc/book/src/ch15-03-drop.md
+++ b/src/doc/book/src/ch15-03-drop.md
@@ -58,7 +58,7 @@
 demonstrate when Rust will call `drop`.
 
 In `main`, we create two instances of `CustomSmartPointer` and then print
-`CustomSmartPointers created.`. At the end of `main`, our instances of
+`CustomSmartPointers created`. At the end of `main`, our instances of
 `CustomSmartPointer` will go out of scope, and Rust will call the code we put
 in the `drop` method, printing our final message. Note that we didn’t need to
 call the `drop` method explicitly.
@@ -84,7 +84,7 @@
 `Drop` trait is that it’s taken care of automatically. Occasionally, however,
 you might want to clean up a value early. One example is when using smart
 pointers that manage locks: you might want to force the `drop` method that
-releases the lock to run so other code in the same scope can acquire the lock.
+releases the lock so that other code in the same scope can acquire the lock.
 Rust doesn’t let you call the `Drop` trait’s `drop` method manually; instead
 you have to call the `std::mem::drop` function provided by the standard library
 if you want to force a value to be dropped before the end of its scope.
@@ -146,7 +146,7 @@
 #
 # impl Drop for CustomSmartPointer {
 #     fn drop(&mut self) {
-#         println!("Dropping CustomSmartPointer!");
+#         println!("Dropping CustomSmartPointer with data `{}`!", self.data);
 #     }
 # }
 #
diff --git a/src/doc/book/src/ch15-05-interior-mutability.md b/src/doc/book/src/ch15-05-interior-mutability.md
index f43d549..34c002b 100644
--- a/src/doc/book/src/ch15-05-interior-mutability.md
+++ b/src/doc/book/src/ch15-05-interior-mutability.md
@@ -1,16 +1,14 @@
 ## `RefCell<T>` and the Interior Mutability Pattern
 
-<!-- NEXT PARAGRAPH WRAPPED WEIRD INTENTIONALLY SEE #199 -->
-
 *Interior mutability* is a design pattern in Rust that allows you to mutate
 data even when there are immutable references to that data; normally, this
 action is disallowed by the borrowing rules. To mutate data, the pattern uses
 `unsafe` code inside a data structure to bend Rust’s usual rules that govern
-mutation and borrowing. We haven’t yet covered unsafe code; we will in
-Chapter 19. We can use types that use the interior mutability pattern when we
-can ensure that the borrowing rules will be followed at runtime, even though
-the compiler can’t guarantee that. The `unsafe` code involved is then wrapped
-in a safe API, and the outer type is still immutable.
+mutation and borrowing. We haven’t yet covered unsafe code; we will in Chapter
+19. We can use types that use the interior mutability pattern when we can
+ensure that the borrowing rules will be followed at runtime, even though the
+compiler can’t guarantee that. The `unsafe` code involved is then wrapped in a
+safe API, and the outer type is still immutable.
 
 Let’s explore this concept by looking at the `RefCell<T>` type that follows the
 interior mutability pattern.
diff --git a/src/doc/book/src/ch16-02-message-passing.md b/src/doc/book/src/ch16-02-message-passing.md
index 56181ea..6b5c23f 100644
--- a/src/doc/book/src/ch16-02-message-passing.md
+++ b/src/doc/book/src/ch16-02-message-passing.md
@@ -55,16 +55,14 @@
 producer for now, but we’ll add multiple producers when we get this example
 working.
 
-<!-- NEXT PARAGRAPH WRAPPED WEIRD INTENTIONALLY SEE #199 -->
-
 The `mpsc::channel` function returns a tuple, the first element of which is the
 sending end and the second element is the receiving end. The abbreviations `tx`
 and `rx` are traditionally used in many fields for *transmitter* and *receiver*
 respectively, so we name our variables as such to indicate each end. We’re
 using a `let` statement with a pattern that destructures the tuples; we’ll
-discuss the use of patterns in `let` statements and destructuring in
-Chapter 18. Using a `let` statement this way is a convenient approach to
-extract the pieces of the tuple returned by `mpsc::channel`.
+discuss the use of patterns in `let` statements and destructuring in Chapter
+18. Using a `let` statement this way is a convenient approach to extract the
+pieces of the tuple returned by `mpsc::channel`.
 
 Let’s move the transmitting end into a spawned thread and have it send one
 string so the spawned thread is communicating with the main thread, as shown in
diff --git a/src/doc/book/src/ch17-02-trait-objects.md b/src/doc/book/src/ch17-02-trait-objects.md
index 6145f21..d7369bf 100644
--- a/src/doc/book/src/ch17-02-trait-objects.md
+++ b/src/doc/book/src/ch17-02-trait-objects.md
@@ -275,14 +275,15 @@
 means it implements the `draw` method.
 
 This concept—of being concerned only with the messages a value responds to
-rather than the value’s concrete type—is similar to the concept *duck typing*
-in dynamically typed languages: if it walks like a duck and quacks like a duck,
-then it must be a duck! In the implementation of `run` on `Screen` in Listing
-17-5, `run` doesn’t need to know what the concrete type of each component is.
-It doesn’t check whether a component is an instance of a `Button` or a
-`SelectBox`, it just calls the `draw` method on the component. By specifying
-`Box<dyn Draw>` as the type of the values in the `components` vector, we’ve
-defined `Screen` to need values that we can call the `draw` method on.
+rather than the value’s concrete type—is similar to the concept of *duck
+typing* in dynamically typed languages: if it walks like a duck and quacks
+like a duck, then it must be a duck! In the implementation of `run` on `Screen`
+in Listing 17-5, `run` doesn’t need to know what the concrete type of each
+component is. It doesn’t check whether a component is an instance of a `Button`
+or a `SelectBox`, it just calls the `draw` method on the component. By
+specifying `Box<dyn Draw>` as the type of the values in the `components`
+vector, we’ve defined `Screen` to need values that we can call the `draw`
+method on.
 
 The advantage of using trait objects and Rust’s type system to write code
 similar to code using duck typing is that we never have to check whether a
diff --git a/src/doc/book/src/ch18-02-refutability.md b/src/doc/book/src/ch18-02-refutability.md
index 55cb038..36fa17d 100644
--- a/src/doc/book/src/ch18-02-refutability.md
+++ b/src/doc/book/src/ch18-02-refutability.md
@@ -10,8 +10,9 @@
 
 Function parameters, `let` statements, and `for` loops can only accept
 irrefutable patterns, because the program cannot do anything meaningful when
-values don’t match. The `if let` and `while let` expressions only accept
-refutable patterns, because by definition they’re intended to handle possible
+values don’t match. The `if let` and `while let` expressions accept
+refutable and irrefutable patterns, but the compiler warns against
+irrefutable patterns because by definition they’re intended to handle possible
 failure: the functionality of a conditional is in its ability to perform
 differently depending on success or failure.
 
@@ -69,9 +70,9 @@
 We’ve given the code an out! This code is perfectly valid, although it means we
 cannot use an irrefutable pattern without receiving an error. If we give `if
 let` a pattern that will always match, such as `x`, as shown in Listing 18-10,
-it will not compile.
+the compiler will give a warning.
 
-```rust,ignore,does_not_compile
+```rust,ignore
 if let x = 5 {
     println!("{}", x);
 };
@@ -84,11 +85,15 @@
 pattern:
 
 ```text
-error[E0162]: irrefutable if-let pattern
- --> <anon>:2:8
+warning: irrefutable if-let pattern
+ --> <anon>:2:5
   |
-2 | if let x = 5 {
-  |        ^ irrefutable pattern
+2 | /     if let x = 5 {
+3 | |     println!("{}", x);
+4 | | };
+  | |_^
+  |
+  = note: #[warn(irrefutable_let_patterns)] on by default
 ```
 
 For this reason, match arms must use refutable patterns, except for the last
diff --git a/src/doc/book/src/ch18-03-pattern-syntax.md b/src/doc/book/src/ch18-03-pattern-syntax.md
index 63eab2f..31b96a8 100644
--- a/src/doc/book/src/ch18-03-pattern-syntax.md
+++ b/src/doc/book/src/ch18-03-pattern-syntax.md
@@ -711,11 +711,11 @@
 
     match x {
         Some(50) => println!("Got 50"),
-        Some(n) if n == y => println!("Matched, n = {:?}", n),
+        Some(n) if n == y => println!("Matched, n = {}", n),
         _ => println!("Default case, x = {:?}", x),
     }
 
-    println!("at the end: x = {:?}, y = {:?}", x, y);
+    println!("at the end: x = {:?}, y = {}", x, y);
 }
 ```
 
diff --git a/src/doc/book/src/ch19-01-unsafe-rust.md b/src/doc/book/src/ch19-01-unsafe-rust.md
index 8c32b36..c7956e8 100644
--- a/src/doc/book/src/ch19-01-unsafe-rust.md
+++ b/src/doc/book/src/ch19-01-unsafe-rust.md
@@ -251,7 +251,7 @@
 This function first gets the total length of the slice. Then it asserts that
 the index given as a parameter is within the slice by checking whether it’s
 less than or equal to the length. The assertion means that if we pass an index
-that is greater than the index to split the slice at, the function will panic
+that is greater than the length to split the slice at, the function will panic
 before it attempts to use that index.
 
 Then we return two mutable slices in a tuple: one from the start of the
diff --git a/src/doc/book/src/ch20-02-multithreaded.md b/src/doc/book/src/ch20-02-multithreaded.md
index 5ca9358..1f80bbb 100644
--- a/src/doc/book/src/ch20-02-multithreaded.md
+++ b/src/doc/book/src/ch20-02-multithreaded.md
@@ -364,7 +364,7 @@
 ```
 
 We still use the `()` after `FnOnce` because this `FnOnce` represents a closure
-that takes no parameters and doesn’t return a value. Just like function
+that takes no parameters and returns the unit type `()`. Just like function
 definitions, the return type can be omitted from the signature, but even if we
 have no parameters, we still need the parentheses.
 
diff --git a/src/doc/book/convert-quotes.sh b/src/doc/book/tools/convert-quotes.sh
similarity index 100%
rename from src/doc/book/convert-quotes.sh
rename to src/doc/book/tools/convert-quotes.sh
diff --git a/src/doc/book/doc-to-md.sh b/src/doc/book/tools/doc-to-md.sh
similarity index 100%
rename from src/doc/book/doc-to-md.sh
rename to src/doc/book/tools/doc-to-md.sh
diff --git a/src/doc/book/nostarch.sh b/src/doc/book/tools/nostarch.sh
similarity index 100%
rename from src/doc/book/nostarch.sh
rename to src/doc/book/tools/nostarch.sh
diff --git a/src/doc/grammar.md b/src/doc/grammar.md
index ee9135b..4501d74 100644
--- a/src/doc/grammar.md
+++ b/src/doc/grammar.md
@@ -1,812 +1,7 @@
 % Grammar
 
-# Introduction
+The Rust grammar may now be found in the [reference]. Additionally, the [grammar
+working group] is working on producing a testable grammar.
 
-This document is the primary reference for the Rust programming language grammar. It
-provides only one kind of material:
-
-  - Chapters that formally define the language grammar.
-
-This document does not serve as an introduction to the language. Background
-familiarity with the language is assumed. A separate [guide] is available to
-help acquire such background.
-
-This document also does not serve as a reference to the [standard] library
-included in the language distribution. Those libraries are documented
-separately by extracting documentation attributes from their source code. Many
-of the features that one might expect to be language features are library
-features in Rust, so what you're looking for may be there, not here.
-
-[guide]: guide.html
-[standard]: std/index.html
-
-# Notation
-
-Rust's grammar is defined over Unicode codepoints, each conventionally denoted
-`U+XXXX`, for 4 or more hexadecimal digits `X`. _Most_ of Rust's grammar is
-confined to the ASCII range of Unicode, and is described in this document by a
-dialect of Extended Backus-Naur Form (EBNF), specifically a dialect of EBNF
-supported by common automated LL(k) parsing tools such as `llgen`, rather than
-the dialect given in ISO 14977. The dialect can be defined self-referentially
-as follows:
-
-```antlr
-grammar : rule + ;
-rule    : nonterminal ':' productionrule ';' ;
-productionrule : production [ '|' production ] * ;
-production : term * ;
-term : element repeats ;
-element : LITERAL | IDENTIFIER | '[' productionrule ']' ;
-repeats : [ '*' | '+' ] NUMBER ? | NUMBER ? | '?' ;
-```
-
-Where:
-
-- Whitespace in the grammar is ignored.
-- Square brackets are used to group rules.
-- `LITERAL` is a single printable ASCII character, or an escaped hexadecimal
-  ASCII code of the form `\xQQ`, in single quotes, denoting the corresponding
-  Unicode codepoint `U+00QQ`.
-- `IDENTIFIER` is a nonempty string of ASCII letters and underscores.
-- The `repeat` forms apply to the adjacent `element`, and are as follows:
-  - `?` means zero or one repetition
-  - `*` means zero or more repetitions
-  - `+` means one or more repetitions
-  - NUMBER trailing a repeat symbol gives a maximum repetition count
-  - NUMBER on its own gives an exact repetition count
-
-This EBNF dialect should hopefully be familiar to many readers.
-
-## Unicode productions
-
-A few productions in Rust's grammar permit Unicode codepoints outside the ASCII
-range. We define these productions in terms of character properties specified
-in the Unicode standard, rather than in terms of ASCII-range codepoints. The
-section [Special Unicode Productions](#special-unicode-productions) lists these
-productions.
-
-## String table productions
-
-Some rules in the grammar &mdash; notably [unary
-operators](#unary-operator-expressions), [binary
-operators](#binary-operator-expressions), and [keywords](#keywords) &mdash; are
-given in a simplified form: as a listing of a table of unquoted, printable
-whitespace-separated strings. These cases form a subset of the rules regarding
-the [token](#tokens) rule, and are assumed to be the result of a
-lexical-analysis phase feeding the parser, driven by a DFA, operating over the
-disjunction of all such string table entries.
-
-When such a string enclosed in double-quotes (`"`) occurs inside the grammar,
-it is an implicit reference to a single member of such a string table
-production. See [tokens](#tokens) for more information.
-
-# Lexical structure
-
-## Input format
-
-Rust input is interpreted as a sequence of Unicode codepoints encoded in UTF-8.
-Most Rust grammar rules are defined in terms of printable ASCII-range
-codepoints, but a small number are defined in terms of Unicode properties or
-explicit codepoint lists. [^inputformat]
-
-[^inputformat]: Substitute definitions for the special Unicode productions are
-  provided to the grammar verifier, restricted to ASCII range, when verifying the
-  grammar in this document.
-
-## Special Unicode Productions
-
-The following productions in the Rust grammar are defined in terms of Unicode
-properties: `ident`, `non_null`, `non_eol`, `non_single_quote` and
-`non_double_quote`.
-
-### Identifiers
-
-The `ident` production is any nonempty Unicode string of
-the following form:
-
-- The first character is in one of the following ranges `U+0041` to `U+005A`
-("A" to "Z"), `U+0061` to `U+007A` ("a" to "z"), or `U+005F` ("\_").
-- The remaining characters are in the range `U+0030` to `U+0039` ("0" to "9"),
-or any of the prior valid initial characters.
-
-as long as the identifier does _not_ occur in the set of [keywords](#keywords).
-
-### Delimiter-restricted productions
-
-Some productions are defined by exclusion of particular Unicode characters:
-
-- `non_null` is any single Unicode character aside from `U+0000` (null)
-- `non_eol` is any single Unicode character aside from `U+000A` (`'\n'`)
-- `non_single_quote` is any single Unicode character aside from `U+0027`  (`'`)
-- `non_double_quote` is any single Unicode character aside from `U+0022` (`"`)
-
-## Comments
-
-```antlr
-comment : block_comment | line_comment ;
-block_comment : "/*" block_comment_body * "*/" ;
-block_comment_body : [block_comment | character] * ;
-line_comment : "//" non_eol * ;
-```
-
-**FIXME:** add doc grammar?
-
-## Whitespace
-
-```antlr
-whitespace_char : '\x20' | '\x09' | '\x0a' | '\x0d' ;
-whitespace : [ whitespace_char | comment ] + ;
-```
-
-## Tokens
-
-```antlr
-simple_token : keyword | unop | binop ;
-token : simple_token | ident | literal | symbol | whitespace token ;
-```
-
-### Keywords
-
-<p id="keyword-table-marker"></p>
-
-|          |          |          |          |          |
-|----------|----------|----------|----------|----------|
-| _        | abstract | alignof  | as       | become   |
-| box      | break    | const    | continue | crate    |
-| do       | else     | enum     | extern   | false    |
-| final    | fn       | for      | if       | impl     |
-| in       | let      | loop     | macro    | match    |
-| mod      | move     | mut      | offsetof | override |
-| priv     | proc     | pub      | pure     | ref      |
-| return   | Self     | self     | sizeof   | static   |
-| struct   | super    | trait    | true     | type     |
-| typeof   | unsafe   | unsized  | use      | virtual  |
-| where    | while    | yield    |          |          |
-
-
-Each of these keywords has special meaning in its grammar, and all of them are
-excluded from the `ident` rule.
-
-Not all of these keywords are used by the language. Some of them were used
-before Rust 1.0, and were left reserved once their implementations were
-removed. Some of them were reserved before 1.0 to make space for possible
-future features.
-
-### Literals
-
-```antlr
-lit_suffix : ident;
-literal : [ string_lit | char_lit | byte_string_lit | byte_lit | num_lit | bool_lit ] lit_suffix ?;
-```
-
-The optional `lit_suffix` production is only used for certain numeric literals,
-but is reserved for future extension. That is, the above gives the lexical
-grammar, but a Rust parser will reject everything but the 12 special cases
-mentioned in [Number literals](reference/tokens.html#number-literals) in the
-reference.
-
-#### Character and string literals
-
-```antlr
-char_lit : '\x27' char_body '\x27' ;
-string_lit : '"' string_body * '"' | 'r' raw_string ;
-
-char_body : non_single_quote
-          | '\x5c' [ '\x27' | common_escape | unicode_escape ] ;
-
-string_body : non_double_quote
-            | '\x5c' [ '\x22' | common_escape | unicode_escape ] ;
-raw_string : '"' raw_string_body '"' | '#' raw_string '#' ;
-
-common_escape : '\x5c'
-              | 'n' | 'r' | 't' | '0'
-              | 'x' hex_digit 2
-unicode_escape : 'u' '{' hex_digit+ 6 '}';
-
-hex_digit : 'a' | 'b' | 'c' | 'd' | 'e' | 'f'
-          | 'A' | 'B' | 'C' | 'D' | 'E' | 'F'
-          | dec_digit ;
-oct_digit : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' ;
-dec_digit : '0' | nonzero_dec ;
-nonzero_dec: '1' | '2' | '3' | '4'
-           | '5' | '6' | '7' | '8' | '9' ;
-```
-
-#### Byte and byte string literals
-
-```antlr
-byte_lit : "b\x27" byte_body '\x27' ;
-byte_string_lit : "b\x22" string_body * '\x22' | "br" raw_byte_string ;
-
-byte_body : ascii_non_single_quote
-          | '\x5c' [ '\x27' | common_escape ] ;
-
-byte_string_body : ascii_non_double_quote
-            | '\x5c' [ '\x22' | common_escape ] ;
-raw_byte_string : '"' raw_byte_string_body '"' | '#' raw_byte_string '#' ;
-
-```
-
-#### Number literals
-
-```antlr
-num_lit : nonzero_dec [ dec_digit | '_' ] * float_suffix ?
-        | '0' [       [ dec_digit | '_' ] * float_suffix ?
-              | 'b'   [ '1' | '0' | '_' ] +
-              | 'o'   [ oct_digit | '_' ] +
-              | 'x'   [ hex_digit | '_' ] +  ] ;
-
-float_suffix : [ exponent | '.' dec_lit exponent ? ] ? ;
-
-exponent : ['E' | 'e'] ['-' | '+' ] ? dec_lit ;
-dec_lit : [ dec_digit | '_' ] + ;
-```
-
-#### Boolean literals
-
-```antlr
-bool_lit : [ "true" | "false" ] ;
-```
-
-The two values of the boolean type are written `true` and `false`.
-
-### Symbols
-
-```antlr
-symbol : "::" | "->"
-       | '#' | '[' | ']' | '(' | ')' | '{' | '}'
-       | ',' | ';' ;
-```
-
-Symbols are a general class of printable [tokens](#tokens) that play structural
-roles in a variety of grammar productions. They are cataloged here for
-completeness as the set of remaining miscellaneous printable tokens that do not
-otherwise appear as [unary operators](#unary-operator-expressions), [binary
-operators](#binary-operator-expressions), or [keywords](#keywords).
-
-## Paths
-
-```antlr
-expr_path : [ "::" ] ident [ "::" expr_path_tail ] + ;
-expr_path_tail : '<' type_expr [ ',' type_expr ] + '>'
-               | expr_path ;
-
-type_path : ident [ type_path_tail ] + ;
-type_path_tail : '<' type_expr [ ',' type_expr ] + '>'
-               | "::" type_path ;
-```
-
-# Syntax extensions
-
-## Macros
-
-```antlr
-expr_macro_rules : "macro_rules" '!' ident '(' macro_rule * ')' ';'
-                 | "macro_rules" '!' ident '{' macro_rule * '}' ;
-macro_rule : '(' matcher * ')' "=>" '(' transcriber * ')' ';' ;
-matcher : '(' matcher * ')' | '[' matcher * ']'
-        | '{' matcher * '}' | '$' ident ':' ident
-        | '$' '(' matcher * ')' sep_token? [ '*' | '+' ]
-        | non_special_token ;
-transcriber : '(' transcriber * ')' | '[' transcriber * ']'
-            | '{' transcriber * '}' | '$' ident
-            | '$' '(' transcriber * ')' sep_token? [ '*' | '+' ]
-            | non_special_token ;
-```
-
-# Crates and source files
-
-**FIXME:** grammar? What production covers #![crate_id = "foo"] ?
-
-# Items and attributes
-
-**FIXME:** grammar?
-
-## Items
-
-```antlr
-item : vis ? mod_item | fn_item | type_item | struct_item | enum_item
-     | const_item | static_item | trait_item | impl_item | extern_block_item ;
-```
-
-### Type Parameters
-
-**FIXME:** grammar?
-
-### Modules
-
-```antlr
-mod_item : "mod" ident ( ';' | '{' mod '}' );
-mod : [ view_item | item ] * ;
-```
-
-#### View items
-
-```antlr
-view_item : extern_crate_decl | use_decl ';' ;
-```
-
-##### Extern crate declarations
-
-```antlr
-extern_crate_decl : "extern" "crate" crate_name
-crate_name: ident | ( ident "as" ident )
-```
-
-##### Use declarations
-
-```antlr
-use_decl : vis ? "use" [ path "as" ident
-                        | path_glob ] ;
-
-path_glob : ident [ "::" [ path_glob
-                          | '*' ] ] ?
-          | '{' path_item [ ',' path_item ] * '}' ;
-
-path_item : ident | "self" ;
-```
-
-### Functions
-
-**FIXME:** grammar?
-
-#### Generic functions
-
-**FIXME:** grammar?
-
-#### Unsafety
-
-**FIXME:** grammar?
-
-##### Unsafe functions
-
-**FIXME:** grammar?
-
-##### Unsafe blocks
-
-**FIXME:** grammar?
-
-#### Diverging functions
-
-**FIXME:** grammar?
-
-### Type definitions
-
-**FIXME:** grammar?
-
-### Structures
-
-**FIXME:** grammar?
-
-### Enumerations
-
-**FIXME:** grammar?
-
-### Constant items
-
-```antlr
-const_item : "const" ident ':' type '=' expr ';' ;
-```
-
-### Static items
-
-```antlr
-static_item : "static" ident ':' type '=' expr ';' ;
-```
-
-#### Mutable statics
-
-**FIXME:** grammar?
-
-### Traits
-
-**FIXME:** grammar?
-
-### Implementations
-
-**FIXME:** grammar?
-
-### External blocks
-
-```antlr
-extern_block_item : "extern" '{' extern_block '}' ;
-extern_block : [ foreign_fn ] * ;
-```
-
-## Visibility and Privacy
-
-```antlr
-vis : "pub" ;
-```
-### Re-exporting and Visibility
-
-See [Use declarations](#use-declarations).
-
-## Attributes
-
-```antlr
-attribute : '#' '!' ? '[' meta_item ']' ;
-meta_item : ident [ '=' literal
-                  | '(' meta_seq ')' ] ? ;
-meta_seq : meta_item [ ',' meta_seq ] ? ;
-```
-
-# Statements and expressions
-
-## Statements
-
-```antlr
-stmt : decl_stmt | expr_stmt | ';' ;
-```
-
-### Declaration statements
-
-```antlr
-decl_stmt : item | let_decl ;
-```
-
-#### Item declarations
-
-See [Items](#items).
-
-#### Variable declarations
-
-```antlr
-let_decl : "let" pat [':' type ] ? [ init ] ? ';' ;
-init : [ '=' ] expr ;
-```
-
-### Expression statements
-
-```antlr
-expr_stmt : expr ';' ;
-```
-
-## Expressions
-
-```antlr
-expr : literal | path | tuple_expr | unit_expr | struct_expr
-     | block_expr | method_call_expr | field_expr | array_expr
-     | idx_expr | range_expr | unop_expr | binop_expr
-     | paren_expr | call_expr | lambda_expr | while_expr
-     | loop_expr | break_expr | continue_expr | for_expr
-     | if_expr | match_expr | if_let_expr | while_let_expr
-     | return_expr ;
-```
-
-#### Lvalues, rvalues and temporaries
-
-**FIXME:** grammar?
-
-#### Moved and copied types
-
-**FIXME:** Do we want to capture this in the grammar as different productions?
-
-### Literal expressions
-
-See [Literals](#literals).
-
-### Path expressions
-
-See [Paths](#paths).
-
-### Tuple expressions
-
-```antlr
-tuple_expr : '(' [ expr [ ',' expr ] * | expr ',' ] ? ')' ;
-```
-
-### Unit expressions
-
-```antlr
-unit_expr : "()" ;
-```
-
-### Structure expressions
-
-```antlr
-struct_expr_field_init : ident | ident ':' expr ;
-struct_expr : expr_path '{' struct_expr_field_init
-                      [ ',' struct_expr_field_init ] *
-                      [ ".." expr ] '}' |
-              expr_path '(' expr
-                      [ ',' expr ] * ')' |
-              expr_path ;
-```
-
-### Block expressions
-
-```antlr
-block_expr : '{' [ stmt | item ] *
-                 [ expr ] '}' ;
-```
-
-### Method-call expressions
-
-```antlr
-method_call_expr : expr '.' ident paren_expr_list ;
-```
-
-### Field expressions
-
-```antlr
-field_expr : expr '.' ident ;
-```
-
-### Array expressions
-
-```antlr
-array_expr : '[' "mut" ? array_elems? ']' ;
-
-array_elems : [expr [',' expr]*] | [expr ';' expr] ;
-```
-
-### Index expressions
-
-```antlr
-idx_expr : expr '[' expr ']' ;
-```
-
-### Range expressions
-
-```antlr
-range_expr : expr ".." expr |
-             expr ".." |
-             ".." expr |
-             ".." ;
-```
-
-### Unary operator expressions
-
-```antlr
-unop_expr : unop expr ;
-unop : '-' | '*' | '!' ;
-```
-
-### Binary operator expressions
-
-```antlr
-binop_expr : expr binop expr | type_cast_expr
-           | assignment_expr | compound_assignment_expr ;
-binop : arith_op | bitwise_op | lazy_bool_op | comp_op
-```
-
-#### Arithmetic operators
-
-```antlr
-arith_op : '+' | '-' | '*' | '/' | '%' ;
-```
-
-#### Bitwise operators
-
-```antlr
-bitwise_op : '&' | '|' | '^' | "<<" | ">>" ;
-```
-
-#### Lazy boolean operators
-
-```antlr
-lazy_bool_op : "&&" | "||" ;
-```
-
-#### Comparison operators
-
-```antlr
-comp_op : "==" | "!=" | '<' | '>' | "<=" | ">=" ;
-```
-
-#### Type cast expressions
-
-```antlr
-type_cast_expr : value "as" type ;
-```
-
-#### Assignment expressions
-
-```antlr
-assignment_expr : expr '=' expr ;
-```
-
-#### Compound assignment expressions
-
-```antlr
-compound_assignment_expr : expr [ arith_op | bitwise_op ] '=' expr ;
-```
-
-### Grouped expressions
-
-```antlr
-paren_expr : '(' expr ')' ;
-```
-
-### Call expressions
-
-```antlr
-expr_list : [ expr [ ',' expr ]* ] ? ;
-paren_expr_list : '(' expr_list ')' ;
-call_expr : expr paren_expr_list ;
-```
-
-### Lambda expressions
-
-```antlr
-ident_list : [ ident [ ',' ident ]* ] ? ;
-lambda_expr : '|' ident_list '|' expr ;
-```
-
-### While loops
-
-```antlr
-while_expr : [ lifetime ':' ] ? "while" no_struct_literal_expr '{' block '}' ;
-```
-
-### Infinite loops
-
-```antlr
-loop_expr : [ lifetime ':' ] ? "loop" '{' block '}';
-```
-
-### Break expressions
-
-```antlr
-break_expr : "break" [ lifetime ] ?;
-```
-
-### Continue expressions
-
-```antlr
-continue_expr : "continue" [ lifetime ] ?;
-```
-
-### For expressions
-
-```antlr
-for_expr : [ lifetime ':' ] ? "for" pat "in" no_struct_literal_expr '{' block '}' ;
-```
-
-### If expressions
-
-```antlr
-if_expr : "if" no_struct_literal_expr '{' block '}'
-          else_tail ? ;
-
-else_tail : "else" [ if_expr | if_let_expr
-                   | '{' block '}' ] ;
-```
-
-### Match expressions
-
-```antlr
-match_expr : "match" no_struct_literal_expr '{' match_arm * '}' ;
-
-match_arm : attribute * match_pat "=>" [ expr "," | '{' block '}' ] ;
-
-match_pat : pat [ '|' pat ] * [ "if" expr ] ? ;
-```
-
-### If let expressions
-
-```antlr
-if_let_expr : "if" "let" pat '=' expr '{' block '}'
-               else_tail ? ;
-```
-
-### While let loops
-
-```antlr
-while_let_expr : [ lifetime ':' ] ? "while" "let" pat '=' expr '{' block '}' ;
-```
-
-### Return expressions
-
-```antlr
-return_expr : "return" expr ? ;
-```
-
-# Type system
-
-**FIXME:** is this entire chapter relevant here? Or should it all have been covered by some production already?
-
-## Types
-
-### Primitive types
-
-**FIXME:** grammar?
-
-#### Machine types
-
-**FIXME:** grammar?
-
-#### Machine-dependent integer types
-
-**FIXME:** grammar?
-
-### Textual types
-
-**FIXME:** grammar?
-
-### Tuple types
-
-**FIXME:** grammar?
-
-### Array, and Slice types
-
-**FIXME:** grammar?
-
-### Structure types
-
-**FIXME:** grammar?
-
-### Enumerated types
-
-**FIXME:** grammar?
-
-### Pointer types
-
-**FIXME:** grammar?
-
-### Function types
-
-**FIXME:** grammar?
-
-### Closure types
-
-```antlr
-closure_type := [ 'unsafe' ] [ '<' lifetime-list '>' ] '|' arg-list '|'
-                [ ':' bound-list ] [ '->' type ]
-lifetime-list := lifetime | lifetime ',' lifetime-list
-arg-list := ident ':' type | ident ':' type ',' arg-list
-```
-
-### Never type
-An empty type
-
-```antlr
-never_type : "!" ;
-```
-
-### Object types
-
-**FIXME:** grammar?
-
-### Type parameters
-
-**FIXME:** grammar?
-
-### Type parameter bounds
-
-```antlr
-bound-list := bound | bound '+' bound-list '+' ?
-bound := ty_bound | lt_bound
-lt_bound := lifetime
-ty_bound := ty_bound_noparen | (ty_bound_noparen)
-ty_bound_noparen := [?] [ for<lt_param_defs> ] simple_path
-```
-
-### Self types
-
-**FIXME:** grammar?
-
-## Type kinds
-
-**FIXME:** this is probably not relevant to the grammar...
-
-# Memory and concurrency models
-
-**FIXME:** is this entire chapter relevant here? Or should it all have been covered by some production already?
-
-## Memory model
-
-### Memory allocation and lifetime
-
-### Memory ownership
-
-### Variables
-
-### Boxes
-
-## Threads
-
-### Communication between threads
-
-### Thread lifecycle
+[reference]: https://doc.rust-lang.org/reference/
+[grammar working group]: https://github.com/rust-lang/wg-grammar
diff --git a/src/doc/nomicon/src/atomics.md b/src/doc/nomicon/src/atomics.md
index 4cd209a..f750f09 100644
--- a/src/doc/nomicon/src/atomics.md
+++ b/src/doc/nomicon/src/atomics.md
@@ -1,20 +1,23 @@
 # Atomics
 
-Rust pretty blatantly just inherits C11's memory model for atomics. This is not
+Rust pretty blatantly just inherits the memory model for atomics from C++20. This is not
 due to this model being particularly excellent or easy to understand. Indeed,
 this model is quite complex and known to have [several flaws][C11-busted].
 Rather, it is a pragmatic concession to the fact that *everyone* is pretty bad
 at modeling atomics. At very least, we can benefit from existing tooling and
-research around C.
+research around the C/C++ memory model.
+(You'll often see this model referred to as "C/C++11" or just "C11". C just copies
+the C++ memory model; and C++11 was the first version of the model but it has
+received some bugfixes since then.)
 
 Trying to fully explain the model in this book is fairly hopeless. It's defined
 in terms of madness-inducing causality graphs that require a full book to
 properly understand in a practical way. If you want all the nitty-gritty
-details, you should check out [C's specification (Section 7.17)][C11-model].
+details, you should check out the [C++20 draft specification (Section 31)][C++-model].
 Still, we'll try to cover the basics and some of the problems Rust developers
 face.
 
-The C11 memory model is fundamentally about trying to bridge the gap between the
+The C++ memory model is fundamentally about trying to bridge the gap between the
 semantics we want, the optimizations compilers want, and the inconsistent chaos
 our hardware wants. *We* would like to just write programs and have them do
 exactly what we said but, you know, fast. Wouldn't that be great?
@@ -113,7 +116,7 @@
 
 # Data Accesses
 
-The C11 memory model attempts to bridge the gap by allowing us to talk about the
+The C++ memory model attempts to bridge the gap by allowing us to talk about the
 *causality* of our program. Generally, this is by establishing a *happens
 before* relationship between parts of the program and the threads that are
 running them. This gives the hardware and compiler room to optimize the program
@@ -148,7 +151,7 @@
 * Acquire
 * Relaxed
 
-(Note: We explicitly do not expose the C11 *consume* ordering)
+(Note: We explicitly do not expose the C++ *consume* ordering)
 
 TODO: negative reasoning vs positive reasoning? TODO: "can't forget to
 synchronize"
@@ -252,4 +255,4 @@
 
 
 [C11-busted]: http://plv.mpi-sws.org/c11comp/popl15.pdf
-[C11-model]: http://www.open-std.org/jtc1/sc22/wg14/www/standards.html#9899
+[C++-model]: http://eel.is/c++draft/atomics.order
diff --git a/src/doc/nomicon/src/working-with-unsafe.md b/src/doc/nomicon/src/working-with-unsafe.md
index 1864dd1..c29a75a 100644
--- a/src/doc/nomicon/src/working-with-unsafe.md
+++ b/src/doc/nomicon/src/working-with-unsafe.md
@@ -16,10 +16,14 @@
 }
 ```
 
-This function is safe and correct. We check that the index is in bounds, and if it
-is, index into the array in an unchecked manner. But even in such a trivial
-function, the scope of the unsafe block is questionable. Consider changing the
-`<` to a `<=`:
+This function is safe and correct. We check that the index is in bounds, and if
+it is, index into the array in an unchecked manner. We say that such a correct
+unsafely implemented function is *sound*, meaning that safe code cannot cause
+Undefined Behavior through it (which, remember, is the single fundamental
+property of Safe Rust).
+
+But even in such a trivial function, the scope of the unsafe block is
+questionable. Consider changing the `<` to a `<=`:
 
 ```rust
 fn index(idx: usize, arr: &[u8]) -> Option<u8> {
@@ -33,10 +37,10 @@
 }
 ```
 
-This program is now unsound, and yet *we only modified safe code*. This is the
-fundamental problem of safety: it's non-local. The soundness of our unsafe
-operations necessarily depends on the state established by otherwise
-"safe" operations.
+This program is now *unsound*, Safe Rust can cause Undefined Behavior, and yet
+*we only modified safe code*. This is the fundamental problem of safety: it's
+non-local. The soundness of our unsafe operations necessarily depends on the
+state established by otherwise "safe" operations.
 
 Safety is modular in the sense that opting into unsafety doesn't require you
 to consider arbitrary other kinds of badness. For instance, doing an unchecked
diff --git a/src/doc/reference/.travis.yml b/src/doc/reference/.travis.yml
index 3d8979f..7330450 100644
--- a/src/doc/reference/.travis.yml
+++ b/src/doc/reference/.travis.yml
@@ -1,7 +1,8 @@
-language: rust
+language: shell
 
-rust:
-  - nightly
+before_install:
+  - curl -sSL https://sh.rustup.rs | sh -s -- -y --default-toolchain=nightly --profile=minimal -c rust-docs
+  - export PATH="$HOME/.cargo/bin:$PATH"
 
 install:
   - travis_retry curl -Lf https://github.com/rust-lang-nursery/mdBook/releases/download/v0.3.1/mdbook-v0.3.1-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=$HOME/.cargo/bin
diff --git a/src/doc/reference/src/SUMMARY.md b/src/doc/reference/src/SUMMARY.md
index b1ba241..fb0e657 100644
--- a/src/doc/reference/src/SUMMARY.md
+++ b/src/doc/reference/src/SUMMARY.md
@@ -45,6 +45,7 @@
     - [Diagnostics](attributes/diagnostics.md)
     - [Code generation](attributes/codegen.md)
     - [Limits](attributes/limits.md)
+    - [Type System](attributes/type_system.md)
 
 - [Statements and expressions](statements-and-expressions.md)
     - [Statements](statements.md)
diff --git a/src/doc/reference/src/attributes.md b/src/doc/reference/src/attributes.md
index 059d4de..dfffe5c 100644
--- a/src/doc/reference/src/attributes.md
+++ b/src/doc/reference/src/attributes.md
@@ -50,6 +50,9 @@
 * [Generic lifetime or type parameter][generics] accept outer attributes.
 * Expressions accept outer attributes in limited situations, see [Expression
   Attributes] for details.
+* [Function][functions], [closure]] and [function pointer]
+  parameters accept outer attributes. This includes attributes on variadic parameters
+  denoted with `...` in function pointers and [external blocks][variadic functions].
 
 Some examples of attributes:
 
@@ -86,8 +89,7 @@
 ## Meta Item Attribute Syntax
 
 A "meta item" is the syntax used for the _Attr_ rule by most [built-in
-attributes] and the [`meta` macro fragment specifier]. It has the following
-grammar:
+attributes]. It has the following grammar:
 
 > **<sup>Syntax</sup>**\
 > _MetaItem_ :\
@@ -236,6 +238,9 @@
 - Features
   - `feature` — Used to enable unstable or experimental compiler features. See
     [The Unstable Book] for features implemented in `rustc`.
+- Type System
+  - [`non_exhaustive`] — Indicate that a type will have more fields/variants
+    added in future.
 
 [Doc comments]: comments.md#doc-comments
 [ECMA-334]: https://www.ecma-international.org/publications/standards/Ecma-334.htm
@@ -268,7 +273,6 @@
 [`link`]: items/external-blocks.md#the-link-attribute
 [`macro_export`]: macros-by-example.md#path-based-scope
 [`macro_use`]: macros-by-example.md#the-macro_use-attribute
-[`meta` macro fragment specifier]: macros-by-example.md
 [`must_use`]: attributes/diagnostics.md#the-must_use-attribute
 [`no_builtins`]: attributes/codegen.md#the-no_builtins-attribute
 [`no_implicit_prelude`]: items/modules.md#prelude-items
@@ -276,6 +280,7 @@
 [`no_main`]: crates-and-source-files.md#the-no_main-attribute
 [`no_mangle`]: abi.md#the-no_mangle-attribute
 [`no_std`]: crates-and-source-files.md#preludes-and-no_std
+[`non_exhaustive`]: attributes/type_system.md#the-non_exhaustive-attribute
 [`panic_handler`]: runtime.md#the-panic_handler-attribute
 [`path`]: items/modules.md#the-path-attribute
 [`proc_macro_attribute`]: procedural-macros.md#attribute-macros
@@ -306,3 +311,6 @@
 [statements]: statements.md
 [struct]: items/structs.md
 [union]: items/unions.md
+[closure]: expressions/closure-expr.md
+[function pointer]: types/function-pointer.md
+[variadic functions]: items/external-blocks.html#variadic-functions
diff --git a/src/doc/reference/src/attributes/type_system.md b/src/doc/reference/src/attributes/type_system.md
new file mode 100644
index 0000000..52bbb68
--- /dev/null
+++ b/src/doc/reference/src/attributes/type_system.md
@@ -0,0 +1,140 @@
+# Type system attributes
+
+The following [attributes] are used for changing how a type can be used.
+
+## The `non_exhaustive` attribute
+
+The *`non_exhaustive` attribute* indicates that a type or variant may have
+more fields or variants added in the future. It can be applied to
+[`struct`s][struct], [`enum`s][enum], and `enum` variants.
+
+The `non_exhaustive` attribute uses the [_MetaWord_] syntax and thus does not
+take any inputs.
+
+Within the defining crate, `non_exhaustive` has no effect.
+
+```rust
+#[non_exhaustive]
+pub struct Config {
+    pub window_width: u16,
+    pub window_height: u16,
+}
+
+#[non_exhaustive]
+pub enum Error {
+    Message(String),
+    Other,
+}
+
+pub enum Message {
+    #[non_exhaustive] Send { from: u32, to: u32, contents: String },
+    #[non_exhaustive] Reaction(u32),
+    #[non_exhaustive] Quit,
+}
+
+// Non-exhaustive structs can be constructed as normal within the defining crate.
+let config = Config { window_width: 640, window_height: 480 };
+
+// Non-exhaustive structs can be matched on exhaustively within the defining crate.
+if let Config { window_width, window_height } = config {
+    // ...
+}
+
+let error = Error::Other;
+let message = Message::Reaction(3);
+
+// Non-exhaustive enums can be matched on exhaustively within the defining crate.
+match error {
+    Error::Message(ref s) => { },
+    Error::Other => { },
+}
+
+match message {
+    // Non-exhaustive variants can be matched on exhaustively within the defining crate.
+    Message::Send { from, to, contents } => { },
+    Message::Reaction(id) => { },
+    Message::Quit => { },
+}
+```
+
+Outside of the defining crate, types annotated with `non_exhaustive` have limitations that
+preserve backwards compatibility when new fields or variants are added.
+
+Non-exhaustive types cannot be constructed outside of the defining crate:
+
+- Non-exhaustive variants ([`struct`][struct] or [`enum` variant][enum]) cannot be constructed
+  with a [_StructExpression_] \(including with [functional update syntax]).
+- [`enum`][enum] instances can be constructed in an [_EnumerationVariantExpression_].
+
+```rust,ignore (requires multiple crates)
+// `Config`, `Error`, and `Message` are types defined in an upstream crate that have been
+// annotated as `#[non_exhaustive]`.
+use upstream::{Config, Error, Message};
+
+// Cannot construct an instance of `Config`, if new fields were added in
+// a new version of `upstream` then this would fail to compile, so it is
+// disallowed.
+let config = Config { window_width: 640, window_height: 480 };
+
+// Can construct an instance of `Error`, new variants being introduced would
+// not result in this failing to compile.
+let error = Error::Message("foo".to_string());
+
+// Cannot construct an instance of `Message::Send` or `Message::Reaction`,
+// if new fields were added in a new version of `upstream` then this would
+// fail to compile, so it is disallowed.
+let message = Message::Send { from: 0, to: 1, contents: "foo".to_string(), };
+let message = Message::Reaction(0);
+
+// Cannot construct an instance of `Message::Quit`, if this were converted to
+// a tuple-variant `upstream` then this would fail to compile.
+let message = Message::Quit;
+```
+
+There are limitations when matching on non-exhaustive types outside of the defining crate:
+
+- When pattern matching on a non-exhaustive variant ([`struct`][struct] or [`enum` variant][enum]),
+  a [_StructPattern_] must be used which must include a `..`. Tuple variant constructor visibility
+  is lowered to `min($vis, pub(crate))`.
+- When pattern matching on a non-exhaustive [`enum`][enum], matching on a variant does not
+  contribute towards the exhaustiveness of the arms.
+
+```rust, ignore (requires multiple crates)
+// `Config`, `Error`, and `Message` are types defined in an upstream crate that have been
+// annotated as `#[non_exhaustive]`.
+use upstream::{Config, Error, Message};
+
+// Cannot match on a non-exhaustive enum without including a wildcard arm.
+match error {
+  Error::Message(ref s) => { },
+  Error::Other => { },
+  // would compile with: `_ => {},`
+}
+
+// Cannot match on a non-exhaustive struct without a wildcard.
+if let Ok(Config { window_width, window_height }) = config {
+    // would compile with: `..`
+}
+
+match message {
+  // Cannot match on a non-exhaustive struct enum variant without including a wildcard.
+  Message::Send { from, to, contents } => { },
+  // Cannot match on a non-exhaustive tuple or unit enum variant.
+  Message::Reaction(type) => { },
+  Message::Quit => { },
+}
+```
+
+Non-exhaustive types are always considered inhabited in downstream crates.
+
+[_EnumerationVariantExpression_]: ../expressions/enum-variant-expr.md
+[_MetaWord_]: ../attributes.md#meta-item-attribute-syntax
+[_StructExpression_]: ../expressions/struct-expr.md
+[_StructPattern_]: ../patterns.md#struct-patterns
+[_TupleStructPattern_]: ../patterns.md#tuple-struct-patterns
+[`if let`]: ../expressions/if-expr.md#if-let-expressions
+[`match`]: ../expressions/match-expr.md
+[attributes]: ../attributes.md
+[enum]: ../items/enumerations.md
+[functional update syntax]: ../expressions/struct-expr.md#functional-update-syntax
+[struct]: ../items/structs.md
diff --git a/src/doc/reference/src/expressions/await-expr.md b/src/doc/reference/src/expressions/await-expr.md
index 95037d7..a6e7dc5 100644
--- a/src/doc/reference/src/expressions/await-expr.md
+++ b/src/doc/reference/src/expressions/await-expr.md
@@ -52,12 +52,13 @@
 equivalent to the following (this desugaring is not normative):
 
 ```rust,ignore
-let future = /* <expr> */;
-loop {
-    let mut pin = unsafe { Pin::new_unchecked(&mut future) };
-    match Pin::future::poll(Pin::borrow(&mut pin), &mut current_context) {
-        Poll::Ready(r) => break r,
-        Poll::Pending => yield Poll::Pending,
+match /* <expr> */ {
+    mut pinned => loop {
+        let mut pin = unsafe { Pin::new_unchecked(&mut pinned) };
+        match Pin::future::poll(Pin::borrow(&mut pin), &mut current_context) {
+            Poll::Ready(r) => break r,
+            Poll::Pending => yield Poll::Pending,
+        }
     }
 }
 ```
diff --git a/src/doc/reference/src/expressions/closure-expr.md b/src/doc/reference/src/expressions/closure-expr.md
index aa9299b..74b8e20 100644
--- a/src/doc/reference/src/expressions/closure-expr.md
+++ b/src/doc/reference/src/expressions/closure-expr.md
@@ -10,7 +10,7 @@
 > &nbsp;&nbsp; _ClosureParam_ (`,` _ClosureParam_)<sup>\*</sup> `,`<sup>?</sup>
 >
 > _ClosureParam_ :\
-> &nbsp;&nbsp; [_Pattern_]&nbsp;( `:` [_Type_] )<sup>?</sup>
+> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> [_Pattern_]&nbsp;( `:` [_Type_] )<sup>?</sup>
 
 A _closure expression_ defines a closure and denotes it as a value, in a single
 expression. A closure expression is a pipe-symbol-delimited (`|`) list of
@@ -67,9 +67,15 @@
 ten_times(move |j| println!("{}, {}", word, j));
 ```
 
+## Attributes on closure parameters
+
+Attributes on closure parameters follow the same rules and restrictions as
+[regular function parameters].
+
 [block]: block-expr.md
 [function definitions]: ../items/functions.md
 [patterns]: ../patterns.md
+[regular function parameters]: ../items/functions.md#attributes-on-function-parameters
 
 [_Expression_]: ../expressions.md
 [_BlockExpression_]: block-expr.md
@@ -77,3 +83,4 @@
 [_Pattern_]: ../patterns.md
 [_Type_]: ../types.md#type-expressions
 [`let` binding]: ../statements.md#let-statements
+[_OuterAttribute_]: ../attributes.md
\ No newline at end of file
diff --git a/src/doc/reference/src/glossary.md b/src/doc/reference/src/glossary.md
index 6dc22b8..36c0c93 100644
--- a/src/doc/reference/src/glossary.md
+++ b/src/doc/reference/src/glossary.md
@@ -65,6 +65,12 @@
 An [item] that is not a member of an [implementation], such as a *free
 function* or a *free const*. Contrast to an [associated item].
 
+### Inhabited
+
+A type is inhabited if it has constructors and therefore can be instantiated. An inhabited type is
+not "empty" in the sense that there can be values of the type. Opposite of
+[Uninhabited](#uninhabited).
+
 ### Inherent implementation
 
 An [implementation] that applies to a nominal type, not to a trait-type pair.
@@ -159,6 +165,13 @@
 or unintended computation; or platform-specific results.
 [More][undefined-behavior].
 
+### Uninhabited
+
+A type is uninhabited if it has no constructors and therefore can never be instantiated. An
+uninhabited type is "empty" in the sense that there are no values of the type. The canonical
+example of an uninhabited type is the [never type] `!`, or an enum with no variants
+`enum Never { }`. Opposite of [Inhabited](#inhabited).
+
 [alignment]: type-layout.md#size-and-alignment
 [associated item]: #associated-item
 [enums]: items/enumerations.md
@@ -168,6 +181,7 @@
 [inherent implementation]: items/implementations.md#inherent-implementations
 [item]: items.md
 [method]: items/associated-items.md#methods
+[never type]: types/never.md
 [object safety]: items/traits.md#object-safety
 [structs]: items/structs.md
 [trait objects]: types/trait-object.md
diff --git a/src/doc/reference/src/items/associated-items.md b/src/doc/reference/src/items/associated-items.md
index 29ea6da..a7bc3de 100644
--- a/src/doc/reference/src/items/associated-items.md
+++ b/src/doc/reference/src/items/associated-items.md
@@ -86,8 +86,13 @@
 > &nbsp;&nbsp; &nbsp;&nbsp; [_BlockExpression_]
 >
 > _SelfParam_ :\
-> &nbsp;&nbsp; &nbsp;&nbsp; (`&` | `&` [_Lifetime_])<sup>?</sup> `mut`<sup>?</sup> `self`\
-> &nbsp;&nbsp; | `mut`<sup>?</sup> `self` (`:` [_Type_])<sup>?</sup>
+> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> ( _ShorthandSelf_ | _TypedSelf_ )
+>
+> _ShorthandSelf_ :\
+> &nbsp;&nbsp;  (`&` | `&` [_Lifetime_])<sup>?</sup> `mut`<sup>?</sup> `self`
+>
+> _TypedSelf_ :\
+> &nbsp;&nbsp; `mut`<sup>?</sup> `self` `:` [_Type_]
 
 Associated functions whose first parameter is named `self` are called *methods*
 and may be invoked using the [method call operator], for example, `x.foo()`, as
@@ -190,6 +195,11 @@
 > methods with anonymous parameters (e.g. `fn foo(u8)`). This is deprecated and
 > an error as of the 2018 edition. All parameters must have an argument name.
 
+#### Attributes on method parameters
+
+Attributes on method parameters follow the same rules and restrictions as
+[regular function parameters].
+
 ## Associated Types
 
 *Associated types* are [type aliases] associated with another type. Associated
@@ -336,6 +346,7 @@
 [`Box<Self>`]: ../special-types-and-traits.md#boxt
 [`Pin<P>`]: ../special-types-and-traits.md#pinp
 [`Rc<Self>`]: ../special-types-and-traits.md#rct
+[_OuterAttribute_]: ../attributes.md
 [traits]: traits.md
 [type aliases]: type-aliases.md
 [inherent implementations]: implementations.md#inherent-implementations
@@ -349,3 +360,4 @@
 [function item]: ../types/function-item.md
 [method call operator]: ../expressions/method-call-expr.md
 [path]: ../paths.md
+[regular function parameters]: functions.md#attributes-on-function-parameters 
\ No newline at end of file
diff --git a/src/doc/reference/src/items/external-blocks.md b/src/doc/reference/src/items/external-blocks.md
index f3e692a..6537084 100644
--- a/src/doc/reference/src/items/external-blocks.md
+++ b/src/doc/reference/src/items/external-blocks.md
@@ -8,9 +8,10 @@
 > &nbsp;&nbsp; `}`
 >
 > _ExternalItem_ :\
-> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup>\
-> &nbsp;&nbsp; [_Visibility_]<sup>?</sup>\
-> &nbsp;&nbsp; ( _ExternalStaticItem_ | _ExternalFunctionItem_ )
+> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> (\
+> &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; [_MacroInvocationSemi_]\
+> &nbsp;&nbsp; &nbsp;&nbsp; | ( [_Visibility_]<sup>?</sup> ( _ExternalStaticItem_ | _ExternalFunctionItem_ ) )\
+> &nbsp;&nbsp; )
 >
 > _ExternalStaticItem_ :\
 > &nbsp;&nbsp; `static` `mut`<sup>?</sup> [IDENTIFIER] `:` [_Type_] `;`
@@ -24,14 +25,14 @@
 > &nbsp;&nbsp; _NamedFunctionParam_ ( `,` _NamedFunctionParam_ )<sup>\*</sup> `,`<sup>?</sup>
 >
 > _NamedFunctionParam_ :\
-> &nbsp;&nbsp; ( [IDENTIFIER] | `_` ) `:` [_Type_]
+> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> ( [IDENTIFIER] | `_` ) `:` [_Type_]
 >
 > _NamedFunctionParametersWithVariadics_ :\
-> &nbsp;&nbsp; ( _NamedFunctionParam_ `,` )<sup>\*</sup> _NamedFunctionParam_ `,` `...`
+> &nbsp;&nbsp; ( _NamedFunctionParam_ `,` )<sup>\*</sup> _NamedFunctionParam_ `,` [_OuterAttribute_]<sup>\*</sup> `...`
 
 External blocks provide _declarations_ of items that are not _defined_ in the
 current crate and are the basis of Rust's foreign function interface. These are
-akin to unchecked imports. 
+akin to unchecked imports.
 
 Two kind of item _declarations_ are allowed in external blocks: [functions] and
 [statics]. Calling functions or accessing statics that are declared in external
@@ -162,6 +163,11 @@
 }
 ```
 
+### Attributes on function parameters
+
+Attributes on extern function parameters follow the same rules and
+restrictions as [regular function parameters].
+
 [IDENTIFIER]: ../identifiers.md
 [WebAssembly module]: https://webassembly.github.io/spec/core/syntax/modules.html
 [functions]: functions.md
@@ -170,6 +176,7 @@
 [_FunctionReturnType_]: functions.md
 [_Generics_]: generics.md
 [_InnerAttribute_]: ../attributes.md
+[_MacroInvocationSemi_]: ../macros.md#macro-invocation
 [_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax
 [_MetaNameValueStr_]: ../attributes.md#meta-item-attribute-syntax
 [_OuterAttribute_]: ../attributes.md
@@ -177,3 +184,4 @@
 [_Visibility_]: ../visibility-and-privacy.md
 [_WhereClause_]: generics.md#where-clauses
 [attributes]: ../attributes.md
+[regular function parameters]: functions.md#attributes-on-function-parameters
\ No newline at end of file
diff --git a/src/doc/reference/src/items/functions.md b/src/doc/reference/src/items/functions.md
index 63f436f..4bc4851 100644
--- a/src/doc/reference/src/items/functions.md
+++ b/src/doc/reference/src/items/functions.md
@@ -20,7 +20,7 @@
 > &nbsp;&nbsp; _FunctionParam_ (`,` _FunctionParam_)<sup>\*</sup> `,`<sup>?</sup>
 >
 > _FunctionParam_ :\
-> &nbsp;&nbsp; [_Pattern_] `:` [_Type_]
+> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> [_Pattern_] `:` [_Type_]
 >
 > _FunctionReturnType_ :\
 > &nbsp;&nbsp; `->` [_Type_]
@@ -180,12 +180,13 @@
 
 ## Const functions
 
-Functions qualified with the `const` keyword are const functions. _Const
-functions_  can be called from within [const context]s. When called from a const
-context, the function is interpreted by the compiler at compile time. The
-interpretation happens in the environment of the compilation target and not the
-host. So `usize` is `32` bits if you are compiling against a `32` bit system,
-irrelevant of whether you are building on a `64` bit or a `32` bit system.
+Functions qualified with the `const` keyword are const functions, as are
+[tuple struct] and [tuple variant] constructors. _Const functions_  can be
+called from within [const context]s. When called from a const context, the
+function is interpreted by the compiler at compile time. The interpretation
+happens in the environment of the compilation target and not the host. So
+`usize` is `32` bits if you are compiling against a `32` bit system, irrelevant
+of whether you are building on a `64` bit or a `32` bit system.
 
 If a const function is called outside a [const context], it is indistinguishable
 from any other function. You can freely do anything with a const function that
@@ -214,7 +215,9 @@
     are all permitted.
 
     This rule also applies to type parameters of impl blocks that
-    contain const methods
+    contain const methods.
+
+    This does not apply to tuple struct and tuple variant constructors.
 
 * Arithmetic and comparison operators on integers
 * All boolean operators except for `&&` and `||` which are banned since
@@ -345,12 +348,40 @@
 > Note: Except for lints, it is idiomatic to only use outer attributes on
 > function items.
 
-The attributes that have meaning on a function are [`cfg`], [`deprecated`],
+The attributes that have meaning on a function are [`cfg`], [`cfg_attr`], [`deprecated`],
 [`doc`], [`export_name`], [`link_section`], [`no_mangle`], [the lint check
 attributes], [`must_use`], [the procedural macro attributes], [the testing
 attributes], and [the optimization hint attributes]. Functions also accept
 attributes macros.
 
+## Attributes on function parameters
+
+[Outer attributes][attributes] are allowed on function parameters and the
+permitted [built-in attributes] are restricted to `cfg`, `cfg_attr`, `allow`,
+`warn`, `deny`, and `forbid`.
+
+```rust
+fn len(
+    #[cfg(windows)] slice: &[u16],
+    #[cfg(not(windows))] slice: &[u8],
+) -> usize {
+    slice.len()
+}
+```
+
+Inert helper attributes used by procedural macro attributes applied to items are also
+allowed but be careful to not include these inert attributes in your final `TokenStream`.
+
+For example, the following code defines an inert `some_inert_attribute` attribute that
+is not formally defined anywhere and the `some_proc_macro_attribute` procedural macro is
+responsible for detecting its presence and removing it from the output token stream.
+
+```rust,ignore
+#[some_proc_macro_attribute]
+fn foo_oof(#[some_inert_attribute] arg: u8) {
+}
+```
+
 [IDENTIFIER]: ../identifiers.md
 [RAW_STRING_LITERAL]: ../tokens.md#raw-string-literals
 [STRING_LITERAL]: ../tokens.md#string-literals
@@ -359,7 +390,10 @@
 [_Pattern_]: ../patterns.md
 [_Type_]: ../types.md#type-expressions
 [_WhereClause_]: generics.md#where-clauses
+[_OuterAttribute_]: ../attributes.md
 [const context]: ../const_eval.md#const-context
+[tuple struct]: structs.md
+[tuple variant]: enumerations.md
 [external block]: external-blocks.md
 [path]: ../paths.md
 [block]: ../expressions/block-expr.md
@@ -368,7 +402,8 @@
 [*function item type*]: ../types/function-item.md
 [Trait]: traits.md
 [attributes]: ../attributes.md
-[`cfg`]: ../conditional-compilation.md
+[`cfg`]: ../conditional-compilation.md#the-cfg-attribute
+[`cfg_attr`]: ../conditional-compilation.md#the-cfg_attr-attribute
 [the lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes
 [the procedural macro attributes]: ../procedural-macros.md
 [the testing attributes]: ../attributes/testing.md
@@ -383,3 +418,4 @@
 [`link_section`]: ../abi.md#the-link_section-attribute
 [`no_mangle`]: ../abi.md#the-no_mangle-attribute
 [external_block_abi]: external-blocks.md#abi
+[built-in attributes]: ../attributes.html#built-in-attributes-index
diff --git a/src/doc/reference/src/items/generics.md b/src/doc/reference/src/items/generics.md
index 074b5cf..6dc8f01 100644
--- a/src/doc/reference/src/items/generics.md
+++ b/src/doc/reference/src/items/generics.md
@@ -92,10 +92,11 @@
 This example shows using a custom derive attribute to modify the meaning of a
 generic parameter.
 
-```ignore
+```rust,ignore
 // Assume that the derive for MyFlexibleClone declared `my_flexible_clone` as
 // an attribute it understands.
-#[derive(MyFlexibleClone)] struct Foo<#[my_flexible_clone(unbounded)] H> {
+#[derive(MyFlexibleClone)]
+struct Foo<#[my_flexible_clone(unbounded)] H> {
     a: *const H
 }
 ```
diff --git a/src/doc/reference/src/items/traits.md b/src/doc/reference/src/items/traits.md
index e835a60..dea8eca 100644
--- a/src/doc/reference/src/items/traits.md
+++ b/src/doc/reference/src/items/traits.md
@@ -38,7 +38,7 @@
 > &nbsp;&nbsp; _TraitFunctionParam_ (`,` _TraitFunctionParam_)<sup>\*</sup> `,`<sup>?</sup>
 >
 > _TraitFunctionParam_<sup>[†](#parameter-patterns)</sup> :\
-> &nbsp;&nbsp; ( [_Pattern_] `:` )<sup>?</sup> [_Type_]
+> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> ( [_Pattern_] `:` )<sup>?</sup> [_Type_]
 >
 > _TraitConst_ :\
 > &nbsp;&nbsp; `const` [IDENTIFIER] `:` [_Type_]&nbsp;( `=` [_Expression_] )<sup>?</sup> `;`
diff --git a/src/doc/reference/src/items/unions.md b/src/doc/reference/src/items/unions.md
index 22c40df..d63bf1e 100644
--- a/src/doc/reference/src/items/unions.md
+++ b/src/doc/reference/src/items/unions.md
@@ -119,8 +119,8 @@
 fn is_zero(v: Value) -> bool {
     unsafe {
         match v {
-            Value { tag: I, u: U { i: 0 } } => true,
-            Value { tag: F, u: U { f: 0.0 } } => true,
+            Value { tag: Tag::I, u: U { i: 0 } } => true,
+            Value { tag: Tag::F, u: U { f: num } } if num == 0.0 => true,
             _ => false,
         }
     }
diff --git a/src/doc/reference/src/keywords.md b/src/doc/reference/src/keywords.md
index 4eac070..9df5b2a 100644
--- a/src/doc/reference/src/keywords.md
+++ b/src/doc/reference/src/keywords.md
@@ -60,6 +60,8 @@
 The following keywords were added beginning in the 2018 edition.
 
 > **<sup>Lexer 2018+</sup>**\
+> KW_ASYNC          : `async`\
+> KW_AWAIT          : `await`\
 > KW_DYN            : `dyn`
 
 ## Reserved keywords
@@ -86,8 +88,6 @@
 The following keywords are reserved beginning in the 2018 edition.
 
 > **<sup>Lexer 2018+</sup>**\
-> KW_ASYNC : `async`\
-> KW_AWAIT : `await`\
 > KW_TRY   : `try`
 
 ## Weak keywords
diff --git a/src/doc/reference/src/macros-by-example.md b/src/doc/reference/src/macros-by-example.md
index 8cae03a..fd7c335 100644
--- a/src/doc/reference/src/macros-by-example.md
+++ b/src/doc/reference/src/macros-by-example.md
@@ -128,7 +128,7 @@
   * `ident`: an [IDENTIFIER_OR_KEYWORD]
   * `path`: a [_TypePath_] style path
   * `tt`: a [_TokenTree_]&nbsp;(a single [token] or tokens in matching delimiters `()`, `[]`, or `{}`)
-  * `meta`: a [_MetaItem_], the contents of an attribute
+  * `meta`: an [_Attr_], the contents of an attribute
   * `lifetime`: a [LIFETIME_TOKEN]
   * `vis`: a possibly empty [_Visibility_] qualifier
   * `literal`: matches `-`<sup>?</sup>[_LiteralExpression_]
@@ -477,12 +477,12 @@
 [LIFETIME_TOKEN]: tokens.md#lifetimes-and-loop-labels
 [Metavariables]: #metavariables
 [Repetitions]: #repetitions
+[_Attr_]: attributes.md
 [_BlockExpression_]: expressions/block-expr.md
 [_DelimTokenTree_]: macros.md
 [_Expression_]: expressions.md
 [_Item_]: items.md
 [_LiteralExpression_]: expressions/literal-expr.md
-[_MetaItem_]: attributes.md#meta-item-attribute-syntax
 [_MetaListIdents_]: attributes.md#meta-item-attribute-syntax
 [_Pattern_]: patterns.md
 [_Statement_]: statements.md
diff --git a/src/doc/reference/src/macros.md b/src/doc/reference/src/macros.md
index cdac0b2..f1ca1a9 100644
--- a/src/doc/reference/src/macros.md
+++ b/src/doc/reference/src/macros.md
@@ -37,6 +37,7 @@
 * [Types]
 * [Items] including [associated items]
 * [`macro_rules`] transcribers
+* [External blocks]
 
 When used as an item or a statement, the _MacroInvocationSemi_ form is used
 where a semicolon is required at the end when not using curly braces.
@@ -99,3 +100,4 @@
 [statements]: statements.md
 [types]: types.md
 [visibility qualifiers]: visibility-and-privacy.md
+[External blocks]: items/external-blocks.md
diff --git a/src/doc/reference/src/procedural-macros.md b/src/doc/reference/src/procedural-macros.md
index 9818b26..ff3f6df 100644
--- a/src/doc/reference/src/procedural-macros.md
+++ b/src/doc/reference/src/procedural-macros.md
@@ -75,9 +75,7 @@
 These macros are defined by a [public]&#32;[function] with the `proc_macro`
 [attribute] and a signature of `(TokenStream) -> TokenStream`. The input
 [`TokenStream`] is what is inside the delimiters of the macro invocation and the
-output [`TokenStream`] replaces the entire macro invocation. It may contain an
-arbitrary number of [items]. These macros cannot expand to syntax that defines
-new `macro_rules` style macros.
+output [`TokenStream`] replaces the entire macro invocation.
 
 For example, the following macro definition ignores its input and outputs a
 function `answer` into its scope.
@@ -105,11 +103,12 @@
 }
 ```
 
-These macros are only invokable in [modules]. They cannot even be invoked to
-create [item declaration statements]. Furthermore, they must either be invoked
-with curly braces and no semicolon or a different delimiter followed by a
-semicolon. For example, `make_answer` from the previous example can be invoked
-as `make_answer!{}`, `make_answer!();` or `make_answer![];`.
+Function-like procedural macros may expand to a [type] or any number of
+[items], including [`macro_rules`] definitions. They may be invoked in a [type
+expression], [item] position (except as a [statement]), including items in
+[`extern` blocks], inherent and trait [implementations], and [trait
+definitions]. They cannot be used in a [statement], [expression], or
+[pattern].
 
 ### Derive macros
 
@@ -192,7 +191,9 @@
 
 ### Attribute macros
 
-*Attribute macros* define new [attributes] which can be attached to [items].
+*Attribute macros* define new [outer attributes][attributes] which can be
+attached to [items], including items in [`extern` blocks], inherent and trait
+[implementations], and [trait definitions].
 
 Attribute macros are defined by a [public]&#32;[function] with the
 `proc_macro_attribute` [attribute] that has a signature of `(TokenStream,
@@ -201,8 +202,7 @@
 the attribute is written as a bare attribute name, the attribute
 [`TokenStream`] is empty. The second [`TokenStream`] is the rest of the [item]
 including other [attributes] on the [item]. The returned [`TokenStream`]
-replaces the [item] with an arbitrary number of [items]. These macros cannot
-expand to syntax that defines new `macro_rules` style macros.
+replaces the [item] with an arbitrary number of [items].
 
 For example, this attribute macro takes the input stream and returns it as is,
 effectively being the no-op of attributes.
@@ -266,28 +266,35 @@
 // out: item: "fn invoke4() {}"
 ```
 
+[Attribute macros]: #attribute-macros
+[Cargo's build scripts]: ../cargo/reference/build-scripts.html
+[Derive macros]: #derive-macros
+[Function-like macros]: #function-like-procedural-macros
 [`TokenStream`]: ../proc_macro/struct.TokenStream.html
 [`TokenStream`s]: ../proc_macro/struct.TokenStream.html
 [`compile_error`]: ../std/macro.compile_error.html
 [`derive` attribute]: attributes/derive.md
+[`extern` blocks]: items/external-blocks.md
+[`macro_rules`]: macros-by-example.md
 [`proc_macro` crate]: ../proc_macro/index.html
-[Cargo's build scripts]: ../cargo/reference/build-scripts.html
-[Derive macros]: #derive-macros
-[Attribute macros]: #attribute-macros
-[Function-like macros]: #function-like-procedural-macros
 [attribute]: attributes.md
 [attributes]: attributes.md
 [block]: expressions/block-expr.md
 [crate type]: linkage.md
 [derive macro helper attributes]: #derive-macro-helper-attributes
 [enum]: items/enumerations.md
+[expression]: expressions.md
+[function]: items/functions.md
+[implementations]: items/implementations.md
 [inert]: attributes.md#active-and-inert-attributes
 [item]: items.md
-[item declaration statements]: statements.md#item-declarations
 [items]: items.md
-[function]: items/functions.md
 [module]: items/modules.md
-[modules]: items/modules.md
+[pattern]: patterns.md
 [public]: visibility-and-privacy.md
+[statement]: statements.md
 [struct]: items/structs.md
+[trait definitions]: items/traits.md
+[type expression]: types.md#type-expressions
+[type]: types.md
 [union]: items/unions.md
diff --git a/src/doc/reference/src/type-layout.md b/src/doc/reference/src/type-layout.md
index b0cc71a..57e801e 100644
--- a/src/doc/reference/src/type-layout.md
+++ b/src/doc/reference/src/type-layout.md
@@ -34,22 +34,17 @@
 
 The size of most primitives is given in this table.
 
-Type | `size_of::<Type>()`
-- | - | -
-bool | 1
-u8 | 1
-u16 | 2
-u32 | 4
-u64 | 8
-u128 | 16
-i8 | 1
-i16 | 2
-i32 | 4
-i64 | 8
-i128 | 16
-f32 | 4
-f64 | 8
-char | 4
+| Type              | `size_of::<Type>()`|
+|--                 |--                  |
+| `bool`            | 1                  |
+| `u8` / `i8`       | 1                  |
+| `u16` / `i16`     | 2                  |
+| `u32` / `i32`     | 4                  |
+| `u64` / `i64`     | 8                  |
+| `u128` / `i128`   | 16                 |
+| `f32`             | 4                  |
+| `f64`             | 8                  |
+| `char`            | 4                  |
 
 `usize` and `isize` have a size big enough to contain every address on the
 target platform. For example, on a 32 bit target, this is 4 bytes and on a 64
diff --git a/src/doc/reference/src/types/function-pointer.md b/src/doc/reference/src/types/function-pointer.md
index 88ef50c..912ee93 100644
--- a/src/doc/reference/src/types/function-pointer.md
+++ b/src/doc/reference/src/types/function-pointer.md
@@ -15,10 +15,10 @@
 > &nbsp;&nbsp; _MaybeNamedParam_ ( `,` _MaybeNamedParam_ )<sup>\*</sup> `,`<sup>?</sup>
 >
 > _MaybeNamedParam_ :\
-> &nbsp;&nbsp; ( ( [IDENTIFIER] | `_` ) `:` )<sup>?</sup> [_Type_]
+> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> ( ( [IDENTIFIER] | `_` ) `:` )<sup>?</sup> [_Type_]
 >
 > _MaybeNamedFunctionParametersVariadic_ :\
-> &nbsp;&nbsp; ( _MaybeNamedParam_ `,` )<sup>\*</sup> _MaybeNamedParam_ `,` `...`
+> &nbsp;&nbsp; ( _MaybeNamedParam_ `,` )<sup>\*</sup> _MaybeNamedParam_ `,` [_OuterAttribute_]<sup>\*</sup> `...`
 
 Function pointer types, written using the `fn` keyword, refer to a function
 whose identity is not necessarily known at compile-time. They can be created
@@ -44,13 +44,20 @@
 x = bo(5,7);
 ```
 
+## Attributes on function pointer parameters
+
+Attributes on function pointer parameters follow the same rules and
+restrictions as [regular function parameters].
+
 [IDENTIFIER]: ../identifiers.md
 [_ForLifetimes_]: ../items/generics.md#where-clauses
 [_FunctionQualifiers_]: ../items/functions.md
 [_TypeNoBounds_]: ../types.md#type-expressions
 [_Type_]: ../types.md#type-expressions
+[_OuterAttribute_]: ../attributes.md
 [`extern`]: ../items/external-blocks.md
 [closures]: closure.md
 [extern function]: ../items/functions.md#extern-function-qualifier
 [function items]: function-item.md
 [unsafe function]: ../unsafe-functions.md
+[regular function parameters]: ../items/functions.md#attributes-on-function-parameters
\ No newline at end of file
diff --git a/src/doc/reference/theme/header.hbs b/src/doc/reference/theme/header.hbs
deleted file mode 100644
index 85db69f..0000000
--- a/src/doc/reference/theme/header.hbs
+++ /dev/null
@@ -1,8 +0,0 @@
-<header><p class="warning">
-    For now, this reference is a best-effort document. We strive for validity
-    and completeness, but are not yet there. In the future, the docs and lang
-    teams will work together to figure out how best to do this. Until then, this
-    is a best-effort attempt. If you find something wrong or missing, file an
-    <a href="https://github.com/rust-lang-nursery/reference/issues">issue</a> or
-    send in a pull request.
-</p></header>
\ No newline at end of file
diff --git a/src/doc/reference/theme/reference.css b/src/doc/reference/theme/reference.css
index e146305..06ea927 100644
--- a/src/doc/reference/theme/reference.css
+++ b/src/doc/reference/theme/reference.css
@@ -1,58 +1,3 @@
-/* These selectors moves things around to make space for the warning on the
-   top of each page. Get rid of it when the warning goes away. */
-.page-wrapper > .nav-chapters {
-    /* add height for warning content & margin */
-    top: 120px;
-}
-
-.sidebar-visible .content {
-    top: 120px;
-}
-
-.nav-chapters {
-    top: 120px;
-}
-
-p.warning {
-    background-color: rgb(242, 222, 222);
-    border-bottom-color: rgb(238, 211, 215);
-    border-bottom-left-radius: 4px;
-    border-bottom-right-radius: 4px;
-    border-bottom-style: solid;
-    border-bottom-width: 0.666667px;
-    border-image-outset: 0 0 0 0;
-    border-image-repeat: stretch stretch;
-    border-image-slice: 100% 100% 100% 100%;
-    border-image-source: none;
-    border-image-width: 1 1 1 1;
-    border-left-color: rgb(238, 211, 215);
-    border-left-style: solid;
-    border-left-width: 0.666667px;
-    border-right-color: rgb(238, 211, 215);
-    border-right-style: solid;
-    border-right-width: 0.666667px;
-    border-top-color: rgb(238, 211, 215);
-    border-top-left-radius: 4px;
-    border-top-right-radius: 4px;
-    border-top-style: solid;
-    border-top-width: 0.666667px;
-    color: rgb(185, 74, 72);
-    margin-bottom: 0px;
-    margin-left: 0px;
-    margin-right: 0px;
-    margin-top: 30px;
-    padding-bottom: 8px;
-    padding-left: 14px;
-    padding-right: 35px;
-    padding-top: 8px;
-}
-p.warning strong {
-    color: rgb(185, 74, 72)
-}
-p.warning a {
-    color: rgb(0, 136, 204)
-}
-
 /*
 .parenthetical class used to keep e.g. "less-than symbol (<)" from wrapping
 the end parenthesis onto its own line. Use in a span between the last word and
diff --git a/src/doc/rust-by-example/src/SUMMARY.md b/src/doc/rust-by-example/src/SUMMARY.md
index cd6bbc7..85711ff 100644
--- a/src/doc/rust-by-example/src/SUMMARY.md
+++ b/src/doc/rust-by-example/src/SUMMARY.md
@@ -69,7 +69,7 @@
         - [As output parameters](fn/closures/output_parameters.md)
         - [Examples in `std`](fn/closures/closure_examples.md)
             - [Iterator::any](fn/closures/closure_examples/iter_any.md)
-            - [Iterator::find](fn/closures/closure_examples/iter_find.md)
+            - [Searching through iterators](fn/closures/closure_examples/iter_find.md)
     - [Higher Order Functions](fn/hof.md)
     - [Diverging functions](fn/diverging.md)
 
@@ -139,8 +139,8 @@
     - [Iterators](trait/iter.md)
     - [`impl Trait`](trait/impl_trait.md)
     - [Clone](trait/clone.md)
-    - [Supertraits](traits/supertraits.md)
-    - [Disambiguating overlapping traits](traits/disambiguating.md)
+    - [Supertraits](trait/supertraits.md)
+    - [Disambiguating overlapping traits](trait/disambiguating.md)
 
 - [macro_rules!](macros.md)
     - [Syntax](macros/syntax.md)
diff --git a/src/doc/rust-by-example/src/cargo/build_scripts.md b/src/doc/rust-by-example/src/cargo/build_scripts.md
index c5da00d..6db3afe 100644
--- a/src/doc/rust-by-example/src/cargo/build_scripts.md
+++ b/src/doc/rust-by-example/src/cargo/build_scripts.md
@@ -1,7 +1,7 @@
 # Build Scripts
 
-Sometimes a normal build from cargo is not enough. Perhaps your crate needs some
-pre-requisites before cargo will successfully compile, things like code
+Sometimes a normal build from `cargo` is not enough. Perhaps your crate needs
+some pre-requisites before `cargo` will successfully compile, things like code
 generation, or some native code that needs to be compiled. To solve this problem
 we have build scripts that Cargo can run.
 
@@ -20,7 +20,7 @@
 ## How to use a build script
 
 The build script is simply another Rust file that will be compiled and invoked
-prior to compiling anything else in the package. Hence it can be used to fulfil
+prior to compiling anything else in the package. Hence it can be used to fulfill
 pre-requisites of your crate.
 
 Cargo provides the script with inputs via environment variables [specified
@@ -29,10 +29,11 @@
 The script provides output via stdout. All lines printed are written to
 `target/debug/build/<pkg>/output`. Further, lines prefixed with `cargo:` will be
 interpreted by Cargo directly and hence can be used to define parameters for the
-packages compilation.
+package's compilation.
 
-For further specification and examples have a read of the [cargo specification].
+For further specification and examples have a read of the
+[Cargo specification][cargo_specification].
 
 [specified here]: https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts
 
-[cargo specification]: https://doc.rust-lang.org/cargo/reference/build-scripts.html
\ No newline at end of file
+[cargo_specification]: https://doc.rust-lang.org/cargo/reference/build-scripts.html
diff --git a/src/doc/rust-by-example/src/cargo/deps.md b/src/doc/rust-by-example/src/cargo/deps.md
index 21db4c2..7403a2a 100644
--- a/src/doc/rust-by-example/src/cargo/deps.md
+++ b/src/doc/rust-by-example/src/cargo/deps.md
@@ -15,10 +15,10 @@
 cargo new --lib foo
 ```
 
-For the rest of this chapter, I will assume we are making a binary, rather than
+For the rest of this chapter, let's assume we are making a binary, rather than
 a library, but all of the concepts are the same.
 
-After the above commands, you should see something like this:
+After the above commands, you should see a file hierarchy like this:
 
 ```txt
 foo
@@ -40,7 +40,7 @@
 [dependencies]
 ```
 
-The `name` field under `package` determines the name of the project. This is
+The `name` field under `[package]` determines the name of the project. This is
 used by `crates.io` if you publish the crate (more later). It is also the name
 of the output binary when you compile.
 
@@ -49,14 +49,14 @@
 
 The `authors` field is a list of authors used when publishing the crate.
 
-The `dependencies` section lets you add a dependency for your project.
+The `[dependencies]` section lets you add dependencies for your project.
 
-For example, suppose that I want my program to have a great CLI. You can find
+For example, suppose that we want our program to have a great CLI. You can find
 lots of great packages on [crates.io](https://crates.io) (the official Rust
 package registry). One popular choice is [clap](https://crates.io/crates/clap).
 As of this writing, the most recent published version of `clap` is `2.27.1`. To
 add a dependency to our program, we can simply add the following to our
-`Cargo.toml` under `dependencies`: `clap = "2.27.1"`.  And of course, `extern
+`Cargo.toml` under `[dependencies]`: `clap = "2.27.1"`.  And of course, `extern
 crate clap` in `main.rs`, just like normal. And that's it! You can start using
 `clap` in your program.
 
diff --git a/src/doc/rust-by-example/src/conversion/string.md b/src/doc/rust-by-example/src/conversion/string.md
index 2bec02f..ab14521 100644
--- a/src/doc/rust-by-example/src/conversion/string.md
+++ b/src/doc/rust-by-example/src/conversion/string.md
@@ -29,16 +29,16 @@
 ## Parsing a String
 
 One of the more common types to convert a string into is a number. The idiomatic
-approach to this is to use the [`parse`] function and provide the type for the
-function to parse the string value into, this can be done either without type
-inference or using the 'turbofish' syntax.
+approach to this is to use the [`parse`] function and either to arrange for
+type inference or to specify the type to parse using the 'turbofish' syntax.
+Both alternatives are shown in the following example.
 
 This will convert the string into the type specified so long as the [`FromStr`]
 trait is implemented for that type. This is implemented for numerous types
 within the standard library. To obtain this functionality on a user defined type
 simply implement the [`FromStr`] trait for that type.
 
-```rust
+```rust,editable
 fn main() {
     let parsed: i32 = "5".parse().unwrap();
     let turbo_parsed = "10".parse::<i32>().unwrap();
diff --git a/src/doc/rust-by-example/src/custom_types/enum.md b/src/doc/rust-by-example/src/custom_types/enum.md
index 8580ce9..e861df9 100644
--- a/src/doc/rust-by-example/src/custom_types/enum.md
+++ b/src/doc/rust-by-example/src/custom_types/enum.md
@@ -55,7 +55,7 @@
 
 ## Type aliases
 
-If you use a type alias, you can refer to each enum variant via its alias. 
+If you use a type alias, you can refer to each enum variant via its alias.
 This might be useful if the enum's name is too long or too generic, and you
 want to rename it.
 
@@ -93,16 +93,17 @@
 }
 ```
 
-To learn more about enums and type aliases, you can read the 
+To learn more about enums and type aliases, you can read the
 [stabilization report][aliasreport] from when this feature was stabilized into
-Rust. 
+Rust.
 
 ### See also:
 
-[`match`][match], [`fn`][fn], and [`String`][str], []
+[`match`][match], [`fn`][fn], and [`String`][str], ["Type alias enum variants" RFC][type_alias_rfc]
 
 [c_struct]: https://en.wikipedia.org/wiki/Struct_(C_programming_language)
 [match]: ../flow_control/match.md
 [fn]: ../fn.md
 [str]: ../std/str.md
 [aliasreport]: https://github.com/rust-lang/rust/pull/61682/#issuecomment-502472847
+[type_alias_rfc]: https://rust-lang.github.io/rfcs/2338-type-alias-enum-variants.html
diff --git a/src/doc/rust-by-example/src/custom_types/structs.md b/src/doc/rust-by-example/src/custom_types/structs.md
index 0b620bf..e863e0e 100644
--- a/src/doc/rust-by-example/src/custom_types/structs.md
+++ b/src/doc/rust-by-example/src/custom_types/structs.md
@@ -10,6 +10,7 @@
 ```rust,editable
 #[derive(Debug)]
 struct Person<'a> {
+    // The 'a defines a lifetime
     name: &'a str,
     age: u8,
 }
@@ -29,8 +30,10 @@
 // Structs can be reused as fields of another struct
 #[allow(dead_code)]
 struct Rectangle {
-    p1: Point,
-    p2: Point,
+    // A rectangle can be specified by where the top left and bottom right
+    // corners are in space.
+    top_left: Point,
+    bottom_right: Point,
 }
 
 fn main() {
@@ -44,23 +47,26 @@
 
 
     // Instantiate a `Point`
-    let point: Point = Point { x: 0.3, y: 0.4 };
+    let point: Point = Point { x: 10.3, y: 0.4 };
 
     // Access the fields of the point
     println!("point coordinates: ({}, {})", point.x, point.y);
 
-    // Make a new point by using struct update syntax to use the fields of our other one
-    let new_point = Point { x: 0.1, ..point };
-    // `new_point.y` will be the same as `point.y` because we used that field from `point`
-    println!("second point: ({}, {})", new_point.x, new_point.y);
+    // Make a new point by using struct update syntax to use the fields of our
+    // other one
+    let bottom_right = Point { x: 5.2, ..point };
+
+    // `bottom_right.y` will be the same as `point.y` because we used that field
+    // from `point`
+    println!("second point: ({}, {})", bottom_right.x, bottom_right.y);
 
     // Destructure the point using a `let` binding
-    let Point { x: my_x, y: my_y } = point;
+    let Point { x: top_edge, y: left_edge } = point;
 
     let _rectangle = Rectangle {
         // struct instantiation is an expression too
-        p1: Point { x: my_y, y: my_x },
-        p2: point,
+        top_left: Point { x: left_edge, y: top_edge },
+        bottom_right: bottom_right,
     };
 
     // Instantiate a unit struct
@@ -81,14 +87,15 @@
 
 ### Activity
 
-1. Add a function `rect_area` which calculates the area of a rectangle (try 
-   using nested destructuring). 
+1. Add a function `rect_area` which calculates the area of a rectangle (try
+   using nested destructuring).
 2. Add a function `square` which takes a `Point` and a `f32` as arguments, and returns a `Rectangle` with its lower left corner on the point, and a width and height corresponding to the `f32`.
 
 ### See also:
 
-[`attributes`][attributes] and [destructuring][destructuring]
+[`attributes`][attributes], [lifetime][lifetime] and [destructuring][destructuring]
 
 [attributes]: ../attribute.md
 [c_struct]: https://en.wikipedia.org/wiki/Struct_(C_programming_language)
 [destructuring]: ../flow_control/match/destructuring.md
+[lifetime]: ../scope/lifetime.md
diff --git a/src/doc/rust-by-example/src/error/result.md b/src/doc/rust-by-example/src/error/result.md
index 3202b31..d779bfd 100644
--- a/src/doc/rust-by-example/src/error/result.md
+++ b/src/doc/rust-by-example/src/error/result.md
@@ -5,8 +5,8 @@
 
 That is, `Result<T, E>` could have one of two outcomes:
 
-* `Ok<T>`: An element `T` was found
-* `Err<E>`: An error was found with element `E`
+* `Ok(T)`: An element `T` was found
+* `Err(E)`: An error was found with element `E`
 
 By convention, the expected outcome is `Ok` while the unexpected outcome is `Err`.
 
diff --git a/src/doc/rust-by-example/src/flow_control/if_let.md b/src/doc/rust-by-example/src/flow_control/if_let.md
index a567133..22bdde8 100644
--- a/src/doc/rust-by-example/src/flow_control/if_let.md
+++ b/src/doc/rust-by-example/src/flow_control/if_let.md
@@ -103,7 +103,7 @@
 
 Would you like a challenge? Fix the following example to use `if let`:
 
-```rust,editable,ignore
+```rust,editable,ignore,mdbook-runnable
 // This enum purposely doesn't #[derive(PartialEq)],
 // neither we implement PartialEq for it. That's why comparing Foo::Bar==a fails below.
 enum Foo {Bar}
diff --git a/src/doc/rust-by-example/src/flow_control/match.md b/src/doc/rust-by-example/src/flow_control/match.md
index fb0f56e..02a8067 100644
--- a/src/doc/rust-by-example/src/flow_control/match.md
+++ b/src/doc/rust-by-example/src/flow_control/match.md
@@ -15,7 +15,7 @@
         // Match several values
         2 | 3 | 5 | 7 | 11 => println!("This is a prime"),
         // Match an inclusive range
-        13...19 => println!("A teen"),
+        13..=19 => println!("A teen"),
         // Handle the rest of cases
         _ => println!("Ain't special"),
     }
@@ -31,4 +31,4 @@
 
     println!("{} -> {}", boolean, binary);
 }
-```
\ No newline at end of file
+```
diff --git a/src/doc/rust-by-example/src/flow_control/match/binding.md b/src/doc/rust-by-example/src/flow_control/match/binding.md
index e1aa232..0407b37 100644
--- a/src/doc/rust-by-example/src/flow_control/match/binding.md
+++ b/src/doc/rust-by-example/src/flow_control/match/binding.md
@@ -15,9 +15,9 @@
 
     match age() {
         0             => println!("I'm not born yet I guess"),
-        // Could `match` 1 ... 12 directly but then what age
+        // Could `match` 1 ..= 12 directly but then what age
         // would the child be? Instead, bind to `n` for the
-        // sequence of 1 .. 12. Now the age can be reported.
+        // sequence of 1 ..= 12. Now the age can be reported.
         n @ 1  ..= 12 => println!("I'm a child of age {:?}", n),
         n @ 13 ..= 19 => println!("I'm a teen of age {:?}", n),
         // Nothing bound. Return the result.
diff --git a/src/doc/rust-by-example/src/fn/closures/capture.md b/src/doc/rust-by-example/src/fn/closures/capture.md
index 3646878..d4fa4ea 100644
--- a/src/doc/rust-by-example/src/fn/closures/capture.md
+++ b/src/doc/rust-by-example/src/fn/closures/capture.md
@@ -18,37 +18,51 @@
     
     let color = "green";
 
-    // A closure to print `color` which immediately borrows (`&`)
-    // `color` and stores the borrow and closure in the `print`
-    // variable. It will remain borrowed until `print` goes out of
-    // scope. `println!` only requires `by reference` so it doesn't
+    // A closure to print `color` which immediately borrows (`&`) `color` and
+    // stores the borrow and closure in the `print` variable. It will remain
+    // borrowed until `print` is used the last time. 
+    //
+    // `println!` only requires arguments by immutable reference so it doesn't
     // impose anything more restrictive.
     let print = || println!("`color`: {}", color);
 
     // Call the closure using the borrow.
     print();
+
+    // `color` can be borrowed immutably again, because the closure only holds
+    // an immutable reference to `color`. 
+    let _reborrow = &color;
     print();
 
-    let mut count = 0;
+    // A move or reborrow is allowed after the final use of `print`
+    let _color_moved = color;
 
-    // A closure to increment `count` could take either `&mut count`
-    // or `count` but `&mut count` is less restrictive so it takes
-    // that. Immediately borrows `count`.
+
+    let mut count = 0;
+    // A closure to increment `count` could take either `&mut count` or `count`
+    // but `&mut count` is less restrictive so it takes that. Immediately
+    // borrows `count`.
     //
-    // A `mut` is required on `inc` because a `&mut` is stored inside.
-    // Thus, calling the closure mutates the closure which requires
-    // a `mut`.
+    // A `mut` is required on `inc` because a `&mut` is stored inside. Thus,
+    // calling the closure mutates the closure which requires a `mut`.
     let mut inc = || {
         count += 1;
         println!("`count`: {}", count);
     };
 
-    // Call the closure.
-    inc();
+    // Call the closure using a mutable borrow.
     inc();
 
-    //let _reborrow = &mut count;
+    // The closure still mutably borrows `count` because it is called later.
+    // An attempt to reborrow will lead to an error.
+    // let _reborrow = &count; 
     // ^ TODO: try uncommenting this line.
+    inc();
+
+    // The closure no longer needs to borrow `&mut count`. Therefore, it is
+    // possible to reborrow without an error
+    let _count_reborrowed = &mut count; 
+
     
     // A non-copy type.
     let movable = Box::new(3);
@@ -64,7 +78,7 @@
 
     // `consume` consumes the variable so this can only be called once.
     consume();
-    //consume();
+    // consume();
     // ^ TODO: Try uncommenting this line.
 }
 ```
@@ -82,7 +96,7 @@
     println!("{}", contains(&1));
     println!("{}", contains(&4));
 
-    // `println!("There're {} elements in vec", haystack.len());`
+    // println!("There're {} elements in vec", haystack.len());
     // ^ Uncommenting above line will result in compile-time error
     // because borrow checker doesn't allow re-using variable after it
     // has been moved.
diff --git a/src/doc/rust-by-example/src/fn/closures/closure_examples/iter_find.md b/src/doc/rust-by-example/src/fn/closures/closure_examples/iter_find.md
index 77ddad2..9eb5072 100644
--- a/src/doc/rust-by-example/src/fn/closures/closure_examples/iter_find.md
+++ b/src/doc/rust-by-example/src/fn/closures/closure_examples/iter_find.md
@@ -1,8 +1,8 @@
-# Iterator::find
+# Searching through iterators
 
-`Iterator::find` is a function which when passed an iterator, will return
-the first element which satisfies the predicate as an `Option`. Its
-signature:
+`Iterator::find` is a function which iterates over an iterator and searches for the 
+first value which satisfies some condition. If none of the values satisfy the 
+condition, it returns `None`. Its signature:
 
 ```rust,ignore
 pub trait Iterator {
@@ -29,9 +29,11 @@
     // `into_iter()` for vecs yields `i32`.
     let mut into_iter = vec2.into_iter();
 
-    // A reference to what is yielded is `&&i32`. Destructure to `i32`.
+    // `iter()` for vecs yields `&i32`, and we want to reference one of its
+    // items, so we have to destructure `&&i32` to `i32`
     println!("Find 2 in vec1: {:?}", iter     .find(|&&x| x == 2));
-    // A reference to what is yielded is `&i32`. Destructure to `i32`.
+    // `into_iter()` for vecs yields `i32`, and we want to reference one of
+    // its items, so we have to destructure `&i32` to `i32`
     println!("Find 2 in vec2: {:?}", into_iter.find(| &x| x == 2));
 
     let array1 = [1, 2, 3];
@@ -44,8 +46,33 @@
 }
 ```
 
+`Iterator::find` gives you a reference to the item. But if you want the _index_ of the
+item, use `Iterator::position`.
+
+```rust,editable
+fn main() {
+    let vec = vec![1, 9, 3, 3, 13, 2];
+
+    let index_of_first_even_number = vec.iter().position(|x| x % 2 == 0);
+    assert_eq!(index_of_first_even_number, Some(5));
+    
+    
+    let index_of_first_negative_number = vec.iter().position(|x| x < &0);
+    assert_eq!(index_of_first_negative_number, None);
+}
+```
+
 ### See also:
 
 [`std::iter::Iterator::find`][find]
 
+[`std::iter::Iterator::find_map`][find_map]
+
+[`std::iter::Iterator::position`][position]
+
+[`std::iter::Iterator::rposition`][rposition]
+
 [find]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.find
+[find_map]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.find_map
+[position]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.position
+[rposition]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.rposition
diff --git a/src/doc/rust-by-example/src/fn/closures/input_parameters.md b/src/doc/rust-by-example/src/fn/closures/input_parameters.md
index c97a4d1..be36c6d 100644
--- a/src/doc/rust-by-example/src/fn/closures/input_parameters.md
+++ b/src/doc/rust-by-example/src/fn/closures/input_parameters.md
@@ -1,33 +1,34 @@
 # As input parameters
 
-While Rust chooses how to capture variables on the fly mostly without type 
-annotation, this ambiguity is not allowed when writing functions. When 
-taking a closure as an input parameter, the closure's complete type must be 
-annotated using one of a few `traits`. In order of decreasing restriction, 
+While Rust chooses how to capture variables on the fly mostly without type
+annotation, this ambiguity is not allowed when writing functions. When
+taking a closure as an input parameter, the closure's complete type must be
+annotated using one of a few `traits`. In order of decreasing restriction,
 they are:
 
 * `Fn`: the closure captures by reference (`&T`)
 * `FnMut`: the closure captures by mutable reference (`&mut T`)
 * `FnOnce`: the closure captures by value (`T`)
 
-On a variable-by-variable basis, the compiler will capture variables in the 
-least restrictive manner possible. 
+On a variable-by-variable basis, the compiler will capture variables in the
+least restrictive manner possible.
 
-For instance, consider a parameter annotated as `FnOnce`. This specifies 
-that the closure *may* capture by `&T`, `&mut T`, or `T`, but the compiler 
-will ultimately choose based on how the captured variables are used in the 
+For instance, consider a parameter annotated as `FnOnce`. This specifies
+that the closure *may* capture by `&T`, `&mut T`, or `T`, but the compiler
+will ultimately choose based on how the captured variables are used in the
 closure.
 
-This is because if a move is possible, then any type of borrow should also 
-be possible. Note that the reverse is not true. If the parameter is 
-annotated as `Fn`, then capturing variables by `&mut T` or `T` are not 
+This is because if a move is possible, then any type of borrow should also
+be possible. Note that the reverse is not true. If the parameter is
+annotated as `Fn`, then capturing variables by `&mut T` or `T` are not
 allowed.
 
-In the following example, try swapping the usage of `Fn`, `FnMut`, and 
+In the following example, try swapping the usage of `Fn`, `FnMut`, and
 `FnOnce` to see what happens:
 
 ```rust,editable
 // A function which takes a closure as an argument and calls it.
+// <F> denotes that F is a "Generic type parameter"
 fn apply<F>(f: F) where
     // The closure takes no input and returns nothing.
     F: FnOnce() {
@@ -81,9 +82,11 @@
 
 ### See also:
 
-[`std::mem::drop`][drop], [`Fn`][fn], [`FnMut`][fnmut], and [`FnOnce`][fnonce]
+[`std::mem::drop`][drop], [`Fn`][fn], [`FnMut`][fnmut], [Generics][generics], [where][where] and [`FnOnce`][fnonce]
 
 [drop]: https://doc.rust-lang.org/std/mem/fn.drop.html
 [fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html
 [fnmut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html
 [fnonce]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html
+[generics]: ../../generics.md
+[where]: ../../generics/where.md
diff --git a/src/doc/rust-by-example/src/fn/closures/output_parameters.md b/src/doc/rust-by-example/src/fn/closures/output_parameters.md
index 4ac4dd0..6cad173 100644
--- a/src/doc/rust-by-example/src/fn/closures/output_parameters.md
+++ b/src/doc/rust-by-example/src/fn/closures/output_parameters.md
@@ -5,13 +5,11 @@
 closure types are, by definition, unknown, so we have to use
 `impl Trait` to return them.
 
-The valid traits for returns are slightly different than before:
+The valid traits for returning a closure are:
 
-* `Fn`: normal
-* `FnMut`: normal
-* `FnOnce`: There are some unusual things at play here, so the [`FnBox`][fnbox]
-  type is currently needed, and is unstable. This is expected to change in
-  the future.
+* `Fn`
+* `FnMut`
+* `FnOnce`
 
 Beyond this, the `move` keyword must be used, which signals that all captures
 occur by value. This is required because any captures by reference would be
@@ -31,12 +29,20 @@
     move || println!("This is a: {}", text)
 }
 
+fn create_fnonce() -> impl FnOnce() {
+    let text = "FnOnce".to_owned();
+
+    move || println!("This is a: {}", text)
+}
+
 fn main() {
     let fn_plain = create_fn();
     let mut fn_mut = create_fnmut();
+    let fn_once = create_fnonce();
 
     fn_plain();
     fn_mut();
+    fn_once();
 }
 ```
 
@@ -46,6 +52,5 @@
 
 [fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html
 [fnmut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html
-[fnbox]: https://doc.rust-lang.org/std/boxed/trait.FnBox.html
 [generics]: ../../generics.md
 [impltrait]: ../../trait/impl_trait.md
diff --git a/src/doc/rust-by-example/src/macros/dry.md b/src/doc/rust-by-example/src/macros/dry.md
index 7333d0e..ca01527 100644
--- a/src/doc/rust-by-example/src/macros/dry.md
+++ b/src/doc/rust-by-example/src/macros/dry.md
@@ -10,7 +10,7 @@
 macro_rules! assert_equal_len {
     // The `tt` (token tree) designator is used for
     // operators and tokens.
-    ($a:ident, $b:ident, $func:ident, $op:tt) => {
+    ($a:expr, $b:expr, $func:ident, $op:tt) => {
         assert!($a.len() == $b.len(),
                 "{:?}: dimension mismatch: {:?} {:?} {:?}",
                 stringify!($func),
diff --git a/src/doc/rust-by-example/src/primitives/array.md b/src/doc/rust-by-example/src/primitives/array.md
index fe4bee9..f612c1d 100644
--- a/src/doc/rust-by-example/src/primitives/array.md
+++ b/src/doc/rust-by-example/src/primitives/array.md
@@ -42,6 +42,9 @@
     analyze_slice(&xs);
 
     // Slices can point to a section of an array
+    // They are of the form [starting_index..ending_index]
+    // starting_index is the first position in the slice
+    // ending_index is one more than the last position in the slice
     println!("borrow a section of the array as a slice");
     analyze_slice(&ys[1 .. 4]);
 
diff --git a/src/doc/rust-by-example/src/scope/borrow/alias.md b/src/doc/rust-by-example/src/scope/borrow/alias.md
index 2a12e60..9cfd5fe 100644
--- a/src/doc/rust-by-example/src/scope/borrow/alias.md
+++ b/src/doc/rust-by-example/src/scope/borrow/alias.md
@@ -1,9 +1,9 @@
 # Aliasing
 
 Data can be immutably borrowed any number of times, but while immutably
-borrowed, the original data can't be mutably borrowed. On the other hand,
-only *one* mutable borrow is allowed at a time. The original data can be
-borrowed again only *after* the mutable reference goes out of scope.
+borrowed, the original data can't be mutably borrowed. On the other hand, only
+*one* mutable borrow is allowed at a time. The original data can be borrowed
+again only *after* the mutable reference has been used for the last time.
 
 ```rust,editable
 struct Point { x: i32, y: i32, z: i32 }
@@ -11,49 +11,48 @@
 fn main() {
     let mut point = Point { x: 0, y: 0, z: 0 };
 
-    {
-        let borrowed_point = &point;
-        let another_borrow = &point;
-
-        // Data can be accessed via the references and the original owner
-        println!("Point has coordinates: ({}, {}, {})",
-                 borrowed_point.x, another_borrow.y, point.z);
-
-        // Error! Can't borrow `point` as mutable because it's currently
-        // borrowed as immutable.
-        //let mutable_borrow = &mut point;
-        // TODO ^ Try uncommenting this line
-
-        // Immutable references go out of scope
-    }
-
-    {
-        let mutable_borrow = &mut point;
-
-        // Change data via mutable reference
-        mutable_borrow.x = 5;
-        mutable_borrow.y = 2;
-        mutable_borrow.z = 1;
-
-        // Error! Can't borrow `point` as immutable because it's currently
-        // borrowed as mutable.
-        //let y = &point.y;
-        // TODO ^ Try uncommenting this line
-
-        // Error! Can't print because `println!` takes an immutable reference.
-        //println!("Point Z coordinate is {}", point.z);
-        // TODO ^ Try uncommenting this line
-
-        // Ok! Mutable references can be passed as immutable to `println!`
-        println!("Point has coordinates: ({}, {}, {})",
-                 mutable_borrow.x, mutable_borrow.y, mutable_borrow.z);
-
-        // Mutable reference goes out of scope
-    }
-
-    // Immutable references to `point` are allowed again
     let borrowed_point = &point;
+    let another_borrow = &point;
+
+    // Data can be accessed via the references and the original owner
+    println!("Point has coordinates: ({}, {}, {})",
+                borrowed_point.x, another_borrow.y, point.z);
+
+    // Error! Can't borrow `point` as mutable because it's currently
+    // borrowed as immutable.
+    // let mutable_borrow = &mut point;
+    // TODO ^ Try uncommenting this line
+
+    // The borrowed values are used again here
+    println!("Point has coordinates: ({}, {}, {})",
+                borrowed_point.x, another_borrow.y, point.z);
+
+    // The immutable references are no longer used for the rest of the code so
+    // it is possible to reborrow with a mutable reference.
+    let mutable_borrow = &mut point;
+
+    // Change data via mutable reference
+    mutable_borrow.x = 5;
+    mutable_borrow.y = 2;
+    mutable_borrow.z = 1;
+
+    // Error! Can't borrow `point` as immutable because it's currently
+    // borrowed as mutable.
+    // let y = &point.y;
+    // TODO ^ Try uncommenting this line
+
+    // Error! Can't print because `println!` takes an immutable reference.
+    // println!("Point Z coordinate is {}", point.z);
+    // TODO ^ Try uncommenting this line
+
+    // Ok! Mutable references can be passed as immutable to `println!`
+    println!("Point has coordinates: ({}, {}, {})",
+                mutable_borrow.x, mutable_borrow.y, mutable_borrow.z);
+
+    // The mutable reference is no longer used for the rest of the code so it
+    // is possible to reborrow
+    let new_borrowed_point = &point;
     println!("Point now has coordinates: ({}, {}, {})",
-             borrowed_point.x, borrowed_point.y, borrowed_point.z);
+             new_borrowed_point.x, new_borrowed_point.y, new_borrowed_point.z);
 }
 ```
diff --git a/src/doc/rust-by-example/src/std/box.md b/src/doc/rust-by-example/src/std/box.md
index 8d45e1a..ebc8ff4 100644
--- a/src/doc/rust-by-example/src/std/box.md
+++ b/src/doc/rust-by-example/src/std/box.md
@@ -18,10 +18,12 @@
     y: f64,
 }
 
+// A Rectangle can be specified by where its top left and bottom right 
+// corners are in space
 #[allow(dead_code)]
 struct Rectangle {
-    p1: Point,
-    p2: Point,
+    top_left: Point,
+    bottom_right: Point,
 }
 
 fn origin() -> Point {
@@ -38,14 +40,14 @@
     // Stack allocated variables
     let point: Point = origin();
     let rectangle: Rectangle = Rectangle {
-        p1: origin(),
-        p2: Point { x: 3.0, y: 4.0 }
+        top_left: origin(),
+        bottom_right: Point { x: 3.0, y: -4.0 }
     };
 
     // Heap allocated rectangle
     let boxed_rectangle: Box<Rectangle> = Box::new(Rectangle {
-        p1: origin(),
-        p2: origin()
+        top_left: origin(),
+        bottom_right: Point { x: 3.0, y: -4.0 },
     });
 
     // The output of functions can be boxed
diff --git a/src/doc/rust-by-example/src/testing/dev_dependencies.md b/src/doc/rust-by-example/src/testing/dev_dependencies.md
index 4c08979..c20decf 100644
--- a/src/doc/rust-by-example/src/testing/dev_dependencies.md
+++ b/src/doc/rust-by-example/src/testing/dev_dependencies.md
@@ -1,7 +1,7 @@
 # Development dependencies
 
-Sometimes there is a need to have a dependencies for tests (examples,
-benchmarks) only. Such dependencies are added to `Cargo.toml` in
+Sometimes there is a need to have dependencies for tests (examples,
+benchmarks) only. Such dependencies are added to `Cargo.toml` in the
 `[dev-dependencies]` section. These dependencies are not propagated to other
 packages which depend on this package.
 
diff --git a/src/doc/rust-by-example/src/traits/disambiguating.md b/src/doc/rust-by-example/src/trait/disambiguating.md
similarity index 100%
rename from src/doc/rust-by-example/src/traits/disambiguating.md
rename to src/doc/rust-by-example/src/trait/disambiguating.md
diff --git a/src/doc/rust-by-example/src/traits/supertraits.md b/src/doc/rust-by-example/src/trait/supertraits.md
similarity index 100%
rename from src/doc/rust-by-example/src/traits/supertraits.md
rename to src/doc/rust-by-example/src/trait/supertraits.md
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 3cda8d9..b603c7b 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -10,9 +10,11 @@
         - [Warn-by-default lints](lints/listing/warn-by-default.md)
         - [Deny-by-default lints](lints/listing/deny-by-default.md)
 - [Codegen options](codegen-options/index.md)
+- [JSON Output](json.md)
 - [Targets](targets/index.md)
     - [Built-in Targets](targets/built-in.md)
     - [Custom Targets](targets/custom.md)
+    - [Known Issues](targets/known-issues.md)
 - [Profile-guided Optimization](profile-guided-optimization.md)
 - [Linker-plugin based LTO](linker-plugin-lto.md)
 - [Contributing to `rustc`](contributing.md)
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index 5c41acc..f5d5f20 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -61,6 +61,8 @@
 To see the valid options and an example of use, run `rustc --print
 target-features`.
 
+Using this flag is unsafe and might result in [undefined runtime behavior](../targets/known-issues.md).
+
 ## passes
 
 This flag can be used to add extra LLVM passes to the compilation.
@@ -105,7 +107,7 @@
 
 ## no-vectorize-slp
 
-By default, `rustc` will attempt to vectorize loops using [superword-level
+By default, `rustc` will attempt to vectorize code using [superword-level
 parallelism](https://llvm.org/docs/Vectorizers.html#the-slp-vectorizer). This
 flag will turn that behavior off.
 
diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md
index 5eea9c8..bdb3c51 100644
--- a/src/doc/rustc/src/command-line-arguments.md
+++ b/src/doc/rustc/src/command-line-arguments.md
@@ -92,6 +92,7 @@
 [edition guide]: ../edition-guide/introduction.html
 
 ## `--emit`: specifies the types of output files to generate
+ <a id="option-emit"></a>
 
 This flag controls the types of output files generated by the compiler. It
 accepts a comma-separated list of values, and may be specified multiple times.
@@ -144,7 +145,7 @@
   target CPU may be selected with the `-C target-cpu=val` flag.
 - `target-features` — List of available target features for the current
   target. Target features may be enabled with the `-C target-feature=val`
-  flag.
+  flag. This flag is unsafe. See [known issues](targets/known-issues.md) for more details.
 - `relocation-models` — List of relocation models. Relocation models may be
   selected with the `-C relocation-model=val` flag.
 - `code-models` — List of code models. Code models may be selected with the
@@ -241,12 +242,13 @@
 distribution; this flag allows that to be overridden.
 
 ## `--error-format`: control how errors are produced
+ <a id="option-error-format"></a>
 
 This flag lets you control the format of messages. Messages are printed to
 stderr. The valid options are:
 
 - `human` — Human-readable output. This is the default.
-- `json` — Structured JSON output.
+- `json` — Structured JSON output. See [the JSON chapter] for more detail.
 - `short` — Short, one-line messages.
 
 ## `--color`: configure coloring of output
@@ -273,6 +275,7 @@
 `foo/lib.rs` but not `./foo/lib.rs`.
 
 ## `--json`: configure json messages printed by the compiler
+ <a id="option-json"></a>
 
 When the `--error-format=json` option is passed to rustc then all of the
 compiler's diagnostic output will be emitted in the form of JSON blobs. The
@@ -305,9 +308,13 @@
 Note that it is invalid to combine the `--json` argument with the `--color`
 argument, and it is required to combine `--json` with `--error-format=json`.
 
+See [the JSON chapter] for more detail.
+
 ## `@path`: load command-line flags from a path
 
 If you specify `@path` on the command-line, then it will open `path` and read
 command line options from it. These options are one per line; a blank line indicates
 an empty option. The file can use Unix or Windows style line endings, and must be
 encoded as UTF-8.
+
+[the JSON chapter]: json.md
diff --git a/src/doc/rustc/src/json.md b/src/doc/rustc/src/json.md
new file mode 100644
index 0000000..b737849
--- /dev/null
+++ b/src/doc/rustc/src/json.md
@@ -0,0 +1,231 @@
+# JSON Output
+
+This chapter documents the JSON structures emitted by `rustc`. JSON may be
+enabled with the [`--error-format=json` flag][option-error-format]. Additional
+options may be specified with the [`--json` flag][option-json] which can
+change which messages are generated, and the format of the messages.
+
+JSON messages are emitted one per line to stderr.
+
+If parsing the output with Rust, the
+[`cargo_metadata`](https://crates.io/crates/cargo_metadata) crate provides
+some support for parsing the messages.
+
+When parsing, care should be taken to be forwards-compatible with future changes
+to the format. Optional values may be `null`. New fields may be added. Enumerated
+fields like "level" or "suggestion_applicability" may add new values.
+
+## Diagnostics
+
+Diagnostic messages provide errors or possible concerns generated during
+compilation. `rustc` provides detailed information about where the diagnostic
+originates, along with hints and suggestions.
+
+Diagnostics are arranged in a parent/child relationship where the parent
+diagnostic value is the core of the diagnostic, and the attached children
+provide additional context, help, and information.
+
+Diagnostics have the following format:
+
+```javascript
+{
+    /* The primary message. */
+    "message": "unused variable: `x`",
+    /* The diagnostic code.
+       Some messages may set this value to null.
+    */
+    "code": {
+        /* A unique string identifying which diagnostic triggered. */
+        "code": "unused_variables",
+        /* An optional string explaining more detail about the diagnostic code. */
+        "explanation": null
+    },
+    /* The severity of the diagnostic.
+       Values may be:
+       - "error": A fatal error that prevents compilation.
+       - "warning": A possible error or concern.
+       - "note": Additional information or context about the diagnostic.
+       - "help": A suggestion on how to resolve the diagnostic.
+       - "failure-note": A note attached to the message for further information.
+       - "error: internal compiler error": Indicates a bug within the compiler.
+    */
+    "level": "warning",
+    /* An array of source code locations to point out specific details about
+       where the diagnostic originates from. This may be empty, for example
+       for some global messages, or child messages attached to a parent.
+
+       Character offsets are offsets of Unicode Scalar Values.
+    */
+    "spans": [
+        {
+            /* The file where the span is located.
+               For spans located within a macro expansion, this will be the
+               name of the expanded macro in the format "<MACRONAME macros>".
+            */
+            "file_name": "lib.rs",
+            /* The byte offset where the span starts (0-based, inclusive). */
+            "byte_start": 21,
+            /* The byte offset where the span ends (0-based, exclusive). */
+            "byte_end": 22,
+            /* The first line number of the span (1-based, inclusive). */
+            "line_start": 2,
+            /* The last line number of the span (1-based, inclusive). */
+            "line_end": 2,
+            /* The first character offset of the line_start (1-based, inclusive). */
+            "column_start": 9,
+            /* The last character offset of the line_end (1-based, exclusive). */
+            "column_end": 10,
+            /* Whether or not this is the "primary" span.
+
+               This indicates that this span is the focal point of the
+               diagnostic.
+
+               There are rare cases where multiple spans may be marked as
+               primary. For example, "immutable borrow occurs here" and
+               "mutable borrow ends here" can be two separate primary spans.
+
+               The top (parent) message should always have at least one
+               primary span, unless it has zero spans. Child messages may have
+               zero or more primary spans.
+            */
+            "is_primary": true,
+            /* An array of objects showing the original source code for this
+               span. This shows the entire lines of text where the span is
+               located. A span across multiple lines will have a separate
+               value for each line.
+            */
+            "text": [
+                {
+                    /* The entire line of the original source code. */
+                    "text": "    let x = 123;",
+                    /* The first character offset of the line of
+                       where the span covers this line (1-based, inclusive). */
+                    "highlight_start": 9,
+                    /* The last character offset of the line of
+                       where the span covers this line (1-based, exclusive). */
+                    "highlight_end": 10
+                }
+            ],
+            /* An optional message to display at this span location.
+               This is typically null for primary spans.
+            */
+            "label": null,
+            /* An optional string of a suggested replacement for this span to
+               solve the issue. Tools may try to replace the contents of the
+               span with this text.
+            */
+            "suggested_replacement": null,
+            /* An optional string that indicates the confidence of the
+               "suggested_replacement". Tools may use this value to determine
+               whether or not suggestions should be automatically applied.
+
+               Possible values may be:
+               - "MachineApplicable": The suggestion is definitely what the
+                 user intended. This suggestion should be automatically
+                 applied.
+               - "MaybeIncorrect": The suggestion may be what the user
+                 intended, but it is uncertain. The suggestion should result
+                 in valid Rust code if it is applied.
+               - "HasPlaceholders": The suggestion contains placeholders like
+                 `(...)`. The suggestion cannot be applied automatically
+                 because it will not result in valid Rust code. The user will
+                 need to fill in the placeholders.
+               - "Unspecified": The applicability of the suggestion is unknown.
+            */
+            "suggestion_applicability": null,
+            /* An optional object indicating the expansion of a macro within
+               this span.
+
+               If a message occurs within a macro invocation, this object will
+               provide details of where within the macro expansion the message
+               is located.
+            */
+            "expansion": {
+                /* The span of the macro invocation.
+                   Uses the same span definition as the "spans" array.
+                */
+                "span": {/*...*/}
+                /* Name of the macro, such as "foo!" or "#[derive(Eq)]". */
+                "macro_decl_name": "some_macro!",
+                /* Optional span where the relevant part of the macro is
+                  defined. */
+                "def_site_span": {/*...*/},
+            }
+        }
+    ],
+    /* Array of attached diagnostic messages.
+       This is an array of objects using the same format as the parent
+       message. Children are not nested (children do not themselves
+       contain "children" definitions).
+    */
+    "children": [
+        {
+            "message": "`#[warn(unused_variables)]` on by default",
+            "code": null,
+            "level": "note",
+            "spans": [],
+            "children": [],
+            "rendered": null
+        },
+        {
+            "message": "consider prefixing with an underscore",
+            "code": null,
+            "level": "help",
+            "spans": [
+                {
+                    "file_name": "lib.rs",
+                    "byte_start": 21,
+                    "byte_end": 22,
+                    "line_start": 2,
+                    "line_end": 2,
+                    "column_start": 9,
+                    "column_end": 10,
+                    "is_primary": true,
+                    "text": [
+                        {
+                            "text": "    let x = 123;",
+                            "highlight_start": 9,
+                            "highlight_end": 10
+                        }
+                    ],
+                    "label": null,
+                    "suggested_replacement": "_x",
+                    "suggestion_applicability": "MachineApplicable",
+                    "expansion": null
+                }
+            ],
+            "children": [],
+            "rendered": null
+        }
+    ],
+    /* Optional string of the rendered version of the diagnostic as displayed
+       by rustc. Note that this may be influenced by the `--json` flag.
+    */
+    "rendered": "warning: unused variable: `x`\n --> lib.rs:2:9\n  |\n2 |     let x = 123;\n  |         ^ help: consider prefixing with an underscore: `_x`\n  |\n  = note: `#[warn(unused_variables)]` on by default\n\n"
+}
+```
+
+## Artifact notifications
+
+Artifact notifications are emitted when the [`--json=artifacts`
+flag][option-json] is used. They indicate that a file artifact has been saved
+to disk. More information about emit kinds may be found in the [`--emit`
+flag][option-emit] documentation.
+
+```javascript
+{
+    /* The filename that was generated. */
+    "artifact": "libfoo.rlib",
+    /* The kind of artifact that was generated. Possible values:
+       - "link": The generated crate as specified by the crate-type.
+       - "dep-info": The `.d` file with dependency information in a Makefile-like syntax.
+       - "metadata": The Rust `.rmeta` file containing metadata about the crate.
+       - "save-analysis": A JSON file emitted by the `-Zsave-analysis` feature.
+    */
+    "emit": "link"
+}
+```
+
+[option-emit]: command-line-arguments.md#option-emit
+[option-error-format]: command-line-arguments.md#option-error-format
+[option-json]: command-line-arguments.md#option-json
diff --git a/src/doc/rustc/src/lints/listing/deny-by-default.md b/src/doc/rustc/src/lints/listing/deny-by-default.md
index 6574267..5688e90 100644
--- a/src/doc/rustc/src/lints/listing/deny-by-default.md
+++ b/src/doc/rustc/src/lints/listing/deny-by-default.md
@@ -222,3 +222,28 @@
   | ^^^^^^^^^^^^^^^^^^^^
   |
 ```
+
+## const-err
+
+This lint detects expressions that will always panic at runtime and would be an
+error in a `const` context.
+
+```rust,ignore
+let _ = [0; 4][4];
+```
+
+This will produce:
+
+```text
+error: index out of bounds: the len is 4 but the index is 4
+ --> src/lib.rs:1:9
+  |
+1 | let _ = [0; 4][4];
+  |         ^^^^^^^^^
+  |
+```
+
+## order-dependent-trait-objects
+
+This lint detects a trait coherency violation that would allow creating two
+trait impls for the same dynamic trait object involving marker traits.
diff --git a/src/doc/rustc/src/lints/listing/warn-by-default.md b/src/doc/rustc/src/lints/listing/warn-by-default.md
index e486240..813d7c4 100644
--- a/src/doc/rustc/src/lints/listing/warn-by-default.md
+++ b/src/doc/rustc/src/lints/listing/warn-by-default.md
@@ -596,30 +596,6 @@
   |
 ```
 
-## unions-with-drop-fields
-
-This lint detects use of unions that contain fields with possibly non-trivial drop code. Some
-example code that triggers this lint:
-
-```rust
-#![feature(untagged_unions)]
-
-union U {
-    s: String,
-}
-```
-
-This will produce:
-
-```text
-warning: union contains a field with possibly non-trivial drop code, drop code of union fields is ignored when dropping the union
- --> src/main.rs:4:5
-  |
-4 |     s: String,
-  |     ^^^^^^^^^
-  |
-```
-
 ## unknown-lints
 
 This lint detects unrecognized lint attribute. Some
diff --git a/src/doc/rustc/src/targets/index.md b/src/doc/rustc/src/targets/index.md
index 3d63d07..5859df8 100644
--- a/src/doc/rustc/src/targets/index.md
+++ b/src/doc/rustc/src/targets/index.md
@@ -11,3 +11,9 @@
 ```bash
 $ rustc src/main.rs --target=wasm32-unknown-unknown
 ```
+## Target Features
+`x86`,  and `ARMv8` are two popular CPU architectures. Their instruction sets form a common baseline across most CPUs. However, some CPUs extend these with custom instruction sets, e.g. vector (`AVX`), bitwise manipulation (`BMI`) or cryptographic (`AES`).
+
+Developers, who know on which CPUs their compiled code is going to run can choose to add (or remove) CPU specific instruction sets via the `-C target-feature=val` flag.
+
+Please note, that this flag is generally considered as unsafe. More details can be found in [this section](known-issues.md).
diff --git a/src/doc/rustc/src/targets/known-issues.md b/src/doc/rustc/src/targets/known-issues.md
new file mode 100644
index 0000000..89fd8ea
--- /dev/null
+++ b/src/doc/rustc/src/targets/known-issues.md
@@ -0,0 +1,13 @@
+# Known Issues
+This section informs you about known "gotchas". Keep in mind, that this section is (and always will be) incomplete. For suggestions and amendments, feel free to [contribute](../contributing.md) to this guide.
+
+## Target Features
+Most target-feature problems arise, when mixing code that have the target-feature _enabled_ with code that have it _disabled_. If you want to avoid undefined behavior, it is recommended to build _all code_ (including the standard library and imported crates) with a common set of target-features.
+
+By default, compiling your code with the `-C target-feature` flag will not recompile the entire standard library and/or imported crates with matching target features. Therefore, target features are generally considered as unsafe. Using `#[target_feature]` on individual functions makes the function unsafe.
+
+Examples:
+
+| Target-Feature | Issue | Seen on | Description | Details |
+| -------------- | ----- | ------- | ----------- | ------- |
+| `+soft-float` <br> and <br> `-sse` | Segfaults and ABI mismatches | `x86` and `x86-64` | The `x86` and `x86_64` architecture uses SSE registers (aka `xmm`) for floating point operations. Using software emulated floats ("soft-floats") disables usage of `xmm` registers, but parts of Rust's core libraries (e.g. `std::f32` or `std::f64`) are compiled without soft-floats and expect parameters to be passed in `xmm` registers. This leads to ABI mismatches. <br><br>  Attempting to compile with disabled SSE causes the same error, too. | [#63466](https://github.com/rust-lang/rust/issues/63466) |
diff --git a/src/doc/rustdoc/src/documentation-tests.md b/src/doc/rustdoc/src/documentation-tests.md
index c9acd3c..bc1da5f 100644
--- a/src/doc/rustdoc/src/documentation-tests.md
+++ b/src/doc/rustdoc/src/documentation-tests.md
@@ -379,3 +379,49 @@
 Not only are fenced code blocks considered more idiomatic for Rust code,
 but there is no way to use directives such as `ignore` or `should_panic` with
 indented code blocks.
+
+### Include items only when collecting doctests
+
+Rustdoc's documentation tests can do some things that regular unit tests can't, so it can
+sometimes be useful to extend your doctests with samples that wouldn't otherwise need to be in
+documentation. To this end, Rustdoc allows you to have certain items only appear when it's
+collecting doctests, so you can utilize doctest functionality without forcing the test to appear in
+docs, or to find an arbitrary private item to include it on.
+
+When compiling a crate for use in doctests (with `--test` option), rustdoc will set `cfg(doctest)`.
+Note that they will still link against only the public items of your crate; if you need to test
+private items, you need to write a unit test.
+
+In this example, we're adding doctests that we know won't compile, to verify that our struct can
+only take in valid data:
+
+```rust
+/// We have a struct here. Remember it doesn't accept negative numbers!
+pub struct MyStruct(pub usize);
+
+/// ```compile_fail
+/// let x = my_crate::MyStruct(-5);
+/// ```
+#[cfg(doctest)]
+pub struct MyStructOnlyTakesUsize;
+```
+
+Note that the struct `MyStructOnlyTakesUsize` here isn't actually part of your public crate
+API. The use of `#[cfg(doctest)]` makes sure that this struct only exists while rustdoc is
+collecting doctests. This means that its doctest is executed when `--test` is passed to rustdoc,
+but is hidden from the public documentation.
+
+Another possible use of `cfg(doctest)` is to test doctests that are included in your README file
+without including it in your main documentation. For example, you could write this into your
+`lib.rs` to test your README as part of your doctests:
+
+```rust,ignore
+#![feature(extern_doc)]
+
+#[doc(include="../README.md")]
+#[cfg(doctest)]
+pub struct ReadmeDoctests;
+```
+
+This will include your README as documentation on the hidden struct `ReadmeDoctests`, which will
+then be tested alongside the rest of your doctests.
diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md
index 49d05b5..3c3e72a 100644
--- a/src/doc/rustdoc/src/unstable-features.md
+++ b/src/doc/rustdoc/src/unstable-features.md
@@ -211,36 +211,6 @@
 Then, when looking for it through the `rustdoc` search, if you enter "x" or
 "big", search will show the `BigX` struct first.
 
-### Include items only when collecting doctests
-
-Rustdoc's [documentation tests] can do some things that regular unit tests can't, so it can
-sometimes be useful to extend your doctests with samples that wouldn't otherwise need to be in
-documentation. To this end, Rustdoc allows you to have certain items only appear when it's
-collecting doctests, so you can utilize doctest functionality without forcing the test to appear in
-docs, or to find an arbitrary private item to include it on.
-
-If you add `#![feature(cfg_doctest)]` to your crate, Rustdoc will set `cfg(doctest)` when collecting
-doctests. Note that they will still link against only the public items of your crate; if you need to
-test private items, unit tests are still the way to go.
-
-In this example, we're adding doctests that we know won't compile, to verify that our struct can
-only take in valid data:
-
-```rust
-#![feature(cfg_doctest)]
-
-/// We have a struct here. Remember it doesn't accept negative numbers!
-pub struct MyStruct(usize);
-
-/// ```compile_fail
-/// let x = my_crate::MyStruct(-5);
-/// ```
-#[cfg(doctest)]
-pub struct MyStructOnlyTakesUsize;
-```
-
-[documentation tests]: documentation-tests.html
-
 ## Unstable command-line arguments
 
 These features are enabled by passing a command-line flag to Rustdoc, but the flags in question are
diff --git a/src/doc/unstable-book/src/compiler-flags/report-time.md b/src/doc/unstable-book/src/compiler-flags/report-time.md
new file mode 100644
index 0000000..ed4e9c6
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/report-time.md
@@ -0,0 +1,80 @@
+# `report-time`
+
+The tracking issue for this feature is: [#64888]
+
+[#64888]: https://github.com/rust-lang/rust/issues/64888
+
+------------------------
+
+The `report-time` feature adds a possibility to report execution time of the
+tests generated via `libtest`.
+
+This is unstable feature, so you have to provide `-Zunstable-options` to get
+this feature working.
+
+Sample usage command:
+
+```sh
+./test_executable -Zunstable-options --report-time
+```
+
+Available options:
+
+```sh
+--report-time [plain|colored]
+                Show execution time of each test. Awailable values:
+                plain = do not colorize the execution time (default);
+                colored = colorize output according to the `color`
+                parameter value;
+                Threshold values for colorized output can be
+                configured via
+                `RUST_TEST_TIME_UNIT`, `RUST_TEST_TIME_INTEGRATION`
+                and
+                `RUST_TEST_TIME_DOCTEST` environment variables.
+                Expected format of environment variable is
+                `VARIABLE=WARN_TIME,CRITICAL_TIME`.
+                Not available for --format=terse
+--ensure-time 
+                Treat excess of the test execution time limit as
+                error.
+                Threshold values for this option can be configured via
+                `RUST_TEST_TIME_UNIT`, `RUST_TEST_TIME_INTEGRATION`
+                and
+                `RUST_TEST_TIME_DOCTEST` environment variables.
+                Expected format of environment variable is
+                `VARIABLE=WARN_TIME,CRITICAL_TIME`.
+                `CRITICAL_TIME` here means the limit that should not be
+                exceeded by test.
+```
+
+Example of the environment variable format:
+
+```sh
+RUST_TEST_TIME_UNIT=100,200
+```
+
+where 100 stands for warn time, and 200 stands for critical time.
+
+## Examples
+
+```sh
+cargo test --tests -- -Zunstable-options --report-time
+    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
+     Running target/debug/deps/example-27fb188025bec02c
+
+running 3 tests
+test tests::unit_test_quick ... ok <0.000s>
+test tests::unit_test_warn ... ok <0.055s>
+test tests::unit_test_critical ... ok <0.110s>
+
+test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
+
+     Running target/debug/deps/tests-cedb06f6526d15d9
+
+running 3 tests
+test unit_test_quick ... ok <0.000s>
+test unit_test_warn ... ok <0.550s>
+test unit_test_critical ... ok <1.100s>
+
+test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
+```
diff --git a/src/doc/unstable-book/src/language-features/lang-items.md b/src/doc/unstable-book/src/language-features/lang-items.md
index 3ee024c..d4ad65e 100644
--- a/src/doc/unstable-book/src/language-features/lang-items.md
+++ b/src/doc/unstable-book/src/language-features/lang-items.md
@@ -249,11 +249,11 @@
 - Runtime
   - `start`: `libstd/rt.rs`
   - `eh_personality`: `libpanic_unwind/emcc.rs` (EMCC)
-  - `eh_personality`: `libpanic_unwind/seh64_gnu.rs` (SEH64 GNU)
+  - `eh_personality`: `libpanic_unwind/gcc.rs` (GNU)
   - `eh_personality`: `libpanic_unwind/seh.rs` (SEH)
-  - `eh_unwind_resume`: `libpanic_unwind/seh64_gnu.rs` (SEH64 GNU)
   - `eh_unwind_resume`: `libpanic_unwind/gcc.rs` (GCC)
-  - `msvc_try_filter`: `libpanic_unwind/seh.rs` (SEH)
+  - `eh_catch_typeinfo`: `libpanic_unwind/seh.rs` (SEH)
+  - `eh_catch_typeinfo`: `libpanic_unwind/emcc.rs` (EMCC)
   - `panic`: `libcore/panicking.rs`
   - `panic_bounds_check`: `libcore/panicking.rs`
   - `panic_impl`: `libcore/panicking.rs`
diff --git a/src/doc/unstable-book/src/language-features/non-exhaustive.md b/src/doc/unstable-book/src/language-features/non-exhaustive.md
deleted file mode 100644
index 907147c..0000000
--- a/src/doc/unstable-book/src/language-features/non-exhaustive.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# `non_exhaustive`
-
-The tracking issue for this feature is: [#44109]
-
-[#44109]: https://github.com/rust-lang/rust/issues/44109
-
-------------------------
-
-The `non_exhaustive` gate allows you to use the `#[non_exhaustive]` attribute
-on structs, enums and enum variants. When applied within a crate, users of the
-crate will need to use the `_` pattern when matching enums and use the `..`
-pattern when matching structs. Enum variants cannot be matched against.
-Structs and enum variants marked as `non_exhaustive` will not be able to
-be created normally outside of the defining crate. This is demonstrated
-below:
-
-```rust,ignore (pseudo-Rust)
-use std::error::Error as StdError;
-
-#[non_exhaustive]
-pub enum Error {
-    Message(String),
-    Other,
-}
-impl StdError for Error {
-    fn description(&self) -> &str {
-        // This will not error, despite being marked as non_exhaustive, as this
-        // enum is defined within the current crate, it can be matched
-        // exhaustively.
-        match *self {
-            Message(ref s) => s,
-            Other => "other or unknown error",
-        }
-    }
-}
-```
-
-```rust,ignore (pseudo-Rust)
-use mycrate::Error;
-
-// This will not error as the non_exhaustive Error enum has been matched with
-// a wildcard.
-match error {
-    Message(ref s) => ...,
-    Other => ...,
-    _ => ...,
-}
-```
-
-```rust,ignore (pseudo-Rust)
-#[non_exhaustive]
-pub struct Config {
-    pub window_width: u16,
-    pub window_height: u16,
-}
-
-// We can create structs as normal within the defining crate when marked as
-// non_exhaustive.
-let config = Config { window_width: 640, window_height: 480 };
-
-// We can match structs exhaustively when within the defining crate.
-if let Ok(Config { window_width, window_height }) = load_config() {
-    // ...
-}
-```
-
-```rust,ignore (pseudo-Rust)
-use mycrate::Config;
-
-// We cannot create a struct like normal if it has been marked as
-// non_exhaustive.
-let config = Config { window_width: 640, window_height: 480 };
-// By adding the `..` we can match the config as below outside of the crate
-// when marked non_exhaustive.
-let &Config { window_width, window_height, .. } = config;
-```
diff --git a/src/doc/unstable-book/src/language-features/track-caller.md b/src/doc/unstable-book/src/language-features/track-caller.md
new file mode 100644
index 0000000..afc11a2
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/track-caller.md
@@ -0,0 +1,5 @@
+# `track_caller`
+
+The tracking issue for this feature is: [#47809](https://github.com/rust-lang/rust/issues/47809).
+
+------------------------
diff --git a/src/grammar/lexer.l b/src/grammar/lexer.l
deleted file mode 100644
index 1feb781..0000000
--- a/src/grammar/lexer.l
+++ /dev/null
@@ -1,350 +0,0 @@
-%{
-#include <stdio.h>
-#include <ctype.h>
-
-static int num_hashes;
-static int end_hashes;
-static int saw_non_hash;
-
-%}
-
-%option stack
-%option yylineno
-
-%x str
-%x rawstr
-%x rawstr_esc_begin
-%x rawstr_esc_body
-%x rawstr_esc_end
-%x byte
-%x bytestr
-%x rawbytestr
-%x rawbytestr_nohash
-%x pound
-%x shebang_or_attr
-%x ltorchar
-%x linecomment
-%x doc_line
-%x blockcomment
-%x doc_block
-%x suffix
-
-ident [a-zA-Z\x80-\xff_][a-zA-Z0-9\x80-\xff_]*
-
-%%
-
-<suffix>{ident}            { BEGIN(INITIAL); }
-<suffix>(.|\n)  { yyless(0); BEGIN(INITIAL); }
-
-[ \n\t\r]             { }
-
-\xef\xbb\xbf {
-  // UTF-8 byte order mark (BOM), ignore if in line 1, error otherwise
-  if (yyget_lineno() != 1) {
-    return -1;
-  }
-}
-
-\/\/(\/|\!)           { BEGIN(doc_line); yymore(); }
-<doc_line>\n          { BEGIN(INITIAL);
-                        yyleng--;
-                        yytext[yyleng] = 0;
-                        return ((yytext[2] == '!') ? INNER_DOC_COMMENT : OUTER_DOC_COMMENT);
-                      }
-<doc_line>[^\n]*      { yymore(); }
-
-\/\/|\/\/\/\/         { BEGIN(linecomment); }
-<linecomment>\n       { BEGIN(INITIAL); }
-<linecomment>[^\n]*   { }
-
-\/\*(\*|\!)[^*]       { yy_push_state(INITIAL); yy_push_state(doc_block); yymore(); }
-<doc_block>\/\*       { yy_push_state(doc_block); yymore(); }
-<doc_block>\*\/       {
-    yy_pop_state();
-    if (yy_top_state() == doc_block) {
-        yymore();
-    } else {
-        return ((yytext[2] == '!') ? INNER_DOC_COMMENT : OUTER_DOC_COMMENT);
-    }
-}
-<doc_block>(.|\n)     { yymore(); }
-
-\/\*                  { yy_push_state(blockcomment); }
-<blockcomment>\/\*    { yy_push_state(blockcomment); }
-<blockcomment>\*\/    { yy_pop_state(); }
-<blockcomment>(.|\n)   { }
-
-_        { return UNDERSCORE; }
-abstract { return ABSTRACT; }
-alignof  { return ALIGNOF; }
-as       { return AS; }
-become   { return BECOME; }
-box      { return BOX; }
-break    { return BREAK; }
-catch    { return CATCH; }
-const    { return CONST; }
-continue { return CONTINUE; }
-crate    { return CRATE; }
-default  { return DEFAULT; }
-do       { return DO; }
-else     { return ELSE; }
-enum     { return ENUM; }
-extern   { return EXTERN; }
-false    { return FALSE; }
-final    { return FINAL; }
-fn       { return FN; }
-for      { return FOR; }
-if       { return IF; }
-impl     { return IMPL; }
-in       { return IN; }
-let      { return LET; }
-loop     { return LOOP; }
-macro    { return MACRO; }
-match    { return MATCH; }
-mod      { return MOD; }
-move     { return MOVE; }
-mut      { return MUT; }
-offsetof { return OFFSETOF; }
-override { return OVERRIDE; }
-priv     { return PRIV; }
-proc     { return PROC; }
-pure     { return PURE; }
-pub      { return PUB; }
-ref      { return REF; }
-return   { return RETURN; }
-self     { return SELF; }
-sizeof   { return SIZEOF; }
-static   { return STATIC; }
-struct   { return STRUCT; }
-super    { return SUPER; }
-trait    { return TRAIT; }
-true     { return TRUE; }
-type     { return TYPE; }
-typeof   { return TYPEOF; }
-union    { return UNION; }
-unsafe   { return UNSAFE; }
-unsized  { return UNSIZED; }
-use      { return USE; }
-virtual  { return VIRTUAL; }
-where    { return WHERE; }
-while    { return WHILE; }
-yield    { return YIELD; }
-
-{ident}  { return IDENT; }
-
-0x[0-9a-fA-F_]+                                    { BEGIN(suffix); return LIT_INTEGER; }
-0o[0-7_]+                                          { BEGIN(suffix); return LIT_INTEGER; }
-0b[01_]+                                           { BEGIN(suffix); return LIT_INTEGER; }
-[0-9][0-9_]*                                       { BEGIN(suffix); return LIT_INTEGER; }
-[0-9][0-9_]*\.(\.|[a-zA-Z])    { yyless(yyleng - 2); BEGIN(suffix); return LIT_INTEGER; }
-
-[0-9][0-9_]*\.[0-9_]*([eE][-\+]?[0-9_]+)?          { BEGIN(suffix); return LIT_FLOAT; }
-[0-9][0-9_]*(\.[0-9_]*)?[eE][-\+]?[0-9_]+          { BEGIN(suffix); return LIT_FLOAT; }
-
-;      { return ';'; }
-,      { return ','; }
-\.\.\. { return DOTDOTDOT; }
-\.\.   { return DOTDOT; }
-\.     { return '.'; }
-\(     { return '('; }
-\)     { return ')'; }
-\{     { return '{'; }
-\}     { return '}'; }
-\[     { return '['; }
-\]     { return ']'; }
-@      { return '@'; }
-#      { BEGIN(pound); yymore(); }
-<pound>\! { BEGIN(shebang_or_attr); yymore(); }
-<shebang_or_attr>\[ {
-  BEGIN(INITIAL);
-  yyless(2);
-  return SHEBANG;
-}
-<shebang_or_attr>[^\[\n]*\n {
-  // Since the \n was eaten as part of the token, yylineno will have
-  // been incremented to the value 2 if the shebang was on the first
-  // line. This yyless undoes that, setting yylineno back to 1.
-  yyless(yyleng - 1);
-  if (yyget_lineno() == 1) {
-    BEGIN(INITIAL);
-    return SHEBANG_LINE;
-  } else {
-    BEGIN(INITIAL);
-    yyless(2);
-    return SHEBANG;
-  }
-}
-<pound>. { BEGIN(INITIAL); yyless(1); return '#'; }
-
-\~     { return '~'; }
-::     { return MOD_SEP; }
-:      { return ':'; }
-\$     { return '$'; }
-\?     { return '?'; }
-
-==    { return EQEQ; }
-=>    { return FAT_ARROW; }
-=     { return '='; }
-\!=   { return NE; }
-\!    { return '!'; }
-\<=   { return LE; }
-\<\<  { return SHL; }
-\<\<= { return SHLEQ; }
-\<    { return '<'; }
-\>=   { return GE; }
-\>\>  { return SHR; }
-\>\>= { return SHREQ; }
-\>    { return '>'; }
-
-\x27                                      { BEGIN(ltorchar); yymore(); }
-<ltorchar>static                          { BEGIN(INITIAL); return STATIC_LIFETIME; }
-<ltorchar>{ident}                         { BEGIN(INITIAL); return LIFETIME; }
-<ltorchar>\\[nrt\\\x27\x220]\x27          { BEGIN(suffix); return LIT_CHAR; }
-<ltorchar>\\x[0-9a-fA-F]{2}\x27           { BEGIN(suffix); return LIT_CHAR; }
-<ltorchar>\\u\{([0-9a-fA-F]_*){1,6}\}\x27 { BEGIN(suffix); return LIT_CHAR; }
-<ltorchar>.\x27                           { BEGIN(suffix); return LIT_CHAR; }
-<ltorchar>[\x80-\xff]{2,4}\x27            { BEGIN(suffix); return LIT_CHAR; }
-<ltorchar><<EOF>>                         { BEGIN(INITIAL); return -1; }
-
-b\x22              { BEGIN(bytestr); yymore(); }
-<bytestr>\x22      { BEGIN(suffix); return LIT_BYTE_STR; }
-
-<bytestr><<EOF>>                     { return -1; }
-<bytestr>\\[n\nrt\\\x27\x220]        { yymore(); }
-<bytestr>\\x[0-9a-fA-F]{2}           { yymore(); }
-<bytestr>\\u\{([0-9a-fA-F]_*){1,6}\} { yymore(); }
-<bytestr>\\[^n\nrt\\\x27\x220]       { return -1; }
-<bytestr>(.|\n)                      { yymore(); }
-
-br\x22                      { BEGIN(rawbytestr_nohash); yymore(); }
-<rawbytestr_nohash>\x22     { BEGIN(suffix); return LIT_BYTE_STR_RAW; }
-<rawbytestr_nohash>(.|\n)   { yymore(); }
-<rawbytestr_nohash><<EOF>>  { return -1; }
-
-br/# {
-    BEGIN(rawbytestr);
-    yymore();
-    num_hashes = 0;
-    saw_non_hash = 0;
-    end_hashes = 0;
-}
-<rawbytestr># {
-    if (!saw_non_hash) {
-        num_hashes++;
-    } else if (end_hashes != 0) {
-        end_hashes++;
-        if (end_hashes == num_hashes) {
-            BEGIN(INITIAL);
-            return LIT_BYTE_STR_RAW;
-        }
-    }
-    yymore();
-}
-<rawbytestr>\x22# {
-    end_hashes = 1;
-    if (end_hashes == num_hashes) {
-        BEGIN(INITIAL);
-        return LIT_BYTE_STR_RAW;
-    }
-    yymore();
-}
-<rawbytestr>(.|\n) {
-    if (!saw_non_hash) {
-        saw_non_hash = 1;
-    }
-    if (end_hashes != 0) {
-        end_hashes = 0;
-    }
-    yymore();
-}
-<rawbytestr><<EOF>> { return -1; }
-
-b\x27                           { BEGIN(byte); yymore(); }
-<byte>\\[nrt\\\x27\x220]\x27    { BEGIN(INITIAL); return LIT_BYTE; }
-<byte>\\x[0-9a-fA-F]{2}\x27     { BEGIN(INITIAL); return LIT_BYTE; }
-<byte>\\u([0-9a-fA-F]_*){4}\x27 { BEGIN(INITIAL); return LIT_BYTE; }
-<byte>\\U([0-9a-fA-F]_*){8}\x27 { BEGIN(INITIAL); return LIT_BYTE; }
-<byte>.\x27                     { BEGIN(INITIAL); return LIT_BYTE; }
-<byte><<EOF>>                   { BEGIN(INITIAL); return -1; }
-
-r\x22           { BEGIN(rawstr); yymore(); }
-<rawstr>\x22    { BEGIN(suffix); return LIT_STR_RAW; }
-<rawstr>(.|\n)  { yymore(); }
-<rawstr><<EOF>> { return -1; }
-
-r/#             {
-    BEGIN(rawstr_esc_begin);
-    yymore();
-    num_hashes = 0;
-    saw_non_hash = 0;
-    end_hashes = 0;
-}
-
-<rawstr_esc_begin># {
-    num_hashes++;
-    yymore();
-}
-<rawstr_esc_begin>\x22 {
-    BEGIN(rawstr_esc_body);
-    yymore();
-}
-<rawstr_esc_begin>(.|\n) { return -1; }
-
-<rawstr_esc_body>\x22/# {
-  BEGIN(rawstr_esc_end);
-  yymore();
- }
-<rawstr_esc_body>(.|\n) {
-  yymore();
- }
-
-<rawstr_esc_end># {
-  end_hashes++;
-  if (end_hashes == num_hashes) {
-    BEGIN(INITIAL);
-    return LIT_STR_RAW;
-  }
-  yymore();
- }
-<rawstr_esc_end>[^#] {
-  end_hashes = 0;
-  BEGIN(rawstr_esc_body);
-  yymore();
- }
-
-<rawstr_esc_begin,rawstr_esc_body,rawstr_esc_end><<EOF>> { return -1; }
-
-\x22                     { BEGIN(str); yymore(); }
-<str>\x22                { BEGIN(suffix); return LIT_STR; }
-
-<str><<EOF>>                     { return -1; }
-<str>\\[n\nr\rt\\\x27\x220]      { yymore(); }
-<str>\\x[0-9a-fA-F]{2}           { yymore(); }
-<str>\\u\{([0-9a-fA-F]_*){1,6}\} { yymore(); }
-<str>\\[^n\nrt\\\x27\x220]       { return -1; }
-<str>(.|\n)                      { yymore(); }
-
-\<-  { return LARROW; }
--\>  { return RARROW; }
--    { return '-'; }
--=   { return MINUSEQ; }
-&&   { return ANDAND; }
-&    { return '&'; }
-&=   { return ANDEQ; }
-\|\| { return OROR; }
-\|   { return '|'; }
-\|=  { return OREQ; }
-\+   { return '+'; }
-\+=  { return PLUSEQ; }
-\*   { return '*'; }
-\*=  { return STAREQ; }
-\/   { return '/'; }
-\/=  { return SLASHEQ; }
-\^   { return '^'; }
-\^=  { return CARETEQ; }
-%    { return '%'; }
-%=   { return PERCENTEQ; }
-
-<<EOF>> { return 0; }
-
-%%
diff --git a/src/grammar/parser-lalr-main.c b/src/grammar/parser-lalr-main.c
deleted file mode 100644
index 6348190..0000000
--- a/src/grammar/parser-lalr-main.c
+++ /dev/null
@@ -1,193 +0,0 @@
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-
-extern int yylex();
-extern int rsparse();
-
-#define PUSHBACK_LEN 4
-
-static char pushback[PUSHBACK_LEN];
-static int verbose;
-
-void print(const char* format, ...) {
-  va_list args;
-  va_start(args, format);
-  if (verbose) {
-    vprintf(format, args);
-  }
-  va_end(args);
-}
-
-// If there is a non-null char at the head of the pushback queue,
-// dequeue it and shift the rest of the queue forwards. Otherwise,
-// return the token from calling yylex.
-int rslex() {
-  if (pushback[0] == '\0') {
-    return yylex();
-  } else {
-    char c = pushback[0];
-    memmove(pushback, pushback + 1, PUSHBACK_LEN - 1);
-    pushback[PUSHBACK_LEN - 1] = '\0';
-    return c;
-  }
-}
-
-// Note: this does nothing if the pushback queue is full. As long as
-// there aren't more than PUSHBACK_LEN consecutive calls to push_back
-// in an action, this shouldn't be a problem.
-void push_back(char c) {
-  for (int i = 0; i < PUSHBACK_LEN; ++i) {
-    if (pushback[i] == '\0') {
-      pushback[i] = c;
-      break;
-    }
-  }
-}
-
-extern int rsdebug;
-
-struct node {
-  struct node *next;
-  struct node *prev;
-  int own_string;
-  char const *name;
-  int n_elems;
-  struct node *elems[];
-};
-
-struct node *nodes = NULL;
-int n_nodes;
-
-struct node *mk_node(char const *name, int n, ...) {
-  va_list ap;
-  int i = 0;
-  unsigned sz = sizeof(struct node) + (n * sizeof(struct node *));
-  struct node *nn, *nd = (struct node *)malloc(sz);
-
-  print("# New %d-ary node: %s = %p\n", n, name, nd);
-
-  nd->own_string = 0;
-  nd->prev = NULL;
-  nd->next = nodes;
-  if (nodes) {
-    nodes->prev = nd;
-  }
-  nodes = nd;
-
-  nd->name = name;
-  nd->n_elems = n;
-
-  va_start(ap, n);
-  while (i < n) {
-    nn = va_arg(ap, struct node *);
-    print("#   arg[%d]: %p\n", i, nn);
-    print("#            (%s ...)\n", nn->name);
-    nd->elems[i++] = nn;
-  }
-  va_end(ap);
-  n_nodes++;
-  return nd;
-}
-
-struct node *mk_atom(char *name) {
-  struct node *nd = mk_node((char const *)strdup(name), 0);
-  nd->own_string = 1;
-  return nd;
-}
-
-struct node *mk_none() {
-  return mk_atom("<none>");
-}
-
-struct node *ext_node(struct node *nd, int n, ...) {
-  va_list ap;
-  int i = 0, c = nd->n_elems + n;
-  unsigned sz = sizeof(struct node) + (c * sizeof(struct node *));
-  struct node *nn;
-
-  print("# Extending %d-ary node by %d nodes: %s = %p",
-        nd->n_elems, c, nd->name, nd);
-
-  if (nd->next) {
-    nd->next->prev = nd->prev;
-  }
-  if (nd->prev) {
-    nd->prev->next = nd->next;
-  }
-  nd = realloc(nd, sz);
-  nd->prev = NULL;
-  nd->next = nodes;
-  nodes->prev = nd;
-  nodes = nd;
-
-  print(" ==> %p\n", nd);
-
-  va_start(ap, n);
-  while (i < n) {
-    nn = va_arg(ap, struct node *);
-    print("#   arg[%d]: %p\n", i, nn);
-    print("#            (%s ...)\n", nn->name);
-    nd->elems[nd->n_elems++] = nn;
-    ++i;
-  }
-  va_end(ap);
-  return nd;
-}
-
-int const indent_step = 4;
-
-void print_indent(int depth) {
-  while (depth) {
-    if (depth-- % indent_step == 0) {
-      print("|");
-    } else {
-      print(" ");
-    }
-  }
-}
-
-void print_node(struct node *n, int depth) {
-  int i = 0;
-  print_indent(depth);
-  if (n->n_elems == 0) {
-    print("%s\n", n->name);
-  } else {
-    print("(%s\n", n->name);
-    for (i = 0; i < n->n_elems; ++i) {
-      print_node(n->elems[i], depth + indent_step);
-    }
-    print_indent(depth);
-    print(")\n");
-  }
-}
-
-int main(int argc, char **argv) {
-  if (argc == 2 && strcmp(argv[1], "-v") == 0) {
-    verbose = 1;
-  } else {
-    verbose = 0;
-  }
-  int ret = 0;
-  struct node *tmp;
-  memset(pushback, '\0', PUSHBACK_LEN);
-  ret = rsparse();
-  print("--- PARSE COMPLETE: ret:%d, n_nodes:%d ---\n", ret, n_nodes);
-  if (nodes) {
-    print_node(nodes, 0);
-  }
-  while (nodes) {
-    tmp = nodes;
-    nodes = tmp->next;
-    if (tmp->own_string) {
-      free((void*)tmp->name);
-    }
-    free(tmp);
-  }
-  return ret;
-}
-
-void rserror(char const *s) {
-  fprintf(stderr, "%s\n", s);
-}
diff --git a/src/grammar/parser-lalr.y b/src/grammar/parser-lalr.y
deleted file mode 100644
index 5585c95..0000000
--- a/src/grammar/parser-lalr.y
+++ /dev/null
@@ -1,1982 +0,0 @@
-%{
-#define YYERROR_VERBOSE
-#define YYSTYPE struct node *
-struct node;
-extern int yylex();
-extern void yyerror(char const *s);
-extern struct node *mk_node(char const *name, int n, ...);
-extern struct node *mk_atom(char *text);
-extern struct node *mk_none();
-extern struct node *ext_node(struct node *nd, int n, ...);
-extern void push_back(char c);
-extern char *yytext;
-%}
-%debug
-
-%token SHL
-%token SHR
-%token LE
-%token EQEQ
-%token NE
-%token GE
-%token ANDAND
-%token OROR
-%token SHLEQ
-%token SHREQ
-%token MINUSEQ
-%token ANDEQ
-%token OREQ
-%token PLUSEQ
-%token STAREQ
-%token SLASHEQ
-%token CARETEQ
-%token PERCENTEQ
-%token DOTDOT
-%token DOTDOTDOT
-%token MOD_SEP
-%token RARROW
-%token LARROW
-%token FAT_ARROW
-%token LIT_BYTE
-%token LIT_CHAR
-%token LIT_INTEGER
-%token LIT_FLOAT
-%token LIT_STR
-%token LIT_STR_RAW
-%token LIT_BYTE_STR
-%token LIT_BYTE_STR_RAW
-%token IDENT
-%token UNDERSCORE
-%token LIFETIME
-
-// keywords
-%token SELF
-%token STATIC
-%token ABSTRACT
-%token ALIGNOF
-%token AS
-%token BECOME
-%token BREAK
-%token CATCH
-%token CRATE
-%token DO
-%token ELSE
-%token ENUM
-%token EXTERN
-%token FALSE
-%token FINAL
-%token FN
-%token FOR
-%token IF
-%token IMPL
-%token IN
-%token LET
-%token LOOP
-%token MACRO
-%token MATCH
-%token MOD
-%token MOVE
-%token MUT
-%token OFFSETOF
-%token OVERRIDE
-%token PRIV
-%token PUB
-%token PURE
-%token REF
-%token RETURN
-%token SIZEOF
-%token STRUCT
-%token SUPER
-%token UNION
-%token UNSIZED
-%token TRUE
-%token TRAIT
-%token TYPE
-%token UNSAFE
-%token VIRTUAL
-%token YIELD
-%token DEFAULT
-%token USE
-%token WHILE
-%token CONTINUE
-%token PROC
-%token BOX
-%token CONST
-%token WHERE
-%token TYPEOF
-%token INNER_DOC_COMMENT
-%token OUTER_DOC_COMMENT
-
-%token SHEBANG
-%token SHEBANG_LINE
-%token STATIC_LIFETIME
-
- /*
-   Quoting from the Bison manual:
-
-   "Finally, the resolution of conflicts works by comparing the precedence
-   of the rule being considered with that of the lookahead token. If the
-   token's precedence is higher, the choice is to shift. If the rule's
-   precedence is higher, the choice is to reduce. If they have equal
-   precedence, the choice is made based on the associativity of that
-   precedence level. The verbose output file made by ‘-v’ (see Invoking
-   Bison) says how each conflict was resolved"
- */
-
-// We expect no shift/reduce or reduce/reduce conflicts in this grammar;
-// all potential ambiguities are scrutinized and eliminated manually.
-%expect 0
-
-// fake-precedence symbol to cause '|' bars in lambda context to parse
-// at low precedence, permit things like |x| foo = bar, where '=' is
-// otherwise lower-precedence than '|'. Also used for proc() to cause
-// things like proc() a + b to parse as proc() { a + b }.
-%precedence LAMBDA
-
-%precedence SELF
-
-// MUT should be lower precedence than IDENT so that in the pat rule,
-// "& MUT pat" has higher precedence than "binding_mode ident [@ pat]"
-%precedence MUT
-
-// IDENT needs to be lower than '{' so that 'foo {' is shifted when
-// trying to decide if we've got a struct-construction expr (esp. in
-// contexts like 'if foo { .')
-//
-// IDENT also needs to be lower precedence than '<' so that '<' in
-// 'foo:bar . <' is shifted (in a trait reference occurring in a
-// bounds list), parsing as foo:(bar<baz>) rather than (foo:bar)<baz>.
-%precedence IDENT
- // Put the weak keywords that can be used as idents here as well
-%precedence CATCH
-%precedence DEFAULT
-%precedence UNION
-
-// A couple fake-precedence symbols to use in rules associated with +
-// and < in trailing type contexts. These come up when you have a type
-// in the RHS of operator-AS, such as "foo as bar<baz>". The "<" there
-// has to be shifted so the parser keeps trying to parse a type, even
-// though it might well consider reducing the type "bar" and then
-// going on to "<" as a subsequent binop. The "+" case is with
-// trailing type-bounds ("foo as bar:A+B"), for the same reason.
-%precedence SHIFTPLUS
-
-%precedence MOD_SEP
-%precedence RARROW ':'
-
-// In where clauses, "for" should have greater precedence when used as
-// a higher ranked constraint than when used as the beginning of a
-// for_in_type (which is a ty)
-%precedence FORTYPE
-%precedence FOR
-
-// Binops & unops, and their precedences
-%precedence '?'
-%precedence BOX
-%nonassoc DOTDOT
-
-// RETURN needs to be lower-precedence than tokens that start
-// prefix_exprs
-%precedence RETURN YIELD
-
-%right '=' SHLEQ SHREQ MINUSEQ ANDEQ OREQ PLUSEQ STAREQ SLASHEQ CARETEQ PERCENTEQ
-%right LARROW
-%left OROR
-%left ANDAND
-%left EQEQ NE
-%left '<' '>' LE GE
-%left '|'
-%left '^'
-%left '&'
-%left SHL SHR
-%left '+' '-'
-%precedence AS
-%left '*' '/' '%'
-%precedence '!'
-
-%precedence '{' '[' '(' '.'
-
-%precedence RANGE
-
-%start crate
-
-%%
-
-////////////////////////////////////////////////////////////////////////
-// Part 1: Items and attributes
-////////////////////////////////////////////////////////////////////////
-
-crate
-: maybe_shebang inner_attrs maybe_mod_items  { mk_node("crate", 2, $2, $3); }
-| maybe_shebang maybe_mod_items  { mk_node("crate", 1, $2); }
-;
-
-maybe_shebang
-: SHEBANG_LINE
-| %empty
-;
-
-maybe_inner_attrs
-: inner_attrs
-| %empty                   { $$ = mk_none(); }
-;
-
-inner_attrs
-: inner_attr               { $$ = mk_node("InnerAttrs", 1, $1); }
-| inner_attrs inner_attr   { $$ = ext_node($1, 1, $2); }
-;
-
-inner_attr
-: SHEBANG '[' meta_item ']'   { $$ = mk_node("InnerAttr", 1, $3); }
-| INNER_DOC_COMMENT           { $$ = mk_node("InnerAttr", 1, mk_node("doc-comment", 1, mk_atom(yytext))); }
-;
-
-maybe_outer_attrs
-: outer_attrs
-| %empty                   { $$ = mk_none(); }
-;
-
-outer_attrs
-: outer_attr               { $$ = mk_node("OuterAttrs", 1, $1); }
-| outer_attrs outer_attr   { $$ = ext_node($1, 1, $2); }
-;
-
-outer_attr
-: '#' '[' meta_item ']'    { $$ = $3; }
-| OUTER_DOC_COMMENT        { $$ = mk_node("doc-comment", 1, mk_atom(yytext)); }
-;
-
-meta_item
-: ident                      { $$ = mk_node("MetaWord", 1, $1); }
-| ident '=' lit              { $$ = mk_node("MetaNameValue", 2, $1, $3); }
-| ident '(' meta_seq ')'     { $$ = mk_node("MetaList", 2, $1, $3); }
-| ident '(' meta_seq ',' ')' { $$ = mk_node("MetaList", 2, $1, $3); }
-;
-
-meta_seq
-: %empty                   { $$ = mk_none(); }
-| meta_item                { $$ = mk_node("MetaItems", 1, $1); }
-| meta_seq ',' meta_item   { $$ = ext_node($1, 1, $3); }
-;
-
-maybe_mod_items
-: mod_items
-| %empty             { $$ = mk_none(); }
-;
-
-mod_items
-: mod_item                               { $$ = mk_node("Items", 1, $1); }
-| mod_items mod_item                     { $$ = ext_node($1, 1, $2); }
-;
-
-attrs_and_vis
-: maybe_outer_attrs visibility           { $$ = mk_node("AttrsAndVis", 2, $1, $2); }
-;
-
-mod_item
-: attrs_and_vis item    { $$ = mk_node("Item", 2, $1, $2); }
-;
-
-// items that can appear outside of a fn block
-item
-: stmt_item
-| item_macro
-;
-
-// items that can appear in "stmts"
-stmt_item
-: item_static
-| item_const
-| item_type
-| block_item
-| view_item
-;
-
-item_static
-: STATIC ident ':' ty '=' expr ';'  { $$ = mk_node("ItemStatic", 3, $2, $4, $6); }
-| STATIC MUT ident ':' ty '=' expr ';'  { $$ = mk_node("ItemStatic", 3, $3, $5, $7); }
-;
-
-item_const
-: CONST ident ':' ty '=' expr ';'  { $$ = mk_node("ItemConst", 3, $2, $4, $6); }
-;
-
-item_macro
-: path_expr '!' maybe_ident parens_delimited_token_trees ';'  { $$ = mk_node("ItemMacro", 3, $1, $3, $4); }
-| path_expr '!' maybe_ident braces_delimited_token_trees      { $$ = mk_node("ItemMacro", 3, $1, $3, $4); }
-| path_expr '!' maybe_ident brackets_delimited_token_trees ';'{ $$ = mk_node("ItemMacro", 3, $1, $3, $4); }
-;
-
-view_item
-: use_item
-| extern_fn_item
-| EXTERN CRATE ident ';'                      { $$ = mk_node("ViewItemExternCrate", 1, $3); }
-| EXTERN CRATE ident AS ident ';'             { $$ = mk_node("ViewItemExternCrate", 2, $3, $5); }
-;
-
-extern_fn_item
-: EXTERN maybe_abi item_fn                    { $$ = mk_node("ViewItemExternFn", 2, $2, $3); }
-;
-
-use_item
-: USE view_path ';'                           { $$ = mk_node("ViewItemUse", 1, $2); }
-;
-
-view_path
-: path_no_types_allowed                                    { $$ = mk_node("ViewPathSimple", 1, $1); }
-| path_no_types_allowed MOD_SEP '{'                '}'     { $$ = mk_node("ViewPathList", 2, $1, mk_atom("ViewPathListEmpty")); }
-|                       MOD_SEP '{'                '}'     { $$ = mk_node("ViewPathList", 1, mk_atom("ViewPathListEmpty")); }
-| path_no_types_allowed MOD_SEP '{' idents_or_self '}'     { $$ = mk_node("ViewPathList", 2, $1, $4); }
-|                       MOD_SEP '{' idents_or_self '}'     { $$ = mk_node("ViewPathList", 1, $3); }
-| path_no_types_allowed MOD_SEP '{' idents_or_self ',' '}' { $$ = mk_node("ViewPathList", 2, $1, $4); }
-|                       MOD_SEP '{' idents_or_self ',' '}' { $$ = mk_node("ViewPathList", 1, $3); }
-| path_no_types_allowed MOD_SEP '*'                        { $$ = mk_node("ViewPathGlob", 1, $1); }
-|                       MOD_SEP '*'                        { $$ = mk_atom("ViewPathGlob"); }
-|                               '*'                        { $$ = mk_atom("ViewPathGlob"); }
-|                               '{'                '}'     { $$ = mk_atom("ViewPathListEmpty"); }
-|                               '{' idents_or_self '}'     { $$ = mk_node("ViewPathList", 1, $2); }
-|                               '{' idents_or_self ',' '}' { $$ = mk_node("ViewPathList", 1, $2); }
-| path_no_types_allowed AS ident                           { $$ = mk_node("ViewPathSimple", 2, $1, $3); }
-;
-
-block_item
-: item_fn
-| item_unsafe_fn
-| item_mod
-| item_foreign_mod          { $$ = mk_node("ItemForeignMod", 1, $1); }
-| item_struct
-| item_enum
-| item_union
-| item_trait
-| item_impl
-;
-
-maybe_ty_ascription
-: ':' ty_sum { $$ = $2; }
-| %empty { $$ = mk_none(); }
-;
-
-maybe_init_expr
-: '=' expr { $$ = $2; }
-| %empty   { $$ = mk_none(); }
-;
-
-// structs
-item_struct
-: STRUCT ident generic_params maybe_where_clause struct_decl_args
-{
-  $$ = mk_node("ItemStruct", 4, $2, $3, $4, $5);
-}
-| STRUCT ident generic_params struct_tuple_args maybe_where_clause ';'
-{
-  $$ = mk_node("ItemStruct", 4, $2, $3, $4, $5);
-}
-| STRUCT ident generic_params maybe_where_clause ';'
-{
-  $$ = mk_node("ItemStruct", 3, $2, $3, $4);
-}
-;
-
-struct_decl_args
-: '{' struct_decl_fields '}'                  { $$ = $2; }
-| '{' struct_decl_fields ',' '}'              { $$ = $2; }
-;
-
-struct_tuple_args
-: '(' struct_tuple_fields ')'                 { $$ = $2; }
-| '(' struct_tuple_fields ',' ')'             { $$ = $2; }
-;
-
-struct_decl_fields
-: struct_decl_field                           { $$ = mk_node("StructFields", 1, $1); }
-| struct_decl_fields ',' struct_decl_field    { $$ = ext_node($1, 1, $3); }
-| %empty                                      { $$ = mk_none(); }
-;
-
-struct_decl_field
-: attrs_and_vis ident ':' ty_sum              { $$ = mk_node("StructField", 3, $1, $2, $4); }
-;
-
-struct_tuple_fields
-: struct_tuple_field                          { $$ = mk_node("StructFields", 1, $1); }
-| struct_tuple_fields ',' struct_tuple_field  { $$ = ext_node($1, 1, $3); }
-| %empty                                      { $$ = mk_none(); }
-;
-
-struct_tuple_field
-: attrs_and_vis ty_sum                    { $$ = mk_node("StructField", 2, $1, $2); }
-;
-
-// enums
-item_enum
-: ENUM ident generic_params maybe_where_clause '{' enum_defs '}'     { $$ = mk_node("ItemEnum", 0); }
-| ENUM ident generic_params maybe_where_clause '{' enum_defs ',' '}' { $$ = mk_node("ItemEnum", 0); }
-;
-
-enum_defs
-: enum_def               { $$ = mk_node("EnumDefs", 1, $1); }
-| enum_defs ',' enum_def { $$ = ext_node($1, 1, $3); }
-| %empty                 { $$ = mk_none(); }
-;
-
-enum_def
-: attrs_and_vis ident enum_args { $$ = mk_node("EnumDef", 3, $1, $2, $3); }
-;
-
-enum_args
-: '{' struct_decl_fields '}'     { $$ = mk_node("EnumArgs", 1, $2); }
-| '{' struct_decl_fields ',' '}' { $$ = mk_node("EnumArgs", 1, $2); }
-| '(' maybe_ty_sums ')'          { $$ = mk_node("EnumArgs", 1, $2); }
-| '=' expr                       { $$ = mk_node("EnumArgs", 1, $2); }
-| %empty                         { $$ = mk_none(); }
-;
-
-// unions
-item_union
-: UNION ident generic_params maybe_where_clause '{' struct_decl_fields '}'     { $$ = mk_node("ItemUnion", 0); }
-| UNION ident generic_params maybe_where_clause '{' struct_decl_fields ',' '}' { $$ = mk_node("ItemUnion", 0); }
-
-item_mod
-: MOD ident ';'                                 { $$ = mk_node("ItemMod", 1, $2); }
-| MOD ident '{' maybe_mod_items '}'             { $$ = mk_node("ItemMod", 2, $2, $4); }
-| MOD ident '{' inner_attrs maybe_mod_items '}' { $$ = mk_node("ItemMod", 3, $2, $4, $5); }
-;
-
-item_foreign_mod
-: EXTERN maybe_abi '{' maybe_foreign_items '}'             { $$ = mk_node("ItemForeignMod", 1, $4); }
-| EXTERN maybe_abi '{' inner_attrs maybe_foreign_items '}' { $$ = mk_node("ItemForeignMod", 2, $4, $5); }
-;
-
-maybe_abi
-: str
-| %empty { $$ = mk_none(); }
-;
-
-maybe_foreign_items
-: foreign_items
-| %empty { $$ = mk_none(); }
-;
-
-foreign_items
-: foreign_item               { $$ = mk_node("ForeignItems", 1, $1); }
-| foreign_items foreign_item { $$ = ext_node($1, 1, $2); }
-;
-
-foreign_item
-: attrs_and_vis STATIC item_foreign_static { $$ = mk_node("ForeignItem", 2, $1, $3); }
-| attrs_and_vis item_foreign_fn            { $$ = mk_node("ForeignItem", 2, $1, $2); }
-| attrs_and_vis UNSAFE item_foreign_fn     { $$ = mk_node("ForeignItem", 2, $1, $3); }
-;
-
-item_foreign_static
-: maybe_mut ident ':' ty ';'               { $$ = mk_node("StaticItem", 3, $1, $2, $4); }
-;
-
-item_foreign_fn
-: FN ident generic_params fn_decl_allow_variadic maybe_where_clause ';' { $$ = mk_node("ForeignFn", 4, $2, $3, $4, $5); }
-;
-
-fn_decl_allow_variadic
-: fn_params_allow_variadic ret_ty { $$ = mk_node("FnDecl", 2, $1, $2); }
-;
-
-fn_params_allow_variadic
-: '(' ')'                      { $$ = mk_none(); }
-| '(' params ')'               { $$ = $2; }
-| '(' params ',' ')'           { $$ = $2; }
-| '(' params ',' DOTDOTDOT ')' { $$ = $2; }
-;
-
-visibility
-: PUB      { $$ = mk_atom("Public"); }
-| %empty   { $$ = mk_atom("Inherited"); }
-;
-
-idents_or_self
-: ident_or_self                    { $$ = mk_node("IdentsOrSelf", 1, $1); }
-| idents_or_self AS ident          { $$ = mk_node("IdentsOrSelf", 2, $1, $3); }
-| idents_or_self ',' ident_or_self { $$ = ext_node($1, 1, $3); }
-;
-
-ident_or_self
-: ident
-| SELF  { $$ = mk_atom(yytext); }
-;
-
-item_type
-: TYPE ident generic_params maybe_where_clause '=' ty_sum ';'  { $$ = mk_node("ItemTy", 4, $2, $3, $4, $6); }
-;
-
-for_sized
-: FOR '?' ident { $$ = mk_node("ForSized", 1, $3); }
-| FOR ident '?' { $$ = mk_node("ForSized", 1, $2); }
-| %empty        { $$ = mk_none(); }
-;
-
-item_trait
-: maybe_unsafe TRAIT ident generic_params for_sized maybe_ty_param_bounds maybe_where_clause '{' maybe_trait_items '}'
-{
-  $$ = mk_node("ItemTrait", 7, $1, $3, $4, $5, $6, $7, $9);
-}
-;
-
-maybe_trait_items
-: trait_items
-| %empty { $$ = mk_none(); }
-;
-
-trait_items
-: trait_item               { $$ = mk_node("TraitItems", 1, $1); }
-| trait_items trait_item   { $$ = ext_node($1, 1, $2); }
-;
-
-trait_item
-: trait_const
-| trait_type
-| trait_method
-| maybe_outer_attrs item_macro { $$ = mk_node("TraitMacroItem", 2, $1, $2); }
-;
-
-trait_const
-: maybe_outer_attrs CONST ident maybe_ty_ascription maybe_const_default ';' { $$ = mk_node("ConstTraitItem", 4, $1, $3, $4, $5); }
-;
-
-maybe_const_default
-: '=' expr { $$ = mk_node("ConstDefault", 1, $2); }
-| %empty   { $$ = mk_none(); }
-;
-
-trait_type
-: maybe_outer_attrs TYPE ty_param ';' { $$ = mk_node("TypeTraitItem", 2, $1, $3); }
-;
-
-maybe_unsafe
-: UNSAFE { $$ = mk_atom("Unsafe"); }
-| %empty { $$ = mk_none(); }
-;
-
-maybe_default_maybe_unsafe
-: DEFAULT UNSAFE { $$ = mk_atom("DefaultUnsafe"); }
-| DEFAULT        { $$ = mk_atom("Default"); }
-|         UNSAFE { $$ = mk_atom("Unsafe"); }
-| %empty { $$ = mk_none(); }
-
-trait_method
-: type_method { $$ = mk_node("Required", 1, $1); }
-| method      { $$ = mk_node("Provided", 1, $1); }
-;
-
-type_method
-: maybe_outer_attrs maybe_unsafe FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause ';'
-{
-  $$ = mk_node("TypeMethod", 6, $1, $2, $4, $5, $6, $7);
-}
-| maybe_outer_attrs CONST maybe_unsafe FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause ';'
-{
-  $$ = mk_node("TypeMethod", 6, $1, $3, $5, $6, $7, $8);
-}
-| maybe_outer_attrs maybe_unsafe EXTERN maybe_abi FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause ';'
-{
-  $$ = mk_node("TypeMethod", 7, $1, $2, $4, $6, $7, $8, $9);
-}
-;
-
-method
-: maybe_outer_attrs maybe_unsafe FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause inner_attrs_and_block
-{
-  $$ = mk_node("Method", 7, $1, $2, $4, $5, $6, $7, $8);
-}
-| maybe_outer_attrs CONST maybe_unsafe FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause inner_attrs_and_block
-{
-  $$ = mk_node("Method", 7, $1, $3, $5, $6, $7, $8, $9);
-}
-| maybe_outer_attrs maybe_unsafe EXTERN maybe_abi FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause inner_attrs_and_block
-{
-  $$ = mk_node("Method", 8, $1, $2, $4, $6, $7, $8, $9, $10);
-}
-;
-
-impl_method
-: attrs_and_vis maybe_default maybe_unsafe FN ident generic_params fn_decl_with_self maybe_where_clause inner_attrs_and_block
-{
-  $$ = mk_node("Method", 8, $1, $2, $3, $5, $6, $7, $8, $9);
-}
-| attrs_and_vis maybe_default CONST maybe_unsafe FN ident generic_params fn_decl_with_self maybe_where_clause inner_attrs_and_block
-{
-  $$ = mk_node("Method", 8, $1, $2, $4, $6, $7, $8, $9, $10);
-}
-| attrs_and_vis maybe_default maybe_unsafe EXTERN maybe_abi FN ident generic_params fn_decl_with_self maybe_where_clause inner_attrs_and_block
-{
-  $$ = mk_node("Method", 9, $1, $2, $3, $5, $7, $8, $9, $10, $11);
-}
-;
-
-// There are two forms of impl:
-//
-// impl (<...>)? TY { ... }
-// impl (<...>)? TRAIT for TY { ... }
-//
-// Unfortunately since TY can begin with '<' itself -- as part of a
-// TyQualifiedPath type -- there's an s/r conflict when we see '<' after IMPL:
-// should we reduce one of the early rules of TY (such as maybe_once)
-// or shall we continue shifting into the generic_params list for the
-// impl?
-//
-// The production parser disambiguates a different case here by
-// permitting / requiring the user to provide parens around types when
-// they are ambiguous with traits. We do the same here, regrettably,
-// by splitting ty into ty and ty_prim.
-item_impl
-: maybe_default_maybe_unsafe IMPL generic_params ty_prim_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
-{
-  $$ = mk_node("ItemImpl", 6, $1, $3, $4, $5, $7, $8);
-}
-| maybe_default_maybe_unsafe IMPL generic_params '(' ty ')' maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
-{
-  $$ = mk_node("ItemImpl", 6, $1, $3, 5, $6, $9, $10);
-}
-| maybe_default_maybe_unsafe IMPL generic_params trait_ref FOR ty_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
-{
-  $$ = mk_node("ItemImpl", 6, $3, $4, $6, $7, $9, $10);
-}
-| maybe_default_maybe_unsafe IMPL generic_params '!' trait_ref FOR ty_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
-{
-  $$ = mk_node("ItemImplNeg", 7, $1, $3, $5, $7, $8, $10, $11);
-}
-| maybe_default_maybe_unsafe IMPL generic_params trait_ref FOR DOTDOT '{' '}'
-{
-  $$ = mk_node("ItemImplDefault", 3, $1, $3, $4);
-}
-| maybe_default_maybe_unsafe IMPL generic_params '!' trait_ref FOR DOTDOT '{' '}'
-{
-  $$ = mk_node("ItemImplDefaultNeg", 3, $1, $3, $4);
-}
-;
-
-maybe_impl_items
-: impl_items
-| %empty { $$ = mk_none(); }
-;
-
-impl_items
-: impl_item               { $$ = mk_node("ImplItems", 1, $1); }
-| impl_item impl_items    { $$ = ext_node($1, 1, $2); }
-;
-
-impl_item
-: impl_method
-| attrs_and_vis item_macro { $$ = mk_node("ImplMacroItem", 2, $1, $2); }
-| impl_const
-| impl_type
-;
-
-maybe_default
-: DEFAULT { $$ = mk_atom("Default"); }
-| %empty { $$ = mk_none(); }
-;
-
-impl_const
-: attrs_and_vis maybe_default item_const { $$ = mk_node("ImplConst", 3, $1, $2, $3); }
-;
-
-impl_type
-: attrs_and_vis maybe_default TYPE ident generic_params '=' ty_sum ';'  { $$ = mk_node("ImplType", 5, $1, $2, $4, $5, $7); }
-;
-
-item_fn
-: FN ident generic_params fn_decl maybe_where_clause inner_attrs_and_block
-{
-  $$ = mk_node("ItemFn", 5, $2, $3, $4, $5, $6);
-}
-| CONST FN ident generic_params fn_decl maybe_where_clause inner_attrs_and_block
-{
-  $$ = mk_node("ItemFn", 5, $3, $4, $5, $6, $7);
-}
-;
-
-item_unsafe_fn
-: UNSAFE FN ident generic_params fn_decl maybe_where_clause inner_attrs_and_block
-{
-  $$ = mk_node("ItemUnsafeFn", 5, $3, $4, $5, $6, $7);
-}
-| CONST UNSAFE FN ident generic_params fn_decl maybe_where_clause inner_attrs_and_block
-{
-  $$ = mk_node("ItemUnsafeFn", 5, $4, $5, $6, $7, $8);
-}
-| UNSAFE EXTERN maybe_abi FN ident generic_params fn_decl maybe_where_clause inner_attrs_and_block
-{
-  $$ = mk_node("ItemUnsafeFn", 6, $3, $5, $6, $7, $8, $9);
-}
-;
-
-fn_decl
-: fn_params ret_ty   { $$ = mk_node("FnDecl", 2, $1, $2); }
-;
-
-fn_decl_with_self
-: fn_params_with_self ret_ty   { $$ = mk_node("FnDecl", 2, $1, $2); }
-;
-
-fn_decl_with_self_allow_anon_params
-: fn_anon_params_with_self ret_ty   { $$ = mk_node("FnDecl", 2, $1, $2); }
-;
-
-fn_params
-: '(' maybe_params ')'  { $$ = $2; }
-;
-
-fn_anon_params
-: '(' anon_param anon_params_allow_variadic_tail ')' { $$ = ext_node($2, 1, $3); }
-| '(' ')'                                            { $$ = mk_none(); }
-;
-
-fn_params_with_self
-: '(' 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("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); }
-;
-
-maybe_params
-: params
-| params ','
-| %empty  { $$ = mk_none(); }
-;
-
-params
-: param                { $$ = mk_node("Args", 1, $1); }
-| params ',' param     { $$ = ext_node($1, 1, $3); }
-;
-
-param
-: pat ':' ty_sum   { $$ = mk_node("Arg", 2, $1, $3); }
-;
-
-inferrable_params
-: inferrable_param                       { $$ = mk_node("InferrableParams", 1, $1); }
-| inferrable_params ',' inferrable_param { $$ = ext_node($1, 1, $3); }
-;
-
-inferrable_param
-: pat maybe_ty_ascription { $$ = mk_node("InferrableParam", 2, $1, $2); }
-;
-
-maybe_comma_params
-: ','            { $$ = mk_none(); }
-| ',' params     { $$ = $2; }
-| ',' params ',' { $$ = $2; }
-| %empty         { $$ = mk_none(); }
-;
-
-maybe_comma_anon_params
-: ','                 { $$ = mk_none(); }
-| ',' anon_params     { $$ = $2; }
-| ',' anon_params ',' { $$ = $2; }
-| %empty              { $$ = mk_none(); }
-;
-
-maybe_anon_params
-: anon_params
-| anon_params ','
-| %empty      { $$ = mk_none(); }
-;
-
-anon_params
-: anon_param                 { $$ = mk_node("Args", 1, $1); }
-| anon_params ',' anon_param { $$ = ext_node($1, 1, $3); }
-;
-
-// anon means it's allowed to be anonymous (type-only), but it can
-// still have a name
-anon_param
-: named_arg ':' ty   { $$ = mk_node("Arg", 2, $1, $3); }
-| ty
-;
-
-anon_params_allow_variadic_tail
-: ',' DOTDOTDOT                                  { $$ = mk_none(); }
-| ',' anon_param anon_params_allow_variadic_tail { $$ = mk_node("Args", 2, $2, $3); }
-| %empty                                         { $$ = mk_none(); }
-;
-
-named_arg
-: ident
-| UNDERSCORE        { $$ = mk_atom("PatWild"); }
-| '&' ident         { $$ = $2; }
-| '&' UNDERSCORE    { $$ = mk_atom("PatWild"); }
-| ANDAND ident      { $$ = $2; }
-| ANDAND UNDERSCORE { $$ = mk_atom("PatWild"); }
-| MUT ident         { $$ = $2; }
-;
-
-ret_ty
-: RARROW '!'         { $$ = mk_none(); }
-| RARROW ty          { $$ = mk_node("ret-ty", 1, $2); }
-| %prec IDENT %empty { $$ = mk_none(); }
-;
-
-generic_params
-: '<' '>'                             { $$ = mk_node("Generics", 2, mk_none(), mk_none()); }
-| '<' lifetimes '>'                   { $$ = mk_node("Generics", 2, $2, mk_none()); }
-| '<' lifetimes ',' '>'               { $$ = mk_node("Generics", 2, $2, mk_none()); }
-| '<' lifetimes SHR                   { push_back('>'); $$ = mk_node("Generics", 2, $2, mk_none()); }
-| '<' lifetimes ',' SHR               { push_back('>'); $$ = mk_node("Generics", 2, $2, mk_none()); }
-| '<' lifetimes ',' ty_params '>'     { $$ = mk_node("Generics", 2, $2, $4); }
-| '<' lifetimes ',' ty_params ',' '>' { $$ = mk_node("Generics", 2, $2, $4); }
-| '<' lifetimes ',' ty_params SHR     { push_back('>'); $$ = mk_node("Generics", 2, $2, $4); }
-| '<' lifetimes ',' ty_params ',' SHR { push_back('>'); $$ = mk_node("Generics", 2, $2, $4); }
-| '<' ty_params '>'                   { $$ = mk_node("Generics", 2, mk_none(), $2); }
-| '<' ty_params ',' '>'               { $$ = mk_node("Generics", 2, mk_none(), $2); }
-| '<' ty_params SHR                   { push_back('>'); $$ = mk_node("Generics", 2, mk_none(), $2); }
-| '<' ty_params ',' SHR               { push_back('>'); $$ = mk_node("Generics", 2, mk_none(), $2); }
-| %empty                              { $$ = mk_none(); }
-;
-
-maybe_where_clause
-: %empty                              { $$ = mk_none(); }
-| where_clause
-;
-
-where_clause
-: WHERE where_predicates              { $$ = mk_node("WhereClause", 1, $2); }
-| WHERE where_predicates ','          { $$ = mk_node("WhereClause", 1, $2); }
-;
-
-where_predicates
-: where_predicate                      { $$ = mk_node("WherePredicates", 1, $1); }
-| where_predicates ',' where_predicate { $$ = ext_node($1, 1, $3); }
-;
-
-where_predicate
-: maybe_for_lifetimes lifetime ':' bounds    { $$ = mk_node("WherePredicate", 3, $1, $2, $4); }
-| maybe_for_lifetimes ty ':' ty_param_bounds { $$ = mk_node("WherePredicate", 3, $1, $2, $4); }
-;
-
-maybe_for_lifetimes
-: FOR '<' lifetimes '>' { $$ = mk_none(); }
-| %prec FORTYPE %empty  { $$ = mk_none(); }
-
-ty_params
-: ty_param               { $$ = mk_node("TyParams", 1, $1); }
-| ty_params ',' ty_param { $$ = ext_node($1, 1, $3); }
-;
-
-// A path with no type parameters; e.g. `foo::bar::Baz`
-//
-// These show up in 'use' view-items, because these are processed
-// without respect to types.
-path_no_types_allowed
-: ident                               { $$ = mk_node("ViewPath", 1, $1); }
-| MOD_SEP ident                       { $$ = mk_node("ViewPath", 1, $2); }
-| SELF                                { $$ = mk_node("ViewPath", 1, mk_atom("Self")); }
-| MOD_SEP SELF                        { $$ = mk_node("ViewPath", 1, mk_atom("Self")); }
-| SUPER                               { $$ = mk_node("ViewPath", 1, mk_atom("Super")); }
-| MOD_SEP SUPER                       { $$ = mk_node("ViewPath", 1, mk_atom("Super")); }
-| path_no_types_allowed MOD_SEP ident { $$ = ext_node($1, 1, $3); }
-;
-
-// A path with a lifetime and type parameters, with no double colons
-// before the type parameters; e.g. `foo::bar<'a>::Baz<T>`
-//
-// These show up in "trait references", the components of
-// type-parameter bounds lists, as well as in the prefix of the
-// path_generic_args_and_bounds rule, which is the full form of a
-// named typed expression.
-//
-// They do not have (nor need) an extra '::' before '<' because
-// unlike in expr context, there are no "less-than" type exprs to
-// be ambiguous with.
-path_generic_args_without_colons
-: %prec IDENT
-  ident                                                                       { $$ = mk_node("components", 1, $1); }
-| %prec IDENT
-  ident generic_args                                                          { $$ = mk_node("components", 2, $1, $2); }
-| %prec IDENT
-  ident '(' maybe_ty_sums ')' ret_ty                                          { $$ = mk_node("components", 2, $1, $3); }
-| %prec IDENT
-  path_generic_args_without_colons MOD_SEP ident                              { $$ = ext_node($1, 1, $3); }
-| %prec IDENT
-  path_generic_args_without_colons MOD_SEP ident generic_args                 { $$ = ext_node($1, 2, $3, $4); }
-| %prec IDENT
-  path_generic_args_without_colons MOD_SEP ident '(' maybe_ty_sums ')' ret_ty { $$ = ext_node($1, 2, $3, $5); }
-;
-
-generic_args
-: '<' generic_values '>'   { $$ = $2; }
-| '<' generic_values SHR   { push_back('>'); $$ = $2; }
-| '<' generic_values GE    { push_back('='); $$ = $2; }
-| '<' generic_values SHREQ { push_back('>'); push_back('='); $$ = $2; }
-// If generic_args starts with "<<", the first arg must be a
-// TyQualifiedPath because that's the only type that can start with a
-// '<'. This rule parses that as the first ty_sum and then continues
-// with the rest of generic_values.
-| SHL ty_qualified_path_and_generic_values '>'   { $$ = $2; }
-| SHL ty_qualified_path_and_generic_values SHR   { push_back('>'); $$ = $2; }
-| SHL ty_qualified_path_and_generic_values GE    { push_back('='); $$ = $2; }
-| SHL ty_qualified_path_and_generic_values SHREQ { push_back('>'); push_back('='); $$ = $2; }
-;
-
-generic_values
-: maybe_ty_sums_and_or_bindings { $$ = mk_node("GenericValues", 1, $1); }
-;
-
-maybe_ty_sums_and_or_bindings
-: ty_sums
-| ty_sums ','
-| ty_sums ',' bindings { $$ = mk_node("TySumsAndBindings", 2, $1, $3); }
-| bindings
-| bindings ','
-| %empty               { $$ = mk_none(); }
-;
-
-maybe_bindings
-: ',' bindings { $$ = $2; }
-| %empty       { $$ = mk_none(); }
-;
-
-////////////////////////////////////////////////////////////////////////
-// Part 2: Patterns
-////////////////////////////////////////////////////////////////////////
-
-pat
-: UNDERSCORE                                      { $$ = mk_atom("PatWild"); }
-| '&' pat                                         { $$ = mk_node("PatRegion", 1, $2); }
-| '&' MUT pat                                     { $$ = mk_node("PatRegion", 1, $3); }
-| ANDAND pat                                      { $$ = mk_node("PatRegion", 1, mk_node("PatRegion", 1, $2)); }
-| '(' ')'                                         { $$ = mk_atom("PatUnit"); }
-| '(' pat_tup ')'                                 { $$ = mk_node("PatTup", 1, $2); }
-| '[' pat_vec ']'                                 { $$ = mk_node("PatVec", 1, $2); }
-| lit_or_path
-| lit_or_path DOTDOTDOT lit_or_path               { $$ = mk_node("PatRange", 2, $1, $3); }
-| path_expr '{' pat_struct '}'                    { $$ = mk_node("PatStruct", 2, $1, $3); }
-| path_expr '(' ')'                               { $$ = mk_node("PatEnum", 2, $1, mk_none()); }
-| path_expr '(' pat_tup ')'                       { $$ = mk_node("PatEnum", 2, $1, $3); }
-| path_expr '!' maybe_ident delimited_token_trees { $$ = mk_node("PatMac", 3, $1, $3, $4); }
-| binding_mode ident                              { $$ = mk_node("PatIdent", 2, $1, $2); }
-|              ident '@' pat                      { $$ = mk_node("PatIdent", 3, mk_node("BindByValue", 1, mk_atom("MutImmutable")), $1, $3); }
-| binding_mode ident '@' pat                      { $$ = mk_node("PatIdent", 3, $1, $2, $4); }
-| BOX pat                                         { $$ = mk_node("PatUniq", 1, $2); }
-| '<' ty_sum maybe_as_trait_ref '>' MOD_SEP ident { $$ = mk_node("PatQualifiedPath", 3, $2, $3, $6); }
-| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident
-{
-  $$ = mk_node("PatQualifiedPath", 3, mk_node("PatQualifiedPath", 3, $2, $3, $6), $7, $10);
-}
-;
-
-pats_or
-: pat              { $$ = mk_node("Pats", 1, $1); }
-| pats_or '|' pat  { $$ = ext_node($1, 1, $3); }
-;
-
-binding_mode
-: REF         { $$ = mk_node("BindByRef", 1, mk_atom("MutImmutable")); }
-| REF MUT     { $$ = mk_node("BindByRef", 1, mk_atom("MutMutable")); }
-| MUT         { $$ = mk_node("BindByValue", 1, mk_atom("MutMutable")); }
-;
-
-lit_or_path
-: path_expr    { $$ = mk_node("PatLit", 1, $1); }
-| lit          { $$ = mk_node("PatLit", 1, $1); }
-| '-' lit      { $$ = mk_node("PatLit", 1, $2); }
-;
-
-pat_field
-:                  ident        { $$ = mk_node("PatField", 1, $1); }
-|     binding_mode ident        { $$ = mk_node("PatField", 2, $1, $2); }
-| BOX              ident        { $$ = mk_node("PatField", 2, mk_atom("box"), $2); }
-| BOX binding_mode ident        { $$ = mk_node("PatField", 3, mk_atom("box"), $2, $3); }
-|              ident ':' pat    { $$ = mk_node("PatField", 2, $1, $3); }
-| binding_mode ident ':' pat    { $$ = mk_node("PatField", 3, $1, $2, $4); }
-|        LIT_INTEGER ':' pat    { $$ = mk_node("PatField", 2, mk_atom(yytext), $3); }
-;
-
-pat_fields
-: pat_field                  { $$ = mk_node("PatFields", 1, $1); }
-| pat_fields ',' pat_field   { $$ = ext_node($1, 1, $3); }
-;
-
-pat_struct
-: pat_fields                 { $$ = mk_node("PatStruct", 2, $1, mk_atom("false")); }
-| pat_fields ','             { $$ = mk_node("PatStruct", 2, $1, mk_atom("false")); }
-| pat_fields ',' DOTDOT      { $$ = mk_node("PatStruct", 2, $1, mk_atom("true")); }
-| DOTDOT                     { $$ = mk_node("PatStruct", 1, mk_atom("true")); }
-| %empty                     { $$ = mk_node("PatStruct", 1, mk_none()); }
-;
-
-pat_tup
-: pat_tup_elts                                  { $$ = mk_node("PatTup", 2, $1, mk_none()); }
-| pat_tup_elts                             ','  { $$ = mk_node("PatTup", 2, $1, mk_none()); }
-| pat_tup_elts     DOTDOT                       { $$ = mk_node("PatTup", 2, $1, mk_none()); }
-| pat_tup_elts ',' DOTDOT                       { $$ = mk_node("PatTup", 2, $1, mk_none()); }
-| pat_tup_elts     DOTDOT ',' pat_tup_elts      { $$ = mk_node("PatTup", 2, $1, $4); }
-| pat_tup_elts     DOTDOT ',' pat_tup_elts ','  { $$ = mk_node("PatTup", 2, $1, $4); }
-| pat_tup_elts ',' DOTDOT ',' pat_tup_elts      { $$ = mk_node("PatTup", 2, $1, $5); }
-| pat_tup_elts ',' DOTDOT ',' pat_tup_elts ','  { $$ = mk_node("PatTup", 2, $1, $5); }
-|                  DOTDOT ',' pat_tup_elts      { $$ = mk_node("PatTup", 2, mk_none(), $3); }
-|                  DOTDOT ',' pat_tup_elts ','  { $$ = mk_node("PatTup", 2, mk_none(), $3); }
-|                  DOTDOT                       { $$ = mk_node("PatTup", 2, mk_none(), mk_none()); }
-;
-
-pat_tup_elts
-: pat                    { $$ = mk_node("PatTupElts", 1, $1); }
-| pat_tup_elts ',' pat   { $$ = ext_node($1, 1, $3); }
-;
-
-pat_vec
-: pat_vec_elts                                  { $$ = mk_node("PatVec", 2, $1, mk_none()); }
-| pat_vec_elts                             ','  { $$ = mk_node("PatVec", 2, $1, mk_none()); }
-| pat_vec_elts     DOTDOT                       { $$ = mk_node("PatVec", 2, $1, mk_none()); }
-| pat_vec_elts ',' DOTDOT                       { $$ = mk_node("PatVec", 2, $1, mk_none()); }
-| pat_vec_elts     DOTDOT ',' pat_vec_elts      { $$ = mk_node("PatVec", 2, $1, $4); }
-| pat_vec_elts     DOTDOT ',' pat_vec_elts ','  { $$ = mk_node("PatVec", 2, $1, $4); }
-| pat_vec_elts ',' DOTDOT ',' pat_vec_elts      { $$ = mk_node("PatVec", 2, $1, $5); }
-| pat_vec_elts ',' DOTDOT ',' pat_vec_elts ','  { $$ = mk_node("PatVec", 2, $1, $5); }
-|                  DOTDOT ',' pat_vec_elts      { $$ = mk_node("PatVec", 2, mk_none(), $3); }
-|                  DOTDOT ',' pat_vec_elts ','  { $$ = mk_node("PatVec", 2, mk_none(), $3); }
-|                  DOTDOT                       { $$ = mk_node("PatVec", 2, mk_none(), mk_none()); }
-| %empty                                        { $$ = mk_node("PatVec", 2, mk_none(), mk_none()); }
-;
-
-pat_vec_elts
-: pat                    { $$ = mk_node("PatVecElts", 1, $1); }
-| pat_vec_elts ',' pat   { $$ = ext_node($1, 1, $3); }
-;
-
-////////////////////////////////////////////////////////////////////////
-// Part 3: Types
-////////////////////////////////////////////////////////////////////////
-
-ty
-: ty_prim
-| ty_closure
-| '<' ty_sum maybe_as_trait_ref '>' MOD_SEP ident                                      { $$ = mk_node("TyQualifiedPath", 3, $2, $3, $6); }
-| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident { $$ = mk_node("TyQualifiedPath", 3, mk_node("TyQualifiedPath", 3, $2, $3, $6), $7, $10); }
-| '(' ty_sums ')'                                                                      { $$ = mk_node("TyTup", 1, $2); }
-| '(' ty_sums ',' ')'                                                                  { $$ = mk_node("TyTup", 1, $2); }
-| '(' ')'                                                                              { $$ = mk_atom("TyNil"); }
-;
-
-ty_prim
-: %prec IDENT path_generic_args_without_colons                                               { $$ = mk_node("TyPath", 2, mk_node("global", 1, mk_atom("false")), $1); }
-| %prec IDENT MOD_SEP path_generic_args_without_colons                                       { $$ = mk_node("TyPath", 2, mk_node("global", 1, mk_atom("true")), $2); }
-| %prec IDENT SELF MOD_SEP path_generic_args_without_colons                                  { $$ = mk_node("TyPath", 2, mk_node("self", 1, mk_atom("true")), $3); }
-| %prec IDENT path_generic_args_without_colons '!' maybe_ident delimited_token_trees         { $$ = mk_node("TyMacro", 3, $1, $3, $4); }
-| %prec IDENT MOD_SEP path_generic_args_without_colons '!' maybe_ident delimited_token_trees { $$ = mk_node("TyMacro", 3, $2, $4, $5); }
-| BOX ty                                                                                     { $$ = mk_node("TyBox", 1, $2); }
-| '*' maybe_mut_or_const ty                                                                  { $$ = mk_node("TyPtr", 2, $2, $3); }
-| '&' ty                                                                                     { $$ = mk_node("TyRptr", 2, mk_atom("MutImmutable"), $2); }
-| '&' MUT ty                                                                                 { $$ = mk_node("TyRptr", 2, mk_atom("MutMutable"), $3); }
-| ANDAND ty                                                                                  { $$ = mk_node("TyRptr", 1, mk_node("TyRptr", 2, mk_atom("MutImmutable"), $2)); }
-| ANDAND MUT ty                                                                              { $$ = mk_node("TyRptr", 1, mk_node("TyRptr", 2, mk_atom("MutMutable"), $3)); }
-| '&' lifetime maybe_mut ty                                                                  { $$ = mk_node("TyRptr", 3, $2, $3, $4); }
-| ANDAND lifetime maybe_mut ty                                                               { $$ = mk_node("TyRptr", 1, mk_node("TyRptr", 3, $2, $3, $4)); }
-| '[' ty ']'                                                                                 { $$ = mk_node("TyVec", 1, $2); }
-| '[' ty ',' DOTDOT expr ']'                                                                 { $$ = mk_node("TyFixedLengthVec", 2, $2, $5); }
-| '[' ty ';' expr ']'                                                                        { $$ = mk_node("TyFixedLengthVec", 2, $2, $4); }
-| TYPEOF '(' expr ')'                                                                        { $$ = mk_node("TyTypeof", 1, $3); }
-| UNDERSCORE                                                                                 { $$ = mk_atom("TyInfer"); }
-| ty_bare_fn
-| for_in_type
-;
-
-ty_bare_fn
-:                         FN ty_fn_decl { $$ = $2; }
-| UNSAFE                  FN ty_fn_decl { $$ = $3; }
-|        EXTERN maybe_abi FN ty_fn_decl { $$ = $4; }
-| UNSAFE EXTERN maybe_abi FN ty_fn_decl { $$ = $5; }
-;
-
-ty_fn_decl
-: generic_params fn_anon_params ret_ty { $$ = mk_node("TyFnDecl", 3, $1, $2, $3); }
-;
-
-ty_closure
-: UNSAFE '|' anon_params '|' maybe_bounds ret_ty { $$ = mk_node("TyClosure", 3, $3, $5, $6); }
-|        '|' anon_params '|' maybe_bounds ret_ty { $$ = mk_node("TyClosure", 3, $2, $4, $5); }
-| UNSAFE OROR maybe_bounds ret_ty                { $$ = mk_node("TyClosure", 2, $3, $4); }
-|        OROR maybe_bounds ret_ty                { $$ = mk_node("TyClosure", 2, $2, $3); }
-;
-
-for_in_type
-: FOR '<' maybe_lifetimes '>' for_in_type_suffix { $$ = mk_node("ForInType", 2, $3, $5); }
-;
-
-for_in_type_suffix
-: ty_bare_fn
-| trait_ref
-| ty_closure
-;
-
-maybe_mut
-: MUT              { $$ = mk_atom("MutMutable"); }
-| %prec MUT %empty { $$ = mk_atom("MutImmutable"); }
-;
-
-maybe_mut_or_const
-: MUT    { $$ = mk_atom("MutMutable"); }
-| CONST  { $$ = mk_atom("MutImmutable"); }
-| %empty { $$ = mk_atom("MutImmutable"); }
-;
-
-ty_qualified_path_and_generic_values
-: ty_qualified_path maybe_bindings
-{
-  $$ = mk_node("GenericValues", 3, mk_none(), mk_node("TySums", 1, mk_node("TySum", 1, $1)), $2);
-}
-| ty_qualified_path ',' ty_sums maybe_bindings
-{
-  $$ = mk_node("GenericValues", 3, mk_none(), mk_node("TySums", 2, $1, $3), $4);
-}
-;
-
-ty_qualified_path
-: ty_sum AS trait_ref '>' MOD_SEP ident                     { $$ = mk_node("TyQualifiedPath", 3, $1, $3, $6); }
-| ty_sum AS trait_ref '>' MOD_SEP ident '+' ty_param_bounds { $$ = mk_node("TyQualifiedPath", 3, $1, $3, $6); }
-;
-
-maybe_ty_sums
-: ty_sums
-| ty_sums ','
-| %empty { $$ = mk_none(); }
-;
-
-ty_sums
-: ty_sum             { $$ = mk_node("TySums", 1, $1); }
-| ty_sums ',' ty_sum { $$ = ext_node($1, 1, $3); }
-;
-
-ty_sum
-: ty_sum_elt            { $$ = mk_node("TySum", 1, $1); }
-| ty_sum '+' ty_sum_elt { $$ = ext_node($1, 1, $3); }
-;
-
-ty_sum_elt
-: ty
-| lifetime
-;
-
-ty_prim_sum
-: ty_prim_sum_elt                 { $$ = mk_node("TySum", 1, $1); }
-| ty_prim_sum '+' ty_prim_sum_elt { $$ = ext_node($1, 1, $3); }
-;
-
-ty_prim_sum_elt
-: ty_prim
-| lifetime
-;
-
-maybe_ty_param_bounds
-: ':' ty_param_bounds { $$ = $2; }
-| %empty              { $$ = mk_none(); }
-;
-
-ty_param_bounds
-: boundseq
-| %empty { $$ = mk_none(); }
-;
-
-boundseq
-: polybound
-| boundseq '+' polybound { $$ = ext_node($1, 1, $3); }
-;
-
-polybound
-: FOR '<' maybe_lifetimes '>' bound { $$ = mk_node("PolyBound", 2, $3, $5); }
-| bound
-| '?' FOR '<' maybe_lifetimes '>' bound { $$ = mk_node("PolyBound", 2, $4, $6); }
-| '?' bound { $$ = $2; }
-;
-
-bindings
-: binding              { $$ = mk_node("Bindings", 1, $1); }
-| bindings ',' binding { $$ = ext_node($1, 1, $3); }
-;
-
-binding
-: ident '=' ty { mk_node("Binding", 2, $1, $3); }
-;
-
-ty_param
-: ident maybe_ty_param_bounds maybe_ty_default           { $$ = mk_node("TyParam", 3, $1, $2, $3); }
-| ident '?' ident maybe_ty_param_bounds maybe_ty_default { $$ = mk_node("TyParam", 4, $1, $3, $4, $5); }
-;
-
-maybe_bounds
-: %prec SHIFTPLUS
-  ':' bounds             { $$ = $2; }
-| %prec SHIFTPLUS %empty { $$ = mk_none(); }
-;
-
-bounds
-: bound            { $$ = mk_node("bounds", 1, $1); }
-| bounds '+' bound { $$ = ext_node($1, 1, $3); }
-;
-
-bound
-: lifetime
-| trait_ref
-;
-
-maybe_ltbounds
-: %prec SHIFTPLUS
-  ':' ltbounds       { $$ = $2; }
-| %empty             { $$ = mk_none(); }
-;
-
-ltbounds
-: lifetime              { $$ = mk_node("ltbounds", 1, $1); }
-| ltbounds '+' lifetime { $$ = ext_node($1, 1, $3); }
-;
-
-maybe_ty_default
-: '=' ty_sum { $$ = mk_node("TyDefault", 1, $2); }
-| %empty     { $$ = mk_none(); }
-;
-
-maybe_lifetimes
-: lifetimes
-| lifetimes ','
-| %empty { $$ = mk_none(); }
-;
-
-lifetimes
-: lifetime_and_bounds               { $$ = mk_node("Lifetimes", 1, $1); }
-| lifetimes ',' lifetime_and_bounds { $$ = ext_node($1, 1, $3); }
-;
-
-lifetime_and_bounds
-: LIFETIME maybe_ltbounds         { $$ = mk_node("lifetime", 2, mk_atom(yytext), $2); }
-| STATIC_LIFETIME                 { $$ = mk_atom("static_lifetime"); }
-;
-
-lifetime
-: LIFETIME         { $$ = mk_node("lifetime", 1, mk_atom(yytext)); }
-| STATIC_LIFETIME  { $$ = mk_atom("static_lifetime"); }
-;
-
-trait_ref
-: %prec IDENT path_generic_args_without_colons
-| %prec IDENT MOD_SEP path_generic_args_without_colons { $$ = $2; }
-;
-
-////////////////////////////////////////////////////////////////////////
-// Part 4: Blocks, statements, and expressions
-////////////////////////////////////////////////////////////////////////
-
-inner_attrs_and_block
-: '{' maybe_inner_attrs maybe_stmts '}'        { $$ = mk_node("ExprBlock", 2, $2, $3); }
-;
-
-block
-: '{' maybe_stmts '}'                          { $$ = mk_node("ExprBlock", 1, $2); }
-;
-
-maybe_stmts
-: stmts
-| stmts nonblock_expr { $$ = ext_node($1, 1, $2); }
-| nonblock_expr
-| %empty              { $$ = mk_none(); }
-;
-
-// There are two sub-grammars within a "stmts: exprs" derivation
-// depending on whether each stmt-expr is a block-expr form; this is to
-// handle the "semicolon rule" for stmt sequencing that permits
-// writing
-//
-//     if foo { bar } 10
-//
-// as a sequence of two stmts (one if-expr stmt, one lit-10-expr
-// stmt). Unfortunately by permitting juxtaposition of exprs in
-// sequence like that, the non-block expr grammar has to have a
-// second limited sub-grammar that excludes the prefix exprs that
-// are ambiguous with binops. That is to say:
-//
-//     {10} - 1
-//
-// should parse as (progn (progn 10) (- 1)) not (- (progn 10) 1), that
-// is to say, two statements rather than one, at least according to
-// the mainline rust parser.
-//
-// So we wind up with a 3-way split in exprs that occur in stmt lists:
-// block, nonblock-prefix, and nonblock-nonprefix.
-//
-// In non-stmts contexts, expr can relax this trichotomy.
-
-stmts
-: stmt           { $$ = mk_node("stmts", 1, $1); }
-| stmts stmt     { $$ = ext_node($1, 1, $2); }
-;
-
-stmt
-: maybe_outer_attrs let     { $$ = $2; }
-|                 stmt_item
-|             PUB stmt_item { $$ = $2; }
-| outer_attrs     stmt_item { $$ = $2; }
-| outer_attrs PUB stmt_item { $$ = $3; }
-| full_block_expr
-| maybe_outer_attrs block   { $$ = $2; }
-|             nonblock_expr ';'
-| outer_attrs nonblock_expr ';' { $$ = $2; }
-| ';'                   { $$ = mk_none(); }
-;
-
-maybe_exprs
-: exprs
-| exprs ','
-| %empty { $$ = mk_none(); }
-;
-
-maybe_expr
-: expr
-| %empty { $$ = mk_none(); }
-;
-
-exprs
-: expr                                                        { $$ = mk_node("exprs", 1, $1); }
-| exprs ',' expr                                              { $$ = ext_node($1, 1, $3); }
-;
-
-path_expr
-: path_generic_args_with_colons
-| MOD_SEP path_generic_args_with_colons      { $$ = $2; }
-| SELF MOD_SEP path_generic_args_with_colons { $$ = mk_node("SelfPath", 1, $3); }
-;
-
-// A path with a lifetime and type parameters with double colons before
-// the type parameters; e.g. `foo::bar::<'a>::Baz::<T>`
-//
-// These show up in expr context, in order to disambiguate from "less-than"
-// expressions.
-path_generic_args_with_colons
-: ident                                              { $$ = mk_node("components", 1, $1); }
-| SUPER                                              { $$ = mk_atom("Super"); }
-| path_generic_args_with_colons MOD_SEP ident        { $$ = ext_node($1, 1, $3); }
-| path_generic_args_with_colons MOD_SEP SUPER        { $$ = ext_node($1, 1, mk_atom("Super")); }
-| path_generic_args_with_colons MOD_SEP generic_args { $$ = ext_node($1, 1, $3); }
-;
-
-// the braces-delimited macro is a block_expr so it doesn't appear here
-macro_expr
-: path_expr '!' maybe_ident parens_delimited_token_trees   { $$ = mk_node("MacroExpr", 3, $1, $3, $4); }
-| path_expr '!' maybe_ident brackets_delimited_token_trees { $$ = mk_node("MacroExpr", 3, $1, $3, $4); }
-;
-
-nonblock_expr
-: lit                                                           { $$ = mk_node("ExprLit", 1, $1); }
-| %prec IDENT
-  path_expr                                                     { $$ = mk_node("ExprPath", 1, $1); }
-| SELF                                                          { $$ = mk_node("ExprPath", 1, mk_node("ident", 1, mk_atom("self"))); }
-| macro_expr                                                    { $$ = mk_node("ExprMac", 1, $1); }
-| path_expr '{' struct_expr_fields '}'                          { $$ = mk_node("ExprStruct", 2, $1, $3); }
-| nonblock_expr '?'                                             { $$ = mk_node("ExprTry", 1, $1); }
-| nonblock_expr '.' path_generic_args_with_colons               { $$ = mk_node("ExprField", 2, $1, $3); }
-| nonblock_expr '.' LIT_INTEGER                                 { $$ = mk_node("ExprTupleIndex", 1, $1); }
-| nonblock_expr '[' maybe_expr ']'                              { $$ = mk_node("ExprIndex", 2, $1, $3); }
-| nonblock_expr '(' maybe_exprs ')'                             { $$ = mk_node("ExprCall", 2, $1, $3); }
-| '[' vec_expr ']'                                              { $$ = mk_node("ExprVec", 1, $2); }
-| '(' maybe_exprs ')'                                           { $$ = mk_node("ExprParen", 1, $2); }
-| CONTINUE                                                      { $$ = mk_node("ExprAgain", 0); }
-| CONTINUE lifetime                                             { $$ = mk_node("ExprAgain", 1, $2); }
-| RETURN                                                        { $$ = mk_node("ExprRet", 0); }
-| RETURN expr                                                   { $$ = mk_node("ExprRet", 1, $2); }
-| BREAK                                                         { $$ = mk_node("ExprBreak", 0); }
-| BREAK lifetime                                                { $$ = mk_node("ExprBreak", 1, $2); }
-| YIELD                                                         { $$ = mk_node("ExprYield", 0); }
-| YIELD expr                                                    { $$ = mk_node("ExprYield", 1, $2); }
-| nonblock_expr '=' expr                                        { $$ = mk_node("ExprAssign", 2, $1, $3); }
-| nonblock_expr SHLEQ expr                                      { $$ = mk_node("ExprAssignShl", 2, $1, $3); }
-| nonblock_expr SHREQ expr                                      { $$ = mk_node("ExprAssignShr", 2, $1, $3); }
-| nonblock_expr MINUSEQ expr                                    { $$ = mk_node("ExprAssignSub", 2, $1, $3); }
-| nonblock_expr ANDEQ expr                                      { $$ = mk_node("ExprAssignBitAnd", 2, $1, $3); }
-| nonblock_expr OREQ expr                                       { $$ = mk_node("ExprAssignBitOr", 2, $1, $3); }
-| nonblock_expr PLUSEQ expr                                     { $$ = mk_node("ExprAssignAdd", 2, $1, $3); }
-| nonblock_expr STAREQ expr                                     { $$ = mk_node("ExprAssignMul", 2, $1, $3); }
-| nonblock_expr SLASHEQ expr                                    { $$ = mk_node("ExprAssignDiv", 2, $1, $3); }
-| nonblock_expr CARETEQ expr                                    { $$ = mk_node("ExprAssignBitXor", 2, $1, $3); }
-| nonblock_expr PERCENTEQ expr                                  { $$ = mk_node("ExprAssignRem", 2, $1, $3); }
-| nonblock_expr OROR expr                                       { $$ = mk_node("ExprBinary", 3, mk_atom("BiOr"), $1, $3); }
-| nonblock_expr ANDAND expr                                     { $$ = mk_node("ExprBinary", 3, mk_atom("BiAnd"), $1, $3); }
-| nonblock_expr EQEQ expr                                       { $$ = mk_node("ExprBinary", 3, mk_atom("BiEq"), $1, $3); }
-| nonblock_expr NE expr                                         { $$ = mk_node("ExprBinary", 3, mk_atom("BiNe"), $1, $3); }
-| nonblock_expr '<' expr                                        { $$ = mk_node("ExprBinary", 3, mk_atom("BiLt"), $1, $3); }
-| nonblock_expr '>' expr                                        { $$ = mk_node("ExprBinary", 3, mk_atom("BiGt"), $1, $3); }
-| nonblock_expr LE expr                                         { $$ = mk_node("ExprBinary", 3, mk_atom("BiLe"), $1, $3); }
-| nonblock_expr GE expr                                         { $$ = mk_node("ExprBinary", 3, mk_atom("BiGe"), $1, $3); }
-| nonblock_expr '|' expr                                        { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitOr"), $1, $3); }
-| nonblock_expr '^' expr                                        { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitXor"), $1, $3); }
-| nonblock_expr '&' expr                                        { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitAnd"), $1, $3); }
-| nonblock_expr SHL expr                                        { $$ = mk_node("ExprBinary", 3, mk_atom("BiShl"), $1, $3); }
-| nonblock_expr SHR expr                                        { $$ = mk_node("ExprBinary", 3, mk_atom("BiShr"), $1, $3); }
-| nonblock_expr '+' expr                                        { $$ = mk_node("ExprBinary", 3, mk_atom("BiAdd"), $1, $3); }
-| nonblock_expr '-' expr                                        { $$ = mk_node("ExprBinary", 3, mk_atom("BiSub"), $1, $3); }
-| nonblock_expr '*' expr                                        { $$ = mk_node("ExprBinary", 3, mk_atom("BiMul"), $1, $3); }
-| nonblock_expr '/' expr                                        { $$ = mk_node("ExprBinary", 3, mk_atom("BiDiv"), $1, $3); }
-| nonblock_expr '%' expr                                        { $$ = mk_node("ExprBinary", 3, mk_atom("BiRem"), $1, $3); }
-| nonblock_expr DOTDOT                                          { $$ = mk_node("ExprRange", 2, $1, mk_none()); }
-| nonblock_expr DOTDOT expr                                     { $$ = mk_node("ExprRange", 2, $1, $3); }
-|               DOTDOT expr                                     { $$ = mk_node("ExprRange", 2, mk_none(), $2); }
-|               DOTDOT                                          { $$ = mk_node("ExprRange", 2, mk_none(), mk_none()); }
-| nonblock_expr AS ty                                           { $$ = mk_node("ExprCast", 2, $1, $3); }
-| nonblock_expr ':' ty                                          { $$ = mk_node("ExprTypeAscr", 2, $1, $3); }
-| BOX expr                                                      { $$ = mk_node("ExprBox", 1, $2); }
-| expr_qualified_path
-| nonblock_prefix_expr
-;
-
-expr
-: lit                                                 { $$ = mk_node("ExprLit", 1, $1); }
-| %prec IDENT
-  path_expr                                           { $$ = mk_node("ExprPath", 1, $1); }
-| SELF                                                { $$ = mk_node("ExprPath", 1, mk_node("ident", 1, mk_atom("self"))); }
-| macro_expr                                          { $$ = mk_node("ExprMac", 1, $1); }
-| path_expr '{' struct_expr_fields '}'                { $$ = mk_node("ExprStruct", 2, $1, $3); }
-| expr '?'                                            { $$ = mk_node("ExprTry", 1, $1); }
-| expr '.' path_generic_args_with_colons              { $$ = mk_node("ExprField", 2, $1, $3); }
-| expr '.' LIT_INTEGER                                { $$ = mk_node("ExprTupleIndex", 1, $1); }
-| expr '[' maybe_expr ']'                             { $$ = mk_node("ExprIndex", 2, $1, $3); }
-| expr '(' maybe_exprs ')'                            { $$ = mk_node("ExprCall", 2, $1, $3); }
-| '(' maybe_exprs ')'                                 { $$ = mk_node("ExprParen", 1, $2); }
-| '[' vec_expr ']'                                    { $$ = mk_node("ExprVec", 1, $2); }
-| CONTINUE                                            { $$ = mk_node("ExprAgain", 0); }
-| CONTINUE ident                                      { $$ = mk_node("ExprAgain", 1, $2); }
-| RETURN                                              { $$ = mk_node("ExprRet", 0); }
-| RETURN expr                                         { $$ = mk_node("ExprRet", 1, $2); }
-| BREAK                                               { $$ = mk_node("ExprBreak", 0); }
-| BREAK ident                                         { $$ = mk_node("ExprBreak", 1, $2); }
-| YIELD                                               { $$ = mk_node("ExprYield", 0); }
-| YIELD expr                                          { $$ = mk_node("ExprYield", 1, $2); }
-| expr '=' expr                                       { $$ = mk_node("ExprAssign", 2, $1, $3); }
-| expr SHLEQ expr                                     { $$ = mk_node("ExprAssignShl", 2, $1, $3); }
-| expr SHREQ expr                                     { $$ = mk_node("ExprAssignShr", 2, $1, $3); }
-| expr MINUSEQ expr                                   { $$ = mk_node("ExprAssignSub", 2, $1, $3); }
-| expr ANDEQ expr                                     { $$ = mk_node("ExprAssignBitAnd", 2, $1, $3); }
-| expr OREQ expr                                      { $$ = mk_node("ExprAssignBitOr", 2, $1, $3); }
-| expr PLUSEQ expr                                    { $$ = mk_node("ExprAssignAdd", 2, $1, $3); }
-| expr STAREQ expr                                    { $$ = mk_node("ExprAssignMul", 2, $1, $3); }
-| expr SLASHEQ expr                                   { $$ = mk_node("ExprAssignDiv", 2, $1, $3); }
-| expr CARETEQ expr                                   { $$ = mk_node("ExprAssignBitXor", 2, $1, $3); }
-| expr PERCENTEQ expr                                 { $$ = mk_node("ExprAssignRem", 2, $1, $3); }
-| expr OROR expr                                      { $$ = mk_node("ExprBinary", 3, mk_atom("BiOr"), $1, $3); }
-| expr ANDAND expr                                    { $$ = mk_node("ExprBinary", 3, mk_atom("BiAnd"), $1, $3); }
-| expr EQEQ expr                                      { $$ = mk_node("ExprBinary", 3, mk_atom("BiEq"), $1, $3); }
-| expr NE expr                                        { $$ = mk_node("ExprBinary", 3, mk_atom("BiNe"), $1, $3); }
-| expr '<' expr                                       { $$ = mk_node("ExprBinary", 3, mk_atom("BiLt"), $1, $3); }
-| expr '>' expr                                       { $$ = mk_node("ExprBinary", 3, mk_atom("BiGt"), $1, $3); }
-| expr LE expr                                        { $$ = mk_node("ExprBinary", 3, mk_atom("BiLe"), $1, $3); }
-| expr GE expr                                        { $$ = mk_node("ExprBinary", 3, mk_atom("BiGe"), $1, $3); }
-| expr '|' expr                                       { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitOr"), $1, $3); }
-| expr '^' expr                                       { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitXor"), $1, $3); }
-| expr '&' expr                                       { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitAnd"), $1, $3); }
-| expr SHL expr                                       { $$ = mk_node("ExprBinary", 3, mk_atom("BiShl"), $1, $3); }
-| expr SHR expr                                       { $$ = mk_node("ExprBinary", 3, mk_atom("BiShr"), $1, $3); }
-| expr '+' expr                                       { $$ = mk_node("ExprBinary", 3, mk_atom("BiAdd"), $1, $3); }
-| expr '-' expr                                       { $$ = mk_node("ExprBinary", 3, mk_atom("BiSub"), $1, $3); }
-| expr '*' expr                                       { $$ = mk_node("ExprBinary", 3, mk_atom("BiMul"), $1, $3); }
-| expr '/' expr                                       { $$ = mk_node("ExprBinary", 3, mk_atom("BiDiv"), $1, $3); }
-| expr '%' expr                                       { $$ = mk_node("ExprBinary", 3, mk_atom("BiRem"), $1, $3); }
-| expr DOTDOT                                         { $$ = mk_node("ExprRange", 2, $1, mk_none()); }
-| expr DOTDOT expr                                    { $$ = mk_node("ExprRange", 2, $1, $3); }
-|      DOTDOT expr                                    { $$ = mk_node("ExprRange", 2, mk_none(), $2); }
-|      DOTDOT                                         { $$ = mk_node("ExprRange", 2, mk_none(), mk_none()); }
-| expr AS ty                                          { $$ = mk_node("ExprCast", 2, $1, $3); }
-| expr ':' ty                                         { $$ = mk_node("ExprTypeAscr", 2, $1, $3); }
-| BOX expr                                            { $$ = mk_node("ExprBox", 1, $2); }
-| expr_qualified_path
-| block_expr
-| block
-| nonblock_prefix_expr
-;
-
-expr_nostruct
-: lit                                                 { $$ = mk_node("ExprLit", 1, $1); }
-| %prec IDENT
-  path_expr                                           { $$ = mk_node("ExprPath", 1, $1); }
-| SELF                                                { $$ = mk_node("ExprPath", 1, mk_node("ident", 1, mk_atom("self"))); }
-| macro_expr                                          { $$ = mk_node("ExprMac", 1, $1); }
-| expr_nostruct '?'                                   { $$ = mk_node("ExprTry", 1, $1); }
-| expr_nostruct '.' path_generic_args_with_colons     { $$ = mk_node("ExprField", 2, $1, $3); }
-| expr_nostruct '.' LIT_INTEGER                       { $$ = mk_node("ExprTupleIndex", 1, $1); }
-| expr_nostruct '[' maybe_expr ']'                    { $$ = mk_node("ExprIndex", 2, $1, $3); }
-| expr_nostruct '(' maybe_exprs ')'                   { $$ = mk_node("ExprCall", 2, $1, $3); }
-| '[' vec_expr ']'                                    { $$ = mk_node("ExprVec", 1, $2); }
-| '(' maybe_exprs ')'                                 { $$ = mk_node("ExprParen", 1, $2); }
-| CONTINUE                                            { $$ = mk_node("ExprAgain", 0); }
-| CONTINUE ident                                      { $$ = mk_node("ExprAgain", 1, $2); }
-| RETURN                                              { $$ = mk_node("ExprRet", 0); }
-| RETURN expr                                         { $$ = mk_node("ExprRet", 1, $2); }
-| BREAK                                               { $$ = mk_node("ExprBreak", 0); }
-| BREAK ident                                         { $$ = mk_node("ExprBreak", 1, $2); }
-| YIELD                                               { $$ = mk_node("ExprYield", 0); }
-| YIELD expr                                          { $$ = mk_node("ExprYield", 1, $2); }
-| expr_nostruct '=' expr_nostruct                     { $$ = mk_node("ExprAssign", 2, $1, $3); }
-| expr_nostruct SHLEQ expr_nostruct                   { $$ = mk_node("ExprAssignShl", 2, $1, $3); }
-| expr_nostruct SHREQ expr_nostruct                   { $$ = mk_node("ExprAssignShr", 2, $1, $3); }
-| expr_nostruct MINUSEQ expr_nostruct                 { $$ = mk_node("ExprAssignSub", 2, $1, $3); }
-| expr_nostruct ANDEQ expr_nostruct                   { $$ = mk_node("ExprAssignBitAnd", 2, $1, $3); }
-| expr_nostruct OREQ expr_nostruct                    { $$ = mk_node("ExprAssignBitOr", 2, $1, $3); }
-| expr_nostruct PLUSEQ expr_nostruct                  { $$ = mk_node("ExprAssignAdd", 2, $1, $3); }
-| expr_nostruct STAREQ expr_nostruct                  { $$ = mk_node("ExprAssignMul", 2, $1, $3); }
-| expr_nostruct SLASHEQ expr_nostruct                 { $$ = mk_node("ExprAssignDiv", 2, $1, $3); }
-| expr_nostruct CARETEQ expr_nostruct                 { $$ = mk_node("ExprAssignBitXor", 2, $1, $3); }
-| expr_nostruct PERCENTEQ expr_nostruct               { $$ = mk_node("ExprAssignRem", 2, $1, $3); }
-| expr_nostruct OROR expr_nostruct                    { $$ = mk_node("ExprBinary", 3, mk_atom("BiOr"), $1, $3); }
-| expr_nostruct ANDAND expr_nostruct                  { $$ = mk_node("ExprBinary", 3, mk_atom("BiAnd"), $1, $3); }
-| expr_nostruct EQEQ expr_nostruct                    { $$ = mk_node("ExprBinary", 3, mk_atom("BiEq"), $1, $3); }
-| expr_nostruct NE expr_nostruct                      { $$ = mk_node("ExprBinary", 3, mk_atom("BiNe"), $1, $3); }
-| expr_nostruct '<' expr_nostruct                     { $$ = mk_node("ExprBinary", 3, mk_atom("BiLt"), $1, $3); }
-| expr_nostruct '>' expr_nostruct                     { $$ = mk_node("ExprBinary", 3, mk_atom("BiGt"), $1, $3); }
-| expr_nostruct LE expr_nostruct                      { $$ = mk_node("ExprBinary", 3, mk_atom("BiLe"), $1, $3); }
-| expr_nostruct GE expr_nostruct                      { $$ = mk_node("ExprBinary", 3, mk_atom("BiGe"), $1, $3); }
-| expr_nostruct '|' expr_nostruct                     { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitOr"), $1, $3); }
-| expr_nostruct '^' expr_nostruct                     { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitXor"), $1, $3); }
-| expr_nostruct '&' expr_nostruct                     { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitAnd"), $1, $3); }
-| expr_nostruct SHL expr_nostruct                     { $$ = mk_node("ExprBinary", 3, mk_atom("BiShl"), $1, $3); }
-| expr_nostruct SHR expr_nostruct                     { $$ = mk_node("ExprBinary", 3, mk_atom("BiShr"), $1, $3); }
-| expr_nostruct '+' expr_nostruct                     { $$ = mk_node("ExprBinary", 3, mk_atom("BiAdd"), $1, $3); }
-| expr_nostruct '-' expr_nostruct                     { $$ = mk_node("ExprBinary", 3, mk_atom("BiSub"), $1, $3); }
-| expr_nostruct '*' expr_nostruct                     { $$ = mk_node("ExprBinary", 3, mk_atom("BiMul"), $1, $3); }
-| expr_nostruct '/' expr_nostruct                     { $$ = mk_node("ExprBinary", 3, mk_atom("BiDiv"), $1, $3); }
-| expr_nostruct '%' expr_nostruct                     { $$ = mk_node("ExprBinary", 3, mk_atom("BiRem"), $1, $3); }
-| expr_nostruct DOTDOT               %prec RANGE      { $$ = mk_node("ExprRange", 2, $1, mk_none()); }
-| expr_nostruct DOTDOT expr_nostruct                  { $$ = mk_node("ExprRange", 2, $1, $3); }
-|               DOTDOT expr_nostruct                  { $$ = mk_node("ExprRange", 2, mk_none(), $2); }
-|               DOTDOT                                { $$ = mk_node("ExprRange", 2, mk_none(), mk_none()); }
-| expr_nostruct AS ty                                 { $$ = mk_node("ExprCast", 2, $1, $3); }
-| expr_nostruct ':' ty                                { $$ = mk_node("ExprTypeAscr", 2, $1, $3); }
-| BOX expr                                            { $$ = mk_node("ExprBox", 1, $2); }
-| expr_qualified_path
-| block_expr
-| block
-| nonblock_prefix_expr_nostruct
-;
-
-nonblock_prefix_expr_nostruct
-: '-' expr_nostruct                         { $$ = mk_node("ExprUnary", 2, mk_atom("UnNeg"), $2); }
-| '!' expr_nostruct                         { $$ = mk_node("ExprUnary", 2, mk_atom("UnNot"), $2); }
-| '*' expr_nostruct                         { $$ = mk_node("ExprUnary", 2, mk_atom("UnDeref"), $2); }
-| '&' maybe_mut expr_nostruct               { $$ = mk_node("ExprAddrOf", 2, $2, $3); }
-| ANDAND maybe_mut expr_nostruct            { $$ = mk_node("ExprAddrOf", 1, mk_node("ExprAddrOf", 2, $2, $3)); }
-| lambda_expr_nostruct
-| MOVE lambda_expr_nostruct                 { $$ = $2; }
-;
-
-nonblock_prefix_expr
-: '-' expr                         { $$ = mk_node("ExprUnary", 2, mk_atom("UnNeg"), $2); }
-| '!' expr                         { $$ = mk_node("ExprUnary", 2, mk_atom("UnNot"), $2); }
-| '*' expr                         { $$ = mk_node("ExprUnary", 2, mk_atom("UnDeref"), $2); }
-| '&' maybe_mut expr               { $$ = mk_node("ExprAddrOf", 2, $2, $3); }
-| ANDAND maybe_mut expr            { $$ = mk_node("ExprAddrOf", 1, mk_node("ExprAddrOf", 2, $2, $3)); }
-| lambda_expr
-| MOVE lambda_expr                 { $$ = $2; }
-;
-
-expr_qualified_path
-: '<' ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_qpath_params
-{
-  $$ = mk_node("ExprQualifiedPath", 4, $2, $3, $6, $7);
-}
-| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident
-{
-  $$ = mk_node("ExprQualifiedPath", 3, mk_node("ExprQualifiedPath", 3, $2, $3, $6), $7, $10);
-}
-| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident generic_args maybe_as_trait_ref '>' MOD_SEP ident
-{
-  $$ = mk_node("ExprQualifiedPath", 3, mk_node("ExprQualifiedPath", 4, $2, $3, $6, $7), $8, $11);
-}
-| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident generic_args
-{
-  $$ = mk_node("ExprQualifiedPath", 4, mk_node("ExprQualifiedPath", 3, $2, $3, $6), $7, $10, $11);
-}
-| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident generic_args maybe_as_trait_ref '>' MOD_SEP ident generic_args
-{
-  $$ = mk_node("ExprQualifiedPath", 4, mk_node("ExprQualifiedPath", 4, $2, $3, $6, $7), $8, $11, $12);
-}
-
-maybe_qpath_params
-: MOD_SEP generic_args { $$ = $2; }
-| %empty               { $$ = mk_none(); }
-;
-
-maybe_as_trait_ref
-: AS trait_ref { $$ = $2; }
-| %empty       { $$ = mk_none(); }
-;
-
-lambda_expr
-: %prec LAMBDA
-  OROR ret_ty expr                                    { $$ = mk_node("ExprFnBlock", 3, mk_none(), $2, $3); }
-| %prec LAMBDA
-  '|' '|' ret_ty expr                                 { $$ = mk_node("ExprFnBlock", 3, mk_none(), $3, $4); }
-| %prec LAMBDA
-  '|' inferrable_params '|' ret_ty expr               { $$ = mk_node("ExprFnBlock", 3, $2, $4, $5); }
-| %prec LAMBDA
-  '|' inferrable_params OROR lambda_expr_no_first_bar { $$ = mk_node("ExprFnBlock", 3, $2, mk_none(), $4); }
-;
-
-lambda_expr_no_first_bar
-: %prec LAMBDA
-  '|' ret_ty expr                                 { $$ = mk_node("ExprFnBlock", 3, mk_none(), $2, $3); }
-| %prec LAMBDA
-  inferrable_params '|' ret_ty expr               { $$ = mk_node("ExprFnBlock", 3, $1, $3, $4); }
-| %prec LAMBDA
-  inferrable_params OROR lambda_expr_no_first_bar { $$ = mk_node("ExprFnBlock", 3, $1, mk_none(), $3); }
-;
-
-lambda_expr_nostruct
-: %prec LAMBDA
-  OROR expr_nostruct                                           { $$ = mk_node("ExprFnBlock", 2, mk_none(), $2); }
-| %prec LAMBDA
-  '|' '|' ret_ty expr_nostruct                                 { $$ = mk_node("ExprFnBlock", 3, mk_none(), $3, $4); }
-| %prec LAMBDA
-  '|' inferrable_params '|' expr_nostruct                      { $$ = mk_node("ExprFnBlock", 2, $2, $4); }
-| %prec LAMBDA
-  '|' inferrable_params OROR lambda_expr_nostruct_no_first_bar { $$ = mk_node("ExprFnBlock", 3, $2, mk_none(), $4); }
-;
-
-lambda_expr_nostruct_no_first_bar
-: %prec LAMBDA
-  '|' ret_ty expr_nostruct                                 { $$ = mk_node("ExprFnBlock", 3, mk_none(), $2, $3); }
-| %prec LAMBDA
-  inferrable_params '|' ret_ty expr_nostruct               { $$ = mk_node("ExprFnBlock", 3, $1, $3, $4); }
-| %prec LAMBDA
-  inferrable_params OROR lambda_expr_nostruct_no_first_bar { $$ = mk_node("ExprFnBlock", 3, $1, mk_none(), $3); }
-;
-
-vec_expr
-: maybe_exprs
-| exprs ';' expr { $$ = mk_node("VecRepeat", 2, $1, $3); }
-;
-
-struct_expr_fields
-: field_inits
-| field_inits ','
-| maybe_field_inits default_field_init { $$ = ext_node($1, 1, $2); }
-| %empty                               { $$ = mk_none(); }
-;
-
-maybe_field_inits
-: field_inits
-| field_inits ','
-| %empty { $$ = mk_none(); }
-;
-
-field_inits
-: field_init                 { $$ = mk_node("FieldInits", 1, $1); }
-| field_inits ',' field_init { $$ = ext_node($1, 1, $3); }
-;
-
-field_init
-: ident                { $$ = mk_node("FieldInit", 1, $1); }
-| ident ':' expr       { $$ = mk_node("FieldInit", 2, $1, $3); }
-| LIT_INTEGER ':' expr { $$ = mk_node("FieldInit", 2, mk_atom(yytext), $3); }
-;
-
-default_field_init
-: DOTDOT expr   { $$ = mk_node("DefaultFieldInit", 1, $2); }
-;
-
-block_expr
-: expr_match
-| expr_if
-| expr_if_let
-| expr_while
-| expr_while_let
-| expr_loop
-| expr_for
-| UNSAFE block                                           { $$ = mk_node("UnsafeBlock", 1, $2); }
-| path_expr '!' maybe_ident braces_delimited_token_trees { $$ = mk_node("Macro", 3, $1, $3, $4); }
-;
-
-full_block_expr
-: block_expr
-| block_expr_dot
-;
-
-block_expr_dot
-: block_expr     '.' path_generic_args_with_colons %prec IDENT         { $$ = mk_node("ExprField", 2, $1, $3); }
-| block_expr_dot '.' path_generic_args_with_colons %prec IDENT         { $$ = mk_node("ExprField", 2, $1, $3); }
-| block_expr     '.' path_generic_args_with_colons '[' maybe_expr ']'  { $$ = mk_node("ExprIndex", 3, $1, $3, $5); }
-| block_expr_dot '.' path_generic_args_with_colons '[' maybe_expr ']'  { $$ = mk_node("ExprIndex", 3, $1, $3, $5); }
-| block_expr     '.' path_generic_args_with_colons '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 3, $1, $3, $5); }
-| block_expr_dot '.' path_generic_args_with_colons '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 3, $1, $3, $5); }
-| block_expr     '.' LIT_INTEGER                                       { $$ = mk_node("ExprTupleIndex", 1, $1); }
-| block_expr_dot '.' LIT_INTEGER                                       { $$ = mk_node("ExprTupleIndex", 1, $1); }
-;
-
-expr_match
-: MATCH expr_nostruct '{' '}'                                     { $$ = mk_node("ExprMatch", 1, $2); }
-| MATCH expr_nostruct '{' match_clauses                       '}' { $$ = mk_node("ExprMatch", 2, $2, $4); }
-| MATCH expr_nostruct '{' match_clauses nonblock_match_clause '}' { $$ = mk_node("ExprMatch", 2, $2, ext_node($4, 1, $5)); }
-| MATCH expr_nostruct '{'               nonblock_match_clause '}' { $$ = mk_node("ExprMatch", 2, $2, mk_node("Arms", 1, $4)); }
-;
-
-match_clauses
-: match_clause               { $$ = mk_node("Arms", 1, $1); }
-| match_clauses match_clause { $$ = ext_node($1, 1, $2); }
-;
-
-match_clause
-: nonblock_match_clause ','
-| block_match_clause
-| block_match_clause ','
-;
-
-nonblock_match_clause
-: maybe_outer_attrs pats_or maybe_guard FAT_ARROW nonblock_expr  { $$ = mk_node("ArmNonblock", 4, $1, $2, $3, $5); }
-| maybe_outer_attrs pats_or maybe_guard FAT_ARROW block_expr_dot { $$ = mk_node("ArmNonblock", 4, $1, $2, $3, $5); }
-;
-
-block_match_clause
-: maybe_outer_attrs pats_or maybe_guard FAT_ARROW block      { $$ = mk_node("ArmBlock", 4, $1, $2, $3, $5); }
-| maybe_outer_attrs pats_or maybe_guard FAT_ARROW block_expr { $$ = mk_node("ArmBlock", 4, $1, $2, $3, $5); }
-;
-
-maybe_guard
-: IF expr_nostruct           { $$ = $2; }
-| %empty                     { $$ = mk_none(); }
-;
-
-expr_if
-: IF expr_nostruct block                              { $$ = mk_node("ExprIf", 2, $2, $3); }
-| IF expr_nostruct block ELSE block_or_if             { $$ = mk_node("ExprIf", 3, $2, $3, $5); }
-;
-
-expr_if_let
-: IF LET pat '=' expr_nostruct block                  { $$ = mk_node("ExprIfLet", 3, $3, $5, $6); }
-| IF LET pat '=' expr_nostruct block ELSE block_or_if { $$ = mk_node("ExprIfLet", 4, $3, $5, $6, $8); }
-;
-
-block_or_if
-: block
-| expr_if
-| expr_if_let
-;
-
-expr_while
-: maybe_label WHILE expr_nostruct block               { $$ = mk_node("ExprWhile", 3, $1, $3, $4); }
-;
-
-expr_while_let
-: maybe_label WHILE LET pat '=' expr_nostruct block   { $$ = mk_node("ExprWhileLet", 4, $1, $4, $6, $7); }
-;
-
-expr_loop
-: maybe_label LOOP block                              { $$ = mk_node("ExprLoop", 2, $1, $3); }
-;
-
-expr_for
-: maybe_label FOR pat IN expr_nostruct block          { $$ = mk_node("ExprForLoop", 4, $1, $3, $5, $6); }
-;
-
-maybe_label
-: lifetime ':'
-| %empty { $$ = mk_none(); }
-;
-
-let
-: LET pat maybe_ty_ascription maybe_init_expr ';' { $$ = mk_node("DeclLocal", 3, $2, $3, $4); }
-;
-
-////////////////////////////////////////////////////////////////////////
-// Part 5: Macros and misc. rules
-////////////////////////////////////////////////////////////////////////
-
-lit
-: LIT_BYTE                   { $$ = mk_node("LitByte", 1, mk_atom(yytext)); }
-| LIT_CHAR                   { $$ = mk_node("LitChar", 1, mk_atom(yytext)); }
-| LIT_INTEGER                { $$ = mk_node("LitInteger", 1, mk_atom(yytext)); }
-| LIT_FLOAT                  { $$ = mk_node("LitFloat", 1, mk_atom(yytext)); }
-| TRUE                       { $$ = mk_node("LitBool", 1, mk_atom(yytext)); }
-| FALSE                      { $$ = mk_node("LitBool", 1, mk_atom(yytext)); }
-| str
-;
-
-str
-: LIT_STR                    { $$ = mk_node("LitStr", 1, mk_atom(yytext), mk_atom("CookedStr")); }
-| LIT_STR_RAW                { $$ = mk_node("LitStr", 1, mk_atom(yytext), mk_atom("RawStr")); }
-| LIT_BYTE_STR                 { $$ = mk_node("LitByteStr", 1, mk_atom(yytext), mk_atom("ByteStr")); }
-| LIT_BYTE_STR_RAW             { $$ = mk_node("LitByteStr", 1, mk_atom(yytext), mk_atom("RawByteStr")); }
-;
-
-maybe_ident
-: %empty { $$ = mk_none(); }
-| ident
-;
-
-ident
-: IDENT                      { $$ = mk_node("ident", 1, mk_atom(yytext)); }
-// Weak keywords that can be used as identifiers
-| CATCH                      { $$ = mk_node("ident", 1, mk_atom(yytext)); }
-| DEFAULT                    { $$ = mk_node("ident", 1, mk_atom(yytext)); }
-| UNION                      { $$ = mk_node("ident", 1, mk_atom(yytext)); }
-;
-
-unpaired_token
-: SHL                        { $$ = mk_atom(yytext); }
-| SHR                        { $$ = mk_atom(yytext); }
-| LE                         { $$ = mk_atom(yytext); }
-| EQEQ                       { $$ = mk_atom(yytext); }
-| NE                         { $$ = mk_atom(yytext); }
-| GE                         { $$ = mk_atom(yytext); }
-| ANDAND                     { $$ = mk_atom(yytext); }
-| OROR                       { $$ = mk_atom(yytext); }
-| LARROW                     { $$ = mk_atom(yytext); }
-| SHLEQ                      { $$ = mk_atom(yytext); }
-| SHREQ                      { $$ = mk_atom(yytext); }
-| MINUSEQ                    { $$ = mk_atom(yytext); }
-| ANDEQ                      { $$ = mk_atom(yytext); }
-| OREQ                       { $$ = mk_atom(yytext); }
-| PLUSEQ                     { $$ = mk_atom(yytext); }
-| STAREQ                     { $$ = mk_atom(yytext); }
-| SLASHEQ                    { $$ = mk_atom(yytext); }
-| CARETEQ                    { $$ = mk_atom(yytext); }
-| PERCENTEQ                  { $$ = mk_atom(yytext); }
-| DOTDOT                     { $$ = mk_atom(yytext); }
-| DOTDOTDOT                  { $$ = mk_atom(yytext); }
-| MOD_SEP                    { $$ = mk_atom(yytext); }
-| RARROW                     { $$ = mk_atom(yytext); }
-| FAT_ARROW                  { $$ = mk_atom(yytext); }
-| LIT_BYTE                   { $$ = mk_atom(yytext); }
-| LIT_CHAR                   { $$ = mk_atom(yytext); }
-| LIT_INTEGER                { $$ = mk_atom(yytext); }
-| LIT_FLOAT                  { $$ = mk_atom(yytext); }
-| LIT_STR                    { $$ = mk_atom(yytext); }
-| LIT_STR_RAW                { $$ = mk_atom(yytext); }
-| LIT_BYTE_STR               { $$ = mk_atom(yytext); }
-| LIT_BYTE_STR_RAW           { $$ = mk_atom(yytext); }
-| IDENT                      { $$ = mk_atom(yytext); }
-| UNDERSCORE                 { $$ = mk_atom(yytext); }
-| LIFETIME                   { $$ = mk_atom(yytext); }
-| SELF                       { $$ = mk_atom(yytext); }
-| STATIC                     { $$ = mk_atom(yytext); }
-| ABSTRACT                   { $$ = mk_atom(yytext); }
-| ALIGNOF                    { $$ = mk_atom(yytext); }
-| AS                         { $$ = mk_atom(yytext); }
-| BECOME                     { $$ = mk_atom(yytext); }
-| BREAK                      { $$ = mk_atom(yytext); }
-| CATCH                      { $$ = mk_atom(yytext); }
-| CRATE                      { $$ = mk_atom(yytext); }
-| DEFAULT                    { $$ = mk_atom(yytext); }
-| DO                         { $$ = mk_atom(yytext); }
-| ELSE                       { $$ = mk_atom(yytext); }
-| ENUM                       { $$ = mk_atom(yytext); }
-| EXTERN                     { $$ = mk_atom(yytext); }
-| FALSE                      { $$ = mk_atom(yytext); }
-| FINAL                      { $$ = mk_atom(yytext); }
-| FN                         { $$ = mk_atom(yytext); }
-| FOR                        { $$ = mk_atom(yytext); }
-| IF                         { $$ = mk_atom(yytext); }
-| IMPL                       { $$ = mk_atom(yytext); }
-| IN                         { $$ = mk_atom(yytext); }
-| LET                        { $$ = mk_atom(yytext); }
-| LOOP                       { $$ = mk_atom(yytext); }
-| MACRO                      { $$ = mk_atom(yytext); }
-| MATCH                      { $$ = mk_atom(yytext); }
-| MOD                        { $$ = mk_atom(yytext); }
-| MOVE                       { $$ = mk_atom(yytext); }
-| MUT                        { $$ = mk_atom(yytext); }
-| OFFSETOF                   { $$ = mk_atom(yytext); }
-| OVERRIDE                   { $$ = mk_atom(yytext); }
-| PRIV                       { $$ = mk_atom(yytext); }
-| PUB                        { $$ = mk_atom(yytext); }
-| PURE                       { $$ = mk_atom(yytext); }
-| REF                        { $$ = mk_atom(yytext); }
-| RETURN                     { $$ = mk_atom(yytext); }
-| STRUCT                     { $$ = mk_atom(yytext); }
-| SIZEOF                     { $$ = mk_atom(yytext); }
-| SUPER                      { $$ = mk_atom(yytext); }
-| TRUE                       { $$ = mk_atom(yytext); }
-| TRAIT                      { $$ = mk_atom(yytext); }
-| TYPE                       { $$ = mk_atom(yytext); }
-| UNION                      { $$ = mk_atom(yytext); }
-| UNSAFE                     { $$ = mk_atom(yytext); }
-| UNSIZED                    { $$ = mk_atom(yytext); }
-| USE                        { $$ = mk_atom(yytext); }
-| VIRTUAL                    { $$ = mk_atom(yytext); }
-| WHILE                      { $$ = mk_atom(yytext); }
-| YIELD                      { $$ = mk_atom(yytext); }
-| CONTINUE                   { $$ = mk_atom(yytext); }
-| PROC                       { $$ = mk_atom(yytext); }
-| BOX                        { $$ = mk_atom(yytext); }
-| CONST                      { $$ = mk_atom(yytext); }
-| WHERE                      { $$ = mk_atom(yytext); }
-| TYPEOF                     { $$ = mk_atom(yytext); }
-| INNER_DOC_COMMENT          { $$ = mk_atom(yytext); }
-| OUTER_DOC_COMMENT          { $$ = mk_atom(yytext); }
-| SHEBANG                    { $$ = mk_atom(yytext); }
-| STATIC_LIFETIME            { $$ = mk_atom(yytext); }
-| ';'                        { $$ = mk_atom(yytext); }
-| ','                        { $$ = mk_atom(yytext); }
-| '.'                        { $$ = mk_atom(yytext); }
-| '@'                        { $$ = mk_atom(yytext); }
-| '#'                        { $$ = mk_atom(yytext); }
-| '~'                        { $$ = mk_atom(yytext); }
-| ':'                        { $$ = mk_atom(yytext); }
-| '$'                        { $$ = mk_atom(yytext); }
-| '='                        { $$ = mk_atom(yytext); }
-| '?'                        { $$ = mk_atom(yytext); }
-| '!'                        { $$ = mk_atom(yytext); }
-| '<'                        { $$ = mk_atom(yytext); }
-| '>'                        { $$ = mk_atom(yytext); }
-| '-'                        { $$ = mk_atom(yytext); }
-| '&'                        { $$ = mk_atom(yytext); }
-| '|'                        { $$ = mk_atom(yytext); }
-| '+'                        { $$ = mk_atom(yytext); }
-| '*'                        { $$ = mk_atom(yytext); }
-| '/'                        { $$ = mk_atom(yytext); }
-| '^'                        { $$ = mk_atom(yytext); }
-| '%'                        { $$ = mk_atom(yytext); }
-;
-
-token_trees
-: %empty                     { $$ = mk_node("TokenTrees", 0); }
-| token_trees token_tree     { $$ = ext_node($1, 1, $2); }
-;
-
-token_tree
-: delimited_token_trees
-| unpaired_token         { $$ = mk_node("TTTok", 1, $1); }
-;
-
-delimited_token_trees
-: parens_delimited_token_trees
-| braces_delimited_token_trees
-| brackets_delimited_token_trees
-;
-
-parens_delimited_token_trees
-: '(' token_trees ')'
-{
-  $$ = mk_node("TTDelim", 3,
-               mk_node("TTTok", 1, mk_atom("(")),
-               $2,
-               mk_node("TTTok", 1, mk_atom(")")));
-}
-;
-
-braces_delimited_token_trees
-: '{' token_trees '}'
-{
-  $$ = mk_node("TTDelim", 3,
-               mk_node("TTTok", 1, mk_atom("{")),
-               $2,
-               mk_node("TTTok", 1, mk_atom("}")));
-}
-;
-
-brackets_delimited_token_trees
-: '[' token_trees ']'
-{
-  $$ = mk_node("TTDelim", 3,
-               mk_node("TTTok", 1, mk_atom("[")),
-               $2,
-               mk_node("TTTok", 1, mk_atom("]")));
-}
-;
diff --git a/src/grammar/raw-string-literal-ambiguity.md b/src/grammar/raw-string-literal-ambiguity.md
deleted file mode 100644
index c909f23..0000000
--- a/src/grammar/raw-string-literal-ambiguity.md
+++ /dev/null
@@ -1,64 +0,0 @@
-Rust's lexical grammar is not context-free. Raw string literals are the source
-of the problem. Informally, a raw string literal is an `r`, followed by `N`
-hashes (where N can be zero), a quote, any characters, then a quote followed
-by `N` hashes. Critically, once inside the first pair of quotes,
-another quote cannot be followed by `N` consecutive hashes. e.g.
-`r###""###"###` is invalid.
-
-This grammar describes this as best possible:
-
-    R -> 'r' S
-    S -> '"' B '"'
-    S -> '#' S '#'
-    B -> . B
-    B -> ε
-
-Where `.` represents any character, and `ε` the empty string. Consider the
-string `r#""#"#`. This string is not a valid raw string literal, but can be
-accepted as one by the above grammar, using the derivation:
-
-    R : #""#"#
-    S : ""#"
-    S : "#
-    B : #
-    B : ε
-
-(Where `T : U` means the rule `T` is applied, and `U` is the remainder of the
-string.) The difficulty arises from the fact that it is fundamentally
-context-sensitive. In particular, the context needed is the number of hashes.
-
-To prove that Rust's string literals are not context-free, we will use
-the fact that context-free languages are closed under intersection with
-regular languages, and the
-[pumping lemma for context-free languages](https://en.wikipedia.org/wiki/Pumping_lemma_for_context-free_languages).
-
-Consider the regular language `R = r#+""#*"#+`. If Rust's raw string literals are
-context-free, then their intersection with `R`, `R'`, should also be context-free.
-Therefore, to prove that raw string literals are not context-free,
-it is sufficient to prove that `R'` is not context-free.
-
-The language `R'` is `{r#^n""#^m"#^n | m < n}`.
-
-Assume `R'` *is* context-free. Then `R'` has some pumping length `p > 0` for which
-the pumping lemma applies. Consider the following string `s` in `R'`:
-
-`r#^p""#^{p-1}"#^p`
-
-e.g. for `p = 2`: `s = r##""#"##`
-
-Then `s = uvwxy` for some choice of `uvwxy` such that `vx` is non-empty,
-`|vwx| < p+1`, and `uv^iwx^iy` is in `R'` for all `i >= 0`.
-
-Neither `v` nor `x` can contain a `"` or `r`, as the number of these characters
-in any string in `R'` is fixed. So `v` and `x` contain only hashes.
-Consequently, of the three sequences of hashes, `v` and `x` combined
-can only pump two of them.
-If we ever choose the central sequence of hashes, then one of the outer sequences
-will not grow when we pump, leading to an imbalance between the outer sequences.
-Therefore, we must pump both outer sequences of hashes. However,
-there are `p+2` characters between these two sequences of hashes, and `|vwx|` must
-be less than `p+1`. Therefore we have a contradiction, and `R'` must not be
-context-free.
-
-Since `R'` is not context-free, it follows that the Rust's raw string literals
-must not be context-free.
diff --git a/src/grammar/testparser.py b/src/grammar/testparser.py
deleted file mode 100755
index 4b5a7fb..0000000
--- a/src/grammar/testparser.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python
-
-# ignore-tidy-linelength
-
-import sys
-
-import os
-import subprocess
-import argparse
-
-# usage: testparser.py [-h] [-p PARSER [PARSER ...]] -s SOURCE_DIR
-
-# Parsers should read from stdin and return exit status 0 for a
-# successful parse, and nonzero for an unsuccessful parse
-
-parser = argparse.ArgumentParser()
-parser.add_argument('-p', '--parser', nargs='+')
-parser.add_argument('-s', '--source-dir', nargs=1, required=True)
-args = parser.parse_args(sys.argv[1:])
-
-total = 0
-ok = {}
-bad = {}
-for parser in args.parser:
-    ok[parser] = 0
-    bad[parser] = []
-devnull = open(os.devnull, 'w')
-print("\n")
-
-for base, dirs, files in os.walk(args.source_dir[0]):
-    for f in filter(lambda p: p.endswith('.rs'), files):
-        p = os.path.join(base, f)
-        parse_fail = 'parse-fail' in p
-        if sys.version_info.major == 3:
-            lines = open(p, encoding='utf-8').readlines()
-        else:
-            lines = open(p).readlines()
-        if any('ignore-test' in line or 'ignore-lexer-test' in line for line in lines):
-            continue
-        total += 1
-        for parser in args.parser:
-            if subprocess.call(parser, stdin=open(p), stderr=subprocess.STDOUT, stdout=devnull) == 0:
-                if parse_fail:
-                    bad[parser].append(p)
-                else:
-                    ok[parser] += 1
-            else:
-                if parse_fail:
-                    ok[parser] += 1
-                else:
-                    bad[parser].append(p)
-        parser_stats = ', '.join(['{}: {}'.format(parser, ok[parser]) for parser in args.parser])
-        sys.stdout.write("\033[K\r total: {}, {}, scanned {}"
-                         .format(total, os.path.relpath(parser_stats), os.path.relpath(p)))
-
-devnull.close()
-
-print("\n")
-
-for parser in args.parser:
-    filename = os.path.basename(parser) + '.bad'
-    print("writing {} files that did not yield the correct result with {} to {}".format(len(bad[parser]), parser, filename))
-    with open(filename, "w") as f:
-        for p in bad[parser]:
-            f.write(p)
-            f.write("\n")
diff --git a/src/grammar/tokens.h b/src/grammar/tokens.h
deleted file mode 100644
index 297e3dc..0000000
--- a/src/grammar/tokens.h
+++ /dev/null
@@ -1,99 +0,0 @@
-enum Token {
-  SHL = 257, // Parser generators reserve 0-256 for char literals
-  SHR,
-  LE,
-  EQEQ,
-  NE,
-  GE,
-  ANDAND,
-  OROR,
-  SHLEQ,
-  SHREQ,
-  MINUSEQ,
-  ANDEQ,
-  OREQ,
-  PLUSEQ,
-  STAREQ,
-  SLASHEQ,
-  CARETEQ,
-  PERCENTEQ,
-  DOTDOT,
-  DOTDOTDOT,
-  MOD_SEP,
-  LARROW,
-  RARROW,
-  FAT_ARROW,
-  LIT_BYTE,
-  LIT_CHAR,
-  LIT_INTEGER,
-  LIT_FLOAT,
-  LIT_STR,
-  LIT_STR_RAW,
-  LIT_BYTE_STR,
-  LIT_BYTE_STR_RAW,
-  IDENT,
-  UNDERSCORE,
-  LIFETIME,
-
-  // keywords
-  SELF,
-  STATIC,
-  ABSTRACT,
-  ALIGNOF,
-  AS,
-  BECOME,
-  BREAK,
-  CATCH,
-  CRATE,
-  DEFAULT,
-  DO,
-  ELSE,
-  ENUM,
-  EXTERN,
-  FALSE,
-  FINAL,
-  FN,
-  FOR,
-  IF,
-  IMPL,
-  IN,
-  LET,
-  LOOP,
-  MACRO,
-  MATCH,
-  MOD,
-  MOVE,
-  MUT,
-  OFFSETOF,
-  OVERRIDE,
-  PRIV,
-  PUB,
-  PURE,
-  REF,
-  RETURN,
-  SIZEOF,
-  STRUCT,
-  SUPER,
-  UNION,
-  TRUE,
-  TRAIT,
-  TYPE,
-  UNSAFE,
-  UNSIZED,
-  USE,
-  VIRTUAL,
-  WHILE,
-  YIELD,
-  CONTINUE,
-  PROC,
-  BOX,
-  CONST,
-  WHERE,
-  TYPEOF,
-  INNER_DOC_COMMENT,
-  OUTER_DOC_COMMENT,
-
-  SHEBANG,
-  SHEBANG_LINE,
-  STATIC_LIFETIME
-};
diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs
index a39fcd5..9bc76f5 100644
--- a/src/liballoc/alloc.rs
+++ b/src/liballoc/alloc.rs
@@ -240,7 +240,6 @@
 #[stable(feature = "global_alloc", since = "1.28.0")]
 #[rustc_allocator_nounwind]
 pub fn handle_alloc_error(layout: Layout) -> ! {
-    #[cfg_attr(bootstrap, allow(improper_ctypes))]
     extern "Rust" {
         #[lang = "oom"]
         fn oom_impl(layout: Layout) -> !;
diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs
index a9c5bce..d2bdda8 100644
--- a/src/liballoc/borrow.rs
+++ b/src/liballoc/borrow.rs
@@ -207,6 +207,47 @@
 }
 
 impl<B: ?Sized + ToOwned> Cow<'_, B> {
+    /// Returns true if the data is borrowed, i.e. if `to_mut` would require additional work.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(cow_is_borrowed)]
+    /// use std::borrow::Cow;
+    ///
+    /// let cow = Cow::Borrowed("moo");
+    /// assert!(cow.is_borrowed());
+    ///
+    /// let bull: Cow<'_, str> = Cow::Owned("...moo?".to_string());
+    /// assert!(!bull.is_borrowed());
+    /// ```
+    #[unstable(feature = "cow_is_borrowed", issue = "65143")]
+    pub fn is_borrowed(&self) -> bool {
+        match *self {
+            Borrowed(_) => true,
+            Owned(_) => false,
+        }
+    }
+
+    /// Returns true if the data is owned, i.e. if `to_mut` would be a no-op.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(cow_is_borrowed)]
+    /// use std::borrow::Cow;
+    ///
+    /// let cow: Cow<'_, str> = Cow::Owned("moo".to_string());
+    /// assert!(cow.is_owned());
+    ///
+    /// let bull = Cow::Borrowed("...moo?");
+    /// assert!(!bull.is_owned());
+    /// ```
+    #[unstable(feature = "cow_is_borrowed", issue = "65143")]
+    pub fn is_owned(&self) -> bool {
+        !self.is_borrowed()
+    }
+
     /// Acquires a mutable reference to the owned form of the data.
     ///
     /// Clones the data if it is not already owned.
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index c61e318..567b8ea 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -29,10 +29,8 @@
 //!     Nil,
 //! }
 //!
-//! fn main() {
-//!     let list: List<i32> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil))));
-//!     println!("{:?}", list);
-//! }
+//! let list: List<i32> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil))));
+//! println!("{:?}", list);
 //! ```
 //!
 //! This will print `Cons(1, Cons(2, Nil))`.
@@ -144,6 +142,9 @@
     #[unstable(feature = "new_uninit", issue = "63291")]
     pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
         let layout = alloc::Layout::new::<mem::MaybeUninit<T>>();
+        if layout.size() == 0 {
+            return Box(NonNull::dangling().into())
+        }
         let ptr = unsafe {
             Global.alloc(layout)
                 .unwrap_or_else(|_| alloc::handle_alloc_error(layout))
@@ -184,9 +185,16 @@
     #[unstable(feature = "new_uninit", issue = "63291")]
     pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
         let layout = alloc::Layout::array::<mem::MaybeUninit<T>>(len).unwrap();
-        let ptr = unsafe { alloc::alloc(layout) };
-        let unique = Unique::new(ptr).unwrap_or_else(|| alloc::handle_alloc_error(layout));
-        let slice = unsafe { slice::from_raw_parts_mut(unique.cast().as_ptr(), len) };
+        let ptr = if layout.size() == 0 {
+            NonNull::dangling()
+        } else {
+            unsafe {
+                Global.alloc(layout)
+                    .unwrap_or_else(|_| alloc::handle_alloc_error(layout))
+                    .cast()
+            }
+        };
+        let slice = unsafe { slice::from_raw_parts_mut(ptr.as_ptr(), len) };
         Box(Unique::from(slice))
     }
 }
@@ -375,14 +383,12 @@
     /// ```
     /// #![feature(box_into_raw_non_null)]
     ///
-    /// fn main() {
-    ///     let x = Box::new(5);
-    ///     let ptr = Box::into_raw_non_null(x);
+    /// let x = Box::new(5);
+    /// let ptr = Box::into_raw_non_null(x);
     ///
-    ///     // Clean up the memory by converting the NonNull pointer back
-    ///     // into a Box and letting the Box be dropped.
-    ///     let x = unsafe { Box::from_raw(ptr.as_ptr()) };
-    /// }
+    /// // Clean up the memory by converting the NonNull pointer back
+    /// // into a Box and letting the Box be dropped.
+    /// let x = unsafe { Box::from_raw(ptr.as_ptr()) };
     /// ```
     #[unstable(feature = "box_into_raw_non_null", issue = "47336")]
     #[inline]
@@ -428,23 +434,19 @@
     /// Simple usage:
     ///
     /// ```
-    /// fn main() {
-    ///     let x = Box::new(41);
-    ///     let static_ref: &'static mut usize = Box::leak(x);
-    ///     *static_ref += 1;
-    ///     assert_eq!(*static_ref, 42);
-    /// }
+    /// let x = Box::new(41);
+    /// let static_ref: &'static mut usize = Box::leak(x);
+    /// *static_ref += 1;
+    /// assert_eq!(*static_ref, 42);
     /// ```
     ///
     /// Unsized data:
     ///
     /// ```
-    /// fn main() {
-    ///     let x = vec![1, 2, 3].into_boxed_slice();
-    ///     let static_ref = Box::leak(x);
-    ///     static_ref[0] = 4;
-    ///     assert_eq!(*static_ref, [4, 2, 3]);
-    /// }
+    /// let x = vec![1, 2, 3].into_boxed_slice();
+    /// let static_ref = Box::leak(x);
+    /// static_ref[0] = 4;
+    /// assert_eq!(*static_ref, [4, 2, 3]);
     /// ```
     #[stable(feature = "box_leak", since = "1.26.0")]
     #[inline]
@@ -780,11 +782,9 @@
     ///     }
     /// }
     ///
-    /// fn main() {
-    ///     let my_string = "Hello World".to_string();
-    ///     print_if_string(Box::new(my_string));
-    ///     print_if_string(Box::new(0i8));
-    /// }
+    /// let my_string = "Hello World".to_string();
+    /// print_if_string(Box::new(my_string));
+    /// print_if_string(Box::new(0i8));
     /// ```
     pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<dyn Any>> {
         if self.is::<T>() {
@@ -814,11 +814,9 @@
     ///     }
     /// }
     ///
-    /// fn main() {
-    ///     let my_string = "Hello World".to_string();
-    ///     print_if_string(Box::new(my_string));
-    ///     print_if_string(Box::new(0i8));
-    /// }
+    /// let my_string = "Hello World".to_string();
+    /// print_if_string(Box::new(my_string));
+    /// print_if_string(Box::new(0i8));
     /// ```
     pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<dyn Any + Send>> {
         <Box<dyn Any>>::downcast(self).map_err(|s| unsafe {
@@ -883,11 +881,33 @@
     fn nth(&mut self, n: usize) -> Option<I::Item> {
         (**self).nth(n)
     }
+    fn last(self) -> Option<I::Item> {
+        BoxIter::last(self)
+    }
 }
 
+trait BoxIter {
+    type Item;
+    fn last(self) -> Option<Self::Item>;
+}
+
+impl<I: Iterator + ?Sized> BoxIter for Box<I> {
+    type Item = I::Item;
+    default fn last(self) -> Option<I::Item> {
+        #[inline]
+        fn some<T>(_: Option<T>, x: T) -> Option<T> {
+            Some(x)
+        }
+
+        self.fold(None, some)
+    }
+}
+
+/// Specialization for sized `I`s that uses `I`s implementation of `last()`
+/// instead of the default.
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I: Iterator + Sized> Iterator for Box<I> {
-    fn last(self) -> Option<I::Item> where I: Sized {
+impl<I: Iterator> BoxIter for Box<I> {
+    fn last(self) -> Option<I::Item> {
         (*self).last()
     }
 }
diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs
index 3d04f30..fda6f09 100644
--- a/src/liballoc/collections/binary_heap.rs
+++ b/src/liballoc/collections/binary_heap.rs
@@ -146,7 +146,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use core::ops::{Deref, DerefMut};
-use core::iter::{FromIterator, FusedIterator};
+use core::iter::{FromIterator, FusedIterator, TrustedLen};
 use core::mem::{swap, size_of, ManuallyDrop};
 use core::ptr;
 use core::fmt;
@@ -648,6 +648,36 @@
             self.extend(other.drain());
         }
     }
+
+    /// Returns an iterator which retrieves elements in heap order.
+    /// The retrieved elements are removed from the original heap.
+    /// The remaining elements will be removed on drop in heap order.
+    ///
+    /// Note:
+    /// * `.drain_sorted()` is O(n lg n); much slower than `.drain()`.
+    ///   You should use the latter for most cases.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(binary_heap_drain_sorted)]
+    /// use std::collections::BinaryHeap;
+    ///
+    /// let mut heap = BinaryHeap::from(vec![1, 2, 3, 4, 5]);
+    /// assert_eq!(heap.len(), 5);
+    ///
+    /// drop(heap.drain_sorted()); // removes all elements in heap order
+    /// assert_eq!(heap.len(), 0);
+    /// ```
+    #[inline]
+    #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
+    pub fn drain_sorted(&mut self) -> DrainSorted<'_, T> {
+        DrainSorted {
+            inner: self,
+        }
+    }
 }
 
 impl<T> BinaryHeap<T> {
@@ -672,6 +702,27 @@
         Iter { iter: self.data.iter() }
     }
 
+    /// Returns an iterator which retrieves elements in heap order.
+    /// This method consumes the original heap.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(binary_heap_into_iter_sorted)]
+    /// use std::collections::BinaryHeap;
+    /// let heap = BinaryHeap::from(vec![1, 2, 3, 4, 5]);
+    ///
+    /// assert_eq!(heap.into_iter_sorted().take(2).collect::<Vec<_>>(), vec![5, 4]);
+    /// ```
+    #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")]
+    pub fn into_iter_sorted(self) -> IntoIterSorted<T> {
+        IntoIterSorted {
+            inner: self,
+        }
+    }
+
     /// Returns the greatest item in the binary heap, or `None` if it is empty.
     ///
     /// # Examples
@@ -1115,6 +1166,37 @@
 #[stable(feature = "fused", since = "1.26.0")]
 impl<T> FusedIterator for IntoIter<T> {}
 
+#[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")]
+#[derive(Clone, Debug)]
+pub struct IntoIterSorted<T> {
+    inner: BinaryHeap<T>,
+}
+
+#[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")]
+impl<T: Ord> Iterator for IntoIterSorted<T> {
+    type Item = T;
+
+    #[inline]
+    fn next(&mut self) -> Option<T> {
+        self.inner.pop()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let exact = self.inner.len();
+        (exact, Some(exact))
+    }
+}
+
+#[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")]
+impl<T: Ord> ExactSizeIterator for IntoIterSorted<T> {}
+
+#[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")]
+impl<T: Ord> FusedIterator for IntoIterSorted<T> {}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<T: Ord> TrustedLen for IntoIterSorted<T> {}
+
 /// A draining iterator over the elements of a `BinaryHeap`.
 ///
 /// This `struct` is created by the [`drain`] method on [`BinaryHeap`]. See its
@@ -1161,6 +1243,52 @@
 #[stable(feature = "fused", since = "1.26.0")]
 impl<T> FusedIterator for Drain<'_, T> {}
 
+/// A draining iterator over the elements of a `BinaryHeap`.
+///
+/// This `struct` is created by the [`drain_sorted`] method on [`BinaryHeap`]. See its
+/// documentation for more.
+///
+/// [`drain_sorted`]: struct.BinaryHeap.html#method.drain_sorted
+/// [`BinaryHeap`]: struct.BinaryHeap.html
+#[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
+#[derive(Debug)]
+pub struct DrainSorted<'a, T: Ord> {
+    inner: &'a mut BinaryHeap<T>,
+}
+
+#[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
+impl<'a, T: Ord> Drop for DrainSorted<'a, T> {
+    /// Removes heap elements in heap order.
+    fn drop(&mut self) {
+        while let Some(_) = self.inner.pop() {}
+    }
+}
+
+#[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
+impl<T: Ord> Iterator for DrainSorted<'_, T> {
+    type Item = T;
+
+    #[inline]
+    fn next(&mut self) -> Option<T> {
+        self.inner.pop()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let exact = self.inner.len();
+        (exact, Some(exact))
+    }
+}
+
+#[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
+impl<T: Ord> ExactSizeIterator for DrainSorted<'_, T> { }
+
+#[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
+impl<T: Ord> FusedIterator for DrainSorted<'_, T> {}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<T: Ord> TrustedLen for DrainSorted<'_, T> {}
+
 #[stable(feature = "binary_heap_extras_15", since = "1.5.0")]
 impl<T: Ord> From<Vec<T>> for BinaryHeap<T> {
     /// Converts a `Vec<T>` into a `BinaryHeap<T>`.
diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs
index 1683b81..83fd448 100644
--- a/src/liballoc/collections/btree/map.rs
+++ b/src/liballoc/collections/btree/map.rs
@@ -580,7 +580,6 @@
     /// # Examples
     ///
     /// ```
-    /// #![feature(map_get_key_value)]
     /// use std::collections::BTreeMap;
     ///
     /// let mut map = BTreeMap::new();
@@ -588,7 +587,7 @@
     /// assert_eq!(map.get_key_value(&1), Some((&1, &"a")));
     /// assert_eq!(map.get_key_value(&2), None);
     /// ```
-    #[unstable(feature = "map_get_key_value", issue = "49347")]
+    #[stable(feature = "map_get_key_value", since = "1.40.0")]
     pub fn get_key_value<Q: ?Sized>(&self, k: &Q) -> Option<(&K, &V)>
         where K: Borrow<Q>,
               Q: Ord
@@ -2227,14 +2226,12 @@
     /// # Examples
     ///
     /// ```
-    /// # fn main() {
     /// use std::collections::BTreeMap;
     ///
     /// let mut map: BTreeMap<&str, Option<usize>> = BTreeMap::new();
     /// map.entry("poneyland").or_default();
     ///
     /// assert_eq!(map["poneyland"], None);
-    /// # }
     /// ```
     pub fn or_default(self) -> &'a mut V {
         match self {
diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs
index 0cb91ba..f079635 100644
--- a/src/liballoc/collections/btree/set.rs
+++ b/src/liballoc/collections/btree/set.rs
@@ -2,7 +2,7 @@
 // to TreeMap
 
 use core::borrow::Borrow;
-use core::cmp::Ordering::{self, Less, Greater, Equal};
+use core::cmp::Ordering::{Less, Greater, Equal};
 use core::cmp::{max, min};
 use core::fmt::{self, Debug};
 use core::iter::{Peekable, FromIterator, FusedIterator};
@@ -109,6 +109,77 @@
     iter: btree_map::Range<'a, T, ()>,
 }
 
+/// Core of SymmetricDifference and Union.
+/// More efficient than btree.map.MergeIter,
+/// and crucially for SymmetricDifference, nexts() reports on both sides.
+#[derive(Clone)]
+struct MergeIterInner<I>
+    where I: Iterator,
+          I::Item: Copy,
+{
+    a: I,
+    b: I,
+    peeked: Option<MergeIterPeeked<I>>,
+}
+
+#[derive(Copy, Clone, Debug)]
+enum MergeIterPeeked<I: Iterator> {
+    A(I::Item),
+    B(I::Item),
+}
+
+impl<I> MergeIterInner<I>
+    where I: ExactSizeIterator + FusedIterator,
+          I::Item: Copy + Ord,
+{
+    fn new(a: I, b: I) -> Self {
+        MergeIterInner { a, b, peeked: None }
+    }
+
+    fn nexts(&mut self) -> (Option<I::Item>, Option<I::Item>) {
+        let mut a_next = match self.peeked {
+            Some(MergeIterPeeked::A(next)) => Some(next),
+            _ => self.a.next(),
+        };
+        let mut b_next = match self.peeked {
+            Some(MergeIterPeeked::B(next)) => Some(next),
+            _ => self.b.next(),
+        };
+        let ord = match (a_next, b_next) {
+            (None, None) => Equal,
+            (_, None) => Less,
+            (None, _) => Greater,
+            (Some(a1), Some(b1)) => a1.cmp(&b1),
+        };
+        self.peeked = match ord {
+            Less => b_next.take().map(MergeIterPeeked::B),
+            Equal => None,
+            Greater => a_next.take().map(MergeIterPeeked::A),
+        };
+        (a_next, b_next)
+    }
+
+    fn lens(&self) -> (usize, usize) {
+        match self.peeked {
+            Some(MergeIterPeeked::A(_)) => (1 + self.a.len(), self.b.len()),
+            Some(MergeIterPeeked::B(_)) => (self.a.len(), 1 + self.b.len()),
+            _ => (self.a.len(), self.b.len()),
+        }
+    }
+}
+
+impl<I> Debug for MergeIterInner<I>
+    where I: Iterator + Debug,
+          I::Item: Copy + Debug,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_tuple("MergeIterInner")
+            .field(&self.a)
+            .field(&self.b)
+            .finish()
+    }
+}
+
 /// A lazy iterator producing elements in the difference of `BTreeSet`s.
 ///
 /// This `struct` is created by the [`difference`] method on [`BTreeSet`].
@@ -120,34 +191,25 @@
 pub struct Difference<'a, T: 'a> {
     inner: DifferenceInner<'a, T>,
 }
+#[derive(Debug)]
 enum DifferenceInner<'a, T: 'a> {
     Stitch {
+        // iterate all of self and some of other, spotting matches along the way
         self_iter: Iter<'a, T>,
         other_iter: Peekable<Iter<'a, T>>,
     },
     Search {
+        // iterate a small set, look up in the large set
         self_iter: Iter<'a, T>,
         other_set: &'a BTreeSet<T>,
     },
+    Iterate(Iter<'a, T>), // simply stream self's elements
 }
 
 #[stable(feature = "collection_debug", since = "1.17.0")]
 impl<T: fmt::Debug> fmt::Debug for Difference<'_, T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match &self.inner {
-            DifferenceInner::Stitch {
-                self_iter,
-                other_iter,
-            } => f
-                .debug_tuple("Difference")
-                .field(&self_iter)
-                .field(&other_iter)
-                .finish(),
-            DifferenceInner::Search {
-                self_iter,
-                other_set: _,
-            } => f.debug_tuple("Difference").field(&self_iter).finish(),
-        }
+        f.debug_tuple("Difference").field(&self.inner).finish()
     }
 }
 
@@ -159,18 +221,12 @@
 /// [`BTreeSet`]: struct.BTreeSet.html
 /// [`symmetric_difference`]: struct.BTreeSet.html#method.symmetric_difference
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct SymmetricDifference<'a, T: 'a> {
-    a: Peekable<Iter<'a, T>>,
-    b: Peekable<Iter<'a, T>>,
-}
+pub struct SymmetricDifference<'a, T: 'a>(MergeIterInner<Iter<'a, T>>);
 
 #[stable(feature = "collection_debug", since = "1.17.0")]
 impl<T: fmt::Debug> fmt::Debug for SymmetricDifference<'_, T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_tuple("SymmetricDifference")
-         .field(&self.a)
-         .field(&self.b)
-         .finish()
+        f.debug_tuple("SymmetricDifference").field(&self.0).finish()
     }
 }
 
@@ -185,34 +241,25 @@
 pub struct Intersection<'a, T: 'a> {
     inner: IntersectionInner<'a, T>,
 }
+#[derive(Debug)]
 enum IntersectionInner<'a, T: 'a> {
     Stitch {
+        // iterate similarly sized sets jointly, spotting matches along the way
         a: Iter<'a, T>,
         b: Iter<'a, T>,
     },
     Search {
+        // iterate a small set, look up in the large set
         small_iter: Iter<'a, T>,
         large_set: &'a BTreeSet<T>,
     },
+    Answer(Option<&'a T>), // return a specific value or emptiness
 }
 
 #[stable(feature = "collection_debug", since = "1.17.0")]
 impl<T: fmt::Debug> fmt::Debug for Intersection<'_, T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match &self.inner {
-            IntersectionInner::Stitch {
-                a,
-                b,
-            } => f
-                .debug_tuple("Intersection")
-                .field(&a)
-                .field(&b)
-                .finish(),
-            IntersectionInner::Search {
-                small_iter,
-                large_set: _,
-            } => f.debug_tuple("Intersection").field(&small_iter).finish(),
-        }
+        f.debug_tuple("Intersection").field(&self.inner).finish()
     }
 }
 
@@ -224,18 +271,12 @@
 /// [`BTreeSet`]: struct.BTreeSet.html
 /// [`union`]: struct.BTreeSet.html#method.union
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct Union<'a, T: 'a> {
-    a: Peekable<Iter<'a, T>>,
-    b: Peekable<Iter<'a, T>>,
-}
+pub struct Union<'a, T: 'a>(MergeIterInner<Iter<'a, T>>);
 
 #[stable(feature = "collection_debug", since = "1.17.0")]
 impl<T: fmt::Debug> fmt::Debug for Union<'_, T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_tuple("Union")
-         .field(&self.a)
-         .field(&self.b)
-         .finish()
+        f.debug_tuple("Union").field(&self.0).finish()
     }
 }
 
@@ -314,24 +355,48 @@
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn difference<'a>(&'a self, other: &'a BTreeSet<T>) -> Difference<'a, T> {
-        if self.len() > other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF {
-            // Self is bigger than or not much smaller than other set.
-            // Iterate both sets jointly, spotting matches along the way.
-            Difference {
-                inner: DifferenceInner::Stitch {
+        let (self_min, self_max) = if let (Some(self_min), Some(self_max)) =
+            (self.iter().next(), self.iter().next_back())
+        {
+            (self_min, self_max)
+        } else {
+            return Difference {
+                inner: DifferenceInner::Iterate(self.iter()),
+            };
+        };
+        let (other_min, other_max) = if let (Some(other_min), Some(other_max)) =
+            (other.iter().next(), other.iter().next_back())
+        {
+            (other_min, other_max)
+        } else {
+            return Difference {
+                inner: DifferenceInner::Iterate(self.iter()),
+            };
+        };
+        Difference {
+            inner: match (self_min.cmp(other_max), self_max.cmp(other_min)) {
+                (Greater, _) | (_, Less) => DifferenceInner::Iterate(self.iter()),
+                (Equal, _) => {
+                    let mut self_iter = self.iter();
+                    self_iter.next();
+                    DifferenceInner::Iterate(self_iter)
+                }
+                (_, Equal) => {
+                    let mut self_iter = self.iter();
+                    self_iter.next_back();
+                    DifferenceInner::Iterate(self_iter)
+                }
+                _ if self.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => {
+                    DifferenceInner::Search {
+                        self_iter: self.iter(),
+                        other_set: other,
+                    }
+                }
+                _ => DifferenceInner::Stitch {
                     self_iter: self.iter(),
                     other_iter: other.iter().peekable(),
                 },
-            }
-        } else {
-            // Self is much smaller than other set, or both sets are empty.
-            // Iterate the small set, searching for matches in the large set.
-            Difference {
-                inner: DifferenceInner::Search {
-                    self_iter: self.iter(),
-                    other_set: other,
-                },
-            }
+            },
         }
     }
 
@@ -359,10 +424,7 @@
     pub fn symmetric_difference<'a>(&'a self,
                                     other: &'a BTreeSet<T>)
                                     -> SymmetricDifference<'a, T> {
-        SymmetricDifference {
-            a: self.iter().peekable(),
-            b: other.iter().peekable(),
-        }
+        SymmetricDifference(MergeIterInner::new(self.iter(), other.iter()))
     }
 
     /// Visits the values representing the intersection,
@@ -387,29 +449,46 @@
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn intersection<'a>(&'a self, other: &'a BTreeSet<T>) -> Intersection<'a, T> {
-        let (small, other) = if self.len() <= other.len() {
-            (self, other)
+        let (self_min, self_max) = if let (Some(self_min), Some(self_max)) =
+            (self.iter().next(), self.iter().next_back())
+        {
+            (self_min, self_max)
         } else {
-            (other, self)
+            return Intersection {
+                inner: IntersectionInner::Answer(None),
+            };
         };
-        if small.len() > other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF {
-            // Small set is not much smaller than other set.
-            // Iterate both sets jointly, spotting matches along the way.
-            Intersection {
-                inner: IntersectionInner::Stitch {
-                    a: small.iter(),
+        let (other_min, other_max) = if let (Some(other_min), Some(other_max)) =
+            (other.iter().next(), other.iter().next_back())
+        {
+            (other_min, other_max)
+        } else {
+            return Intersection {
+                inner: IntersectionInner::Answer(None),
+            };
+        };
+        Intersection {
+            inner: match (self_min.cmp(other_max), self_max.cmp(other_min)) {
+                (Greater, _) | (_, Less) => IntersectionInner::Answer(None),
+                (Equal, _) => IntersectionInner::Answer(Some(self_min)),
+                (_, Equal) => IntersectionInner::Answer(Some(self_max)),
+                _ if self.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => {
+                    IntersectionInner::Search {
+                        small_iter: self.iter(),
+                        large_set: other,
+                    }
+                }
+                _ if other.len() <= self.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => {
+                    IntersectionInner::Search {
+                        small_iter: other.iter(),
+                        large_set: self,
+                    }
+                }
+                _ => IntersectionInner::Stitch {
+                    a: self.iter(),
                     b: other.iter(),
                 },
-            }
-        } else {
-            // Big difference in number of elements, or both sets are empty.
-            // Iterate the small set, searching for matches in the large set.
-            Intersection {
-                inner: IntersectionInner::Search {
-                    small_iter: small.iter(),
-                    large_set: other,
-                },
-            }
+            },
         }
     }
 
@@ -433,10 +512,7 @@
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn union<'a>(&'a self, other: &'a BTreeSet<T>) -> Union<'a, T> {
-        Union {
-            a: self.iter().peekable(),
-            b: other.iter().peekable(),
-        }
+        Union(MergeIterInner::new(self.iter(), other.iter()))
     }
 
     /// Clears the set, removing all values.
@@ -544,43 +620,61 @@
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_subset(&self, other: &BTreeSet<T>) -> bool {
         // Same result as self.difference(other).next().is_none()
-        // but the 3 paths below are faster (in order: hugely, 20%, 5%).
+        // but the code below is faster (hugely in some cases).
         if self.len() > other.len() {
-            false
-        } else if self.len() > other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF {
-            // Self is not much smaller than other set.
-            // Stolen from TreeMap
-            let mut x = self.iter();
-            let mut y = other.iter();
-            let mut a = x.next();
-            let mut b = y.next();
-            while a.is_some() {
-                if b.is_none() {
-                    return false;
-                }
-
-                let a1 = a.unwrap();
-                let b1 = b.unwrap();
-
-                match b1.cmp(a1) {
-                    Less => (),
-                    Greater => return false,
-                    Equal => a = x.next(),
-                }
-
-                b = y.next();
-            }
-            true
+            return false;
+        }
+        let (self_min, self_max) = if let (Some(self_min), Some(self_max)) =
+            (self.iter().next(), self.iter().next_back())
+        {
+            (self_min, self_max)
         } else {
-            // Big difference in number of elements, or both sets are empty.
-            // Iterate the small set, searching for matches in the large set.
-            for next in self {
+            return true; // self is empty
+        };
+        let (other_min, other_max) = if let (Some(other_min), Some(other_max)) =
+            (other.iter().next(), other.iter().next_back())
+        {
+            (other_min, other_max)
+        } else {
+            return false; // other is empty
+        };
+        let mut self_iter = self.iter();
+        match self_min.cmp(other_min) {
+            Less => return false,
+            Equal => {
+                self_iter.next();
+            }
+            Greater => (),
+        }
+        match self_max.cmp(other_max) {
+            Greater => return false,
+            Equal => {
+                self_iter.next_back();
+            }
+            Less => (),
+        }
+        if self_iter.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF {
+            // Big difference in number of elements.
+            for next in self_iter {
                 if !other.contains(next) {
                     return false;
                 }
             }
-            true
+        } else {
+            // Self is not much smaller than other set.
+            let mut other_iter = other.iter();
+            other_iter.next();
+            other_iter.next_back();
+            let mut self_next = self_iter.next();
+            while let Some(self1) = self_next {
+                match other_iter.next().map_or(Less, |other1| self1.cmp(other1)) {
+                    Less => return false,
+                    Equal => self_next = self_iter.next(),
+                    Greater => (),
+                }
+            }
         }
+        true
     }
 
     /// Returns `true` if the set is a superset of another,
@@ -1092,15 +1186,6 @@
 #[stable(feature = "fused", since = "1.26.0")]
 impl<T> FusedIterator for Range<'_, T> {}
 
-/// Compares `x` and `y`, but return `short` if x is None and `long` if y is None
-fn cmp_opt<T: Ord>(x: Option<&T>, y: Option<&T>, short: Ordering, long: Ordering) -> Ordering {
-    match (x, y) {
-        (None, _) => short,
-        (_, None) => long,
-        (Some(x1), Some(y1)) => x1.cmp(y1),
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Clone for Difference<'_, T> {
     fn clone(&self) -> Self {
@@ -1120,6 +1205,7 @@
                     self_iter: self_iter.clone(),
                     other_set,
                 },
+                DifferenceInner::Iterate(iter) => DifferenceInner::Iterate(iter.clone()),
             },
         }
     }
@@ -1138,7 +1224,7 @@
                 loop {
                     match other_iter
                         .peek()
-                        .map_or(Less, |other_next| Ord::cmp(self_next, other_next))
+                        .map_or(Less, |other_next| self_next.cmp(other_next))
                     {
                         Less => return Some(self_next),
                         Equal => {
@@ -1160,6 +1246,7 @@
                     return Some(self_next);
                 }
             },
+            DifferenceInner::Iterate(iter) => iter.next(),
         }
     }
 
@@ -1167,12 +1254,13 @@
         let (self_len, other_len) = match &self.inner {
             DifferenceInner::Stitch {
                 self_iter,
-                other_iter
+                other_iter,
             } => (self_iter.len(), other_iter.len()),
             DifferenceInner::Search {
                 self_iter,
-                other_set
+                other_set,
             } => (self_iter.len(), other_set.len()),
+            DifferenceInner::Iterate(iter) => (iter.len(), 0),
         };
         (self_len.saturating_sub(other_len), Some(self_len))
     }
@@ -1184,10 +1272,7 @@
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Clone for SymmetricDifference<'_, T> {
     fn clone(&self) -> Self {
-        SymmetricDifference {
-            a: self.a.clone(),
-            b: self.b.clone(),
-        }
+        SymmetricDifference(self.0.clone())
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1196,19 +1281,19 @@
 
     fn next(&mut self) -> Option<&'a T> {
         loop {
-            match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) {
-                Less => return self.a.next(),
-                Equal => {
-                    self.a.next();
-                    self.b.next();
-                }
-                Greater => return self.b.next(),
+            let (a_next, b_next) = self.0.nexts();
+            if a_next.and(b_next).is_none() {
+                return a_next.or(b_next);
             }
         }
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        (0, Some(self.a.len() + self.b.len()))
+        let (a_len, b_len) = self.0.lens();
+        // No checked_add, because even if a and b refer to the same set,
+        // and T is an empty type, the storage overhead of sets limits
+        // the number of elements to less than half the range of usize.
+        (0, Some(a_len + b_len))
     }
 }
 
@@ -1234,6 +1319,7 @@
                     small_iter: small_iter.clone(),
                     large_set,
                 },
+                IntersectionInner::Answer(answer) => IntersectionInner::Answer(*answer),
             },
         }
     }
@@ -1251,7 +1337,7 @@
                 let mut a_next = a.next()?;
                 let mut b_next = b.next()?;
                 loop {
-                    match Ord::cmp(a_next, b_next) {
+                    match a_next.cmp(b_next) {
                         Less => a_next = a.next()?,
                         Greater => b_next = b.next()?,
                         Equal => return Some(a_next),
@@ -1267,15 +1353,17 @@
                     return Some(small_next);
                 }
             },
+            IntersectionInner::Answer(answer) => answer.take(),
         }
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let min_len = match &self.inner {
-            IntersectionInner::Stitch { a, b } => min(a.len(), b.len()),
-            IntersectionInner::Search { small_iter, .. } => small_iter.len(),
-        };
-        (0, Some(min_len))
+        match &self.inner {
+            IntersectionInner::Stitch { a, b } => (0, Some(min(a.len(), b.len()))),
+            IntersectionInner::Search { small_iter, .. } => (0, Some(small_iter.len())),
+            IntersectionInner::Answer(None) => (0, Some(0)),
+            IntersectionInner::Answer(Some(_)) => (1, Some(1)),
+        }
     }
 }
 
@@ -1285,10 +1373,7 @@
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Clone for Union<'_, T> {
     fn clone(&self) -> Self {
-        Union {
-            a: self.a.clone(),
-            b: self.b.clone(),
-        }
+        Union(self.0.clone())
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1296,19 +1381,13 @@
     type Item = &'a T;
 
     fn next(&mut self) -> Option<&'a T> {
-        match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) {
-            Less => self.a.next(),
-            Equal => {
-                self.b.next();
-                self.a.next()
-            }
-            Greater => self.b.next(),
-        }
+        let (a_next, b_next) = self.0.nexts();
+        a_next.or(b_next)
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let a_len = self.a.len();
-        let b_len = self.b.len();
+        let (a_len, b_len) = self.0.lens();
+        // No checked_add - see SymmetricDifference::size_hint.
         (max(a_len, b_len), Some(a_len + b_len))
     }
 }
diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs
index 816a71f..702df25 100644
--- a/src/liballoc/collections/linked_list.rs
+++ b/src/liballoc/collections/linked_list.rs
@@ -1197,6 +1197,19 @@
     fn clone(&self) -> Self {
         self.iter().cloned().collect()
     }
+
+    fn clone_from(&mut self, other: &Self) {
+        let mut iter_other = other.iter();
+        if self.len() > other.len() {
+            self.split_off(other.len());
+        }
+        for (elem, elem_other) in self.iter_mut().zip(&mut iter_other) {
+            elem.clone_from(elem_other);
+        }
+        if !iter_other.is_empty() {
+            self.extend(iter_other.cloned());
+        }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/liballoc/collections/linked_list/tests.rs b/src/liballoc/collections/linked_list/tests.rs
index ecb5948..1001f6b 100644
--- a/src/liballoc/collections/linked_list/tests.rs
+++ b/src/liballoc/collections/linked_list/tests.rs
@@ -111,6 +111,49 @@
 }
 
 #[test]
+fn test_clone_from() {
+    // Short cloned from long
+    {
+        let v = vec![1, 2, 3, 4, 5];
+        let u = vec![8, 7, 6, 2, 3, 4, 5];
+        let mut m = list_from(&v);
+        let n = list_from(&u);
+        m.clone_from(&n);
+        check_links(&m);
+        assert_eq!(m, n);
+        for elt in u {
+            assert_eq!(m.pop_front(), Some(elt))
+        }
+    }
+    // Long cloned from short
+    {
+        let v = vec![1, 2, 3, 4, 5];
+        let u = vec![6, 7, 8];
+        let mut m = list_from(&v);
+        let n = list_from(&u);
+        m.clone_from(&n);
+        check_links(&m);
+        assert_eq!(m, n);
+        for elt in u {
+            assert_eq!(m.pop_front(), Some(elt))
+        }
+    }
+    // Two equal length lists
+    {
+        let v = vec![1, 2, 3, 4, 5];
+        let u = vec![9, 8, 1, 2, 3];
+        let mut m = list_from(&v);
+        let n = list_from(&u);
+        m.clone_from(&n);
+        check_links(&m);
+        assert_eq!(m, n);
+        for elt in u {
+            assert_eq!(m.pop_front(), Some(elt))
+        }
+    }
+}
+
+#[test]
 fn test_insert_prev() {
     let mut m = list_from(&[0, 2, 4, 6, 8]);
     let len = m.len();
diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs
index a4a0fbb..8f3dfab 100644
--- a/src/liballoc/collections/vec_deque.rs
+++ b/src/liballoc/collections/vec_deque.rs
@@ -10,8 +10,8 @@
 use core::array::LengthAtMost32;
 use core::cmp::{self, Ordering};
 use core::fmt;
-use core::iter::{repeat_with, FromIterator, FusedIterator};
-use core::mem;
+use core::iter::{once, repeat_with, FromIterator, FusedIterator};
+use core::mem::{self, replace};
 use core::ops::Bound::{Excluded, Included, Unbounded};
 use core::ops::{Index, IndexMut, RangeBounds, Try};
 use core::ptr::{self, NonNull};
@@ -57,11 +57,88 @@
     buf: RawVec<T>,
 }
 
+/// PairSlices pairs up equal length slice parts of two deques
+///
+/// For example, given deques "A" and "B" with the following division into slices:
+///
+/// A: [0 1 2] [3 4 5]
+/// B: [a b] [c d e]
+///
+/// It produces the following sequence of matching slices:
+///
+/// ([0 1], [a b])
+/// ([2], [c])
+/// ([3 4], [d e])
+///
+/// and the uneven remainder of either A or B is skipped.
+struct PairSlices<'a, 'b, T> {
+    a0: &'a mut [T],
+    a1: &'a mut [T],
+    b0: &'b [T],
+    b1: &'b [T],
+}
+
+impl<'a, 'b, T> PairSlices<'a, 'b, T> {
+    fn from(to: &'a mut VecDeque<T>, from: &'b VecDeque<T>) -> Self {
+        let (a0, a1) = to.as_mut_slices();
+        let (b0, b1) = from.as_slices();
+        PairSlices { a0, a1, b0, b1 }
+    }
+
+    fn has_remainder(&self) -> bool {
+        !self.b0.is_empty()
+    }
+
+    fn remainder(self) -> impl Iterator<Item=&'b [T]> {
+        once(self.b0).chain(once(self.b1))
+    }
+}
+
+impl<'a, 'b, T> Iterator for PairSlices<'a, 'b, T>
+{
+    type Item = (&'a mut [T], &'b [T]);
+    fn next(&mut self) -> Option<Self::Item> {
+        // Get next part length
+        let part = cmp::min(self.a0.len(), self.b0.len());
+        if part == 0 {
+            return None;
+        }
+        let (p0, p1) = replace(&mut self.a0, &mut []).split_at_mut(part);
+        let (q0, q1) = self.b0.split_at(part);
+
+        // Move a1 into a0, if it's empty (and b1, b0 the same way).
+        self.a0 = p1;
+        self.b0 = q1;
+        if self.a0.is_empty() {
+            self.a0 = replace(&mut self.a1, &mut []);
+        }
+        if self.b0.is_empty() {
+            self.b0 = replace(&mut self.b1, &[]);
+        }
+        Some((p0, q0))
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Clone> Clone for VecDeque<T> {
     fn clone(&self) -> VecDeque<T> {
         self.iter().cloned().collect()
     }
+
+    fn clone_from(&mut self, other: &Self) {
+        self.truncate(other.len());
+
+        let mut iter = PairSlices::from(self, other);
+        while let Some((dst, src)) = iter.next() {
+            dst.clone_from_slice(&src);
+        }
+
+        if iter.has_remainder() {
+            for remainder in iter.remainder() {
+                self.extend(remainder.iter().cloned());
+            }
+        }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1740,7 +1817,7 @@
             }
         }
 
-        return elem;
+        elem
     }
 
     /// Splits the `VecDeque` into two at the given index.
@@ -2209,6 +2286,16 @@
         final_res
     }
 
+    fn nth(&mut self, n: usize) -> Option<Self::Item> {
+        if n >= count(self.tail, self.head, self.ring.len()) {
+            self.tail = self.head;
+            None
+        } else {
+            self.tail = wrap_index(self.tail.wrapping_add(n), self.ring.len());
+            self.next()
+        }
+    }
+
     #[inline]
     fn last(mut self) -> Option<&'a T> {
         self.next_back()
@@ -2327,6 +2414,16 @@
         back.iter_mut().fold(accum, &mut f)
     }
 
+    fn nth(&mut self, n: usize) -> Option<Self::Item> {
+        if n >= count(self.tail, self.head, self.ring.len()) {
+            self.tail = self.head;
+            None
+        } else {
+            self.tail = wrap_index(self.tail.wrapping_add(n), self.ring.len());
+            self.next()
+        }
+    }
+
     #[inline]
     fn last(mut self) -> Option<&'a mut T> {
         self.next_back()
diff --git a/src/liballoc/collections/vec_deque/tests.rs b/src/liballoc/collections/vec_deque/tests.rs
index d253523..d578ee0 100644
--- a/src/liballoc/collections/vec_deque/tests.rs
+++ b/src/liballoc/collections/vec_deque/tests.rs
@@ -362,6 +362,29 @@
 }
 
 #[test]
+fn test_clone_from() {
+    let m = vec![1; 8];
+    let n = vec![2; 12];
+    for pfv in 0..8 {
+        for pfu in 0..8 {
+            for longer in 0..2 {
+                let (vr, ur) = if longer == 0 { (&m, &n) } else { (&n, &m) };
+                let mut v = VecDeque::from(vr.clone());
+                for _ in 0..pfv {
+                    v.push_front(1);
+                }
+                let mut u = VecDeque::from(ur.clone());
+                for _ in 0..pfu {
+                    u.push_front(2);
+                }
+                v.clone_from(&u);
+                assert_eq!(&v, &u);
+            }
+        }
+    }
+}
+
+#[test]
 fn issue_53529() {
     use crate::boxed::Box;
 
diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs
index 68cbc36..cbfc552 100644
--- a/src/liballoc/fmt.rs
+++ b/src/liballoc/fmt.rs
@@ -80,24 +80,210 @@
 //! arguments which have names. Like with positional parameters, it is not
 //! valid to provide named parameters that are unused by the format string.
 //!
-//! ## Argument types
+//! # Formatting Parameters
 //!
-//! Each argument's type is dictated by the format string.
-//! There are various parameters which require a particular type, however.
-//! An example is the `{:.*}` syntax, which sets the number of decimal places
-//! in floating-point types:
+//! Each argument being formatted can be transformed by a number of formatting
+//! parameters (corresponding to `format_spec` in the syntax above). These
+//! parameters affect the string representation of what's being formatted.
+//!
+//! ## Width
 //!
 //! ```
-//! let formatted_number = format!("{:.*}", 2, 1.234567);
-//!
-//! assert_eq!("1.23", formatted_number)
+//! // All of these print "Hello x    !"
+//! println!("Hello {:5}!", "x");
+//! println!("Hello {:1$}!", "x", 5);
+//! println!("Hello {1:0$}!", 5, "x");
+//! println!("Hello {:width$}!", "x", width = 5);
 //! ```
 //!
-//! If this syntax is used, then the number of characters to print precedes the
-//! actual object being formatted, and the number of characters must have the
-//! type [`usize`].
+//! This is a parameter for the "minimum width" that the format should take up.
+//! If the value's string does not fill up this many characters, then the
+//! padding specified by fill/alignment will be used to take up the required
+//! space (see below).
 //!
-//! ## Formatting traits
+//! The value for the width can also be provided as a [`usize`] in the list of
+//! parameters by adding a postfix `$`, indicating that the second argument is
+//! a [`usize`] specifying the width.
+//!
+//! Referring to an argument with the dollar syntax does not affect the "next
+//! argument" counter, so it's usually a good idea to refer to arguments by
+//! position, or use named arguments.
+//!
+//! ## Fill/Alignment
+//!
+//! ```
+//! assert_eq!(format!("Hello {:<5}!", "x"),  "Hello x    !");
+//! assert_eq!(format!("Hello {:-<5}!", "x"), "Hello x----!");
+//! assert_eq!(format!("Hello {:^5}!", "x"),  "Hello   x  !");
+//! assert_eq!(format!("Hello {:>5}!", "x"),  "Hello     x!");
+//! ```
+//!
+//! The optional fill character and alignment is provided normally in conjunction with the
+//! [`width`](#width) parameter. It must be defined before `width`, right after the `:`.
+//! This indicates that if the value being formatted is smaller than
+//! `width` some extra characters will be printed around it.
+//! Filling comes in the following variants for different alignments:
+//!
+//! * `[fill]<` - the argument is left-aligned in `width` columns
+//! * `[fill]^` - the argument is center-aligned in `width` columns
+//! * `[fill]>` - the argument is right-aligned in `width` columns
+//!
+//! The default [fill/alignment](#fillalignment) for non-numerics is a space and
+//! left-aligned. The
+//! defaults for numeric formatters is also a space but with right-alignment. If
+//! the `0` flag (see below) is specified for numerics, then the implicit fill character is
+//! `0`.
+//!
+//! Note that alignment may not be implemented by some types. In particular, it
+//! is not generally implemented for the `Debug` trait.  A good way to ensure
+//! padding is applied is to format your input, then pad this resulting string
+//! to obtain your output:
+//!
+//! ```
+//! println!("Hello {:^15}!", format!("{:?}", Some("hi"))); // => "Hello   Some("hi")   !"
+//! ```
+//!
+//! ## Sign/`#`/`0`
+//!
+//! ```
+//! assert_eq!(format!("Hello {:+}!", 5), "Hello +5!");
+//! assert_eq!(format!("{:#x}!", 27), "0x1b!");
+//! assert_eq!(format!("Hello {:05}!", 5),  "Hello 00005!");
+//! assert_eq!(format!("Hello {:05}!", -5), "Hello -0005!");
+//! assert_eq!(format!("{:#010x}!", 27), "0x0000001b!");
+//! ```
+//!
+//! These are all flags altering the behavior of the formatter.
+//!
+//! * `+` - This is intended for numeric types and indicates that the sign
+//!         should always be printed. Positive signs are never printed by
+//!         default, and the negative sign is only printed by default for the
+//!         `Signed` trait. This flag indicates that the correct sign (`+` or `-`)
+//!         should always be printed.
+//! * `-` - Currently not used
+//! * `#` - This flag is indicates that the "alternate" form of printing should
+//!         be used. The alternate forms are:
+//!     * `#?` - pretty-print the [`Debug`] formatting
+//!     * `#x` - precedes the argument with a `0x`
+//!     * `#X` - precedes the argument with a `0x`
+//!     * `#b` - precedes the argument with a `0b`
+//!     * `#o` - precedes the argument with a `0o`
+//! * `0` - This is used to indicate for integer formats that the padding to `width` should
+//!         both be done with a `0` character as well as be sign-aware. A format
+//!         like `{:08}` would yield `00000001` for the integer `1`, while the
+//!         same format would yield `-0000001` for the integer `-1`. Notice that
+//!         the negative version has one fewer zero than the positive version.
+//!         Note that padding zeroes are always placed after the sign (if any)
+//!         and before the digits. When used together with the `#` flag, a similar
+//!         rule applies: padding zeroes are inserted after the prefix but before
+//!         the digits. The prefix is included in the total width.
+//!
+//! ## Precision
+//!
+//! For non-numeric types, this can be considered a "maximum width". If the resulting string is
+//! longer than this width, then it is truncated down to this many characters and that truncated
+//! value is emitted with proper `fill`, `alignment` and `width` if those parameters are set.
+//!
+//! For integral types, this is ignored.
+//!
+//! For floating-point types, this indicates how many digits after the decimal point should be
+//! printed.
+//!
+//! There are three possible ways to specify the desired `precision`:
+//!
+//! 1. An integer `.N`:
+//!
+//!    the integer `N` itself is the precision.
+//!
+//! 2. An integer or name followed by dollar sign `.N$`:
+//!
+//!    use format *argument* `N` (which must be a `usize`) as the precision.
+//!
+//! 3. An asterisk `.*`:
+//!
+//!    `.*` means that this `{...}` is associated with *two* format inputs rather than one: the
+//!    first input holds the `usize` precision, and the second holds the value to print. Note that
+//!    in this case, if one uses the format string `{<arg>:<spec>.*}`, then the `<arg>` part refers
+//!    to the *value* to print, and the `precision` must come in the input preceding `<arg>`.
+//!
+//! For example, the following calls all print the same thing `Hello x is 0.01000`:
+//!
+//! ```
+//! // Hello {arg 0 ("x")} is {arg 1 (0.01) with precision specified inline (5)}
+//! println!("Hello {0} is {1:.5}", "x", 0.01);
+//!
+//! // Hello {arg 1 ("x")} is {arg 2 (0.01) with precision specified in arg 0 (5)}
+//! println!("Hello {1} is {2:.0$}", 5, "x", 0.01);
+//!
+//! // Hello {arg 0 ("x")} is {arg 2 (0.01) with precision specified in arg 1 (5)}
+//! println!("Hello {0} is {2:.1$}", "x", 5, 0.01);
+//!
+//! // Hello {next arg ("x")} is {second of next two args (0.01) with precision
+//! //                          specified in first of next two args (5)}
+//! println!("Hello {} is {:.*}",    "x", 5, 0.01);
+//!
+//! // Hello {next arg ("x")} is {arg 2 (0.01) with precision
+//! //                          specified in its predecessor (5)}
+//! println!("Hello {} is {2:.*}",   "x", 5, 0.01);
+//!
+//! // Hello {next arg ("x")} is {arg "number" (0.01) with precision specified
+//! //                          in arg "prec" (5)}
+//! println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01);
+//! ```
+//!
+//! While these:
+//!
+//! ```
+//! println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56);
+//! println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56");
+//! println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56");
+//! ```
+//!
+//! print two significantly different things:
+//!
+//! ```text
+//! Hello, `1234.560` has 3 fractional digits
+//! Hello, `123` has 3 characters
+//! Hello, `     123` has 3 right-aligned characters
+//! ```
+//!
+//! # Escaping
+//!
+//! The literal characters `{` and `}` may be included in a string by preceding
+//! them with the same character. For example, the `{` character is escaped with
+//! `{{` and the `}` character is escaped with `}}`.
+//!
+//! ```
+//! assert_eq!(format!("Hello {{}}"), "Hello {}");
+//! assert_eq!(format!("{{ Hello"), "{ Hello");
+//! ```
+//!
+//! # Syntax
+//!
+//! To summarize, here you can find the full grammar of format strings.
+//! The syntax for the formatting language used is drawn from other languages,
+//! so it should not be too alien. Arguments are formatted with Python-like
+//! syntax, meaning that arguments are surrounded by `{}` instead of the C-like
+//! `%`. The actual grammar for the formatting syntax is:
+//!
+//! ```text
+//! format_string := <text> [ maybe-format <text> ] *
+//! maybe-format := '{' '{' | '}' '}' | <format>
+//! format := '{' [ argument ] [ ':' format_spec ] '}'
+//! argument := integer | identifier
+//!
+//! format_spec := [[fill]align][sign]['#']['0'][width]['.' precision][type]
+//! fill := character
+//! align := '<' | '^' | '>'
+//! sign := '+' | '-'
+//! width := count
+//! precision := count | '*'
+//! type := identifier | '?' | ''
+//! count := parameter | integer
+//! parameter := argument '$'
+//! ```
+//!
+//! # Formatting traits
 //!
 //! When requesting that an argument be formatted with a particular type, you
 //! are actually requesting that an argument ascribes to a particular trait.
@@ -220,7 +406,7 @@
 //! assert_eq!(format!("{} {:?}", "foo\n", "bar\n"), "foo\n \"bar\\n\"");
 //! ```
 //!
-//! ## Related macros
+//! # Related macros
 //!
 //! There are a number of related macros in the [`format!`] family. The ones that
 //! are currently implemented are:
@@ -300,185 +486,6 @@
 //! it would internally pass around this structure until it has been determined
 //! where output should go to.
 //!
-//! # Syntax
-//!
-//! The syntax for the formatting language used is drawn from other languages,
-//! so it should not be too alien. Arguments are formatted with Python-like
-//! syntax, meaning that arguments are surrounded by `{}` instead of the C-like
-//! `%`. The actual grammar for the formatting syntax is:
-//!
-//! ```text
-//! format_string := <text> [ maybe-format <text> ] *
-//! maybe-format := '{' '{' | '}' '}' | <format>
-//! format := '{' [ argument ] [ ':' format_spec ] '}'
-//! argument := integer | identifier
-//!
-//! format_spec := [[fill]align][sign]['#']['0'][width]['.' precision][type]
-//! fill := character
-//! align := '<' | '^' | '>'
-//! sign := '+' | '-'
-//! width := count
-//! precision := count | '*'
-//! type := identifier | '?' | ''
-//! count := parameter | integer
-//! parameter := argument '$'
-//! ```
-//!
-//! # Formatting Parameters
-//!
-//! Each argument being formatted can be transformed by a number of formatting
-//! parameters (corresponding to `format_spec` in the syntax above). These
-//! parameters affect the string representation of what's being formatted.
-//!
-//! ## Fill/Alignment
-//!
-//! The fill character is provided normally in conjunction with the
-//! [`width`](#width)
-//! parameter. This indicates that if the value being formatted is smaller than
-//! `width` some extra characters will be printed around it. The extra
-//! characters are specified by `fill`, and the alignment can be one of the
-//! following options:
-//!
-//! * `<` - the argument is left-aligned in `width` columns
-//! * `^` - the argument is center-aligned in `width` columns
-//! * `>` - the argument is right-aligned in `width` columns
-//!
-//! Note that alignment may not be implemented by some types. In particular, it
-//! is not generally implemented for the `Debug` trait.  A good way to ensure
-//! padding is applied is to format your input, then use this resulting string
-//! to pad your output.
-//!
-//! ## Sign/`#`/`0`
-//!
-//! These can all be interpreted as flags for a particular formatter.
-//!
-//! * `+` - This is intended for numeric types and indicates that the sign
-//!         should always be printed. Positive signs are never printed by
-//!         default, and the negative sign is only printed by default for the
-//!         `Signed` trait. This flag indicates that the correct sign (`+` or `-`)
-//!         should always be printed.
-//! * `-` - Currently not used
-//! * `#` - This flag is indicates that the "alternate" form of printing should
-//!         be used. The alternate forms are:
-//!     * `#?` - pretty-print the [`Debug`] formatting
-//!     * `#x` - precedes the argument with a `0x`
-//!     * `#X` - precedes the argument with a `0x`
-//!     * `#b` - precedes the argument with a `0b`
-//!     * `#o` - precedes the argument with a `0o`
-//! * `0` - This is used to indicate for integer formats that the padding should
-//!         both be done with a `0` character as well as be sign-aware. A format
-//!         like `{:08}` would yield `00000001` for the integer `1`, while the
-//!         same format would yield `-0000001` for the integer `-1`. Notice that
-//!         the negative version has one fewer zero than the positive version.
-//!         Note that padding zeroes are always placed after the sign (if any)
-//!         and before the digits. When used together with the `#` flag, a similar
-//!         rule applies: padding zeroes are inserted after the prefix but before
-//!         the digits.
-//!
-//! ## Width
-//!
-//! This is a parameter for the "minimum width" that the format should take up.
-//! If the value's string does not fill up this many characters, then the
-//! padding specified by fill/alignment will be used to take up the required
-//! space.
-//!
-//! The default [fill/alignment](#fillalignment) for non-numerics is a space and
-//! left-aligned. The
-//! defaults for numeric formatters is also a space but with right-alignment. If
-//! the `0` flag is specified for numerics, then the implicit fill character is
-//! `0`.
-//!
-//! The value for the width can also be provided as a [`usize`] in the list of
-//! parameters by using the dollar syntax indicating that the second argument is
-//! a [`usize`] specifying the width, for example:
-//!
-//! ```
-//! // All of these print "Hello x    !"
-//! println!("Hello {:5}!", "x");
-//! println!("Hello {:1$}!", "x", 5);
-//! println!("Hello {1:0$}!", 5, "x");
-//! println!("Hello {:width$}!", "x", width = 5);
-//! ```
-//!
-//! Referring to an argument with the dollar syntax does not affect the "next
-//! argument" counter, so it's usually a good idea to refer to arguments by
-//! position, or use named arguments.
-//!
-//! ## Precision
-//!
-//! For non-numeric types, this can be considered a "maximum width". If the resulting string is
-//! longer than this width, then it is truncated down to this many characters and that truncated
-//! value is emitted with proper `fill`, `alignment` and `width` if those parameters are set.
-//!
-//! For integral types, this is ignored.
-//!
-//! For floating-point types, this indicates how many digits after the decimal point should be
-//! printed.
-//!
-//! There are three possible ways to specify the desired `precision`:
-//!
-//! 1. An integer `.N`:
-//!
-//!    the integer `N` itself is the precision.
-//!
-//! 2. An integer or name followed by dollar sign `.N$`:
-//!
-//!    use format *argument* `N` (which must be a `usize`) as the precision.
-//!
-//! 3. An asterisk `.*`:
-//!
-//!    `.*` means that this `{...}` is associated with *two* format inputs rather than one: the
-//!    first input holds the `usize` precision, and the second holds the value to print. Note that
-//!    in this case, if one uses the format string `{<arg>:<spec>.*}`, then the `<arg>` part refers
-//!    to the *value* to print, and the `precision` must come in the input preceding `<arg>`.
-//!
-//! For example, the following calls all print the same thing `Hello x is 0.01000`:
-//!
-//! ```
-//! // Hello {arg 0 ("x")} is {arg 1 (0.01) with precision specified inline (5)}
-//! println!("Hello {0} is {1:.5}", "x", 0.01);
-//!
-//! // Hello {arg 1 ("x")} is {arg 2 (0.01) with precision specified in arg 0 (5)}
-//! println!("Hello {1} is {2:.0$}", 5, "x", 0.01);
-//!
-//! // Hello {arg 0 ("x")} is {arg 2 (0.01) with precision specified in arg 1 (5)}
-//! println!("Hello {0} is {2:.1$}", "x", 5, 0.01);
-//!
-//! // Hello {next arg ("x")} is {second of next two args (0.01) with precision
-//! //                          specified in first of next two args (5)}
-//! println!("Hello {} is {:.*}",    "x", 5, 0.01);
-//!
-//! // Hello {next arg ("x")} is {arg 2 (0.01) with precision
-//! //                          specified in its predecessor (5)}
-//! println!("Hello {} is {2:.*}",   "x", 5, 0.01);
-//!
-//! // Hello {next arg ("x")} is {arg "number" (0.01) with precision specified
-//! //                          in arg "prec" (5)}
-//! println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01);
-//! ```
-//!
-//! While these:
-//!
-//! ```
-//! println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56);
-//! println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56");
-//! println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56");
-//! ```
-//!
-//! print two significantly different things:
-//!
-//! ```text
-//! Hello, `1234.560` has 3 fractional digits
-//! Hello, `123` has 3 characters
-//! Hello, `     123` has 3 right-aligned characters
-//! ```
-//!
-//! # Escaping
-//!
-//! The literal characters `{` and `}` may be included in a string by preceding
-//! them with the same character. For example, the `{` character is escaped with
-//! `{{` and the `}` character is escaped with `}}`.
-//!
 //! [`usize`]: ../../std/primitive.usize.html
 //! [`isize`]: ../../std/primitive.isize.html
 //! [`i8`]: ../../std/primitive.i8.html
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 9e6ed92..94379af 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -85,6 +85,7 @@
 #![feature(const_generic_impls_guard)]
 #![feature(const_generics)]
 #![feature(const_in_array_repeat_expressions)]
+#![feature(cow_is_borrowed)]
 #![feature(dispatch_from_dyn)]
 #![feature(core_intrinsics)]
 #![feature(container_error_extra)]
@@ -117,12 +118,10 @@
 #![feature(allocator_internals)]
 #![feature(on_unimplemented)]
 #![feature(rustc_const_unstable)]
-#![cfg_attr(bootstrap, feature(const_vec_new))]
 #![feature(slice_partition_dedup)]
 #![feature(maybe_uninit_extra, maybe_uninit_slice)]
 #![feature(alloc_layout_extra)]
 #![feature(try_trait)]
-#![feature(mem_take)]
 #![feature(associated_type_bounds)]
 
 // Allow testing this library
@@ -155,7 +154,7 @@
 #[cfg(test)]
 mod tests;
 pub mod collections;
-#[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))]
+#[cfg(target_has_atomic = "ptr")]
 pub mod sync;
 pub mod rc;
 pub mod raw_vec;
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index f234ac5..f1c4c32 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -3,8 +3,9 @@
 //!
 //! The type [`Rc<T>`][`Rc`] provides shared ownership of a value of type `T`,
 //! allocated in the heap. Invoking [`clone`][clone] on [`Rc`] produces a new
-//! pointer to the same value in the heap. When the last [`Rc`] pointer to a
-//! given value is destroyed, the pointed-to value is also destroyed.
+//! pointer to the same allocation in the heap. When the last [`Rc`] pointer to a
+//! given allocation is destroyed, the value stored in that allocation (often
+//! referred to as "inner value") is also dropped.
 //!
 //! Shared references in Rust disallow mutation by default, and [`Rc`]
 //! is no exception: you cannot generally obtain a mutable reference to
@@ -21,8 +22,10 @@
 //!
 //! The [`downgrade`][downgrade] method can be used to create a non-owning
 //! [`Weak`] pointer. A [`Weak`] pointer can be [`upgrade`][upgrade]d
-//! to an [`Rc`], but this will return [`None`] if the value has
-//! already been dropped.
+//! to an [`Rc`], but this will return [`None`] if the value stored in the allocation has
+//! already been dropped. In other words, `Weak` pointers do not keep the value
+//! inside the allocation alive; however, they *do* keep the allocation
+//! (the backing store for the inner value) alive.
 //!
 //! A cycle between [`Rc`] pointers will never be deallocated. For this reason,
 //! [`Weak`] is used to break cycles. For example, a tree could have strong
@@ -41,13 +44,13 @@
 //! Rc::downgrade(&my_rc);
 //! ```
 //!
-//! [`Weak<T>`][`Weak`] does not auto-dereference to `T`, because the value may have
-//! already been destroyed.
+//! [`Weak<T>`][`Weak`] does not auto-dereference to `T`, because the inner value may have
+//! already been dropped.
 //!
 //! # Cloning references
 //!
-//! Creating a new reference from an existing reference counted pointer is done using the
-//! `Clone` trait implemented for [`Rc<T>`][`Rc`] and [`Weak<T>`][`Weak`].
+//! Creating a new reference to the same allocation as an existing reference counted pointer
+//! is done using the `Clone` trait implemented for [`Rc<T>`][`Rc`] and [`Weak<T>`][`Weak`].
 //!
 //! ```
 //! use std::rc::Rc;
@@ -93,7 +96,7 @@
 //!     );
 //!
 //!     // Create `Gadget`s belonging to `gadget_owner`. Cloning the `Rc<Owner>`
-//!     // value gives us a new pointer to the same `Owner` value, incrementing
+//!     // gives us a new pointer to the same `Owner` allocation, incrementing
 //!     // the reference count in the process.
 //!     let gadget1 = Gadget {
 //!         id: 1,
@@ -110,8 +113,8 @@
 //!     // Despite dropping `gadget_owner`, we're still able to print out the name
 //!     // of the `Owner` of the `Gadget`s. This is because we've only dropped a
 //!     // single `Rc<Owner>`, not the `Owner` it points to. As long as there are
-//!     // other `Rc<Owner>` values pointing at the same `Owner`, it will remain
-//!     // allocated. The field projection `gadget1.owner.name` works because
+//!     // other `Rc<Owner>` pointing at the same `Owner` allocation, it will remain
+//!     // live. The field projection `gadget1.owner.name` works because
 //!     // `Rc<Owner>` automatically dereferences to `Owner`.
 //!     println!("Gadget {} owned by {}", gadget1.id, gadget1.owner.name);
 //!     println!("Gadget {} owned by {}", gadget2.id, gadget2.owner.name);
@@ -124,9 +127,9 @@
 //!
 //! If our requirements change, and we also need to be able to traverse from
 //! `Owner` to `Gadget`, we will run into problems. An [`Rc`] pointer from `Owner`
-//! to `Gadget` introduces a cycle between the values. This means that their
-//! reference counts can never reach 0, and the values will remain allocated
-//! forever: a memory leak. In order to get around this, we can use [`Weak`]
+//! to `Gadget` introduces a cycle. This means that their
+//! reference counts can never reach 0, and the allocation will never be destroyed:
+//! a memory leak. In order to get around this, we can use [`Weak`]
 //! pointers.
 //!
 //! Rust actually makes it somewhat difficult to produce this loop in the first
@@ -193,10 +196,10 @@
 //!     for gadget_weak in gadget_owner.gadgets.borrow().iter() {
 //!
 //!         // `gadget_weak` is a `Weak<Gadget>`. Since `Weak` pointers can't
-//!         // guarantee the value is still allocated, we need to call
+//!         // guarantee the allocation still exists, we need to call
 //!         // `upgrade`, which returns an `Option<Rc<Gadget>>`.
 //!         //
-//!         // In this case we know the value still exists, so we simply
+//!         // In this case we know the allocation still exists, so we simply
 //!         // `unwrap` the `Option`. In a more complicated program, you might
 //!         // need graceful error handling for a `None` result.
 //!
@@ -365,7 +368,7 @@
         unsafe { Pin::new_unchecked(Rc::new(value)) }
     }
 
-    /// Returns the contained value, if the `Rc` has exactly one strong reference.
+    /// Returns the inner value, if the `Rc` has exactly one strong reference.
     ///
     /// Otherwise, an [`Err`][result] is returned with the same `Rc` that was
     /// passed in.
@@ -446,7 +449,7 @@
     /// # Safety
     ///
     /// As with [`MaybeUninit::assume_init`],
-    /// it is up to the caller to guarantee that the value
+    /// it is up to the caller to guarantee that the inner value
     /// really is in an initialized state.
     /// Calling this when the content is not yet fully initialized
     /// causes immediate undefined behavior.
@@ -485,7 +488,7 @@
     /// # Safety
     ///
     /// As with [`MaybeUninit::assume_init`],
-    /// it is up to the caller to guarantee that the value
+    /// it is up to the caller to guarantee that the inner value
     /// really is in an initialized state.
     /// Calling this when the content is not yet fully initialized
     /// causes immediate undefined behavior.
@@ -604,7 +607,7 @@
         unsafe { NonNull::new_unchecked(Rc::into_raw(this) as *mut _) }
     }
 
-    /// Creates a new [`Weak`][weak] pointer to this value.
+    /// Creates a new [`Weak`][weak] pointer to this allocation.
     ///
     /// [weak]: struct.Weak.html
     ///
@@ -625,7 +628,7 @@
         Weak { ptr: this.ptr }
     }
 
-    /// Gets the number of [`Weak`][weak] pointers to this value.
+    /// Gets the number of [`Weak`][weak] pointers to this allocation.
     ///
     /// [weak]: struct.Weak.html
     ///
@@ -645,7 +648,7 @@
         this.weak() - 1
     }
 
-    /// Gets the number of strong (`Rc`) pointers to this value.
+    /// Gets the number of strong (`Rc`) pointers to this allocation.
     ///
     /// # Examples
     ///
@@ -664,7 +667,7 @@
     }
 
     /// Returns `true` if there are no other `Rc` or [`Weak`][weak] pointers to
-    /// this inner value.
+    /// this allocation.
     ///
     /// [weak]: struct.Weak.html
     #[inline]
@@ -672,14 +675,14 @@
         Rc::weak_count(this) == 0 && Rc::strong_count(this) == 1
     }
 
-    /// Returns a mutable reference to the inner value, if there are
-    /// no other `Rc` or [`Weak`][weak] pointers to the same value.
+    /// Returns a mutable reference into the given `Rc`, if there are
+    /// no other `Rc` or [`Weak`][weak] pointers to the same allocation.
     ///
     /// Returns [`None`] otherwise, because it is not safe to
     /// mutate a shared value.
     ///
     /// See also [`make_mut`][make_mut], which will [`clone`][clone]
-    /// the inner value when it's shared.
+    /// the inner value when there are other pointers.
     ///
     /// [weak]: struct.Weak.html
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
@@ -710,7 +713,7 @@
         }
     }
 
-    /// Returns a mutable reference to the inner value,
+    /// Returns a mutable reference into the given `Rc`,
     /// without any check.
     ///
     /// See also [`get_mut`], which is safe and does appropriate checks.
@@ -719,7 +722,7 @@
     ///
     /// # Safety
     ///
-    /// Any other `Rc` or [`Weak`] pointers to the same value must not be dereferenced
+    /// Any other `Rc` or [`Weak`] pointers to the same allocation must not be dereferenced
     /// for the duration of the returned borrow.
     /// This is trivially the case if no such pointers exist,
     /// for example immediately after `Rc::new`.
@@ -745,8 +748,8 @@
 
     #[inline]
     #[stable(feature = "ptr_eq", since = "1.17.0")]
-    /// Returns `true` if the two `Rc`s point to the same value (not
-    /// just values that compare as equal).
+    /// Returns `true` if the two `Rc`s point to the same allocation
+    /// (in a vein similar to [`ptr::eq`]).
     ///
     /// # Examples
     ///
@@ -760,6 +763,8 @@
     /// assert!(Rc::ptr_eq(&five, &same_five));
     /// assert!(!Rc::ptr_eq(&five, &other_five));
     /// ```
+    ///
+    /// [`ptr::eq`]: ../../std/ptr/fn.eq.html
     pub fn ptr_eq(this: &Self, other: &Self) -> bool {
         this.ptr.as_ptr() == other.ptr.as_ptr()
     }
@@ -768,12 +773,12 @@
 impl<T: Clone> Rc<T> {
     /// Makes a mutable reference into the given `Rc`.
     ///
-    /// If there are other `Rc` pointers to the same value, then `make_mut` will
-    /// [`clone`] the inner value to ensure unique ownership.  This is also
+    /// If there are other `Rc` pointers to the same allocation, then `make_mut` will
+    /// [`clone`] the inner value to a new allocation to ensure unique ownership.  This is also
     /// referred to as clone-on-write.
     ///
-    /// If there are no other `Rc` pointers to this value, then [`Weak`]
-    /// pointers to this value will be dissassociated.
+    /// If there are no other `Rc` pointers to this allocation, then [`Weak`]
+    /// pointers to this allocation will be disassociated.
     ///
     /// See also [`get_mut`], which will fail rather than cloning.
     ///
@@ -794,12 +799,12 @@
     /// *Rc::make_mut(&mut data) += 1;        // Won't clone anything
     /// *Rc::make_mut(&mut other_data) *= 2;  // Won't clone anything
     ///
-    /// // Now `data` and `other_data` point to different values.
+    /// // Now `data` and `other_data` point to different allocations.
     /// assert_eq!(*data, 8);
     /// assert_eq!(*other_data, 12);
     /// ```
     ///
-    /// [`Weak`] pointers will be dissassociated:
+    /// [`Weak`] pointers will be disassociated:
     ///
     /// ```
     /// use std::rc::Rc;
@@ -837,7 +842,7 @@
         // returned is the *only* pointer that will ever be returned to T. Our
         // reference count is guaranteed to be 1 at this point, and we required
         // the `Rc<T>` itself to be `mut`, so we're returning the only possible
-        // reference to the inner value.
+        // reference to the allocation.
         unsafe {
             &mut this.ptr.as_mut().value
         }
@@ -861,11 +866,9 @@
     ///     }
     /// }
     ///
-    /// fn main() {
-    ///     let my_string = "Hello World".to_string();
-    ///     print_if_string(Rc::new(my_string));
-    ///     print_if_string(Rc::new(0i8));
-    /// }
+    /// let my_string = "Hello World".to_string();
+    /// print_if_string(Rc::new(my_string));
+    /// print_if_string(Rc::new(0i8));
     /// ```
     pub fn downcast<T: Any>(self) -> Result<Rc<T>, Rc<dyn Any>> {
         if (*self).is::<T>() {
@@ -880,7 +883,7 @@
 
 impl<T: ?Sized> Rc<T> {
     /// Allocates an `RcBox<T>` with sufficient space for
-    /// a possibly-unsized value where the value has the layout provided.
+    /// a possibly-unsized inner value where the value has the layout provided.
     ///
     /// The function `mem_to_rcbox` is called with the data pointer
     /// and must return back a (potentially fat)-pointer for the `RcBox<T>`.
@@ -910,7 +913,7 @@
         inner
     }
 
-    /// Allocates an `RcBox<T>` with sufficient space for an unsized value
+    /// Allocates an `RcBox<T>` with sufficient space for an unsized inner value
     unsafe fn allocate_for_ptr(ptr: *const T) -> *mut RcBox<T> {
         // Allocate for the `RcBox<T>` using the given value.
         Self::allocate_for_layout(
@@ -1113,7 +1116,7 @@
 impl<T: ?Sized> Clone for Rc<T> {
     /// Makes a clone of the `Rc` pointer.
     ///
-    /// This creates another pointer to the same inner value, increasing the
+    /// This creates another pointer to the same allocation, increasing the
     /// strong reference count.
     ///
     /// # Examples
@@ -1174,6 +1177,8 @@
 /// store large values, that are slow to clone, but also heavy to check for equality, causing this
 /// cost to pay off more easily. It's also more likely to have two `Rc` clones, that point to
 /// the same value, than two `&T`s.
+///
+/// We can only do this when `T: Eq` as a `PartialEq` might be deliberately irreflexive.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + Eq> RcEqIdent<T> for Rc<T> {
     #[inline]
@@ -1191,9 +1196,11 @@
 impl<T: ?Sized + PartialEq> PartialEq for Rc<T> {
     /// Equality for two `Rc`s.
     ///
-    /// Two `Rc`s are equal if their inner values are equal.
+    /// Two `Rc`s are equal if their inner values are equal, even if they are
+    /// stored in different allocation.
     ///
-    /// If `T` also implements `Eq`, two `Rc`s that point to the same value are
+    /// If `T` also implements `Eq` (implying reflexivity of equality),
+    /// two `Rc`s that point to the same allocation are
     /// always equal.
     ///
     /// # Examples
@@ -1214,7 +1221,8 @@
     ///
     /// Two `Rc`s are unequal if their inner values are unequal.
     ///
-    /// If `T` also implements `Eq`, two `Rc`s that point to the same value are
+    /// If `T` also implements `Eq` (implying reflexivity of equality),
+    /// two `Rc`s that point to the same allocation are
     /// never unequal.
     ///
     /// # Examples
@@ -1543,17 +1551,18 @@
 }
 
 /// `Weak` is a version of [`Rc`] that holds a non-owning reference to the
-/// managed value. The value is accessed by calling [`upgrade`] on the `Weak`
+/// managed allocation. The allocation is accessed by calling [`upgrade`] on the `Weak`
 /// pointer, which returns an [`Option`]`<`[`Rc`]`<T>>`.
 ///
 /// Since a `Weak` reference does not count towards ownership, it will not
-/// prevent the inner value from being dropped, and `Weak` itself makes no
-/// guarantees about the value still being present and may return [`None`]
-/// when [`upgrade`]d.
+/// prevent the value stored in the allocation from being dropped, and `Weak` itself makes no
+/// guarantees about the value still being present. Thus it may return [`None`]
+/// when [`upgrade`]d. Note however that a `Weak` reference *does* prevent the allocation
+/// itself (the backing store) from being deallocated.
 ///
-/// A `Weak` pointer is useful for keeping a temporary reference to the value
-/// within [`Rc`] without extending its lifetime. It is also used to prevent
-/// circular references between [`Rc`] pointers, since mutual owning references
+/// A `Weak` pointer is useful for keeping a temporary reference to the allocation
+/// managed by [`Rc`] without preventing its inner value from being dropped. It is also used to
+/// prevent circular references between [`Rc`] pointers, since mutual owning references
 /// would never allow either [`Rc`] to be dropped. For example, a tree could
 /// have strong [`Rc`] pointers from parent nodes to children, and `Weak`
 /// pointers from children back to their parents.
@@ -1752,10 +1761,10 @@
 }
 
 impl<T: ?Sized> Weak<T> {
-    /// Attempts to upgrade the `Weak` pointer to an [`Rc`], extending
-    /// the lifetime of the value if successful.
+    /// Attempts to upgrade the `Weak` pointer to an [`Rc`], delaying
+    /// dropping of the inner value if successful.
     ///
-    /// Returns [`None`] if the value has since been dropped.
+    /// Returns [`None`] if the inner value has since been dropped.
     ///
     /// [`Rc`]: struct.Rc.html
     /// [`None`]: ../../std/option/enum.Option.html
@@ -1789,7 +1798,7 @@
         }
     }
 
-    /// Gets the number of strong (`Rc`) pointers pointing to this value.
+    /// Gets the number of strong (`Rc`) pointers pointing to this allocation.
     ///
     /// If `self` was created using [`Weak::new`], this will return 0.
     ///
@@ -1803,11 +1812,11 @@
         }
     }
 
-    /// Gets the number of `Weak` pointers pointing to this value.
+    /// Gets the number of `Weak` pointers pointing to this allocation.
     ///
     /// If `self` was created using [`Weak::new`], this will return `None`. If
     /// not, the returned value is at least 1, since `self` still points to the
-    /// value.
+    /// allocation.
     ///
     /// [`Weak::new`]: #method.new
     #[unstable(feature = "weak_counts", issue = "57977")]
@@ -1832,14 +1841,14 @@
         }
     }
 
-    /// Returns `true` if the two `Weak`s point to the same value (not just
-    /// values that compare as equal), or if both don't point to any value
+    /// Returns `true` if the two `Weak`s point to the same allocation (similar to
+    /// [`ptr::eq`]), or if both don't point to any allocation
     /// (because they were created with `Weak::new()`).
     ///
     /// # Notes
     ///
     /// Since this compares pointers it means that `Weak::new()` will equal each
-    /// other, even though they don't point to any value.
+    /// other, even though they don't point to any allocation.
     ///
     /// # Examples
     ///
@@ -1871,6 +1880,8 @@
     /// let third = Rc::downgrade(&third_rc);
     /// assert!(!first.ptr_eq(&third));
     /// ```
+    ///
+    /// [`ptr::eq`]: ../../std/ptr/fn.eq.html
     #[inline]
     #[stable(feature = "weak_ptr_eq", since = "1.39.0")]
     pub fn ptr_eq(&self, other: &Self) -> bool {
@@ -1920,7 +1931,7 @@
 
 #[stable(feature = "rc_weak", since = "1.4.0")]
 impl<T: ?Sized> Clone for Weak<T> {
-    /// Makes a clone of the `Weak` pointer that points to the same value.
+    /// Makes a clone of the `Weak` pointer that points to the same allocation.
     ///
     /// # Examples
     ///
diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs
index 881d499..08243ef 100644
--- a/src/liballoc/slice.rs
+++ b/src/liballoc/slice.rs
@@ -411,25 +411,16 @@
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(repeat_generic_slice)]
-    ///
-    /// fn main() {
-    ///     assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
-    /// }
+    /// assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
     /// ```
     ///
     /// A panic upon overflow:
     ///
     /// ```should_panic
-    /// #![feature(repeat_generic_slice)]
-    /// fn main() {
-    ///     // this will panic at runtime
-    ///     b"0123456789abcdef".repeat(usize::max_value());
-    /// }
+    /// // this will panic at runtime
+    /// b"0123456789abcdef".repeat(usize::max_value());
     /// ```
-    #[unstable(feature = "repeat_generic_slice",
-               reason = "it's on str, why not on slice?",
-               issue = "48784")]
+    #[stable(feature = "repeat_generic_slice", since = "1.40.0")]
     pub fn repeat(&self, n: usize) -> Vec<T> where T: Copy {
         if n == 0 {
             return Vec::new();
diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs
index 9a1342c..83816d8 100644
--- a/src/liballoc/str.rs
+++ b/src/liballoc/str.rs
@@ -456,7 +456,7 @@
                 }
             }
         }
-        return s;
+        s
     }
 
     /// Converts a [`Box<str>`] into a [`String`] without copying or allocating.
@@ -500,10 +500,8 @@
     /// A panic upon overflow:
     ///
     /// ```should_panic
-    /// fn main() {
-    ///     // this will panic at runtime
-    ///     "0123456789abcdef".repeat(usize::max_value());
-    /// }
+    /// // this will panic at runtime
+    /// "0123456789abcdef".repeat(usize::max_value());
     /// ```
     #[stable(feature = "repeat_str", since = "1.16.0")]
     pub fn repeat(&self, n: usize) -> String {
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index 1166e7b..d9927c6 100644
--- a/src/liballoc/string.rs
+++ b/src/liballoc/string.rs
@@ -164,10 +164,8 @@
 ///
 /// fn example_func<A: TraitExample>(example_arg: A) {}
 ///
-/// fn main() {
-///     let example_string = String::from("example_string");
-///     example_func(&example_string);
-/// }
+/// let example_string = String::from("example_string");
+/// example_func(&example_string);
 /// ```
 ///
 /// There are two options that would work instead. The first would be to
@@ -198,20 +196,21 @@
 ///
 /// let story = String::from("Once upon a time...");
 ///
-/// let ptr = story.as_ptr();
+// FIXME Update this when vec_into_raw_parts is stabilized
+/// // Prevent automatically dropping the String's data
+/// let mut story = mem::ManuallyDrop::new(story);
+///
+/// let ptr = story.as_mut_ptr();
 /// let len = story.len();
 /// let capacity = story.capacity();
 ///
 /// // story has nineteen bytes
 /// assert_eq!(19, len);
 ///
-/// // Now that we have our parts, we throw the story away.
-/// mem::forget(story);
-///
 /// // We can re-build a String out of ptr, len, and capacity. This is all
 /// // unsafe because we are responsible for making sure the components are
 /// // valid:
-/// let s = unsafe { String::from_raw_parts(ptr as *mut _, len, capacity) } ;
+/// let s = unsafe { String::from_raw_parts(ptr, len, capacity) } ;
 ///
 /// assert_eq!(String::from("Once upon a time..."), s);
 /// ```
@@ -369,7 +368,6 @@
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_string_new"))]
     pub const fn new() -> String {
         String { vec: Vec::new() }
     }
@@ -429,7 +427,7 @@
 
     /// Converts a vector of bytes to a `String`.
     ///
-    /// A string slice ([`&str`]) is made of bytes ([`u8`]), and a vector of bytes
+    /// A string ([`String`]) is made of bytes ([`u8`]), and a vector of bytes
     /// ([`Vec<u8>`]) is made of bytes, so this function converts between the
     /// two. Not all byte slices are valid `String`s, however: `String`
     /// requires that it is valid UTF-8. `from_utf8()` checks to ensure that
@@ -446,7 +444,7 @@
     /// If you need a [`&str`] instead of a `String`, consider
     /// [`str::from_utf8`].
     ///
-    /// The inverse of this method is [`as_bytes`].
+    /// The inverse of this method is [`into_bytes`].
     ///
     /// # Errors
     ///
@@ -480,11 +478,11 @@
     /// with this error.
     ///
     /// [`from_utf8_unchecked`]: struct.String.html#method.from_utf8_unchecked
-    /// [`&str`]: ../../std/primitive.str.html
+    /// [`String`]: struct.String.html
     /// [`u8`]: ../../std/primitive.u8.html
     /// [`Vec<u8>`]: ../../std/vec/struct.Vec.html
     /// [`str::from_utf8`]: ../../std/str/fn.from_utf8.html
-    /// [`as_bytes`]: struct.String.html#method.as_bytes
+    /// [`into_bytes`]: struct.String.html#method.into_bytes
     /// [`FromUtf8Error`]: struct.FromUtf8Error.html
     /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
     #[inline]
@@ -650,6 +648,37 @@
         decode_utf16(v.iter().cloned()).map(|r| r.unwrap_or(REPLACEMENT_CHARACTER)).collect()
     }
 
+    /// Decomposes a `String` into its raw components.
+    ///
+    /// Returns the raw pointer to the underlying data, the length of
+    /// the string (in bytes), and the allocated capacity of the data
+    /// (in bytes). These are the same arguments in the same order as
+    /// the arguments to [`from_raw_parts`].
+    ///
+    /// After calling this function, the caller is responsible for the
+    /// memory previously managed by the `String`. The only way to do
+    /// this is to convert the raw pointer, length, and capacity back
+    /// into a `String` with the [`from_raw_parts`] function, allowing
+    /// the destructor to perform the cleanup.
+    ///
+    /// [`from_raw_parts`]: #method.from_raw_parts
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(vec_into_raw_parts)]
+    /// let s = String::from("hello");
+    ///
+    /// let (ptr, len, cap) = s.into_raw_parts();
+    ///
+    /// let rebuilt = unsafe { String::from_raw_parts(ptr, len, cap) };
+    /// assert_eq!(rebuilt, "hello");
+    /// ```
+    #[unstable(feature = "vec_into_raw_parts", reason = "new API", issue = "65816")]
+    pub fn into_raw_parts(self) -> (*mut u8, usize, usize) {
+        self.vec.into_raw_parts()
+    }
+
     /// Creates a new `String` from a length, capacity, and pointer.
     ///
     /// # Safety
@@ -680,13 +709,16 @@
     ///
     /// unsafe {
     ///     let s = String::from("hello");
-    ///     let ptr = s.as_ptr();
+    ///
+    // FIXME Update this when vec_into_raw_parts is stabilized
+    ///     // Prevent automatically dropping the String's data
+    ///     let mut s = mem::ManuallyDrop::new(s);
+    ///
+    ///     let ptr = s.as_mut_ptr();
     ///     let len = s.len();
     ///     let capacity = s.capacity();
     ///
-    ///     mem::forget(s);
-    ///
-    ///     let s = String::from_raw_parts(ptr as *mut _, len, capacity);
+    ///     let s = String::from_raw_parts(ptr, len, capacity);
     ///
     ///     assert_eq!(String::from("hello"), s);
     /// }
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 45f9816..80d6c6e 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -45,10 +45,10 @@
 ///
 /// The type `Arc<T>` provides shared ownership of a value of type `T`,
 /// allocated in the heap. Invoking [`clone`][clone] on `Arc` produces
-/// a new `Arc` instance, which points to the same value on the heap as the
+/// a new `Arc` instance, which points to the same allocation on the heap as the
 /// source `Arc`, while increasing a reference count. When the last `Arc`
-/// pointer to a given value is destroyed, the pointed-to value is also
-/// destroyed.
+/// pointer to a given allocation is destroyed, the value stored in that allocation (often
+/// referred to as "inner value") is also dropped.
 ///
 /// Shared references in Rust disallow mutation by default, and `Arc` is no
 /// exception: you cannot generally obtain a mutable reference to something
@@ -61,7 +61,7 @@
 /// Unlike [`Rc<T>`], `Arc<T>` uses atomic operations for its reference
 /// counting. This means that it is thread-safe. The disadvantage is that
 /// atomic operations are more expensive than ordinary memory accesses. If you
-/// are not sharing reference-counted values between threads, consider using
+/// are not sharing reference-counted allocations between threads, consider using
 /// [`Rc<T>`] for lower overhead. [`Rc<T>`] is a safe default, because the
 /// compiler will catch any attempt to send an [`Rc<T>`] between threads.
 /// However, a library might choose `Arc<T>` in order to give library consumers
@@ -85,8 +85,10 @@
 ///
 /// The [`downgrade`][downgrade] method can be used to create a non-owning
 /// [`Weak`][weak] pointer. A [`Weak`][weak] pointer can be [`upgrade`][upgrade]d
-/// to an `Arc`, but this will return [`None`] if the value has already been
-/// dropped.
+/// to an `Arc`, but this will return [`None`] if the value stored in the allocation has
+/// already been dropped. In other words, `Weak` pointers do not keep the value
+/// inside the allocation alive; however, they *do* keep the allocation
+/// (the backing store for the value) alive.
 ///
 /// A cycle between `Arc` pointers will never be