diff --git a/Cargo.lock b/Cargo.lock
index 781184af9a96c..bb2bd3c314caa 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -54,7 +54,7 @@ version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
 dependencies = [
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -104,7 +104,7 @@ checksum = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
 dependencies = [
  "libc",
  "termion",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -212,12 +212,6 @@ dependencies = [
  "toml",
 ]
 
-[[package]]
-name = "build_const"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
-
 [[package]]
 name = "build_helper"
 version = "0.1.0"
@@ -311,7 +305,7 @@ dependencies = [
  "num_cpus",
  "opener",
  "openssl",
- "percent-encoding 2.0.0",
+ "percent-encoding 2.1.0",
  "pretty_env_logger",
  "remove_dir_all",
  "rustc-workspace-hack",
@@ -330,7 +324,7 @@ dependencies = [
  "unicode-width",
  "url 2.1.0",
  "walkdir",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -482,7 +476,7 @@ dependencies = [
  "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",
@@ -511,6 +505,26 @@ dependencies = [
  "cc",
 ]
 
+[[package]]
+name = "codespan"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de67bdcd653002a6dba3eb53850ce3a485547225d81cb6c2bbdbc5a0cba5d15d"
+dependencies = [
+ "unicode-segmentation",
+]
+
+[[package]]
+name = "codespan-reporting"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "efd1d915d9e2b2ad696b2cd73215a84823ef3f0e3084d90304204415921b62c6"
+dependencies = [
+ "codespan",
+ "termcolor",
+ "unicode-width",
+]
+
 [[package]]
 name = "colored"
 version = "1.6.0"
@@ -564,7 +578,7 @@ dependencies = [
  "serde",
  "serde_json",
  "walkdir",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -585,7 +599,7 @@ dependencies = [
  "serde_derive",
  "serde_json",
  "tempfile",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -594,6 +608,34 @@ version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
 
+[[package]]
+name = "cookie"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "888604f00b3db336d2af898ec3c1d5d0ddf5e6d462220f2ededc33a87ac4bbd5"
+dependencies = [
+ "time",
+ "url 1.7.2",
+]
+
+[[package]]
+name = "cookie_store"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46750b3f362965f197996c4448e4a0935e791bf7d6631bfce9ee0af3d24c919c"
+dependencies = [
+ "cookie",
+ "failure",
+ "idna 0.1.5",
+ "log",
+ "publicsuffix",
+ "serde",
+ "serde_json",
+ "time",
+ "try_from",
+ "url 1.7.2",
+]
+
 [[package]]
 name = "core"
 version = "0.0.0"
@@ -623,22 +665,13 @@ version = "0.29.0"
 dependencies = [
  "curl",
  "failure",
- "percent-encoding 2.0.0",
+ "percent-encoding 2.1.0",
  "serde",
  "serde_derive",
  "serde_json",
  "url 2.1.0",
 ]
 
-[[package]]
-name = "crc"
-version = "1.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
-dependencies = [
- "build_const",
-]
-
 [[package]]
 name = "crc32fast"
 version = "1.1.2"
@@ -754,7 +787,7 @@ dependencies = [
  "commoncrypto",
  "hex 0.3.2",
  "openssl",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -769,7 +802,7 @@ dependencies = [
  "openssl-sys",
  "schannel",
  "socket2",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -785,7 +818,7 @@ dependencies = [
  "openssl-sys",
  "pkg-config",
  "vcpkg",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -901,7 +934,7 @@ dependencies = [
  "cfg-if",
  "libc",
  "redox_users",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -921,6 +954,12 @@ version = "0.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e"
 
+[[package]]
+name = "dunce"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0ad6bf6a88548d1126045c413548df1453d9be094a8ab9fd59bf1fdd338da4f"
+
 [[package]]
 name = "either"
 version = "1.5.0"
@@ -1050,15 +1089,15 @@ checksum = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
 
 [[package]]
 name = "flate2"
-version = "1.0.6"
+version = "1.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2291c165c8e703ee54ef3055ad6188e3d51108e2ded18e9f2476e774fc5ad3d4"
+checksum = "ad3c5233c9a940c8719031b423d7e6c16af66e031cb0420b0896f5245bf181d3"
 dependencies = [
+ "cfg-if",
  "crc32fast",
  "libc",
  "libz-sys",
- "miniz-sys",
- "miniz_oxide_c_api",
+ "miniz_oxide",
 ]
 
 [[package]]
@@ -1107,7 +1146,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
 dependencies = [
  "libc",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -1359,7 +1398,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a3753954f7bd71f0e671afb8b5a992d1724cf43b7f95a563cd4a0bde94659ca8"
 dependencies = [
  "scopeguard 1.0.0",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -1378,9 +1417,9 @@ dependencies = [
 
 [[package]]
 name = "http"
-version = "0.1.16"
+version = "0.1.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fe67e3678f2827030e89cc4b9e7ecd16d52f132c0b940ab5005f88e821500f6a"
+checksum = "d7e06e336150b178206af098a055e3621e8336027e2b4d126bda0bc64824baaf"
 dependencies = [
  "bytes",
  "fnv",
@@ -1539,7 +1578,7 @@ dependencies = [
  "remove_dir_all",
  "tar",
  "walkdir",
- "winapi 0.3.6",
+ "winapi 0.3.8",
  "xz2",
 ]
 
@@ -1704,7 +1743,7 @@ dependencies = [
  "num_cpus",
  "tokio",
  "tokio-codec",
- "unicase 2.5.1",
+ "unicase",
 ]
 
 [[package]]
@@ -1744,19 +1783,6 @@ 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"
@@ -1926,9 +1952,9 @@ checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
 
 [[package]]
 name = "mdbook"
-version = "0.3.3"
+version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a070268274c566082efb6b2ace7743e43ba91a70d5c6982981e96d3c05ac81c"
+checksum = "031bdd9d4893c983e2f69ebc4b59070feee8276a584c4aabdcb351235ea28016"
 dependencies = [
  "ammonia",
  "chrono",
@@ -1942,7 +1968,7 @@ dependencies = [
  "log",
  "memchr",
  "open",
- "pulldown-cmark 0.5.3",
+ "pulldown-cmark 0.6.1",
  "regex",
  "serde",
  "serde_derive",
@@ -1955,16 +1981,21 @@ dependencies = [
 
 [[package]]
 name = "mdbook-linkcheck"
-version = "0.3.0"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77d1f0ba4d1e6b86fa18e8853d026d7d76a97eb7eb5eb052ed80901e43b7fc10"
+checksum = "c0a04db564ca37c47771f8455c825dc941ea851ff0deffcf55a04c512406b409"
 dependencies = [
- "env_logger 0.6.2",
+ "codespan",
+ "codespan-reporting",
+ "dunce",
+ "either",
+ "env_logger 0.7.1",
  "failure",
+ "http",
  "log",
  "mdbook",
- "memchr",
- "pulldown-cmark 0.5.3",
+ "percent-encoding 2.1.0",
+ "pulldown-cmark 0.6.1",
  "rayon",
  "regex",
  "reqwest",
@@ -1972,8 +2003,7 @@ dependencies = [
  "serde",
  "serde_derive",
  "serde_json",
- "structopt 0.2.18",
- "url 1.7.2",
+ "structopt",
 ]
 
 [[package]]
@@ -2000,7 +2030,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
 dependencies = [
  "libc",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -2024,19 +2054,17 @@ version = "0.3.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3e27ca21f40a310bd06d9031785f4801710d566c184a6e15bad4f1d9b65f9425"
 dependencies = [
- "unicase 2.5.1",
+ "unicase",
 ]
 
 [[package]]
 name = "mime_guess"
-version = "2.0.0-alpha.6"
+version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30de2e4613efcba1ec63d8133f344076952090c122992a903359be5a4f99c3ed"
+checksum = "1a0ed03949aef72dbdf3116a383d7b38b4768e6f960528cd6a6044aa9ed68599"
 dependencies = [
  "mime",
- "phf",
- "phf_codegen",
- "unicase 1.4.2",
+ "unicase",
 ]
 
 [[package]]
@@ -2048,37 +2076,15 @@ dependencies = [
  "macro-utils",
 ]
 
-[[package]]
-name = "miniz-sys"
-version = "0.1.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0300eafb20369952951699b68243ab4334f4b10a88f411c221d444b36c40e649"
-dependencies = [
- "cc",
- "libc",
-]
-
 [[package]]
 name = "miniz_oxide"
-version = "0.2.0"
+version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ad30a47319c16cde58d0314f5d98202a80c9083b5f61178457403dfb14e509c"
+checksum = "6f3f74f726ae935c3f514300cc6773a0c9492abc5e972d42ba0c0ebb88757625"
 dependencies = [
  "adler32",
 ]
 
-[[package]]
-name = "miniz_oxide_c_api"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28edaef377517fd9fe3e085c37d892ce7acd1fbeab9239c5a36eec352d8a8b7e"
-dependencies = [
- "cc",
- "crc",
- "libc",
- "miniz_oxide",
-]
-
 [[package]]
 name = "mio"
 version = "0.6.16"
@@ -2107,7 +2113,7 @@ dependencies = [
  "log",
  "mio",
  "miow 0.3.3",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -2140,7 +2146,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226"
 dependencies = [
  "socket2",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -2190,7 +2196,7 @@ checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
 dependencies = [
  "cfg-if",
  "libc",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -2247,7 +2253,7 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "998c59e83d9474c01127a96e023b7a04bb061dd286bf8bb939d31dc8d31a7448"
 dependencies = [
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -2359,7 +2365,7 @@ dependencies = [
  "tokio",
  "tokio-named-pipes",
  "tokio-uds",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -2393,7 +2399,7 @@ dependencies = [
  "rand 0.6.1",
  "rustc_version",
  "smallvec 0.6.10",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -2408,7 +2414,7 @@ dependencies = [
  "redox_syscall",
  "rustc_version",
  "smallvec 0.6.10",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -2419,9 +2425,9 @@ checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
 
 [[package]]
 name = "percent-encoding"
-version = "2.0.0"
+version = "2.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba4f28a6faf4ffea762ba8f4baef48c61a6db348647c73095034041fc79dd954"
+checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
 
 [[package]]
 name = "pest"
@@ -2512,7 +2518,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0"
 dependencies = [
  "siphasher",
- "unicase 1.4.2",
 ]
 
 [[package]]
@@ -2619,6 +2624,19 @@ dependencies = [
  "core",
 ]
 
+[[package]]
+name = "publicsuffix"
+version = "1.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9bf259a81de2b2eb9850ec990ec78e6a25319715584fd7652b9b26f96fcb1510"
+dependencies = [
+ "error-chain",
+ "idna 0.2.0",
+ "lazy_static 1.3.0",
+ "regex",
+ "url 2.1.0",
+]
+
 [[package]]
 name = "pulldown-cmark"
 version = "0.5.3"
@@ -2626,21 +2644,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 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]]
@@ -2712,7 +2729,7 @@ dependencies = [
  "rand_pcg",
  "rand_xorshift 0.1.0",
  "rustc_version",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -2807,7 +2824,7 @@ dependencies = [
  "libc",
  "rand_core 0.4.0",
  "rdrand",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -2934,23 +2951,25 @@ version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
 dependencies = [
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
 name = "reqwest"
-version = "0.9.11"
+version = "0.9.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e542d9f077c126af32536b6aacc75bb7325400eab8cd0743543be5d91660780d"
+checksum = "2c2064233e442ce85c77231ebd67d9eca395207dec2127fe0bbedde4bd29a650"
 dependencies = [
  "base64",
  "bytes",
+ "cookie",
+ "cookie_store",
  "encoding_rs",
+ "flate2",
  "futures",
  "http",
  "hyper",
  "hyper-tls",
- "libflate",
  "log",
  "mime",
  "mime_guess",
@@ -2958,6 +2977,7 @@ dependencies = [
  "serde",
  "serde_json",
  "serde_urlencoded",
+ "time",
  "tokio",
  "tokio-executor",
  "tokio-io",
@@ -2965,14 +2985,9 @@ dependencies = [
  "tokio-timer",
  "url 1.7.2",
  "uuid",
+ "winreg",
 ]
 
-[[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.40.0"
@@ -3100,6 +3115,7 @@ name = "rustbook"
 version = "0.1.0"
 dependencies = [
  "clap",
+ "codespan-reporting",
  "failure",
  "mdbook",
  "mdbook-linkcheck",
@@ -3397,7 +3413,7 @@ dependencies = [
  "smallvec 0.6.10",
  "syn 0.15.35",
  "url 2.1.0",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -3946,7 +3962,7 @@ dependencies = [
  "rustfmt-config_proc_macro",
  "serde",
  "serde_json",
- "structopt 0.3.1",
+ "structopt",
  "term 0.6.0",
  "toml",
  "unicode-segmentation",
@@ -3976,7 +3992,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0e1a231dc10abf6749cfa5d7767f25888d484201accbd919b66ab5413c502d56"
 dependencies = [
  "lazy_static 1.3.0",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -4187,7 +4203,7 @@ dependencies = [
  "cfg-if",
  "libc",
  "redox_syscall",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -4280,16 +4296,6 @@ version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
 
-[[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"
@@ -4297,19 +4303,7 @@ 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]]
@@ -4453,12 +4447,6 @@ dependencies = [
  "unicode-width",
 ]
 
-[[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"
@@ -4482,7 +4470,7 @@ dependencies = [
  "rand 0.7.0",
  "redox_syscall",
  "remove_dir_all",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -4512,7 +4500,7 @@ checksum = "0dd90505d5006a4422d3520b30c781d480b3f36768c2fa2187c3e950bc110464"
 dependencies = [
  "byteorder",
  "dirs",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -4591,13 +4579,13 @@ dependencies = [
 
 [[package]]
 name = "time"
-version = "0.1.40"
+version = "0.1.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
+checksum = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
 dependencies = [
  "libc",
  "redox_syscall",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -4713,7 +4701,7 @@ dependencies = [
  "tokio-io",
  "tokio-reactor",
  "tokio-signal",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -4757,7 +4745,7 @@ dependencies = [
  "tokio-executor",
  "tokio-io",
  "tokio-reactor",
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -4876,6 +4864,15 @@ version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
 
+[[package]]
+name = "try_from"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "283d3b89e1368717881a9d51dad843cc435380d8109c9e47d38780a324698d8b"
+dependencies = [
+ "cfg-if",
+]
+
 [[package]]
 name = "typenum"
 version = "1.10.0"
@@ -4894,15 +4891,6 @@ version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
 
-[[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"
@@ -4929,9 +4917,9 @@ checksum = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
 
 [[package]]
 name = "unicode-segmentation"
-version = "1.2.1"
+version = "1.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
+checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
 
 [[package]]
 name = "unicode-width"
@@ -5000,7 +4988,7 @@ checksum = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61"
 dependencies = [
  "idna 0.2.0",
  "matches",
- "percent-encoding 2.0.0",
+ "percent-encoding 2.1.0",
  "serde",
 ]
 
@@ -5076,7 +5064,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1"
 dependencies = [
  "same-file",
- "winapi 0.3.6",
+ "winapi 0.3.8",
  "winapi-util",
 ]
 
@@ -5110,9 +5098,9 @@ checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
 
 [[package]]
 name = "winapi"
-version = "0.3.6"
+version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
+checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
 dependencies = [
  "winapi-i686-pc-windows-gnu",
  "winapi-x86_64-pc-windows-gnu",
@@ -5136,7 +5124,7 @@ version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
 dependencies = [
- "winapi 0.3.6",
+ "winapi 0.3.8",
 ]
 
 [[package]]
@@ -5151,10 +5139,19 @@ version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba"
 dependencies = [
- "winapi 0.3.6",
+ "winapi 0.3.8",
  "winapi-util",
 ]
 
+[[package]]
+name = "winreg"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9"
+dependencies = [
+ "winapi 0.3.8",
+]
+
 [[package]]
 name = "ws2_32-sys"
 version = "0.2.1"
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 9c09ce9948672..619ebd383d65a 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -454,7 +454,6 @@ impl<'a> LoweringContext<'a> {
                     | ItemKind::Union(_, ref generics)
                     | ItemKind::Enum(_, ref generics)
                     | ItemKind::TyAlias(_, ref generics)
-                    | ItemKind::OpaqueTy(_, ref generics)
                     | ItemKind::Trait(_, _, ref generics, ..) => {
                         let def_id = self.lctx.resolver.definitions().local_def_id(item.id);
                         let count = generics
diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs
index 137d21c35804f..4cd42927868d7 100644
--- a/src/librustc/hir/lowering/item.rs
+++ b/src/librustc/hir/lowering/item.rs
@@ -337,20 +337,22 @@ impl LoweringContext<'_> {
             ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
             ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)),
             ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)),
-            ItemKind::TyAlias(ref t, ref generics) => hir::ItemKind::TyAlias(
-                self.lower_ty(t, ImplTraitContext::disallowed()),
-                self.lower_generics(generics, ImplTraitContext::disallowed()),
-            ),
-            ItemKind::OpaqueTy(ref b, ref generics) => hir::ItemKind::OpaqueTy(
-                hir::OpaqueTy {
-                    generics: self.lower_generics(generics,
-                        ImplTraitContext::OpaqueTy(None)),
-                    bounds: self.lower_param_bounds(b,
-                        ImplTraitContext::OpaqueTy(None)),
-                    impl_trait_fn: None,
-                    origin: hir::OpaqueTyOrigin::TypeAlias,
+            ItemKind::TyAlias(ref ty, ref generics) => match ty.kind.opaque_top_hack() {
+                None => {
+                    let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
+                    let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
+                    hir::ItemKind::TyAlias(ty, generics)
                 },
-            ),
+                Some(bounds) => {
+                    let ty = hir::OpaqueTy {
+                        generics: self.lower_generics(generics, ImplTraitContext::OpaqueTy(None)),
+                        bounds: self.lower_param_bounds(bounds, ImplTraitContext::OpaqueTy(None)),
+                        impl_trait_fn: None,
+                        origin: hir::OpaqueTyOrigin::TypeAlias,
+                    };
+                    hir::ItemKind::OpaqueTy(ty)
+                }
+            }
             ItemKind::Enum(ref enum_definition, ref generics) => {
                 hir::ItemKind::Enum(
                     hir::EnumDef {
@@ -916,16 +918,20 @@ impl LoweringContext<'_> {
 
                 (generics, hir::ImplItemKind::Method(sig, body_id))
             }
-            ImplItemKind::TyAlias(ref ty) => (
-                self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
-                hir::ImplItemKind::TyAlias(self.lower_ty(ty, ImplTraitContext::disallowed())),
-            ),
-            ImplItemKind::OpaqueTy(ref bounds) => (
-                self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
-                hir::ImplItemKind::OpaqueTy(
-                    self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
-                ),
-            ),
+            ImplItemKind::TyAlias(ref ty) => {
+                let generics = self.lower_generics(&i.generics, ImplTraitContext::disallowed());
+                let kind = match ty.kind.opaque_top_hack() {
+                    None => {
+                        let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
+                        hir::ImplItemKind::TyAlias(ty)
+                    }
+                    Some(bs) => {
+                        let bounds = self.lower_param_bounds(bs, ImplTraitContext::disallowed());
+                        hir::ImplItemKind::OpaqueTy(bounds)
+                    }
+                };
+                (generics, kind)
+            },
             ImplItemKind::Macro(..) => bug!("`TyMac` should have been expanded by now"),
         };
 
@@ -950,11 +956,13 @@ impl LoweringContext<'_> {
             span: i.span,
             vis: self.lower_visibility(&i.vis, Some(i.id)),
             defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
-            kind: match i.kind {
+            kind: match &i.kind {
                 ImplItemKind::Const(..) => hir::AssocItemKind::Const,
-                ImplItemKind::TyAlias(..) => hir::AssocItemKind::Type,
-                ImplItemKind::OpaqueTy(..) => hir::AssocItemKind::OpaqueTy,
-                ImplItemKind::Method(ref sig, _) => hir::AssocItemKind::Method {
+                ImplItemKind::TyAlias(ty) => match ty.kind.opaque_top_hack() {
+                    None => hir::AssocItemKind::Type,
+                    Some(_) => hir::AssocItemKind::OpaqueTy,
+                },
+                ImplItemKind::Method(sig, _) => hir::AssocItemKind::Method {
                     has_self: sig.decl.has_self(),
                 },
                 ImplItemKind::Macro(..) => unimplemented!(),
diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index d858e00a2e9cd..cfd90f50b1b04 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -107,7 +107,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
             }
             ItemKind::Mod(..) | ItemKind::Trait(..) | ItemKind::TraitAlias(..) |
             ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) |
-            ItemKind::OpaqueTy(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) |
+            ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) |
             ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name),
             ItemKind::Fn(sig, generics, body) if sig.header.asyncness.node.is_async() => {
                 return self.visit_async_fn(
@@ -239,8 +239,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
             }
             ImplItemKind::Method(..) |
             ImplItemKind::Const(..) => DefPathData::ValueNs(ii.ident.name),
-            ImplItemKind::TyAlias(..) |
-            ImplItemKind::OpaqueTy(..) => DefPathData::TypeNs(ii.ident.name),
+            ImplItemKind::TyAlias(..) => DefPathData::TypeNs(ii.ident.name),
             ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id),
         };
 
diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs
index 1bb4d9ea4d6d9..7c77b2c0711b9 100644
--- a/src/librustc/mir/interpret/pointer.rs
+++ b/src/librustc/mir/interpret/pointer.rs
@@ -1,4 +1,5 @@
 use std::fmt::{self, Display};
+use std::convert::TryFrom;
 
 use crate::mir;
 use crate::ty::layout::{self, HasDataLayout, Size};
@@ -40,6 +41,18 @@ pub trait PointerArithmetic: layout::HasDataLayout {
         self.data_layout().pointer_size
     }
 
+    #[inline]
+    fn usize_max(&self) -> u64 {
+        let max_usize_plus_1 = 1u128 << self.pointer_size().bits();
+        u64::try_from(max_usize_plus_1-1).unwrap()
+    }
+
+    #[inline]
+    fn isize_max(&self) -> i64 {
+        let max_isize_plus_1 = 1u128 << (self.pointer_size().bits()-1);
+        i64::try_from(max_isize_plus_1-1).unwrap()
+    }
+
     /// Helper function: truncate given value-"overflowed flag" pair to pointer size and
     /// update "overflowed flag" if there was an overflow.
     /// This should be called by all the other methods before returning!
diff --git a/src/librustc_error_codes/error_codes/E0744.md b/src/librustc_error_codes/error_codes/E0744.md
index 254223f3565f9..b299102fd6934 100644
--- a/src/librustc_error_codes/error_codes/E0744.md
+++ b/src/librustc_error_codes/error_codes/E0744.md
@@ -15,3 +15,10 @@ const _: i32 = {
     x
 };
 ```
+
+This will be allowed at some point in the future, but the implementation is not
+yet complete. See the tracking issue for [conditionals] or [loops] in a const
+context for the current status.
+
+[conditionals]: https://github.com/rust-lang/rust/issues/49146
+[loops]: https://github.com/rust-lang/rust/issues/52000
diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs
index 88f16299dc0f7..74b22d8e14366 100644
--- a/src/librustc_mir/transform/check_consts/validation.rs
+++ b/src/librustc_mir/transform/check_consts/validation.rs
@@ -326,17 +326,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
                 let is_thread_local = self.tcx.has_attr(*def_id, sym::thread_local);
                 if is_thread_local {
                     self.check_op(ops::ThreadLocalAccess);
-                } else if self.const_kind() == ConstKind::Static && context.is_mutating_use() {
-                    // this is not strictly necessary as miri will also bail out
-                    // For interior mutability we can't really catch this statically as that
-                    // goes through raw pointers and intermediate temporaries, so miri has
-                    // to catch this anyway
-
-                    self.tcx.sess.span_err(
-                        self.span,
-                        "cannot mutate statics in the initializer of another static",
-                    );
-                } else {
+                } else if self.const_kind() != ConstKind::Static || !context.is_mutating_use() {
                     self.check_op(ops::StaticAccess);
                 }
             }
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 185a499bf487b..964efdec2b9d2 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -787,19 +787,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
 
                 // Only allow statics (not consts) to refer to other statics.
                 if self.mode == Mode::Static || self.mode == Mode::StaticMut {
-                    if self.mode == Mode::Static
-                        && context.is_mutating_use()
-                        && !self.suppress_errors
-                    {
-                        // this is not strictly necessary as miri will also bail out
-                        // For interior mutability we can't really catch this statically as that
-                        // goes through raw pointers and intermediate temporaries, so miri has
-                        // to catch this anyway
-                        self.tcx.sess.span_err(
-                            self.span,
-                            "cannot mutate statics in the initializer of another static",
-                        );
-                    }
                     return;
                 }
                 unleash_miri!(self);
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index cb496f2ecbe58..7309916987989 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -7,7 +7,7 @@ use syntax::ast::{self, Abi, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyl
 use syntax::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind};
 use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness};
 use syntax::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
-use syntax::ast::{Ty, TyKind, Generics, GenericBounds, TraitRef, EnumDef, VariantData, StructField};
+use syntax::ast::{Ty, TyKind, Generics, TraitRef, EnumDef, VariantData, StructField};
 use syntax::ast::{Mac, MacDelimiter, Block, BindingMode, FnDecl, FnSig, SelfKind, Param};
 use syntax::ptr::P;
 use syntax::ThinVec;
@@ -24,15 +24,6 @@ use log::debug;
 use std::mem;
 use errors::{PResult, Applicability, DiagnosticBuilder, StashKey};
 
-/// Whether the type alias or associated type is a concrete type or an opaque type.
-#[derive(Debug)]
-pub(super) enum AliasKind {
-    /// Just a new name for the same type.
-    Weak(P<Ty>),
-    /// Only trait impls of the type will be usable, not the actual type itself.
-    OpaqueTy(GenericBounds),
-}
-
 pub(super) type ItemInfo = (Ident, ItemKind, Option<Vec<Attribute>>);
 
 impl<'a> Parser<'a> {
@@ -269,15 +260,11 @@ impl<'a> Parser<'a> {
             return self.mk_item_with_info(attrs, lo, vis, info);
         }
 
-        if let Some(type_) = self.eat_type() {
-            let (ident, alias, generics) = type_?;
+        if self.eat_keyword(kw::Type) {
             // TYPE ITEM
-            let item_ = match alias {
-                AliasKind::Weak(ty) => ItemKind::TyAlias(ty, generics),
-                AliasKind::OpaqueTy(bounds) => ItemKind::OpaqueTy(bounds, generics),
-            };
-            let span = lo.to(self.prev_span);
-            return Ok(Some(self.mk_item(span, ident, item_, vis, attrs)));
+            let (ident, ty, generics) = self.parse_type_alias()?;
+            let kind = ItemKind::TyAlias(ty, generics);
+            return self.mk_item_with_info(attrs, lo, vis, (ident, kind, None));
         }
 
         if self.eat_keyword(kw::Enum) {
@@ -711,13 +698,9 @@ impl<'a> Parser<'a> {
         let lo = self.token.span;
         let vis = self.parse_visibility(false)?;
         let defaultness = self.parse_defaultness();
-        let (name, kind, generics) = if let Some(type_) = self.eat_type() {
-            let (name, alias, generics) = type_?;
-            let kind = match alias {
-                AliasKind::Weak(typ) => ast::ImplItemKind::TyAlias(typ),
-                AliasKind::OpaqueTy(bounds) => ast::ImplItemKind::OpaqueTy(bounds),
-            };
-            (name, kind, generics)
+        let (name, kind, generics) = if self.eat_keyword(kw::Type) {
+            let (name, ty, generics) = self.parse_type_alias()?;
+            (name, ast::ImplItemKind::TyAlias(ty), generics)
         } else if self.is_const_item() {
             self.parse_impl_const()?
         } else if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(&vis), at_end)? {
@@ -1322,34 +1305,16 @@ impl<'a> Parser<'a> {
         })
     }
 
-    /// Parses `type Foo = Bar;` or returns `None`
-    /// without modifying the parser state.
-    fn eat_type(&mut self) -> Option<PResult<'a, (Ident, AliasKind, Generics)>> {
-        // This parses the grammar:
-        //     Ident ["<"...">"] ["where" ...] ("=" | ":") Ty ";"
-        if self.eat_keyword(kw::Type) {
-            Some(self.parse_type_alias())
-        } else {
-            None
-        }
-    }
-
-    /// Parses a type alias or opaque type.
-    fn parse_type_alias(&mut self) -> PResult<'a, (Ident, AliasKind, Generics)> {
+    /// Parses the grammar:
+    ///     Ident ["<"...">"] ["where" ...] ("=" | ":") Ty ";"
+    fn parse_type_alias(&mut self) -> PResult<'a, (Ident, P<Ty>, Generics)> {
         let ident = self.parse_ident()?;
         let mut tps = self.parse_generics()?;
         tps.where_clause = self.parse_where_clause()?;
         self.expect(&token::Eq)?;
-        let alias = if self.check_keyword(kw::Impl) {
-            self.bump();
-            let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
-            AliasKind::OpaqueTy(bounds)
-        } else {
-            let ty = self.parse_ty()?;
-            AliasKind::Weak(ty)
-        };
+        let ty = self.parse_ty()?;
         self.expect_semi()?;
-        Ok((ident, alias, tps))
+        Ok((ident, ty, tps))
     }
 
     /// Parses an enum declaration.
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index c48d2c61e6570..edb91d5bf18ed 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -20,7 +20,7 @@ use syntax::source_map::Spanned;
 use syntax::symbol::{kw, sym};
 use syntax::visit::{self, Visitor};
 use syntax::{span_err, struct_span_err, walk_list};
-use syntax_pos::{Span, MultiSpan};
+use syntax_pos::Span;
 use errors::{Applicability, FatalError};
 
 use rustc_error_codes::*;
@@ -586,14 +586,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                                                 "unions cannot have zero fields");
                 }
             }
-            ItemKind::OpaqueTy(ref bounds, _) => {
-                if !bounds.iter()
-                          .any(|b| if let GenericBound::Trait(..) = *b { true } else { false }) {
-                    let msp = MultiSpan::from_spans(bounds.iter()
-                        .map(|bound| bound.span()).collect());
-                    self.err_handler().span_err(msp, "at least one trait must be specified");
-                }
-            }
             _ => {}
         }
 
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index fa7c2cdda68a8..fd401fde20454 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -701,13 +701,12 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
             }
 
             // These items live in the type namespace.
-            ItemKind::TyAlias(..) => {
-                let res = Res::Def(DefKind::TyAlias, self.r.definitions.local_def_id(item.id));
-                self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
-            }
-
-            ItemKind::OpaqueTy(_, _) => {
-                let res = Res::Def(DefKind::OpaqueTy, self.r.definitions.local_def_id(item.id));
+            ItemKind::TyAlias(ref ty, _) => {
+                let def_kind = match ty.kind.opaque_top_hack() {
+                    None => DefKind::TyAlias,
+                    Some(_) => DefKind::OpaqueTy,
+                };
+                let res = Res::Def(def_kind, self.r.definitions.local_def_id(item.id));
                 self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
             }
 
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 24d6331bbd37d..0a1b20074855c 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -732,7 +732,6 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
 
         match item.kind {
             ItemKind::TyAlias(_, ref generics) |
-            ItemKind::OpaqueTy(_, ref generics) |
             ItemKind::Fn(_, ref generics, _) => {
                 self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes),
                                             |this| visit::walk_item(this, item));
@@ -1087,18 +1086,6 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
 
                                                 this.visit_ty(ty);
                                             }
-                                            ImplItemKind::OpaqueTy(ref bounds) => {
-                                                // If this is a trait impl, ensure the type
-                                                // exists in trait
-                                                this.check_trait_item(impl_item.ident,
-                                                                      TypeNS,
-                                                                      impl_item.span,
-                                                    |n, s| TypeNotMemberOfTrait(n, s));
-
-                                                for bound in bounds {
-                                                    this.visit_param_bound(bound);
-                                                }
-                                            }
                                             ImplItemKind::Macro(_) =>
                                                 panic!("unexpanded macro in resolve!"),
                                         }
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 92c391fb4a338..5bec5b5eb6bfd 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -1133,12 +1133,6 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
                 // trait.
                 self.visit_ty(ty)
             }
-            ast::ImplItemKind::OpaqueTy(ref bounds) => {
-                // FIXME: uses of the assoc type should ideally point to this
-                // 'def' and the name here should be a ref to the def in the
-                // trait.
-                self.process_bounds(&bounds);
-            }
             ast::ImplItemKind::Macro(_) => {}
         }
     }
@@ -1384,38 +1378,6 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
                 self.visit_ty(&ty);
                 self.process_generic_params(ty_params, &qualname, item.id);
             }
-            OpaqueTy(ref bounds, ref ty_params) => {
-                let qualname = format!("::{}",
-                    self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
-
-                let value = String::new();
-                if !self.span.filter_generated(item.ident.span) {
-                    let span = self.span_from_span(item.ident.span);
-                    let id = id_from_node_id(item.id, &self.save_ctxt);
-                    let hir_id = self.tcx.hir().node_to_hir_id(item.id);
-
-                    self.dumper.dump_def(
-                        &access_from!(self.save_ctxt, item, hir_id),
-                        Def {
-                            kind: DefKind::Type,
-                            id,
-                            span,
-                            name: item.ident.to_string(),
-                            qualname: qualname.clone(),
-                            value,
-                            parent: None,
-                            children: vec![],
-                            decl_id: None,
-                            docs: self.save_ctxt.docs_for_attrs(&item.attrs),
-                            sig: sig::item_signature(item, &self.save_ctxt),
-                            attributes: lower_attributes(item.attrs.clone(), &self.save_ctxt),
-                        },
-                    );
-                }
-
-                self.process_bounds(bounds);
-                self.process_generic_params(ty_params, &qualname, item.id);
-            }
             Mac(_) => (),
             _ => visit::walk_item(self, item),
         }
diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs
index d1b9b8ff44ddb..50dfac62024b1 100644
--- a/src/librustc_save_analysis/sig.rs
+++ b/src/librustc_save_analysis/sig.rs
@@ -447,16 +447,6 @@ impl Sig for ast::Item {
 
                 Ok(merge_sigs(sig.text.clone(), vec![sig, ty]))
             }
-            ast::ItemKind::OpaqueTy(ref bounds, ref generics) => {
-                let text = "type ".to_owned();
-                let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?;
-
-                sig.text.push_str(" = impl ");
-                sig.text.push_str(&pprust::bounds_to_string(bounds));
-                sig.text.push(';');
-
-                Ok(sig)
-            }
             ast::ItemKind::Enum(_, ref generics) => {
                 let text = "enum ".to_owned();
                 let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?;
diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs
index ff9c945eec452..6e37c0dbbdf9d 100644
--- a/src/librustc_typeck/check/generator_interior.rs
+++ b/src/librustc_typeck/check/generator_interior.rs
@@ -244,7 +244,13 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
         // can be reborrowed without needing to spill to a temporary.
         // If this were not the case, then we could conceivably have
         // to create intermediate temporaries.)
-        let ty = self.fcx.tables.borrow().expr_ty(expr);
-        self.record(ty, scope, Some(expr), expr.span);
+        //
+        // The type table might not have information for this expression
+        // if it is in a malformed scope. (#66387)
+        if let Some(ty) = self.fcx.tables.borrow().expr_ty_opt(expr) {
+            self.record(ty, scope, Some(expr), expr.span);
+        } else {
+            self.fcx.tcx.sess.delay_span_bug(expr.span, "no type for node");
+        }
     }
 }
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 6b9a35fccc4dc..df24b6635f411 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -725,6 +725,9 @@ impl dyn Error {
     /// Returns an iterator starting with the current error and continuing with
     /// recursively calling [`source`].
     ///
+    /// If you want to omit the current error and only use its sources,
+    /// use `skip(1)`.
+    ///
     /// # Examples
     ///
     /// ```
@@ -763,7 +766,7 @@ impl dyn Error {
     /// // let err : Box<Error> = b.into(); // or
     /// let err = &b as &(dyn Error);
     ///
-    /// let mut iter = err.iter_chain();
+    /// let mut iter = err.chain();
     ///
     /// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
     /// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
@@ -774,98 +777,27 @@ impl dyn Error {
     /// [`source`]: trait.Error.html#method.source
     #[unstable(feature = "error_iter", issue = "58520")]
     #[inline]
-    pub fn iter_chain(&self) -> ErrorIter<'_> {
-        ErrorIter {
+    pub fn chain(&self) -> Chain<'_> {
+        Chain {
             current: Some(self),
         }
     }
-
-    /// Returns an iterator starting with the [`source`] of this error
-    /// and continuing with recursively calling [`source`].
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(error_iter)]
-    /// use std::error::Error;
-    /// use std::fmt;
-    ///
-    /// #[derive(Debug)]
-    /// struct A;
-    ///
-    /// #[derive(Debug)]
-    /// struct B(Option<Box<dyn Error + 'static>>);
-    ///
-    /// #[derive(Debug)]
-    /// struct C(Option<Box<dyn Error + 'static>>);
-    ///
-    /// impl fmt::Display for A {
-    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    ///         write!(f, "A")
-    ///     }
-    /// }
-    ///
-    /// impl fmt::Display for B {
-    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    ///         write!(f, "B")
-    ///     }
-    /// }
-    ///
-    /// impl fmt::Display for C {
-    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    ///         write!(f, "C")
-    ///     }
-    /// }
-    ///
-    /// impl Error for A {}
-    ///
-    /// impl Error for B {
-    ///     fn source(&self) -> Option<&(dyn Error + 'static)> {
-    ///         self.0.as_ref().map(|e| e.as_ref())
-    ///     }
-    /// }
-    ///
-    /// impl Error for C {
-    ///     fn source(&self) -> Option<&(dyn Error + 'static)> {
-    ///         self.0.as_ref().map(|e| e.as_ref())
-    ///     }
-    /// }
-    ///
-    /// let b = B(Some(Box::new(A)));
-    /// let c = C(Some(Box::new(b)));
-    ///
-    /// // let err : Box<Error> = c.into(); // or
-    /// let err = &c as &(dyn Error);
-    ///
-    /// let mut iter = err.iter_sources();
-    ///
-    /// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
-    /// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
-    /// assert!(iter.next().is_none());
-    /// assert!(iter.next().is_none());
-    /// ```
-    ///
-    /// [`source`]: trait.Error.html#method.source
-    #[inline]
-    #[unstable(feature = "error_iter", issue = "58520")]
-    pub fn iter_sources(&self) -> ErrorIter<'_> {
-        ErrorIter {
-            current: self.source(),
-        }
-    }
 }
 
-/// An iterator over [`Error`]
+/// An iterator over an [`Error`] and its sources.
+///
+/// If you want to omit the initial error and only process
+/// its sources, use `skip(1)`.
 ///
 /// [`Error`]: trait.Error.html
 #[unstable(feature = "error_iter", issue = "58520")]
 #[derive(Copy, Clone, Debug)]
-pub struct ErrorIter<'a> {
+pub struct Chain<'a> {
     current: Option<&'a (dyn Error + 'static)>,
 }
 
 #[unstable(feature = "error_iter", issue = "58520")]
-impl<'a> Iterator for ErrorIter<'a> {
+impl<'a> Iterator for Chain<'a> {
     type Item = &'a (dyn Error + 'static);
 
     fn next(&mut self) -> Option<Self::Item> {
diff --git a/src/libstd/future.rs b/src/libstd/future.rs
index c65f71fb1a4e2..6de3f1d545b57 100644
--- a/src/libstd/future.rs
+++ b/src/libstd/future.rs
@@ -40,10 +40,11 @@ impl<T: Generator<Yield = ()>> Future for GenFuture<T> {
     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         // Safe because we're !Unpin + !Drop mapping to a ?Unpin value
         let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) };
-        set_task_context(cx, || match gen.resume() {
+        let _guard = unsafe { set_task_context(cx) };
+        match gen.resume() {
             GeneratorState::Yielded(()) => Poll::Pending,
             GeneratorState::Complete(x) => Poll::Ready(x),
-        })
+        }
     }
 }
 
@@ -61,35 +62,23 @@ impl Drop for SetOnDrop {
     }
 }
 
-#[doc(hidden)]
-#[unstable(feature = "gen_future", issue = "50547")]
-/// Sets the thread-local task context used by async/await futures.
-pub fn set_task_context<F, R>(cx: &mut Context<'_>, f: F) -> R
-where
-    F: FnOnce() -> R
-{
+// Safety: the returned guard must drop before `cx` is dropped and before
+// any previous guard is dropped.
+unsafe fn set_task_context(cx: &mut Context<'_>) -> SetOnDrop {
     // transmute the context's lifetime to 'static so we can store it.
-    let cx = unsafe {
-        core::mem::transmute::<&mut Context<'_>, &mut Context<'static>>(cx)
-    };
+    let cx = core::mem::transmute::<&mut Context<'_>, &mut Context<'static>>(cx);
     let old_cx = TLS_CX.with(|tls_cx| {
         tls_cx.replace(Some(NonNull::from(cx)))
     });
-    let _reset = SetOnDrop(old_cx);
-    f()
+    SetOnDrop(old_cx)
 }
 
 #[doc(hidden)]
 #[unstable(feature = "gen_future", issue = "50547")]
-/// Retrieves the thread-local task context used by async/await futures.
-///
-/// This function acquires exclusive access to the task context.
-///
-/// Panics if no context has been set or if the context has already been
-/// retrieved by a surrounding call to get_task_context.
-pub fn get_task_context<F, R>(f: F) -> R
+/// Polls a future in the current thread-local task waker.
+pub fn poll_with_tls_context<F>(f: Pin<&mut F>) -> Poll<F::Output>
 where
-    F: FnOnce(&mut Context<'_>) -> R
+    F: Future
 {
     let cx_ptr = TLS_CX.with(|tls_cx| {
         // Clear the entry so that nested `get_task_waker` calls
@@ -108,15 +97,5 @@ where
     //
     // The pointer that was inserted came from an `&mut Context<'_>`,
     // so it is safe to treat as mutable.
-    unsafe { f(cx_ptr.as_mut()) }
-}
-
-#[doc(hidden)]
-#[unstable(feature = "gen_future", issue = "50547")]
-/// Polls a future in the current thread-local task waker.
-pub fn poll_with_tls_context<F>(f: Pin<&mut F>) -> Poll<F::Output>
-where
-    F: Future
-{
-    get_task_context(|cx| F::poll(f, cx))
+    unsafe { F::poll(f, cx_ptr.as_mut()) }
 }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 13bf6752ba2bc..d358efbe54364 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1579,7 +1579,6 @@ pub enum ImplItemKind {
     Const(P<Ty>, P<Expr>),
     Method(FnSig, P<Block>),
     TyAlias(P<Ty>),
-    OpaqueTy(GenericBounds),
     Macro(Mac),
 }
 
@@ -1816,6 +1815,15 @@ impl TyKind {
             false
         }
     }
+
+    /// HACK(type_alias_impl_trait, Centril): A temporary crutch used
+    /// in lowering to avoid making larger changes there and beyond.
+    pub fn opaque_top_hack(&self) -> Option<&GenericBounds> {
+        match self {
+            Self::ImplTrait(_, bounds) => Some(bounds),
+            _ => None,
+        }
+    }
 }
 
 /// Syntax used to declare a trait object.
@@ -2483,10 +2491,6 @@ pub enum ItemKind {
     ///
     /// E.g., `type Foo = Bar<u8>;`.
     TyAlias(P<Ty>, Generics),
-    /// An opaque `impl Trait` type alias.
-    ///
-    /// E.g., `type Foo = impl Bar + Boo;`.
-    OpaqueTy(GenericBounds, Generics),
     /// An enum definition (`enum`).
     ///
     /// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
@@ -2540,7 +2544,6 @@ impl ItemKind {
             ItemKind::ForeignMod(..) => "foreign module",
             ItemKind::GlobalAsm(..) => "global asm",
             ItemKind::TyAlias(..) => "type alias",
-            ItemKind::OpaqueTy(..) => "opaque type",
             ItemKind::Enum(..) => "enum",
             ItemKind::Struct(..) => "struct",
             ItemKind::Union(..) => "union",
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index d95dac9bf5242..bd836eee42af8 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -321,6 +321,27 @@ impl<'a> PostExpansionVisitor<'a> {
             );
         }
     }
+
+    /// Feature gate `impl Trait` inside `type Alias = $type_expr;`.
+    fn check_impl_trait(&self, ty: &ast::Ty) {
+        struct ImplTraitVisitor<'a> {
+            vis: &'a PostExpansionVisitor<'a>,
+        }
+        impl Visitor<'_> for ImplTraitVisitor<'_> {
+            fn visit_ty(&mut self, ty: &ast::Ty) {
+                if let ast::TyKind::ImplTrait(..) = ty.kind {
+                    gate_feature_post!(
+                        &self.vis,
+                        type_alias_impl_trait,
+                        ty.span,
+                        "`impl Trait` in type aliases is unstable"
+                    );
+                }
+                visit::walk_ty(self, ty);
+            }
+        }
+        ImplTraitVisitor { vis: self }.visit_ty(ty);
+    }
 }
 
 impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
@@ -455,14 +476,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                 gate_feature_post!(&self, decl_macro, i.span, msg);
             }
 
-            ast::ItemKind::OpaqueTy(..) => {
-                gate_feature_post!(
-                    &self,
-                    type_alias_impl_trait,
-                    i.span,
-                    "`impl Trait` in type aliases is unstable"
-                );
-            }
+            ast::ItemKind::TyAlias(ref ty, ..) => self.check_impl_trait(&ty),
 
             _ => {}
         }
@@ -636,9 +650,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                 }
             }
             ast::TraitItemKind::Type(_, ref default) => {
-                // We use three if statements instead of something like match guards so that all
-                // of these errors can be emitted if all cases apply.
-                if default.is_some() {
+                if let Some(ty) = default {
+                    self.check_impl_trait(ty);
                     gate_feature_post!(&self, associated_type_defaults, ti.span,
                                        "associated type defaults are unstable");
                 }
@@ -663,15 +676,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                                        "C-variadic functions are unstable");
                 }
             }
-            ast::ImplItemKind::OpaqueTy(..) => {
-                gate_feature_post!(
-                    &self,
-                    type_alias_impl_trait,
-                    ii.span,
-                    "`impl Trait` in type aliases is unstable"
-                );
-            }
-            ast::ImplItemKind::TyAlias(_) => {
+            ast::ImplItemKind::TyAlias(ref ty) => {
+                self.check_impl_trait(ty);
                 self.check_gat(&ii.generics, ii.span);
             }
             _ => {}
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index 376323a83eacc..f4ef993edb95a 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -887,10 +887,6 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
             vis.visit_ty(ty);
             vis.visit_generics(generics);
         }
-        ItemKind::OpaqueTy(bounds, generics) => {
-            visit_bounds(bounds, vis);
-            vis.visit_generics(generics);
-        }
         ItemKind::Enum(EnumDef { variants }, generics) => {
             variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
             vis.visit_generics(generics);
@@ -970,7 +966,6 @@ pub fn noop_flat_map_impl_item<T: MutVisitor>(mut item: ImplItem, visitor: &mut
             visitor.visit_block(body);
         }
         ImplItemKind::TyAlias(ty) => visitor.visit_ty(ty),
-        ImplItemKind::OpaqueTy(bounds) => visit_bounds(bounds, visitor),
         ImplItemKind::Macro(mac) => visitor.visit_mac(mac),
     }
     visitor.visit_span(span);
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index f154b7bde9821..ef65a744e83b0 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1255,19 +1255,6 @@ impl<'a> State<'a> {
                 self.s.word(";");
                 self.end(); // end the outer ibox
             }
-            ast::ItemKind::OpaqueTy(ref bounds, ref generics) => {
-                self.head(visibility_qualified(&item.vis, "type"));
-                self.print_ident(item.ident);
-                self.word_space("= impl");
-                self.print_generic_params(&generics.params);
-                self.end(); // end the inner ibox
-
-                self.print_where_clause(&generics.where_clause);
-                self.s.space();
-                self.print_type_bounds(":", bounds);
-                self.s.word(";");
-                self.end(); // end the outer ibox
-            }
             ast::ItemKind::Enum(ref enum_definition, ref params) => {
                 self.print_enum_def(
                     enum_definition,
@@ -1620,13 +1607,6 @@ impl<'a> State<'a> {
             ast::ImplItemKind::TyAlias(ref ty) => {
                 self.print_associated_type(ii.ident, None, Some(ty));
             }
-            ast::ImplItemKind::OpaqueTy(ref bounds) => {
-                self.word_space("type");
-                self.print_ident(ii.ident);
-                self.word_space("= impl");
-                self.print_type_bounds(":", bounds);
-                self.s.word(";");
-            }
             ast::ImplItemKind::Macro(ref mac) => {
                 self.print_mac(mac);
                 match mac.delim {
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index ea2dc357e6ebf..2597ffd750d77 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -263,10 +263,6 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
             visitor.visit_ty(typ);
             visitor.visit_generics(generics)
         }
-        ItemKind::OpaqueTy(ref bounds, ref generics) => {
-            walk_list!(visitor, visit_param_bound, bounds);
-            visitor.visit_generics(generics)
-        }
         ItemKind::Enum(ref enum_definition, ref generics) => {
             visitor.visit_generics(generics);
             visitor.visit_enum_def(enum_definition, generics, item.id, item.span)
@@ -628,9 +624,6 @@ pub fn walk_impl_item<'a, V: Visitor<'a>>(visitor: &mut V, impl_item: &'a ImplIt
         ImplItemKind::TyAlias(ref ty) => {
             visitor.visit_ty(ty);
         }
-        ImplItemKind::OpaqueTy(ref bounds) => {
-            walk_list!(visitor, visit_param_bound, bounds);
-        }
         ImplItemKind::Macro(ref mac) => {
             visitor.visit_mac(mac);
         }
diff --git a/src/test/run-make-fulldeps/sysroot-crates-are-unstable/Makefile b/src/test/run-make-fulldeps/sysroot-crates-are-unstable/Makefile
index a35174b3c2ac4..87bbab2427bc7 100644
--- a/src/test/run-make-fulldeps/sysroot-crates-are-unstable/Makefile
+++ b/src/test/run-make-fulldeps/sysroot-crates-are-unstable/Makefile
@@ -1,2 +1,2 @@
 all:
-	python2.7 test.py
+	python test.py
diff --git a/src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py b/src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py
index 855b6421cf822..927edff4c22a5 100644
--- a/src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py
+++ b/src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py
@@ -33,7 +33,7 @@ def check_lib(lib):
     print('verifying if {} is an unstable crate'.format(lib['name']))
     stdout, stderr = exec_command([os.environ['RUSTC'], '-', '--crate-type', 'rlib',
                                    '--extern', '{}={}'.format(lib['name'], lib['path'])],
-                                  to_input='extern crate {};'.format(lib['name']))
+                                  to_input=('extern crate {};'.format(lib['name'])).encode('utf-8'))
     if not 'use of unstable library feature' in '{}{}'.format(stdout, stderr):
         print('crate {} "{}" is not unstable'.format(lib['name'], lib['path']))
         print('{}{}'.format(stdout, stderr))
diff --git a/src/test/ui/async-await/issue-66387-if-without-else.rs b/src/test/ui/async-await/issue-66387-if-without-else.rs
new file mode 100644
index 0000000000000..aa5a8db61210d
--- /dev/null
+++ b/src/test/ui/async-await/issue-66387-if-without-else.rs
@@ -0,0 +1,10 @@
+// edition:2018
+async fn f() -> i32 {
+    if true { //~ ERROR if may be missing an else clause
+        return 0;
+    }
+    // An `if` block without `else` causes the type table not to have a type for this expr.
+    // Check that we do not unconditionally access the type table and we don't ICE.
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issue-66387-if-without-else.stderr b/src/test/ui/async-await/issue-66387-if-without-else.stderr
new file mode 100644
index 0000000000000..32952059525a0
--- /dev/null
+++ b/src/test/ui/async-await/issue-66387-if-without-else.stderr
@@ -0,0 +1,16 @@
+error[E0317]: if may be missing an else clause
+  --> $DIR/issue-66387-if-without-else.rs:3:5
+   |
+LL | /     if true {
+LL | |         return 0;
+LL | |     }
+   | |_____^ expected (), found i32
+   |
+   = note: expected type `()`
+              found type `i32`
+   = note: `if` expressions without `else` evaluate to `()`
+   = help: consider adding an `else` block that evaluates to the expected type
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0317`.
diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs
index b4c416b1c55f0..648caae30b427 100644
--- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs
+++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs
@@ -7,7 +7,8 @@ use std::cell::UnsafeCell;
 
 static mut FOO: u32 = 42;
 static BOO: () = unsafe {
-    FOO = 5; //~ ERROR cannot mutate statics in the initializer of another static
+    FOO = 5;
+    //~^ could not evaluate static initializer [E0080]
 };
 
 fn main() {}
diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr
index 02b72765b377e..cb4d35b9a1809 100644
--- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr
+++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr
@@ -1,8 +1,9 @@
-error: cannot mutate statics in the initializer of another static
+error[E0080]: could not evaluate static initializer
   --> $DIR/assign-to-static-within-other-static.rs:10:5
    |
 LL |     FOO = 5;
-   |     ^^^^^^^
+   |     ^^^^^^^ tried to modify a static's initial value from another static's initializer
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/error-codes/E0017.rs b/src/test/ui/error-codes/E0017.rs
index 71250eb4621f8..94b6587eb815a 100644
--- a/src/test/ui/error-codes/E0017.rs
+++ b/src/test/ui/error-codes/E0017.rs
@@ -4,6 +4,5 @@ const C: i32 = 2;
 const CR: &'static mut i32 = &mut C; //~ ERROR E0017
 static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
                                               //~| ERROR cannot borrow
-                                              //~| ERROR cannot mutate statics
 static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
 fn main() {}
diff --git a/src/test/ui/error-codes/E0017.stderr b/src/test/ui/error-codes/E0017.stderr
index 67ff7da611bb1..47863f0221405 100644
--- a/src/test/ui/error-codes/E0017.stderr
+++ b/src/test/ui/error-codes/E0017.stderr
@@ -10,12 +10,6 @@ error[E0017]: references in statics may only refer to immutable values
 LL | static STATIC_REF: &'static mut i32 = &mut X;
    |                                       ^^^^^^ statics require immutable values
 
-error: cannot mutate statics in the initializer of another static
-  --> $DIR/E0017.rs:5:39
-   |
-LL | static STATIC_REF: &'static mut i32 = &mut X;
-   |                                       ^^^^^^
-
 error[E0596]: cannot borrow immutable static item `X` as mutable
   --> $DIR/E0017.rs:5:39
    |
@@ -23,12 +17,12 @@ LL | static STATIC_REF: &'static mut i32 = &mut X;
    |                                       ^^^^^^ cannot borrow as mutable
 
 error[E0017]: references in statics may only refer to immutable values
-  --> $DIR/E0017.rs:8:38
+  --> $DIR/E0017.rs:7:38
    |
 LL | static CONST_REF: &'static mut i32 = &mut C;
    |                                      ^^^^^^ statics require immutable values
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0017, E0596.
 For more information about an error, try `rustc --explain E0017`.
diff --git a/src/test/ui/error-codes/E0388.rs b/src/test/ui/error-codes/E0388.rs
index 817f2554adef0..3aa4ac9655cc9 100644
--- a/src/test/ui/error-codes/E0388.rs
+++ b/src/test/ui/error-codes/E0388.rs
@@ -4,7 +4,6 @@ const C: i32 = 2;
 const CR: &'static mut i32 = &mut C; //~ ERROR E0017
 static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
                                               //~| ERROR cannot borrow
-                                              //~| ERROR cannot mutate statics
 static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
 
 fn main() {}
diff --git a/src/test/ui/error-codes/E0388.stderr b/src/test/ui/error-codes/E0388.stderr
index e0ca431673240..b52d5260b13c8 100644
--- a/src/test/ui/error-codes/E0388.stderr
+++ b/src/test/ui/error-codes/E0388.stderr
@@ -10,12 +10,6 @@ error[E0017]: references in statics may only refer to immutable values
 LL | static STATIC_REF: &'static mut i32 = &mut X;
    |                                       ^^^^^^ statics require immutable values
 
-error: cannot mutate statics in the initializer of another static
-  --> $DIR/E0388.rs:5:39
-   |
-LL | static STATIC_REF: &'static mut i32 = &mut X;
-   |                                       ^^^^^^
-
 error[E0596]: cannot borrow immutable static item `X` as mutable
   --> $DIR/E0388.rs:5:39
    |
@@ -23,12 +17,12 @@ LL | static STATIC_REF: &'static mut i32 = &mut X;
    |                                       ^^^^^^ cannot borrow as mutable
 
 error[E0017]: references in statics may only refer to immutable values
-  --> $DIR/E0388.rs:8:38
+  --> $DIR/E0388.rs:7:38
    |
 LL | static CONST_REF: &'static mut i32 = &mut C;
    |                                      ^^^^^^ statics require immutable values
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0017, E0596.
 For more information about an error, try `rustc --explain E0017`.
diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs
index 4a0c8c52c4ed7..6088331cded77 100644
--- a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs
+++ b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs
@@ -1,15 +1,45 @@
-type Foo = impl std::fmt::Debug; //~ ERROR `impl Trait` in type aliases is unstable
+use std::fmt::Debug;
+
+type Foo = impl Debug; //~ ERROR `impl Trait` in type aliases is unstable
 
 trait Bar {
-    type Baa: std::fmt::Debug;
+    type Baa: Debug;
     fn define() -> Self::Baa;
 }
 
 impl Bar for () {
-    type Baa = impl std::fmt::Debug; //~ ERROR `impl Trait` in type aliases is unstable
+    type Baa = impl Debug; //~ ERROR `impl Trait` in type aliases is unstable
     fn define() -> Self::Baa { 0 }
 }
 
 fn define() -> Foo { 0 }
 
+trait TraitWithDefault {
+    type Assoc = impl Debug;
+    //~^ ERROR associated type defaults are unstable
+    //~| ERROR `impl Trait` not allowed outside of function
+    //~| ERROR `impl Trait` in type aliases is unstable
+}
+
+type NestedFree = (Vec<impl Debug>, impl Debug, impl Iterator<Item = impl Debug>);
+//~^ ERROR `impl Trait` in type aliases is unstable
+//~| ERROR `impl Trait` in type aliases is unstable
+//~| ERROR `impl Trait` in type aliases is unstable
+//~| ERROR `impl Trait` in type aliases is unstable
+//~| ERROR `impl Trait` not allowed outside of function
+//~| ERROR `impl Trait` not allowed outside of function
+//~| ERROR `impl Trait` not allowed outside of function
+
+impl Bar for u8 {
+    type Baa = (Vec<impl Debug>, impl Debug, impl Iterator<Item = impl Debug>);
+    //~^ ERROR `impl Trait` in type aliases is unstable
+    //~| ERROR `impl Trait` in type aliases is unstable
+    //~| ERROR `impl Trait` in type aliases is unstable
+    //~| ERROR `impl Trait` in type aliases is unstable
+    //~| ERROR `impl Trait` not allowed outside of function
+    //~| ERROR `impl Trait` not allowed outside of function
+    //~| ERROR `impl Trait` not allowed outside of function
+    fn define() -> Self::Baa { (vec![true], 0u8, 0i32..1) }
+}
+
 fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr
index 2d0710ea37cf6..d9ebcdecb9bfd 100644
--- a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr
+++ b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr
@@ -1,21 +1,154 @@
 error[E0658]: `impl Trait` in type aliases is unstable
-  --> $DIR/feature-gate-type_alias_impl_trait.rs:1:1
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:3:12
    |
-LL | type Foo = impl std::fmt::Debug;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | type Foo = impl Debug;
+   |            ^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/63063
    = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
 
 error[E0658]: `impl Trait` in type aliases is unstable
-  --> $DIR/feature-gate-type_alias_impl_trait.rs:9:5
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:11:16
    |
-LL |     type Baa = impl std::fmt::Debug;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     type Baa = impl Debug;
+   |                ^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/63063
    = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
 
-error: aborting due to 2 previous errors
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:18:18
+   |
+LL |     type Assoc = impl Debug;
+   |                  ^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/63063
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+
+error[E0658]: associated type defaults are unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:18:5
+   |
+LL |     type Assoc = impl Debug;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29661
+   = help: add `#![feature(associated_type_defaults)]` to the crate attributes to enable
+
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:24:24
+   |
+LL | type NestedFree = (Vec<impl Debug>, impl Debug, impl Iterator<Item = impl Debug>);
+   |                        ^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/63063
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:24:37
+   |
+LL | type NestedFree = (Vec<impl Debug>, impl Debug, impl Iterator<Item = impl Debug>);
+   |                                     ^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/63063
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:24:49
+   |
+LL | type NestedFree = (Vec<impl Debug>, impl Debug, impl Iterator<Item = impl Debug>);
+   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/63063
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:24:70
+   |
+LL | type NestedFree = (Vec<impl Debug>, impl Debug, impl Iterator<Item = impl Debug>);
+   |                                                                      ^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/63063
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:34:21
+   |
+LL |     type Baa = (Vec<impl Debug>, impl Debug, impl Iterator<Item = impl Debug>);
+   |                     ^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/63063
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:34:34
+   |
+LL |     type Baa = (Vec<impl Debug>, impl Debug, impl Iterator<Item = impl Debug>);
+   |                                  ^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/63063
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:34:46
+   |
+LL |     type Baa = (Vec<impl Debug>, impl Debug, impl Iterator<Item = impl Debug>);
+   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/63063
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:34:67
+   |
+LL |     type Baa = (Vec<impl Debug>, impl Debug, impl Iterator<Item = impl Debug>);
+   |                                                                   ^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/63063
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:18:18
+   |
+LL |     type Assoc = impl Debug;
+   |                  ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:24:24
+   |
+LL | type NestedFree = (Vec<impl Debug>, impl Debug, impl Iterator<Item = impl Debug>);
+   |                        ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:24:37
+   |
+LL | type NestedFree = (Vec<impl Debug>, impl Debug, impl Iterator<Item = impl Debug>);
+   |                                     ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:24:49
+   |
+LL | type NestedFree = (Vec<impl Debug>, impl Debug, impl Iterator<Item = impl Debug>);
+   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:34:21
+   |
+LL |     type Baa = (Vec<impl Debug>, impl Debug, impl Iterator<Item = impl Debug>);
+   |                     ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:34:34
+   |
+LL |     type Baa = (Vec<impl Debug>, impl Debug, impl Iterator<Item = impl Debug>);
+   |                                  ^^^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:34:46
+   |
+LL |     type Baa = (Vec<impl Debug>, impl Debug, impl Iterator<Item = impl Debug>);
+   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 19 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0562, E0658.
+For more information about an error, try `rustc --explain E0562`.
diff --git a/src/test/ui/impl-trait/where-allowed.rs b/src/test/ui/impl-trait/where-allowed.rs
index 65c4b78bf6a40..5ab74e02e0e40 100644
--- a/src/test/ui/impl-trait/where-allowed.rs
+++ b/src/test/ui/impl-trait/where-allowed.rs
@@ -163,6 +163,7 @@ type InTypeAlias<R> = impl Debug;
 
 type InReturnInTypeAlias<R> = fn() -> impl Debug;
 //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~| ERROR `impl Trait` in type aliases is unstable
 
 // Disallowed in impl headers
 impl PartialEq<impl Debug> for () {
diff --git a/src/test/ui/impl-trait/where-allowed.stderr b/src/test/ui/impl-trait/where-allowed.stderr
index b01095f15a978..fcd4c357afdbe 100644
--- a/src/test/ui/impl-trait/where-allowed.stderr
+++ b/src/test/ui/impl-trait/where-allowed.stderr
@@ -17,19 +17,28 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic
    |                                                 outer `impl Trait`
 
 error[E0658]: `impl Trait` in type aliases is unstable
-  --> $DIR/where-allowed.rs:124:5
+  --> $DIR/where-allowed.rs:124:16
    |
 LL |     type Out = impl Debug;
-   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/63063
    = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
 
 error[E0658]: `impl Trait` in type aliases is unstable
-  --> $DIR/where-allowed.rs:160:1
+  --> $DIR/where-allowed.rs:160:23
    |
 LL | type InTypeAlias<R> = impl Debug;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/63063
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/where-allowed.rs:164:39
+   |
+LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
+   |                                       ^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/63063
    = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
@@ -179,61 +188,61 @@ LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    |                                       ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:168:16
+  --> $DIR/where-allowed.rs:169:16
    |
 LL | impl PartialEq<impl Debug> for () {
    |                ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:173:24
+  --> $DIR/where-allowed.rs:174:24
    |
 LL | impl PartialEq<()> for impl Debug {
    |                        ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:178:6
+  --> $DIR/where-allowed.rs:179:6
    |
 LL | impl impl Debug {
    |      ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:184:24
+  --> $DIR/where-allowed.rs:185:24
    |
 LL | impl InInherentImplAdt<impl Debug> {
    |                        ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:190:11
+  --> $DIR/where-allowed.rs:191:11
    |
 LL |     where impl Debug: Debug
    |           ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:197:15
+  --> $DIR/where-allowed.rs:198:15
    |
 LL |     where Vec<impl Debug>: Debug
    |               ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:204:24
+  --> $DIR/where-allowed.rs:205:24
    |
 LL |     where T: PartialEq<impl Debug>
    |                        ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:211:17
+  --> $DIR/where-allowed.rs:212:17
    |
 LL |     where T: Fn(impl Debug)
    |                 ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:218:22
+  --> $DIR/where-allowed.rs:219:22
    |
 LL |     where T: Fn() -> impl Debug
    |                      ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:224:29
+  --> $DIR/where-allowed.rs:225:29
    |
 LL |     let _in_local_variable: impl Fn() = || {};
    |                             ^^^^^^^^^
@@ -241,7 +250,7 @@ LL |     let _in_local_variable: impl Fn() = || {};
    = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:226:46
+  --> $DIR/where-allowed.rs:227:46
    |
 LL |     let _in_return_in_local_variable = || -> impl Fn() { || {} };
    |                                              ^^^^^^^^^
@@ -270,7 +279,7 @@ error: could not find defining uses
 LL |     type Out = impl Debug;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 43 previous errors
+error: aborting due to 44 previous errors
 
 Some errors have detailed explanations: E0282, E0562, E0658, E0666.
 For more information about an error, try `rustc --explain E0282`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr
index d98d349be3c84..c31d3912d9731 100644
--- a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr
@@ -1,8 +1,8 @@
 error: at least one trait must be specified
-  --> $DIR/generic_nondefining_use.rs:5:20
+  --> $DIR/generic_nondefining_use.rs:5:15
    |
 LL | type Cmp<T> = impl 'static;
-   |                    ^^^^^^^
+   |               ^^^^^^^^^^^^
 
 error: defining opaque type use does not fully define opaque type
   --> $DIR/generic_nondefining_use.rs:11:1
diff --git a/src/test/ui/type-alias-impl-trait/generic_not_used.stderr b/src/test/ui/type-alias-impl-trait/generic_not_used.stderr
index fe353f6e3d2a4..8015ff7eded90 100644
--- a/src/test/ui/type-alias-impl-trait/generic_not_used.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_not_used.stderr
@@ -1,8 +1,8 @@
 error: at least one trait must be specified
-  --> $DIR/generic_not_used.rs:5:38
+  --> $DIR/generic_not_used.rs:5:33
    |
 LL | type WrongGeneric<T: 'static> = impl 'static;
-   |                                      ^^^^^^^
+   |                                 ^^^^^^^^^^^^
 
 error: type parameter `V` is part of concrete type but not used in parameter list for the `impl Trait` type alias
   --> $DIR/generic_not_used.rs:8:73
diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr
index 3f25d5fbd9c46..b4ecf81ad8827 100644
--- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr
@@ -1,8 +1,8 @@
 error: at least one trait must be specified
-  --> $DIR/generic_type_does_not_live_long_enough.rs:9:29
+  --> $DIR/generic_type_does_not_live_long_enough.rs:9:24
    |
 LL | type WrongGeneric<T> = impl 'static;
-   |                             ^^^^^^^
+   |                        ^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/generic_type_does_not_live_long_enough.rs:6:18
diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr
index 12569211df368..d9600f1d1d6bc 100644
--- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr
@@ -1,8 +1,8 @@
 error: at least one trait must be specified
-  --> $DIR/generic_type_does_not_live_long_enough.rs:9:29
+  --> $DIR/generic_type_does_not_live_long_enough.rs:9:24
    |
 LL | type WrongGeneric<T> = impl 'static;
-   |                             ^^^^^^^
+   |                        ^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/generic_type_does_not_live_long_enough.rs:6:18
diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr
index 63c07224353e2..5f04391d7537f 100644
--- a/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr
@@ -1,8 +1,8 @@
 error: at least one trait must be specified
-  --> $DIR/generic_underconstrained.rs:6:40
+  --> $DIR/generic_underconstrained.rs:6:35
    |
 LL | type Underconstrained<T: Trait> = impl 'static;
-   |                                        ^^^^^^^
+   |                                   ^^^^^^^^^^^^
 
 error[E0277]: the trait bound `T: Trait` is not satisfied
   --> $DIR/generic_underconstrained.rs:6:1
diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr
index ba892f6ed7c7b..d4c7c7c74529e 100644
--- a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr
@@ -1,14 +1,14 @@
 error: at least one trait must be specified
-  --> $DIR/generic_underconstrained2.rs:5:50
+  --> $DIR/generic_underconstrained2.rs:5:45
    |
 LL | type Underconstrained<T: std::fmt::Debug> = impl 'static;
-   |                                                  ^^^^^^^
+   |                                             ^^^^^^^^^^^^
 
 error: at least one trait must be specified
-  --> $DIR/generic_underconstrained2.rs:14:51
+  --> $DIR/generic_underconstrained2.rs:14:46
    |
 LL | type Underconstrained2<T: std::fmt::Debug> = impl 'static;
-   |                                                   ^^^^^^^
+   |                                              ^^^^^^^^^^^^
 
 error[E0277]: `U` doesn't implement `std::fmt::Debug`
   --> $DIR/generic_underconstrained2.rs:5:1
diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.stderr b/src/test/ui/type-alias-impl-trait/issue-60371.stderr
index 1e9b12ebc39aa..cb35706a51e09 100644
--- a/src/test/ui/type-alias-impl-trait/issue-60371.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-60371.stderr
@@ -1,8 +1,8 @@
 error[E0658]: `impl Trait` in type aliases is unstable
-  --> $DIR/issue-60371.rs:8:5
+  --> $DIR/issue-60371.rs:8:17
    |
 LL |     type Item = impl Bug;
-   |     ^^^^^^^^^^^^^^^^^^^^^
+   |                 ^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/63063
    = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr
index 58028bd0861db..3f7acd3383010 100644
--- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr
@@ -1,8 +1,8 @@
 error: at least one trait must be specified
-  --> $DIR/type-alias-impl-trait-with-no-traits.rs:3:17
+  --> $DIR/type-alias-impl-trait-with-no-traits.rs:3:12
    |
 LL | type Foo = impl 'static;
-   |                 ^^^^^^^
+   |            ^^^^^^^^^^^^
 
 error: at least one trait must be specified
   --> $DIR/type-alias-impl-trait-with-no-traits.rs:10:13
diff --git a/src/test/ui/type-alias-impl-trait/unused_generic_param.stderr b/src/test/ui/type-alias-impl-trait/unused_generic_param.stderr
index 23105026964c1..9c63701ed3350 100644
--- a/src/test/ui/type-alias-impl-trait/unused_generic_param.stderr
+++ b/src/test/ui/type-alias-impl-trait/unused_generic_param.stderr
@@ -1,14 +1,14 @@
 error: at least one trait must be specified
-  --> $DIR/unused_generic_param.rs:6:33
+  --> $DIR/unused_generic_param.rs:6:28
    |
 LL | type PartiallyDefined<T> = impl 'static;
-   |                                 ^^^^^^^
+   |                            ^^^^^^^^^^^^
 
 error: at least one trait must be specified
-  --> $DIR/unused_generic_param.rs:13:34
+  --> $DIR/unused_generic_param.rs:13:29
    |
 LL | type PartiallyDefined2<T> = impl 'static;
-   |                                  ^^^^^^^
+   |                             ^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml
index 89bbde4d5a9e3..327de29037cc3 100644
--- a/src/tools/rustbook/Cargo.toml
+++ b/src/tools/rustbook/Cargo.toml
@@ -6,12 +6,15 @@ license = "MIT OR Apache-2.0"
 edition = "2018"
 
 [features]
-linkcheck = ["mdbook-linkcheck"]
+linkcheck = ["mdbook-linkcheck", "codespan-reporting"]
 
 [dependencies]
 clap = "2.25.0"
 failure = "0.1"
-mdbook-linkcheck = { version = "0.3.0", optional = true }
+mdbook-linkcheck = { version = "0.5.0", optional = true }
+# Keep in sync with mdbook-linkcheck.
+codespan-reporting = { version = "0.5", optional = true }
+
 
 # A noop dependency that changes in the Rust repository, it's a bit of a hack.
 # See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`
diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs
index d5dc9a79b5acb..fc28315669376 100644
--- a/src/tools/rustbook/src/main.rs
+++ b/src/tools/rustbook/src/main.rs
@@ -12,8 +12,6 @@ use mdbook::MDBook;
 use failure::Error;
 #[cfg(feature = "linkcheck")]
 use mdbook::renderer::RenderContext;
-#[cfg(feature = "linkcheck")]
-use mdbook_linkcheck::{self, errors::BrokenLinks};
 
 fn main() {
     let d_message = "-d, --dest-dir=[dest-dir]
@@ -57,26 +55,7 @@ fn main() {
             {
                 if let Err(err) = linkcheck(sub_matches) {
                     eprintln!("Error: {}", err);
-
-                    // HACK: ignore timeouts
-                    let actually_broken = err
-                        .downcast::<BrokenLinks>()
-                        .map(|broken_links| {
-                            broken_links
-                                .links()
-                                .iter()
-                                .inspect(|cause| eprintln!("\tCaused By: {}", cause))
-                                .fold(false, |already_broken, cause| {
-                                    already_broken || !format!("{}", cause).contains("timed out")
-                                })
-                        })
-                        .unwrap_or(false);
-
-                    if actually_broken {
-                        std::process::exit(101);
-                    } else {
-                        std::process::exit(0);
-                    }
+                    std::process::exit(101);
                 }
             }
 
@@ -99,8 +78,9 @@ pub fn linkcheck(args: &ArgMatches<'_>) -> Result<(), Error> {
     let book = MDBook::load(&book_dir).unwrap();
     let cfg = book.config;
     let render_ctx = RenderContext::new(&book_dir, book.book, cfg, &book_dir);
-
-    mdbook_linkcheck::check_links(&render_ctx)
+    let cache_file = render_ctx.destination.join("cache.json");
+    let color = codespan_reporting::term::termcolor::ColorChoice::Auto;
+    mdbook_linkcheck::run(&cache_file, color, &render_ctx)
 }
 
 // Build command implementation
@@ -124,11 +104,7 @@ fn get_book_dir(args: &ArgMatches<'_>) -> PathBuf {
     if let Some(dir) = args.value_of("dir") {
         // Check if path is relative from current dir, or absolute...
         let p = Path::new(dir);
-        if p.is_relative() {
-            env::current_dir().unwrap().join(dir)
-        } else {
-            p.to_path_buf()
-        }
+        if p.is_relative() { env::current_dir().unwrap().join(dir) } else { p.to_path_buf() }
     } else {
         env::current_dir().unwrap()
     }
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index e6ea1c75e2899..e65f7a62cacb7 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -55,6 +55,9 @@ const EXCEPTIONS: &[&str] = &[
     "sized-chunks",       // MPL-2.0+, cargo via im-rc
     // FIXME: this dependency violates the documentation comment above:
     "fortanix-sgx-abi",   // MPL-2.0+, libstd but only for `sgx` target
+    "dunce",              // CC0-1.0 mdbook-linkcheck
+    "codespan-reporting", // Apache-2.0 mdbook-linkcheck
+    "codespan",           // Apache-2.0 mdbook-linkcheck
 ];
 
 /// Which crates to check against the whitelist?