Rollup merge of #70713 - jsgf:rust-gdb-rustc, r=Mark-Simulacrum

Prefer sysroot from rustc in same directory as rust-gdb

If there isn't a rustc in the same directory, then fall back to searching
the path.
diff --git a/.gitmodules b/.gitmodules
index 003e50d..b2b580d 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -31,9 +31,9 @@
 [submodule "src/stdarch"]
 	path = src/stdarch
 	url = https://github.com/rust-lang/stdarch.git
-[submodule "src/doc/rustc-guide"]
-	path = src/doc/rustc-guide
-	url = https://github.com/rust-lang/rustc-guide.git
+[submodule "src/doc/rustc-dev-guide"]
+	path = src/doc/rustc-dev-guide
+	url = https://github.com/rust-lang/rustc-dev-guide.git
 [submodule "src/doc/edition-guide"]
 	path = src/doc/edition-guide
 	url = https://github.com/rust-lang/edition-guide.git
diff --git a/Cargo.lock b/Cargo.lock
index 15d016a..908bfa3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -88,12 +88,6 @@
 ]
 
 [[package]]
-name = "arrayref"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
-
-[[package]]
 name = "arrayvec"
 version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -187,11 +181,22 @@
 
 [[package]]
 name = "block-buffer"
-version = "0.3.3"
+version = "0.7.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"
+checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
 dependencies = [
- "arrayref",
+ "block-padding",
+ "byte-tools",
+ "byteorder",
+ "generic-array",
+]
+
+[[package]]
+name = "block-padding"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
+dependencies = [
  "byte-tools",
 ]
 
@@ -240,9 +245,9 @@
 
 [[package]]
 name = "byte-tools"
-version = "0.2.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
+checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
 
 [[package]]
 name = "bytecount"
@@ -897,9 +902,9 @@
 
 [[package]]
 name = "digest"
-version = "0.7.6"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
+checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
 dependencies = [
  "generic-array",
 ]
@@ -1226,9 +1231,9 @@
 
 [[package]]
 name = "generic-array"
-version = "0.9.0"
+version = "0.12.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
+checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
 dependencies = [
  "typenum",
 ]
@@ -1372,9 +1377,9 @@
 
 [[package]]
 name = "hermit-abi"
-version = "0.1.1"
+version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f22b8f315b98f415780ddbe9163c7dbbc5a07225b6d102ace1d8aeef85775140"
+checksum = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e"
 dependencies = [
  "compiler_builtins",
  "libc",
@@ -1963,6 +1968,17 @@
 checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
 
 [[package]]
+name = "md-5"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a18af3dcaf2b0219366cdb4e2af65a6101457b415c3d1a5c71dd9c2b7c77b9c8"
+dependencies = [
+ "block-buffer",
+ "digest",
+ "opaque-debug",
+]
+
+[[package]]
 name = "mdbook"
 version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2251,6 +2267,12 @@
 checksum = "d6a04cb71e910d0034815600180f62a95bf6e67942d7ab52a166a68c7d7e9cd0"
 
 [[package]]
+name = "opaque-debug"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
+
+[[package]]
 name = "open"
 version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2287,9 +2309,9 @@
 
 [[package]]
 name = "openssl-src"
-version = "111.6.1+1.1.1d"
+version = "111.8.1+1.1.1f"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c91b04cb43c1a8a90e934e0cd612e2a5715d976d2d6cff4490278a0cddf35005"
+checksum = "f04f0299a91de598dde58d2e99101895498dcf3d58896a3297798f28b27c8b72"
 dependencies = [
  "cc",
 ]
@@ -2467,9 +2489,9 @@
 
 [[package]]
 name = "pest_meta"
-version = "2.1.0"
+version = "2.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f5a3492a4ed208ffc247adcdcc7ba2a95be3104f58877d0d02f0df39bf3efb5e"
+checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
 dependencies = [
  "maplit",
  "pest",
@@ -2693,9 +2715,9 @@
 
 [[package]]
 name = "racer"
-version = "2.1.31"
+version = "2.1.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ff33fa15ac0384376741d16ddb05a65263dde4e2c5d0f7a9f3747db788764aa"
+checksum = "e805a6c323d08b26270f0276cef35608456916dc266ef27434edbe666eceeeb5"
 dependencies = [
  "bitflags",
  "clap",
@@ -2705,13 +2727,13 @@
  "lazy_static 1.4.0",
  "log",
  "rls-span",
+ "rustc-ap-rustc_ast",
  "rustc-ap-rustc_ast_pretty",
  "rustc-ap-rustc_data_structures",
  "rustc-ap-rustc_errors",
  "rustc-ap-rustc_parse",
  "rustc-ap-rustc_session",
  "rustc-ap-rustc_span",
- "rustc-ap-syntax",
 ]
 
 [[package]]
@@ -3091,6 +3113,7 @@
 dependencies = [
  "clippy_lints",
  "env_logger 0.7.1",
+ "failure",
  "futures",
  "log",
  "rand 0.7.3",
@@ -3134,9 +3157,9 @@
 
 [[package]]
 name = "rustc-ap-arena"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea82fa3d9a8add7422228ca1a2cbba0784fa8861f56148ff64da08b3c7921b03"
+checksum = "632704fb93ca8148957191e5d2d827082f93c4aa20cdd242fb46d8cca57029da"
 dependencies = [
  "rustc-ap-rustc_data_structures",
  "smallvec 1.0.0",
@@ -3144,28 +3167,64 @@
 
 [[package]]
 name = "rustc-ap-graphviz"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "638d0b2b3bcf99824e0cb5a25dbc547b61dc20942e11daf6a97e981918aa18e5"
+checksum = "bdd4689b814859c9f1b3e314ed2bde596acac428a256a16894635f600bed46b4"
 
 [[package]]
-name = "rustc-ap-rustc_ast_pretty"
-version = "642.0.0"
+name = "rustc-ap-rustc_ast"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d38bab04dd676dee6d2f9670506a18c31bfce38bf7f8420aa83eb1140ecde049"
+checksum = "101c1517d3fd19d083aaca5b113f9965e6ae353a0bb09c49959b0f62b95b75d9"
 dependencies = [
  "log",
  "rustc-ap-rustc_data_structures",
+ "rustc-ap-rustc_index",
+ "rustc-ap-rustc_lexer",
+ "rustc-ap-rustc_macros",
  "rustc-ap-rustc_span",
- "rustc-ap-syntax",
+ "rustc-ap-serialize",
+ "scoped-tls",
+ "smallvec 1.0.0",
+]
+
+[[package]]
+name = "rustc-ap-rustc_ast_passes"
+version = "651.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3ab3f5a7e939b37c99d8ca371f09b10bb5b5c85ad5d5b8d1d736ce8248c71be0"
+dependencies = [
+ "log",
+ "rustc-ap-rustc_ast",
+ "rustc-ap-rustc_ast_pretty",
+ "rustc-ap-rustc_attr",
+ "rustc-ap-rustc_data_structures",
+ "rustc-ap-rustc_errors",
+ "rustc-ap-rustc_feature",
+ "rustc-ap-rustc_parse",
+ "rustc-ap-rustc_session",
+ "rustc-ap-rustc_span",
+]
+
+[[package]]
+name = "rustc-ap-rustc_ast_pretty"
+version = "651.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05046d3a2b8de22b20bcda9a1c063dc5c1f2f721f042b6c2809df2d23c64a13e"
+dependencies = [
+ "log",
+ "rustc-ap-rustc_ast",
+ "rustc-ap-rustc_data_structures",
+ "rustc-ap-rustc_span",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_attr"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10b843ba8b1ed43739133047673b9f6a54d3b3b4d328d69c6ea89ff971395f35"
+checksum = "f00b7ccad6fc3628fb44950435772945a425575f9ea0b3708c536fe75623a6e8"
 dependencies = [
+ "rustc-ap-rustc_ast",
  "rustc-ap-rustc_ast_pretty",
  "rustc-ap-rustc_data_structures",
  "rustc-ap-rustc_errors",
@@ -3174,26 +3233,25 @@
  "rustc-ap-rustc_session",
  "rustc-ap-rustc_span",
  "rustc-ap-serialize",
- "rustc-ap-syntax",
  "smallvec 1.0.0",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_data_structures"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc3d1c6d0a80ab0c1df76405377cec0f3d5423fb5b0953a8eac70a2ad6c44df2"
+checksum = "4c6121ab6766644fa76b711f65d4c39f2e335488ab768324567fed0ed191166e"
 dependencies = [
  "bitflags",
  "cfg-if",
- "crossbeam-utils 0.6.5",
+ "crossbeam-utils 0.7.2",
  "ena",
  "indexmap",
  "jobserver",
  "lazy_static 1.4.0",
  "log",
  "measureme",
- "parking_lot 0.9.0",
+ "parking_lot 0.10.0",
  "rustc-ap-graphviz",
  "rustc-ap-rustc_index",
  "rustc-ap-serialize",
@@ -3207,9 +3265,9 @@
 
 [[package]]
 name = "rustc-ap-rustc_errors"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4909a1eca29331332257230f29120a8ff68c9e37d868c564fcd599e430cf8914"
+checksum = "adab84c842003ad1c8435fd71b8d0cc19bf0d702a8a2147d5be06e083db2d207"
 dependencies = [
  "annotate-snippets",
  "atty",
@@ -3224,10 +3282,32 @@
 ]
 
 [[package]]
-name = "rustc-ap-rustc_feature"
-version = "642.0.0"
+name = "rustc-ap-rustc_expand"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "63ab887a181d795cf5fd3edadf367760deafb90aefb844f168ab5255266e3478"
+checksum = "bb001df541ea02b65c8e294252530010c6f90e3c6a5716e8e24e58c12dd1cd86"
+dependencies = [
+ "log",
+ "rustc-ap-rustc_ast",
+ "rustc-ap-rustc_ast_passes",
+ "rustc-ap-rustc_ast_pretty",
+ "rustc-ap-rustc_attr",
+ "rustc-ap-rustc_data_structures",
+ "rustc-ap-rustc_errors",
+ "rustc-ap-rustc_feature",
+ "rustc-ap-rustc_lexer",
+ "rustc-ap-rustc_parse",
+ "rustc-ap-rustc_session",
+ "rustc-ap-rustc_span",
+ "rustc-ap-serialize",
+ "smallvec 1.0.0",
+]
+
+[[package]]
+name = "rustc-ap-rustc_feature"
+version = "651.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "446cc60613cc3b05d0bdbcab7feb02305790b5617fa43c532d51ae3223d677a4"
 dependencies = [
  "lazy_static 1.4.0",
  "rustc-ap-rustc_data_structures",
@@ -3236,15 +3316,15 @@
 
 [[package]]
 name = "rustc-ap-rustc_fs_util"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70814116df3c5fbec8f06f6a1d013ca481f620fd22a9475754e9bf3ee9ba70d8"
+checksum = "9ac99d6f67e7db3bb300895630e769ed41bd3e336c0e725870c70e676c1a5ff1"
 
 [[package]]
 name = "rustc-ap-rustc_index"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac1bf1d3cf3d119d41353d6fd229ef7272d5097bc0924de021c0294bf86d48bf"
+checksum = "5608c1cf50d2251b7e10a138cf6dd388e97f139b21c00b06a22d06f89c6591f6"
 dependencies = [
  "rustc-ap-serialize",
  "smallvec 1.0.0",
@@ -3252,20 +3332,19 @@
 
 [[package]]
 name = "rustc-ap-rustc_lexer"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4cda21a32cebdc11ec4f5393aa2fcde5ed1b2f673a8571e5a4dcdf07e4ae9cac"
+checksum = "74e9c1c6f5dc85977b3adb6fb556b2ff23354d1a12021da15eb1d36353458bde"
 dependencies = [
  "unicode-xid 0.2.0",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_macros"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75c47b48ea51910ecfd853c9248a9bf4c767bc823449ab6a1d864dff65fbae16"
+checksum = "3226b5ec864312a5d23eb40a5d621ee06bdc0754228d20d6eb76d4ddc4f2d4a1"
 dependencies = [
- "itertools 0.8.0",
  "proc-macro2 1.0.3",
  "quote 1.0.2",
  "syn 1.0.11",
@@ -3274,33 +3353,33 @@
 
 [[package]]
 name = "rustc-ap-rustc_parse"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abd88e89cd5b5d28dcd3a347a3d534c08627d9455570dc1a2d402cb8437b9d30"
+checksum = "ba3b042344c2280b50d5df0058d11379028a8f016a407e575bb3ea8b6c798049"
 dependencies = [
  "bitflags",
  "log",
+ "rustc-ap-rustc_ast",
  "rustc-ap-rustc_ast_pretty",
- "rustc-ap-rustc_attr",
  "rustc-ap-rustc_data_structures",
  "rustc-ap-rustc_errors",
  "rustc-ap-rustc_feature",
  "rustc-ap-rustc_lexer",
  "rustc-ap-rustc_session",
  "rustc-ap-rustc_span",
- "rustc-ap-syntax",
  "smallvec 1.0.0",
  "unicode-normalization",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_session"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b8487b4575fbb2d1fc6f1cd61225efd108a4d36817e6fb9b643d57fcae9cb12"
+checksum = "ff35ef4b5d9fbcb2fd539c7c908eb3cdd1f68ddbccd042945ef50ae65564f941"
 dependencies = [
  "log",
  "num_cpus",
+ "rustc-ap-rustc_ast",
  "rustc-ap-rustc_data_structures",
  "rustc-ap-rustc_errors",
  "rustc-ap-rustc_feature",
@@ -3309,14 +3388,13 @@
  "rustc-ap-rustc_span",
  "rustc-ap-rustc_target",
  "rustc-ap-serialize",
- "rustc-ap-syntax",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_span"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f69746c0d4c21bf20a5bb2bd247261a1aa8631f04202d7303352942dde70d987"
+checksum = "e323b1f4a824039886eed8e33cad20ea4f492a9f9b3c9441009797c91de3e87a"
 dependencies = [
  "cfg-if",
  "log",
@@ -3331,9 +3409,9 @@
 
 [[package]]
 name = "rustc-ap-rustc_target"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8bbc6ae09b5d42ec66edd520e8412e0615c53a7c93607fe33dc4abab60ba7c8b"
+checksum = "e161eb7b3a5b7993c6b480135296dc61476db80041d49dd446422742426e390b"
 dependencies = [
  "bitflags",
  "log",
@@ -3346,32 +3424,15 @@
 
 [[package]]
 name = "rustc-ap-serialize"
-version = "642.0.0"
+version = "651.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e13a1ead0252fc3d96da4c336a95950be6795f2b00c84a67ccadf26142f8cb41"
+checksum = "af510a659098d8c45a7303fb882fa780f4a87ec5f5d7a2053521e7d5d7f332c4"
 dependencies = [
  "indexmap",
  "smallvec 1.0.0",
 ]
 
 [[package]]
-name = "rustc-ap-syntax"
-version = "642.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1f59f48ca3a2ec16a7e82e718ed5aadf9c9e08cf63015d28b4e774767524a6a"
-dependencies = [
- "log",
- "rustc-ap-rustc_data_structures",
- "rustc-ap-rustc_index",
- "rustc-ap-rustc_lexer",
- "rustc-ap-rustc_macros",
- "rustc-ap-rustc_span",
- "rustc-ap-serialize",
- "scoped-tls",
- "smallvec 1.0.0",
-]
-
-[[package]]
 name = "rustc-demangle"
 version = "0.1.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3448,7 +3509,7 @@
 name = "rustc-workspace-hack"
 version = "1.0.0"
 dependencies = [
- "crossbeam-utils 0.6.5",
+ "crossbeam-utils 0.7.2",
  "serde",
  "serde_json",
  "smallvec 0.6.10",
@@ -3503,6 +3564,7 @@
 name = "rustc_ast_passes"
 version = "0.0.0"
 dependencies = [
+ "itertools 0.8.0",
  "log",
  "rustc_ast",
  "rustc_ast_pretty",
@@ -4155,11 +4217,13 @@
  "arena",
  "cfg-if",
  "log",
+ "md-5",
  "rustc_data_structures",
  "rustc_index",
  "rustc_macros",
  "scoped-tls",
  "serialize",
+ "sha-1",
  "unicode-width",
 ]
 
@@ -4346,7 +4410,7 @@
 
 [[package]]
 name = "rustfmt-nightly"
-version = "1.4.12"
+version = "1.4.13"
 dependencies = [
  "annotate-snippets",
  "bytecount",
@@ -4362,14 +4426,14 @@
  "lazy_static 1.4.0",
  "log",
  "regex",
+ "rustc-ap-rustc_ast",
  "rustc-ap-rustc_ast_pretty",
  "rustc-ap-rustc_data_structures",
  "rustc-ap-rustc_errors",
+ "rustc-ap-rustc_expand",
  "rustc-ap-rustc_parse",
  "rustc-ap-rustc_session",
  "rustc-ap-rustc_span",
- "rustc-ap-rustc_target",
- "rustc-ap-syntax",
  "rustc-workspace-hack",
  "rustfmt-config_proc_macro",
  "serde",
@@ -4535,14 +4599,14 @@
 
 [[package]]
 name = "sha-1"
-version = "0.7.0"
+version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51b9d1f3b5de8a167ab06834a7c883bd197f2191e1dda1a22d9ccfeedbf9aded"
+checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
 dependencies = [
  "block-buffer",
- "byte-tools",
  "digest",
  "fake-simd",
+ "opaque-debug",
 ]
 
 [[package]]
diff --git a/rustfmt.toml b/rustfmt.toml
index 8f4c901..9b2c082 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -20,7 +20,7 @@
     "src/doc/nomicon",
     "src/doc/reference",
     "src/doc/rust-by-example",
-    "src/doc/rustc-guide",
+    "src/doc/rustc-dev-guide",
     "src/llvm-project",
     "src/stdarch",
     "src/tools/cargo",
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 243cd3f..b14352d 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -1022,8 +1022,13 @@
             cargo.env("RUSTC_HOST_CRT_STATIC", x.to_string());
         }
 
-        if let Some(map) = self.build.debuginfo_map(GitRepo::Rustc) {
+        if let Some(map_to) = self.build.debuginfo_map_to(GitRepo::Rustc) {
+            let map = format!("{}={}", self.build.src.display(), map_to);
             cargo.env("RUSTC_DEBUGINFO_MAP", map);
+
+            // `rustc` needs to know the virtual `/rustc/$hash` we're mapping to,
+            // in order to opportunistically reverse it later.
+            cargo.env("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR", map_to);
         }
 
         // Enable usage of unstable features
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index ad494b8..32ce170 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -22,7 +22,7 @@
 use crate::builder::Cargo;
 use crate::dist;
 use crate::native;
-use crate::util::{exe, is_dylib};
+use crate::util::{exe, is_dylib, symlink_dir};
 use crate::{Compiler, GitRepo, Mode};
 
 use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
@@ -633,6 +633,30 @@
         };
         let _ = fs::remove_dir_all(&sysroot);
         t!(fs::create_dir_all(&sysroot));
+
+        // Symlink the source root into the same location inside the sysroot,
+        // where `rust-src` component would go (`$sysroot/lib/rustlib/src/rust`),
+        // so that any tools relying on `rust-src` also work for local builds,
+        // and also for translating the virtual `/rustc/$hash` back to the real
+        // directory (for running tests with `rust.remap-debuginfo = true`).
+        let sysroot_lib_rustlib_src = sysroot.join("lib/rustlib/src");
+        t!(fs::create_dir_all(&sysroot_lib_rustlib_src));
+        let sysroot_lib_rustlib_src_rust = sysroot_lib_rustlib_src.join("rust");
+        if let Err(e) = symlink_dir(&builder.config, &builder.src, &sysroot_lib_rustlib_src_rust) {
+            eprintln!(
+                "warning: creating symbolic link `{}` to `{}` failed with {}",
+                sysroot_lib_rustlib_src_rust.display(),
+                builder.src.display(),
+                e,
+            );
+            if builder.config.rust_remap_debuginfo {
+                eprintln!(
+                    "warning: some `src/test/ui` tests will fail when lacking `{}`",
+                    sysroot_lib_rustlib_src_rust.display(),
+                );
+            }
+        }
+
         INTERNER.intern_path(sysroot)
     }
 }
@@ -911,7 +935,11 @@
     }
     // Instruct Cargo to give us json messages on stdout, critically leaving
     // stderr as piped so we can get those pretty colors.
-    let mut message_format = String::from("json-render-diagnostics");
+    let mut message_format = if builder.config.json_output {
+        String::from("json")
+    } else {
+        String::from("json-render-diagnostics")
+    };
     if let Some(s) = &builder.config.rustc_error_format {
         message_format.push_str(",json-diagnostic-");
         message_format.push_str(s);
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 56164b7..1337094 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -48,6 +48,7 @@
     pub ignore_git: bool,
     pub exclude: Vec<PathBuf>,
     pub rustc_error_format: Option<String>,
+    pub json_output: bool,
     pub test_compare_mode: bool,
     pub llvm_libunwind: bool,
 
@@ -415,6 +416,7 @@
         let mut config = Config::default_opts();
         config.exclude = flags.exclude;
         config.rustc_error_format = flags.rustc_error_format;
+        config.json_output = flags.json_output;
         config.on_fail = flags.on_fail;
         config.stage = flags.stage;
         config.jobs = flags.jobs.map(threads_from_config);
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index eda26f7..5d6e401 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -31,6 +31,7 @@
     pub incremental: bool,
     pub exclude: Vec<PathBuf>,
     pub rustc_error_format: Option<String>,
+    pub json_output: bool,
     pub dry_run: bool,
 
     // This overrides the deny-warnings configuration option,
@@ -156,6 +157,7 @@
             "VALUE",
         );
         opts.optopt("", "error-format", "rustc error format", "FORMAT");
+        opts.optflag("", "json-output", "use message-format=json");
         opts.optopt(
             "",
             "llvm-skip-rebuild",
@@ -503,6 +505,7 @@
             dry_run: matches.opt_present("dry-run"),
             on_fail: matches.opt_str("on-fail"),
             rustc_error_format: matches.opt_str("error-format"),
+            json_output: matches.opt_present("json-output"),
             keep_stage: matches
                 .opt_strs("keep-stage")
                 .into_iter()
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 6436fa7..31bbd92 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -740,19 +740,18 @@
         self.config.jobs.unwrap_or_else(|| num_cpus::get() as u32)
     }
 
-    fn debuginfo_map(&self, which: GitRepo) -> Option<String> {
+    fn debuginfo_map_to(&self, which: GitRepo) -> Option<String> {
         if !self.config.rust_remap_debuginfo {
             return None;
         }
 
-        let path = match which {
+        match which {
             GitRepo::Rustc => {
                 let sha = self.rust_sha().unwrap_or(channel::CFG_RELEASE_NUM);
-                format!("/rustc/{}", sha)
+                Some(format!("/rustc/{}", sha))
             }
-            GitRepo::Llvm => String::from("/rustc/llvm"),
-        };
-        Some(format!("{}={}", self.src.display(), path))
+            GitRepo::Llvm => Some(String::from("/rustc/llvm")),
+        }
     }
 
     /// Returns the path to the C compiler for the target specified.
@@ -787,7 +786,8 @@
             base.push("-fno-omit-frame-pointer".into());
         }
 
-        if let Some(map) = self.debuginfo_map(which) {
+        if let Some(map_to) = self.debuginfo_map_to(which) {
+            let map = format!("{}={}", self.src.display(), map_to);
             let cc = self.cc(target);
             if cc.ends_with("clang") || cc.ends_with("gcc") {
                 base.push(format!("-fdebug-prefix-map={}", map));
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 2499856..0bf507f 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1532,7 +1532,7 @@
     const ONLY_HOSTS: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.path("src/doc/rustc-guide")
+        run.path("src/doc/rustc-dev-guide")
     }
 
     fn make_run(run: RunConfig<'_>) {
@@ -1540,14 +1540,14 @@
     }
 
     fn run(self, builder: &Builder<'_>) {
-        let src = builder.src.join("src/doc/rustc-guide");
+        let src = builder.src.join("src/doc/rustc-dev-guide");
         let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook);
         let toolstate = if try_run(builder, rustbook_cmd.arg("linkcheck").arg(&src)) {
             ToolState::TestPass
         } else {
             ToolState::TestFail
         };
-        builder.save_toolstate("rustc-guide", toolstate);
+        builder.save_toolstate("rustc-dev-guide", toolstate);
     }
 }
 
diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs
index f0e0f92..095c3c0 100644
--- a/src/bootstrap/toolstate.rs
+++ b/src/bootstrap/toolstate.rs
@@ -89,7 +89,7 @@
 static NIGHTLY_TOOLS: &[(&str, &str)] = &[
     ("miri", "src/tools/miri"),
     ("embedded-book", "src/doc/embedded-book"),
-    ("rustc-guide", "src/doc/rustc-guide"),
+    ("rustc-dev-guide", "src/doc/rustc-dev-guide"),
 ];
 
 fn print_error(tool: &str, submodule: &str) {
diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile
index 2a68a25..4ac5e23 100644
--- a/src/ci/docker/dist-various-1/Dockerfile
+++ b/src/ci/docker/dist-various-1/Dockerfile
@@ -72,6 +72,9 @@
 COPY dist-various-1/install-mipsel-musl.sh /build
 RUN ./install-mipsel-musl.sh
 
+COPY dist-various-1/install-aarch64-none-elf.sh /build
+RUN ./install-aarch64-none-elf.sh
+
 # Suppress some warnings in the openwrt toolchains we downloaded
 ENV STAGING_DIR=/tmp
 
@@ -140,6 +143,8 @@
 ENV TARGETS=$TARGETS,armv5te-unknown-linux-musleabi
 ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabihf
 ENV TARGETS=$TARGETS,aarch64-unknown-linux-musl
+ENV TARGETS=$TARGETS,aarch64-unknown-none
+ENV TARGETS=$TARGETS,aarch64-unknown-none-softfloat
 ENV TARGETS=$TARGETS,sparc64-unknown-linux-gnu
 ENV TARGETS=$TARGETS,x86_64-unknown-redox
 ENV TARGETS=$TARGETS,thumbv6m-none-eabi
@@ -178,6 +183,10 @@
     CC_armv7a_none_eabihf=arm-none-eabi-gcc \
     CFLAGS_armv7a_none_eabi=-march=armv7-a \
     CFLAGS_armv7a_none_eabihf=-march=armv7-a+vfpv3 \
+    CC_aarch64_unknown_none_softfloat=aarch64-none-elf-gcc \
+    CFLAGS_aarch64_unknown_none_softfloat=-mstrict-align -march=armv8-a+nofp+nosimd \
+    CC_aarch64_unknown_none=aarch64-none-elf-gcc \
+    CFLAGS_aarch64_unknown_none=-mstrict-align -march=armv8-a+fp+simd \
     CC_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-gcc \
     AR_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-ar \
     CXX_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-g++ \
diff --git a/src/ci/docker/dist-various-1/install-aarch64-none-elf.sh b/src/ci/docker/dist-various-1/install-aarch64-none-elf.sh
new file mode 100755
index 0000000..d72976c
--- /dev/null
+++ b/src/ci/docker/dist-various-1/install-aarch64-none-elf.sh
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+
+set -ex
+
+curl -L https://developer.arm.com/-/media/Files/downloads/gnu-a/9.2-2019.12/binrel/gcc-arm-9.2-2019.12-x86_64-aarch64-none-elf.tar.xz \
+| tar --extract --xz --strip 1 --directory /usr/local
diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh
index e57fe22..72325c7 100755
--- a/src/ci/docker/x86_64-gnu-tools/checktools.sh
+++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh
@@ -14,7 +14,7 @@
     src/doc/rust-by-example \
     src/doc/embedded-book \
     src/doc/edition-guide \
-    src/doc/rustc-guide \
+    src/doc/rustc-dev-guide \
     src/tools/clippy \
     src/tools/rls \
     src/tools/rustfmt \
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
new file mode 160000
index 0000000..66be765
--- /dev/null
+++ b/src/doc/rustc-dev-guide
@@ -0,0 +1 @@
+Subproject commit 66be765404efb82c6bc2735473cbd3472f777dc0
diff --git a/src/doc/rustc-guide b/src/doc/rustc-guide
deleted file mode 160000
index 5bd60bc..0000000
--- a/src/doc/rustc-guide
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 5bd60bc51efaec04e69e2e18b59678e2af066433
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index 0dc8137..8dc6257 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -257,9 +257,8 @@
 also produce slower code. Setting this to 1 may improve the performance of
 generated code, but may be slower to compile.
 
-The default, if not specified, is 16. This flag is ignored if
-[incremental](#incremental) is enabled, in which case an internal heuristic is
-used to split the crate.
+The default, if not specified, is 16 for non-incremental builds. For
+incremental builds the default is 256 which allows caching to be more granular.
 
 ## remark
 
diff --git a/src/doc/unstable-book/src/compiler-flags/src-hash-algorithm.md b/src/doc/unstable-book/src/compiler-flags/src-hash-algorithm.md
new file mode 100644
index 0000000..5a7d065
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/src-hash-algorithm.md
@@ -0,0 +1,11 @@
+# `src-hash-algorithm`
+
+The tracking issue for this feature is: [#70401](https://github.com/rust-lang/rust/issues/70401).
+
+------------------------
+
+The `-Z src-hash-algorithm` compiler flag controls which algorithm is used when hashing each source file. The hash is stored in the debug info and can be used by a debugger to verify the source code matches the executable.
+
+Supported hash algorithms are: `md5`, and `sha1`. Note that not all hash algorithms are supported by all debug info formats.
+
+By default, the compiler chooses the hash algorithm based on the target specification.
diff --git a/src/doc/unstable-book/src/language-features/generators.md b/src/doc/unstable-book/src/language-features/generators.md
index 8bc6241..7b865c9c 100644
--- a/src/doc/unstable-book/src/language-features/generators.md
+++ b/src/doc/unstable-book/src/language-features/generators.md
@@ -87,7 +87,7 @@
 
 The `Generator` trait in `std::ops` currently looks like:
 
-```
+```rust
 # #![feature(arbitrary_self_types, generator_trait)]
 # use std::ops::GeneratorState;
 # use std::pin::Pin;
@@ -107,7 +107,7 @@
 
 The return value of `resume`, `GeneratorState`, looks like:
 
-```
+```rust
 pub enum GeneratorState<Y, R> {
     Yielded(Y),
     Complete(R),
diff --git a/src/doc/unstable-book/src/library-features/llvm-asm.md b/src/doc/unstable-book/src/library-features/llvm-asm.md
index e07f716..da01d92 100644
--- a/src/doc/unstable-book/src/library-features/llvm-asm.md
+++ b/src/doc/unstable-book/src/library-features/llvm-asm.md
@@ -86,7 +86,7 @@
 
 Input and output operands follow the same format: `:
 "constraints1"(expr1), "constraints2"(expr2), ..."`. Output operand
-expressions must be mutable lvalues, or not yet assigned:
+expressions must be mutable place, or not yet assigned:
 
 ```rust
 # #![feature(llvm_asm)]
diff --git a/src/etc/generate-deriving-span-tests.py b/src/etc/generate-deriving-span-tests.py
index c42f942..a0ba47e 100755
--- a/src/etc/generate-deriving-span-tests.py
+++ b/src/etc/generate-deriving-span-tests.py
@@ -15,9 +15,6 @@
     os.path.join(os.path.dirname(__file__), '../test/ui/derives/'))
 
 TEMPLATE = """\
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 {error_deriving}
diff --git a/src/etc/test-float-parse/u64-pow2.rs b/src/etc/test-float-parse/u64-pow2.rs
index 1c9bda9..7e67e2b 100644
--- a/src/etc/test-float-parse/u64-pow2.rs
+++ b/src/etc/test-float-parse/u64-pow2.rs
@@ -1,7 +1,6 @@
 mod _common;
 
 use _common::validate;
-use std::u64;
 
 fn main() {
     for exp in 19..64 {
diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs
index 66575e3..d31c73c 100644
--- a/src/liballoc/alloc.rs
+++ b/src/liballoc/alloc.rs
@@ -4,7 +4,6 @@
 
 use core::intrinsics::{self, min_align_of_val, size_of_val};
 use core::ptr::{NonNull, Unique};
-use core::usize;
 
 #[stable(feature = "alloc_module", since = "1.28.0")]
 #[doc(inline)]
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 5406956..db74209 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -469,8 +469,8 @@
     #[inline]
     #[doc(hidden)]
     pub fn into_unique(b: Box<T>) -> Unique<T> {
+        let b = mem::ManuallyDrop::new(b);
         let mut unique = b.0;
-        mem::forget(b);
         // Box is kind-of a library type, but recognized as a "unique pointer" by
         // Stacked Borrows.  This function here corresponds to "reborrowing to
         // a raw pointer", but there is no actual reborrow here -- so
diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs
index 9908a30..a01e9b2 100644
--- a/src/liballoc/collections/binary_heap.rs
+++ b/src/liballoc/collections/binary_heap.rs
@@ -20,7 +20,6 @@
 //! ```
 //! use std::cmp::Ordering;
 //! use std::collections::BinaryHeap;
-//! use std::usize;
 //!
 //! #[derive(Copy, Clone, Eq, PartialEq)]
 //! struct State {
diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs
index bbeced1..7096896 100644
--- a/src/liballoc/collections/btree/map.rs
+++ b/src/liballoc/collections/btree/map.rs
@@ -4,9 +4,10 @@
 use core::hash::{Hash, Hasher};
 use core::iter::{FromIterator, FusedIterator, Peekable};
 use core::marker::PhantomData;
+use core::mem::{self, ManuallyDrop};
 use core::ops::Bound::{Excluded, Included, Unbounded};
 use core::ops::{Index, RangeBounds};
-use core::{fmt, mem, ptr};
+use core::{fmt, ptr};
 
 use super::node::{self, marker, ForceResult::*, Handle, InsertResult::*, NodeRef};
 use super::search::{self, SearchResult::*};
@@ -190,9 +191,9 @@
                             // We can't destructure subtree directly
                             // because BTreeMap implements Drop
                             let (subroot, sublength) = unsafe {
+                                let subtree = ManuallyDrop::new(subtree);
                                 let root = ptr::read(&subtree.root);
                                 let length = subtree.length;
-                                mem::forget(subtree);
                                 (root, length)
                             };
 
@@ -1515,15 +1516,14 @@
     type IntoIter = IntoIter<K, V>;
 
     fn into_iter(self) -> IntoIter<K, V> {
-        if self.root.is_none() {
-            mem::forget(self);
+        let me = ManuallyDrop::new(self);
+        if me.root.is_none() {
             return IntoIter { front: None, back: None, length: 0 };
         }
 
-        let root1 = unsafe { unwrap_unchecked(ptr::read(&self.root)).into_ref() };
-        let root2 = unsafe { unwrap_unchecked(ptr::read(&self.root)).into_ref() };
-        let len = self.length;
-        mem::forget(self);
+        let root1 = unsafe { unwrap_unchecked(ptr::read(&me.root)).into_ref() };
+        let root2 = unsafe { unwrap_unchecked(ptr::read(&me.root)).into_ref() };
+        let len = me.length;
 
         IntoIter {
             front: Some(root1.first_leaf_edge()),
@@ -1780,18 +1780,12 @@
     where
         F: FnMut(&K, &mut V) -> bool,
     {
-        while let Some(kv) = unsafe { self.next_kv() } {
-            let (k, v) = unsafe { ptr::read(&kv) }.into_kv_mut();
+        while let Some(mut kv) = unsafe { self.next_kv() } {
+            let (k, v) = kv.kv_mut();
             if pred(k, v) {
                 *self.length -= 1;
                 let (k, v, leaf_edge_location) = kv.remove_kv_tracking();
-                // `remove_kv_tracking` has either preserved or invalidated `self.cur_leaf_edge`
-                if let Some(node) = leaf_edge_location {
-                    match search::search_tree(node, &k) {
-                        search::SearchResult::Found(_) => unreachable!(),
-                        search::SearchResult::GoDown(leaf) => self.cur_leaf_edge = Some(leaf),
-                    }
-                };
+                self.cur_leaf_edge = Some(leaf_edge_location);
                 return Some((k, v));
             }
             self.cur_leaf_edge = Some(kv.next_leaf_edge());
@@ -2698,28 +2692,26 @@
 
 impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV> {
     /// Removes a key/value-pair from the map, and returns that pair, as well as
-    /// the whereabouts of the leaf edge corresponding to that former pair:
-    /// if None is returned, the leaf edge is still the left leaf edge of the KV handle;
-    /// if a node is returned, it heads the subtree where the leaf edge may be found.
+    /// the leaf edge corresponding to that former pair.
     fn remove_kv_tracking(
         self,
-    ) -> (K, V, Option<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>>) {
-        let mut levels_down_handled: isize;
-        let (small_leaf, old_key, old_val) = match self.force() {
+    ) -> (K, V, Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>) {
+        let (mut pos, old_key, old_val, was_internal) = match self.force() {
             Leaf(leaf) => {
-                levels_down_handled = 1; // handled at same level, but affects only the right side
                 let (hole, old_key, old_val) = leaf.remove();
-                (hole.into_node(), old_key, old_val)
+                (hole, old_key, old_val, false)
             }
             Internal(mut internal) => {
                 // Replace the location freed in the internal node with the next KV,
                 // and remove that next KV from its leaf.
-                levels_down_handled = unsafe { ptr::read(&internal).into_node().height() } as isize;
 
                 let key_loc = internal.kv_mut().0 as *mut K;
                 let val_loc = internal.kv_mut().1 as *mut V;
 
-                let to_remove = internal.right_edge().descend().first_leaf_edge().right_kv().ok();
+                // Deleting from the left side is typically faster since we can
+                // just pop an element from the end of the KV array without
+                // needing to shift the other values.
+                let to_remove = internal.left_edge().descend().last_leaf_edge().left_kv().ok();
                 let to_remove = unsafe { unwrap_unchecked(to_remove) };
 
                 let (hole, key, val) = to_remove.remove();
@@ -2727,50 +2719,69 @@
                 let old_key = unsafe { mem::replace(&mut *key_loc, key) };
                 let old_val = unsafe { mem::replace(&mut *val_loc, val) };
 
-                (hole.into_node(), old_key, old_val)
+                (hole, old_key, old_val, true)
             }
         };
 
         // Handle underflow
-        let mut cur_node = small_leaf.forget_type();
+        let mut cur_node = unsafe { ptr::read(&pos).into_node().forget_type() };
+        let mut at_leaf = true;
         while cur_node.len() < node::MIN_LEN {
             match handle_underfull_node(cur_node) {
-                AtRoot(root) => {
-                    cur_node = root;
-                    break;
-                }
-                EmptyParent(_) => unreachable!(),
-                Merged(parent) => {
-                    levels_down_handled -= 1;
+                AtRoot => break,
+                Merged(edge, merged_with_left, offset) => {
+                    // If we merged with our right sibling then our tracked
+                    // position has not changed. However if we merged with our
+                    // left sibling then our tracked position is now dangling.
+                    if at_leaf && merged_with_left {
+                        let idx = pos.idx() + offset;
+                        let node = match unsafe { ptr::read(&edge).descend().force() } {
+                            Leaf(leaf) => leaf,
+                            Internal(_) => unreachable!(),
+                        };
+                        pos = unsafe { Handle::new_edge(node, idx) };
+                    }
+
+                    let parent = edge.into_node();
                     if parent.len() == 0 {
                         // We must be at the root
-                        let root = parent.into_root_mut();
-                        root.pop_level();
-                        cur_node = root.as_mut();
+                        parent.into_root_mut().pop_level();
                         break;
                     } else {
                         cur_node = parent.forget_type();
+                        at_leaf = false;
                     }
                 }
-                Stole(internal_node) => {
-                    levels_down_handled -= 1;
-                    cur_node = internal_node.forget_type();
+                Stole(stole_from_left) => {
+                    // Adjust the tracked position if we stole from a left sibling
+                    if stole_from_left && at_leaf {
+                        // SAFETY: This is safe since we just added an element to our node.
+                        unsafe {
+                            pos.next_unchecked();
+                        }
+                    }
+
                     // This internal node might be underfull, but only if it's the root.
                     break;
                 }
             }
         }
 
-        let leaf_edge_location = if levels_down_handled > 0 { None } else { Some(cur_node) };
-        (old_key, old_val, leaf_edge_location)
+        // If we deleted from an internal node then we need to compensate for
+        // the earlier swap and adjust the tracked position to point to the
+        // next element.
+        if was_internal {
+            pos = unsafe { unwrap_unchecked(pos.next_kv().ok()).next_leaf_edge() };
+        }
+
+        (old_key, old_val, pos)
     }
 }
 
 enum UnderflowResult<'a, K, V> {
-    AtRoot(NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>),
-    EmptyParent(NodeRef<marker::Mut<'a>, K, V, marker::Internal>),
-    Merged(NodeRef<marker::Mut<'a>, K, V, marker::Internal>),
-    Stole(NodeRef<marker::Mut<'a>, K, V, marker::Internal>),
+    AtRoot,
+    Merged(Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::Edge>, bool, usize),
+    Stole(bool),
 }
 
 fn handle_underfull_node<K, V>(
@@ -2778,28 +2789,27 @@
 ) -> UnderflowResult<'_, K, V> {
     let parent = match node.ascend() {
         Ok(parent) => parent,
-        Err(root) => return AtRoot(root),
+        Err(_) => return AtRoot,
     };
 
     let (is_left, mut handle) = match parent.left_kv() {
         Ok(left) => (true, left),
-        Err(parent) => match parent.right_kv() {
-            Ok(right) => (false, right),
-            Err(parent) => {
-                return EmptyParent(parent.into_node());
-            }
-        },
+        Err(parent) => {
+            let right = unsafe { unwrap_unchecked(parent.right_kv().ok()) };
+            (false, right)
+        }
     };
 
     if handle.can_merge() {
-        Merged(handle.merge().into_node())
+        let offset = if is_left { handle.reborrow().left_edge().descend().len() + 1 } else { 0 };
+        Merged(handle.merge(), is_left, offset)
     } else {
         if is_left {
             handle.steal_left();
         } else {
             handle.steal_right();
         }
-        Stole(handle.into_node())
+        Stole(is_left)
     }
 }
 
diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs
index 11c1429..bc4e271 100644
--- a/src/liballoc/collections/btree/node.rs
+++ b/src/liballoc/collections/btree/node.rs
@@ -723,6 +723,11 @@
     pub fn into_node(self) -> Node {
         self.node
     }
+
+    /// Returns the position of this handle in the node.
+    pub fn idx(&self) -> usize {
+        self.idx
+    }
 }
 
 impl<BorrowType, K, V, NodeType> Handle<NodeRef<BorrowType, K, V, NodeType>, marker::KV> {
diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs
index 9453252..c17a37c 100644
--- a/src/liballoc/collections/vec_deque.rs
+++ b/src/liballoc/collections/vec_deque.rs
@@ -12,7 +12,7 @@
 use core::fmt;
 use core::hash::{Hash, Hasher};
 use core::iter::{once, repeat_with, FromIterator, FusedIterator};
-use core::mem::{self, replace};
+use core::mem::{self, replace, ManuallyDrop};
 use core::ops::Bound::{Excluded, Included, Unbounded};
 use core::ops::{Index, IndexMut, RangeBounds, Try};
 use core::ptr::{self, NonNull};
@@ -2898,12 +2898,12 @@
     /// This avoids reallocating where possible, but the conditions for that are
     /// strict, and subject to change, and so shouldn't be relied upon unless the
     /// `Vec<T>` came from `From<VecDeque<T>>` and hasn't been reallocated.
-    fn from(mut other: Vec<T>) -> Self {
+    fn from(other: Vec<T>) -> Self {
         unsafe {
+            let mut other = ManuallyDrop::new(other);
             let other_buf = other.as_mut_ptr();
             let mut buf = RawVec::from_raw_parts(other_buf, other.capacity());
             let len = other.len();
-            mem::forget(other);
 
             // We need to extend the buf if it's not a power of two, too small
             // or doesn't have at least one free space
@@ -2955,6 +2955,7 @@
         other.make_contiguous();
 
         unsafe {
+            let other = ManuallyDrop::new(other);
             let buf = other.buf.ptr();
             let len = other.len();
             let cap = other.cap();
@@ -2962,9 +2963,7 @@
             if other.head != 0 {
                 ptr::copy(buf.add(other.tail), buf, len);
             }
-            let out = Vec::from_raw_parts(buf, len, cap);
-            mem::forget(other);
-            out
+            Vec::from_raw_parts(buf, len, cap)
         }
     }
 }
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index 2bf4049..7ac6787 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -3,7 +3,7 @@
 
 use core::alloc::MemoryBlock;
 use core::cmp;
-use core::mem::{self, MaybeUninit};
+use core::mem::{self, ManuallyDrop, MaybeUninit};
 use core::ops::Drop;
 use core::ptr::{NonNull, Unique};
 use core::slice;
@@ -112,11 +112,10 @@
     }
 
     /// Converts a `Box<[T]>` into a `RawVec<T>`.
-    pub fn from_box(mut slice: Box<[T]>) -> Self {
+    pub fn from_box(slice: Box<[T]>) -> Self {
         unsafe {
-            let result = RawVec::from_raw_parts(slice.as_mut_ptr(), slice.len());
-            mem::forget(slice);
-            result
+            let mut slice = ManuallyDrop::new(slice);
+            RawVec::from_raw_parts(slice.as_mut_ptr(), slice.len())
         }
     }
 }
@@ -571,19 +570,21 @@
     ///
     /// # Safety
     ///
-    /// `shrink_to_fit(len)` must be called immediately prior to calling this function. This
-    /// implies, that `len` must be smaller than or equal to `self.capacity()`.
+    /// * `len` must be greater than or equal to the most recently requested capacity, and
+    /// * `len` must be less than or equal to `self.capacity()`.
+    ///
+    /// Note, that the requested capacity and `self.capacity()` could differ, as
+    /// an allocator could overallocate and return a greater memory block than requested.
     pub unsafe fn into_box(self, len: usize) -> Box<[MaybeUninit<T>]> {
+        // Sanity-check one half of the safety requirement (we cannot check the other half).
         debug_assert!(
             len <= self.capacity(),
             "`len` must be smaller than or equal to `self.capacity()`"
         );
 
-        // NOTE: not calling `capacity()` here; actually using the real `cap` field!
-        let slice = slice::from_raw_parts_mut(self.ptr() as *mut MaybeUninit<T>, len);
-        let output = Box::from_raw(slice);
-        mem::forget(self);
-        output
+        let me = ManuallyDrop::new(self);
+        let slice = slice::from_raw_parts_mut(me.ptr() as *mut MaybeUninit<T>, len);
+        Box::from_raw(slice)
     }
 }
 
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 6a78a73..9db997e 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -250,7 +250,6 @@
 use core::pin::Pin;
 use core::ptr::{self, NonNull};
 use core::slice::{self, from_raw_parts_mut};
-use core::usize;
 
 use crate::alloc::{box_free, handle_alloc_error, AllocInit, AllocRef, Global, Layout};
 use crate::string::String;
diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs
index d8fc1fac..a3d9c78 100644
--- a/src/liballoc/slice.rs
+++ b/src/liballoc/slice.rs
@@ -90,7 +90,6 @@
 use core::cmp::Ordering::{self, Less};
 use core::mem::{self, size_of};
 use core::ptr;
-use core::{u16, u32, u8};
 
 use crate::borrow::ToOwned;
 use crate::boxed::Box;
@@ -432,7 +431,7 @@
     ///
     /// ```should_panic
     /// // this will panic at runtime
-    /// b"0123456789abcdef".repeat(usize::max_value());
+    /// b"0123456789abcdef".repeat(usize::MAX);
     /// ```
     #[stable(feature = "repeat_generic_slice", since = "1.40.0")]
     pub fn repeat(&self, n: usize) -> Vec<T>
diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs
index 843a2f1..70860c0 100644
--- a/src/liballoc/str.rs
+++ b/src/liballoc/str.rs
@@ -499,7 +499,7 @@
     ///
     /// ```should_panic
     /// // this will panic at runtime
-    /// "0123456789abcdef".repeat(usize::max_value());
+    /// "0123456789abcdef".repeat(usize::MAX);
     /// ```
     #[stable(feature = "repeat_str", since = "1.16.0")]
     pub fn repeat(&self, n: usize) -> String {
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 111a765..1cfb26e 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -23,7 +23,6 @@
 use core::slice::{self, from_raw_parts_mut};
 use core::sync::atomic;
 use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};
-use core::{isize, usize};
 
 use crate::alloc::{box_free, handle_alloc_error, AllocInit, AllocRef, Global, Layout};
 use crate::boxed::Box;
diff --git a/src/liballoc/task.rs b/src/liballoc/task.rs
index 9810953..a64d5d7 100644
--- a/src/liballoc/task.rs
+++ b/src/liballoc/task.rs
@@ -12,10 +12,12 @@
 /// to the tasks that are executed on that executor.
 ///
 /// This trait is a memory-safe and ergonomic alternative to constructing a
-/// [`RawWaker`]. It supports the common executor design in which the data
-/// used to wake up a task is stored in an [`Arc`]. Some executors (especially
+/// [`RawWaker`]. It supports the common executor design in which the data used
+/// to wake up a task is stored in an [`Arc`][arc]. Some executors (especially
 /// those for embedded systems) cannot use this API, which is why [`RawWaker`]
 /// exists as an alternative for those systems.
+///
+/// [arc]: ../../std/sync/struct.Arc.html
 #[unstable(feature = "wake_trait", issue = "69912")]
 pub trait Wake {
     /// Wake this task.
diff --git a/src/liballoc/tests.rs b/src/liballoc/tests.rs
index 1b6e0bb..bddaab0 100644
--- a/src/liballoc/tests.rs
+++ b/src/liballoc/tests.rs
@@ -3,8 +3,6 @@
 use core::any::Any;
 use core::clone::Clone;
 use core::convert::TryInto;
-use core::f64;
-use core::i64;
 use core::ops::Deref;
 use core::result::Result::{Err, Ok};
 
diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs
index d2f09eb..6e2a5ab 100644
--- a/src/liballoc/tests/string.rs
+++ b/src/liballoc/tests/string.rs
@@ -1,7 +1,6 @@
 use std::borrow::Cow;
 use std::collections::TryReserveError::*;
 use std::mem::size_of;
-use std::{isize, usize};
 
 pub trait IntoCow<'a, B: ?Sized>
 where
diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs
index 9c4ac52..b63d817 100644
--- a/src/liballoc/tests/vec.rs
+++ b/src/liballoc/tests/vec.rs
@@ -3,7 +3,6 @@
 use std::mem::size_of;
 use std::panic::{catch_unwind, AssertUnwindSafe};
 use std::vec::{Drain, IntoIter};
-use std::{isize, usize};
 
 struct DropCounter<'a> {
     count: &'a mut u32,
@@ -1351,17 +1350,26 @@
 }
 
 #[test]
-fn test_stable_push_pop() {
+fn test_stable_pointers() {
+    /// Pull an element from the iterator, then drop it.
+    /// Useful to cover both the `next` and `drop` paths of an iterator.
+    fn next_then_drop<I: Iterator>(mut i: I) {
+        i.next().unwrap();
+        drop(i);
+    }
+
     // Test that, if we reserved enough space, adding and removing elements does not
     // invalidate references into the vector (such as `v0`).  This test also
     // runs in Miri, which would detect such problems.
-    let mut v = Vec::with_capacity(10);
+    let mut v = Vec::with_capacity(128);
     v.push(13);
 
-    // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
-    let v0 = unsafe { &*(&v[0] as *const _) };
-
+    // Laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
+    let v0 = &mut v[0];
+    let v0 = unsafe { &mut *(v0 as *mut _) };
     // Now do a bunch of things and occasionally use `v0` again to assert it is still valid.
+
+    // Pushing/inserting and popping/removing
     v.push(1);
     v.push(2);
     v.insert(1, 1);
@@ -1369,6 +1377,58 @@
     v.remove(1);
     v.pop().unwrap();
     assert_eq!(*v0, 13);
+    v.push(1);
+    v.swap_remove(1);
+    assert_eq!(v.len(), 2);
+    v.swap_remove(1); // swap_remove the last element
+    assert_eq!(*v0, 13);
+
+    // Appending
+    v.append(&mut vec![27, 19]);
+    assert_eq!(*v0, 13);
+
+    // Extending
+    v.extend_from_slice(&[1, 2]);
+    v.extend(&[1, 2]); // `slice::Iter` (with `T: Copy`) specialization
+    v.extend(vec![2, 3]); // `vec::IntoIter` specialization
+    v.extend(std::iter::once(3)); // `TrustedLen` specialization
+    v.extend(std::iter::empty::<i32>()); // `TrustedLen` specialization with empty iterator
+    v.extend(std::iter::once(3).filter(|_| true)); // base case
+    v.extend(std::iter::once(&3)); // `cloned` specialization
+    assert_eq!(*v0, 13);
+
+    // Truncation
+    v.truncate(2);
+    assert_eq!(*v0, 13);
+
+    // Resizing
+    v.resize_with(v.len() + 10, || 42);
+    assert_eq!(*v0, 13);
+    v.resize_with(2, || panic!());
+    assert_eq!(*v0, 13);
+
+    // No-op reservation
+    v.reserve(32);
+    v.reserve_exact(32);
+    assert_eq!(*v0, 13);
+
+    // Partial draining
+    v.resize_with(10, || 42);
+    next_then_drop(v.drain(5..));
+    assert_eq!(*v0, 13);
+
+    // Splicing
+    v.resize_with(10, || 42);
+    next_then_drop(v.splice(5.., vec![1, 2, 3, 4, 5])); // empty tail after range
+    assert_eq!(*v0, 13);
+    next_then_drop(v.splice(5..8, vec![1])); // replacement is smaller than original range
+    assert_eq!(*v0, 13);
+    next_then_drop(v.splice(5..6, vec![1; 10].into_iter().filter(|_| true))); // lower bound not exact
+    assert_eq!(*v0, 13);
+
+    // Smoke test that would fire even outside Miri if an actual relocation happened.
+    *v0 -= 13;
+    assert_eq!(v[0], 0);
 }
 
 // https://github.com/rust-lang/rust/pull/49496 introduced specialization based on:
diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs
index 101dd67..c287d56 100644
--- a/src/liballoc/tests/vec_deque.rs
+++ b/src/liballoc/tests/vec_deque.rs
@@ -3,7 +3,6 @@
 use std::fmt::Debug;
 use std::mem::size_of;
 use std::panic::{catch_unwind, AssertUnwindSafe};
-use std::{isize, usize};
 
 use crate::hash;
 
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 96a6399..a48e48d 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -66,7 +66,7 @@
 use core::intrinsics::{arith_offset, assume};
 use core::iter::{FromIterator, FusedIterator, TrustedLen};
 use core::marker::PhantomData;
-use core::mem;
+use core::mem::{self, ManuallyDrop};
 use core::ops::Bound::{Excluded, Included, Unbounded};
 use core::ops::{self, Index, IndexMut, RangeBounds};
 use core::ptr::{self, NonNull};
@@ -392,7 +392,7 @@
     /// ```
     #[unstable(feature = "vec_into_raw_parts", reason = "new API", issue = "65816")]
     pub fn into_raw_parts(self) -> (*mut T, usize, usize) {
-        let mut me = mem::ManuallyDrop::new(self);
+        let mut me = ManuallyDrop::new(self);
         (me.as_mut_ptr(), me.len(), me.capacity())
     }
 
@@ -678,9 +678,9 @@
     pub fn into_boxed_slice(mut self) -> Box<[T]> {
         unsafe {
             self.shrink_to_fit();
-            let buf = ptr::read(&self.buf);
-            let len = self.len();
-            mem::forget(self);
+            let me = ManuallyDrop::new(self);
+            let buf = ptr::read(&me.buf);
+            let len = me.len();
             buf.into_box(len).assume_init()
         }
     }
@@ -740,7 +740,8 @@
             if len > self.len {
                 return;
             }
-            let s = self.get_unchecked_mut(len..) as *mut _;
+            let remaining_len = self.len - len;
+            let s = slice::from_raw_parts_mut(self.as_mut_ptr().add(len), remaining_len);
             self.len = len;
             ptr::drop_in_place(s);
         }
@@ -963,13 +964,15 @@
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn swap_remove(&mut self, index: usize) -> T {
+        let len = self.len();
+        assert!(index < len);
         unsafe {
             // We replace self[index] with the last element. Note that if the
-            // bounds check on hole succeeds there must be a last element (which
+            // bounds check above succeeds there must be a last element (which
             // can be self[index] itself).
-            let hole: *mut T = &mut self[index];
-            let last = ptr::read(self.get_unchecked(self.len - 1));
-            self.len -= 1;
+            let last = ptr::read(self.as_ptr().add(len - 1));
+            let hole: *mut T = self.as_mut_ptr().add(index);
+            self.set_len(len - 1);
             ptr::replace(hole, last)
         }
     }
@@ -1200,7 +1203,7 @@
         } else {
             unsafe {
                 self.len -= 1;
-                Some(ptr::read(self.get_unchecked(self.len())))
+                Some(ptr::read(self.as_ptr().add(self.len())))
             }
         }
     }
@@ -1949,16 +1952,16 @@
     /// }
     /// ```
     #[inline]
-    fn into_iter(mut self) -> IntoIter<T> {
+    fn into_iter(self) -> IntoIter<T> {
         unsafe {
-            let begin = self.as_mut_ptr();
+            let mut me = ManuallyDrop::new(self);
+            let begin = me.as_mut_ptr();
             let end = if mem::size_of::<T>() == 0 {
-                arith_offset(begin as *const i8, self.len() as isize) as *const T
+                arith_offset(begin as *const i8, me.len() as isize) as *const T
             } else {
-                begin.add(self.len()) as *const T
+                begin.add(me.len()) as *const T
             };
-            let cap = self.buf.capacity();
-            mem::forget(self);
+            let cap = me.buf.capacity();
             IntoIter {
                 buf: NonNull::new_unchecked(begin),
                 phantom: PhantomData,
@@ -2020,7 +2023,7 @@
                 let (lower, _) = iterator.size_hint();
                 let mut vector = Vec::with_capacity(lower.saturating_add(1));
                 unsafe {
-                    ptr::write(vector.get_unchecked_mut(0), element);
+                    ptr::write(vector.as_mut_ptr(), element);
                     vector.set_len(1);
                 }
                 vector
@@ -2081,9 +2084,8 @@
         // has not been advanced at all.
         if iterator.buf.as_ptr() as *const _ == iterator.ptr {
             unsafe {
-                let vec = Vec::from_raw_parts(iterator.buf.as_ptr(), iterator.len(), iterator.cap);
-                mem::forget(iterator);
-                vec
+                let it = ManuallyDrop::new(iterator);
+                Vec::from_raw_parts(it.buf.as_ptr(), it.len(), it.cap)
             }
         } else {
             let mut vector = Vec::new();
@@ -2123,8 +2125,9 @@
         self.reserve(slice.len());
         unsafe {
             let len = self.len();
+            let dst_slice = slice::from_raw_parts_mut(self.as_mut_ptr().add(len), slice.len());
+            dst_slice.copy_from_slice(slice);
             self.set_len(len + slice.len());
-            self.get_unchecked_mut(len..).copy_from_slice(slice);
         }
     }
 }
@@ -2145,7 +2148,7 @@
                 self.reserve(lower.saturating_add(1));
             }
             unsafe {
-                ptr::write(self.get_unchecked_mut(len), element);
+                ptr::write(self.as_mut_ptr().add(len), element);
                 // NB can't overflow since we would have had to alloc the address space
                 self.set_len(len + 1);
             }
diff --git a/src/libcore/alloc/mod.rs b/src/libcore/alloc/mod.rs
index e8c4b68..e1892ed 100644
--- a/src/libcore/alloc/mod.rs
+++ b/src/libcore/alloc/mod.rs
@@ -33,9 +33,7 @@
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
 #[unstable(feature = "allocator_api", issue = "32838")]
 pub enum AllocInit {
-    /// The contents of the new memory are undefined.
-    ///
-    /// Reading uninitialized memory is Undefined Behavior; it must be initialized before use.
+    /// The contents of the new memory are uninitialized.
     Uninitialized,
     /// The new memory is guaranteed to be zeroed.
     Zeroed,
@@ -121,7 +119,7 @@
 ///
 /// Unlike [`GlobalAlloc`][], zero-sized allocations are allowed in `AllocRef`. If an underlying
 /// allocator does not support this (like jemalloc) or return a null pointer (such as
-/// `libc::malloc`), this case must be caught.
+/// `libc::malloc`), this must be caught by the implementation.
 ///
 /// ### Currently allocated memory
 ///
@@ -159,10 +157,10 @@
 /// # Safety
 ///
 /// * Memory blocks returned from an allocator must point to valid memory and retain their validity
-///   until the instance and all of its clones are dropped, and
+///   until the instance and all of its clones are dropped,
 ///
 /// * cloning or moving the allocator must not invalidate memory blocks returned from this
-///   allocator. A cloned allocator must behave like the same allocator.
+///   allocator. A cloned allocator must behave like the same allocator, and
 ///
 /// * any pointer to a memory block which is [*currently allocated*] may be passed to any other
 ///   method of the allocator.
@@ -170,7 +168,9 @@
 /// [*currently allocated*]: #currently-allocated-memory
 #[unstable(feature = "allocator_api", issue = "32838")]
 pub unsafe trait AllocRef {
-    /// On success, returns a memory block meeting the size and alignment guarantees of `layout`.
+    /// Attempts to allocate a block of memory.
+    ///
+    /// On success, returns a [`MemoryBlock`][] meeting the size and alignment guarantees of `layout`.
     ///
     /// The returned block may have a larger size than specified by `layout.size()` and is
     /// initialized as specified by [`init`], all the way up to the returned size of the block.
@@ -192,22 +192,26 @@
     /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
     fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr>;
 
-    /// Deallocates the memory denoted by `memory`.
+    /// Deallocates the memory referenced by `ptr`.
     ///
     /// # Safety
     ///
-    /// `memory` must be a memory block returned by this allocator.
+    /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator, and
+    /// * `layout` must [*fit*] that block of memory.
+    ///
+    /// [*currently allocated*]: #currently-allocated-memory
+    /// [*fit*]: #memory-fitting
     unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout);
 
     /// Attempts to extend the memory block.
     ///
-    /// Returns a new memory block containing a pointer and the actual size of the allocated
-    /// block. The pointer is suitable for holding data described by a new layout with `layout`’s
+    /// Returns a new [`MemoryBlock`][] containing a pointer and the actual size of the allocated
+    /// memory. The pointer is suitable for holding data described by a new layout with `layout`’s
     /// alignment and a size given by `new_size`. To accomplish this, the allocator may extend the
     /// allocation referenced by `ptr` to fit the new layout. If the [`placement`] is
     /// [`InPlace`], the returned pointer is guaranteed to be the same as the passed `ptr`.
     ///
-    /// If `ReallocPlacement::MayMove` is used then ownership of the memory block referenced by `ptr`
+    /// If [`MayMove`] is used then ownership of the memory block referenced by `ptr`
     /// is transferred to this allocator. The memory may or may not be freed, and should be
     /// considered unusable (unless of course it is transferred back to the caller again via the
     /// return value of this method).
@@ -225,19 +229,20 @@
     ///     the size of the `MemoryBlock` returned by the `grow` call.
     ///
     /// [`InPlace`]: ReallocPlacement::InPlace
+    /// [`MayMove`]: ReallocPlacement::MayMove
     /// [`placement`]: ReallocPlacement
     /// [`init`]: AllocInit
     ///
     /// # Safety
     ///
-    /// * `ptr` must be [*currently allocated*] via this allocator,
-    /// * `layout` must [*fit*] the `ptr`. (The `new_size` argument need not fit it.)
+    /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator,
+    /// * `layout` must [*fit*] that block of memory (The `new_size` argument need not fit it.),
     // We can't require that `new_size` is strictly greater than `memory.size` because of ZSTs.
     // An alternative would be
     // * `new_size must be strictly greater than `memory.size` or both are zero
-    /// * `new_size` must be greater than or equal to `layout.size()`
+    /// * `new_size` must be greater than or equal to `layout.size()`, and
     /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`, must not overflow
-    ///   (i.e., the rounded value must be less than `usize::MAX`).
+    ///   (i.e., the rounded value must be less than or equal to `usize::MAX`).
     ///
     /// [*currently allocated*]: #currently-allocated-memory
     /// [*fit*]: #memory-fitting
@@ -287,8 +292,8 @@
 
     /// Attempts to shrink the memory block.
     ///
-    /// Returns a new memory block containing a pointer and the actual size of the allocated
-    /// block. The pointer is suitable for holding data described by a new layout with `layout`’s
+    /// Returns a new [`MemoryBlock`][] containing a pointer and the actual size of the allocated
+    /// memory. The pointer is suitable for holding data described by a new layout with `layout`’s
     /// alignment and a size given by `new_size`. To accomplish this, the allocator may shrink the
     /// allocation referenced by `ptr` to fit the new layout. If the [`placement`] is
     /// [`InPlace`], the returned pointer is guaranteed to be the same as the passed `ptr`.
@@ -308,12 +313,12 @@
     ///
     /// # Safety
     ///
-    /// * `ptr` must be [*currently allocated*] via this allocator,
-    /// * `layout` must [*fit*] the `ptr`. (The `new_size` argument need not fit it.)
+    /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator,
+    /// * `layout` must [*fit*] that block of memory (The `new_size` argument need not fit it.), and
     // We can't require that `new_size` is strictly smaller than `memory.size` because of ZSTs.
     // An alternative would be
     // * `new_size must be strictly smaller than `memory.size` or both are zero
-    /// * `new_size` must be smaller than or equal to `layout.size()`
+    /// * `new_size` must be smaller than or equal to `layout.size()`.
     ///
     /// [*currently allocated*]: #currently-allocated-memory
     /// [*fit*]: #memory-fitting
@@ -321,7 +326,7 @@
     /// # Errors
     ///
     /// Returns `Err` if the new layout does not meet the allocator's size and alignment
-    /// constraints of the allocator, or if growing otherwise fails.
+    /// constraints of the allocator, or if shrinking otherwise fails.
     ///
     /// Implementations are encouraged to return `Err` on memory exhaustion rather than panicking or
     /// aborting, but this is not a strict requirement. (Specifically: it is *legal* to implement
diff --git a/src/libcore/benches/num/flt2dec/strategy/dragon.rs b/src/libcore/benches/num/flt2dec/strategy/dragon.rs
index 4052fec..4e1fd8b 100644
--- a/src/libcore/benches/num/flt2dec/strategy/dragon.rs
+++ b/src/libcore/benches/num/flt2dec/strategy/dragon.rs
@@ -1,6 +1,5 @@
 use super::super::*;
 use core::num::flt2dec::strategy::dragon::*;
-use std::{f64, i16};
 use test::Bencher;
 
 #[bench]
diff --git a/src/libcore/benches/num/flt2dec/strategy/grisu.rs b/src/libcore/benches/num/flt2dec/strategy/grisu.rs
index 4950747..77ca901 100644
--- a/src/libcore/benches/num/flt2dec/strategy/grisu.rs
+++ b/src/libcore/benches/num/flt2dec/strategy/grisu.rs
@@ -1,6 +1,5 @@
 use super::super::*;
 use core::num::flt2dec::strategy::grisu::*;
-use std::{f64, i16};
 use test::Bencher;
 
 pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs
index 9cc0109..6165941 100644
--- a/src/libcore/clone.rs
+++ b/src/libcore/clone.rs
@@ -169,7 +169,8 @@
 /// Implementations of `Clone` for primitive types.
 ///
 /// Implementations that cannot be described in Rust
-/// are implemented in `SelectionContext::copy_clone_conditions()` in librustc_middle.
+/// are implemented in `traits::SelectionContext::copy_clone_conditions()`
+/// in `rustc_trait_selection`.
 mod impls {
 
     use super::Clone;
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 604be7d..8c54213 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -817,7 +817,7 @@
     /// When comparison is impossible:
     ///
     /// ```
-    /// let result = std::f64::NAN.partial_cmp(&1.0);
+    /// let result = f64::NAN.partial_cmp(&1.0);
     /// assert_eq!(result, None);
     /// ```
     #[must_use]
diff --git a/src/libcore/convert/mod.rs b/src/libcore/convert/mod.rs
index 47ab871..eef9ee7 100644
--- a/src/libcore/convert/mod.rs
+++ b/src/libcore/convert/mod.rs
@@ -41,6 +41,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::fmt;
+use crate::hash::{Hash, Hasher};
 
 mod num;
 
@@ -746,3 +747,10 @@
         x
     }
 }
+
+#[stable(feature = "convert_infallible_hash", since = "1.44.0")]
+impl Hash for Infallible {
+    fn hash<H: Hasher>(&self, _: &mut H) {
+        match *self {}
+    }
+}
diff --git a/src/libcore/convert/num.rs b/src/libcore/convert/num.rs
index 752199c..66ae760 100644
--- a/src/libcore/convert/num.rs
+++ b/src/libcore/convert/num.rs
@@ -13,9 +13,9 @@
 /// Typically doesn’t need to be used directly.
 #[unstable(feature = "convert_float_to_int", issue = "67057")]
 pub trait FloatToInt<Int>: private::Sealed + Sized {
-    #[unstable(feature = "float_approx_unchecked_to", issue = "67058")]
+    #[unstable(feature = "convert_float_to_int", issue = "67057")]
     #[doc(hidden)]
-    unsafe fn approx_unchecked(self) -> Int;
+    unsafe fn to_int_unchecked(self) -> Int;
 }
 
 macro_rules! impl_float_to_int {
@@ -27,8 +27,15 @@
             impl FloatToInt<$Int> for $Float {
                 #[doc(hidden)]
                 #[inline]
-                unsafe fn approx_unchecked(self) -> $Int {
-                    crate::intrinsics::float_to_int_approx_unchecked(self)
+                unsafe fn to_int_unchecked(self) -> $Int {
+                    #[cfg(bootstrap)]
+                    {
+                        crate::intrinsics::float_to_int_approx_unchecked(self)
+                    }
+                    #[cfg(not(bootstrap))]
+                    {
+                        crate::intrinsics::float_to_int_unchecked(self)
+                    }
                 }
             }
         )+
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index fe728d4..95411b5 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -852,7 +852,7 @@
 ///     }
 /// }
 ///
-/// let l = Length(i32::max_value());
+/// let l = Length(i32::MAX);
 ///
 /// assert_eq!(format!("l as hex is: {:X}", l), "l as hex is: 7FFFFFFF");
 ///
diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
index 698c979..d406b3c 100644
--- a/src/libcore/hint.rs
+++ b/src/libcore/hint.rs
@@ -43,7 +43,7 @@
 ///
 /// assert_eq!(div_1(7, 0), 7);
 /// assert_eq!(div_1(9, 1), 4);
-/// assert_eq!(div_1(11, std::u32::MAX), 0);
+/// assert_eq!(div_1(11, u32::MAX), 0);
 /// ```
 #[inline]
 #[stable(feature = "unreachable", since = "1.27.0")]
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 0c95610..4a11fb3 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -1582,8 +1582,16 @@
     /// Convert with LLVM’s fptoui/fptosi, which may return undef for values out of range
     /// (<https://github.com/rust-lang/rust/issues/10184>)
     /// This is under stabilization at <https://github.com/rust-lang/rust/issues/67058>
+    #[cfg(bootstrap)]
     pub fn float_to_int_approx_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
 
+    /// Convert with LLVM’s fptoui/fptosi, which may return undef for values out of range
+    /// (<https://github.com/rust-lang/rust/issues/10184>)
+    ///
+    /// Stabilized as `f32::to_int_unchecked` and `f64::to_int_unchecked`.
+    #[cfg(not(bootstrap))]
+    pub fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+
     /// Returns the number of bits set in an integer type `T`
     ///
     /// The stabilized versions of this intrinsic are available on the integer
@@ -1731,11 +1739,11 @@
     pub fn mul_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
 
     /// Performs an exact division, resulting in undefined behavior where
-    /// `x % y != 0` or `y == 0` or `x == T::min_value() && y == -1`
+    /// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`
     pub fn exact_div<T: Copy>(x: T, y: T) -> T;
 
     /// Performs an unchecked division, resulting in undefined behavior
-    /// where y = 0 or x = `T::min_value()` and y = -1
+    /// where y = 0 or x = `T::MIN` and y = -1
     ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `checked_div` method. For example,
@@ -1743,7 +1751,7 @@
     #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
     pub fn unchecked_div<T: Copy>(x: T, y: T) -> T;
     /// Returns the remainder of an unchecked division, resulting in
-    /// undefined behavior where y = 0 or x = `T::min_value()` and y = -1
+    /// undefined behavior where y = 0 or x = `T::MIN` and y = -1
     ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `checked_rem` method. For example,
@@ -1769,17 +1777,17 @@
     pub fn unchecked_shr<T: Copy>(x: T, y: T) -> T;
 
     /// Returns the result of an unchecked addition, resulting in
-    /// undefined behavior when `x + y > T::max_value()` or `x + y < T::min_value()`.
+    /// undefined behavior when `x + y > T::MAX` or `x + y < T::MIN`.
     #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
     pub fn unchecked_add<T: Copy>(x: T, y: T) -> T;
 
     /// Returns the result of an unchecked subtraction, resulting in
-    /// undefined behavior when `x - y > T::max_value()` or `x - y < T::min_value()`.
+    /// undefined behavior when `x - y > T::MAX` or `x - y < T::MIN`.
     #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
     pub fn unchecked_sub<T: Copy>(x: T, y: T) -> T;
 
     /// Returns the result of an unchecked multiplication, resulting in
-    /// undefined behavior when `x * y > T::max_value()` or `x * y < T::min_value()`.
+    /// undefined behavior when `x * y > T::MAX` or `x * y < T::MIN`.
     #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
     pub fn unchecked_mul<T: Copy>(x: T, y: T) -> T;
 
diff --git a/src/libcore/iter/adapters/fuse.rs b/src/libcore/iter/adapters/fuse.rs
index a60ca64..23bc215 100644
--- a/src/libcore/iter/adapters/fuse.rs
+++ b/src/libcore/iter/adapters/fuse.rs
@@ -28,6 +28,22 @@
 #[stable(feature = "fused", since = "1.26.0")]
 impl<I> FusedIterator for Fuse<I> where I: Iterator {}
 
+/// Fuse the iterator if the expression is `None`.
+macro_rules! fuse {
+    ($self:ident . iter . $($call:tt)+) => {
+        match $self.iter {
+            Some(ref mut iter) => match iter.$($call)+ {
+                None => {
+                    $self.iter = None;
+                    None
+                }
+                item => item,
+            },
+            None => None,
+        }
+    };
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I> Iterator for Fuse<I>
 where
@@ -37,35 +53,36 @@
 
     #[inline]
     default fn next(&mut self) -> Option<<I as Iterator>::Item> {
-        let next = self.iter.as_mut()?.next();
-        if next.is_none() {
-            self.iter = None;
-        }
-        next
+        fuse!(self.iter.next())
     }
 
     #[inline]
     default fn nth(&mut self, n: usize) -> Option<I::Item> {
-        let nth = self.iter.as_mut()?.nth(n);
-        if nth.is_none() {
-            self.iter = None;
-        }
-        nth
+        fuse!(self.iter.nth(n))
     }
 
     #[inline]
     default fn last(self) -> Option<I::Item> {
-        self.iter?.last()
+        match self.iter {
+            Some(iter) => iter.last(),
+            None => None,
+        }
     }
 
     #[inline]
     default fn count(self) -> usize {
-        self.iter.map_or(0, I::count)
+        match self.iter {
+            Some(iter) => iter.count(),
+            None => 0,
+        }
     }
 
     #[inline]
     default fn size_hint(&self) -> (usize, Option<usize>) {
-        self.iter.as_ref().map_or((0, Some(0)), I::size_hint)
+        match self.iter {
+            Some(ref iter) => iter.size_hint(),
+            None => (0, Some(0)),
+        }
     }
 
     #[inline]
@@ -98,11 +115,7 @@
     where
         P: FnMut(&Self::Item) -> bool,
     {
-        let found = self.iter.as_mut()?.find(predicate);
-        if found.is_none() {
-            self.iter = None;
-        }
-        found
+        fuse!(self.iter.find(predicate))
     }
 }
 
@@ -113,20 +126,12 @@
 {
     #[inline]
     default fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
-        let next = self.iter.as_mut()?.next_back();
-        if next.is_none() {
-            self.iter = None;
-        }
-        next
+        fuse!(self.iter.next_back())
     }
 
     #[inline]
     default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
-        let nth = self.iter.as_mut()?.nth_back(n);
-        if nth.is_none() {
-            self.iter = None;
-        }
-        nth
+        fuse!(self.iter.nth_back(n))
     }
 
     #[inline]
@@ -159,11 +164,7 @@
     where
         P: FnMut(&Self::Item) -> bool,
     {
-        let found = self.iter.as_mut()?.rfind(predicate);
-        if found.is_none() {
-            self.iter = None;
-        }
-        found
+        fuse!(self.iter.rfind(predicate))
     }
 }
 
@@ -173,42 +174,30 @@
     I: ExactSizeIterator,
 {
     default fn len(&self) -> usize {
-        self.iter.as_ref().map_or(0, I::len)
+        match self.iter {
+            Some(ref iter) => iter.len(),
+            None => 0,
+        }
     }
 
     default fn is_empty(&self) -> bool {
-        self.iter.as_ref().map_or(true, I::is_empty)
+        match self.iter {
+            Some(ref iter) => iter.is_empty(),
+            None => true,
+        }
     }
 }
 
-// NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some`
-impl<I: FusedIterator> Fuse<I> {
-    #[inline(always)]
-    fn as_inner(&self) -> &I {
-        match self.iter {
-            Some(ref iter) => iter,
+// NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some`.
+// Implementing this as a directly-expanded macro helps codegen performance.
+macro_rules! unchecked {
+    ($self:ident) => {
+        match $self {
+            Fuse { iter: Some(iter) } => iter,
             // SAFETY: the specialized iterator never sets `None`
-            None => unsafe { intrinsics::unreachable() },
+            Fuse { iter: None } => unsafe { intrinsics::unreachable() },
         }
-    }
-
-    #[inline(always)]
-    fn as_inner_mut(&mut self) -> &mut I {
-        match self.iter {
-            Some(ref mut iter) => iter,
-            // SAFETY: the specialized iterator never sets `None`
-            None => unsafe { intrinsics::unreachable() },
-        }
-    }
-
-    #[inline(always)]
-    fn into_inner(self) -> I {
-        match self.iter {
-            Some(iter) => iter,
-            // SAFETY: the specialized iterator never sets `None`
-            None => unsafe { intrinsics::unreachable() },
-        }
-    }
+    };
 }
 
 #[stable(feature = "fused", since = "1.26.0")]
@@ -218,27 +207,27 @@
 {
     #[inline]
     fn next(&mut self) -> Option<<I as Iterator>::Item> {
-        self.as_inner_mut().next()
+        unchecked!(self).next()
     }
 
     #[inline]
     fn nth(&mut self, n: usize) -> Option<I::Item> {
-        self.as_inner_mut().nth(n)
+        unchecked!(self).nth(n)
     }
 
     #[inline]
     fn last(self) -> Option<I::Item> {
-        self.into_inner().last()
+        unchecked!(self).last()
     }
 
     #[inline]
     fn count(self) -> usize {
-        self.into_inner().count()
+        unchecked!(self).count()
     }
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        self.as_inner().size_hint()
+        unchecked!(self).size_hint()
     }
 
     #[inline]
@@ -248,7 +237,7 @@
         Fold: FnMut(Acc, Self::Item) -> R,
         R: Try<Ok = Acc>,
     {
-        self.as_inner_mut().try_fold(init, fold)
+        unchecked!(self).try_fold(init, fold)
     }
 
     #[inline]
@@ -256,7 +245,7 @@
     where
         Fold: FnMut(Acc, Self::Item) -> Acc,
     {
-        self.into_inner().fold(init, fold)
+        unchecked!(self).fold(init, fold)
     }
 
     #[inline]
@@ -264,7 +253,7 @@
     where
         P: FnMut(&Self::Item) -> bool,
     {
-        self.as_inner_mut().find(predicate)
+        unchecked!(self).find(predicate)
     }
 }
 
@@ -275,12 +264,12 @@
 {
     #[inline]
     fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
-        self.as_inner_mut().next_back()
+        unchecked!(self).next_back()
     }
 
     #[inline]
     fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
-        self.as_inner_mut().nth_back(n)
+        unchecked!(self).nth_back(n)
     }
 
     #[inline]
@@ -290,7 +279,7 @@
         Fold: FnMut(Acc, Self::Item) -> R,
         R: Try<Ok = Acc>,
     {
-        self.as_inner_mut().try_rfold(init, fold)
+        unchecked!(self).try_rfold(init, fold)
     }
 
     #[inline]
@@ -298,7 +287,7 @@
     where
         Fold: FnMut(Acc, Self::Item) -> Acc,
     {
-        self.into_inner().rfold(init, fold)
+        unchecked!(self).rfold(init, fold)
     }
 
     #[inline]
@@ -306,7 +295,7 @@
     where
         P: FnMut(&Self::Item) -> bool,
     {
-        self.as_inner_mut().rfind(predicate)
+        unchecked!(self).rfind(predicate)
     }
 }
 
@@ -316,11 +305,11 @@
     I: ExactSizeIterator + FusedIterator,
 {
     fn len(&self) -> usize {
-        self.as_inner().len()
+        unchecked!(self).len()
     }
 
     fn is_empty(&self) -> bool {
-        self.as_inner().is_empty()
+        unchecked!(self).is_empty()
     }
 }
 
diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs
index daa880e..c882981 100644
--- a/src/libcore/iter/traits/iterator.rs
+++ b/src/libcore/iter/traits/iterator.rs
@@ -198,7 +198,7 @@
     /// // and the maximum possible lower bound
     /// let iter = 0..;
     ///
-    /// assert_eq!((usize::max_value(), None), iter.size_hint());
+    /// assert_eq!((usize::MAX, None), iter.size_hint());
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -2920,7 +2920,7 @@
     /// assert_eq!([1.].iter().partial_cmp([1., 2.].iter()), Some(Ordering::Less));
     /// assert_eq!([1., 2.].iter().partial_cmp([1.].iter()), Some(Ordering::Greater));
     ///
-    /// assert_eq!([std::f64::NAN].iter().partial_cmp([1.].iter()), None);
+    /// assert_eq!([f64::NAN].iter().partial_cmp([1.].iter()), None);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
     fn partial_cmp<I>(self, other: I) -> Option<Ordering>
@@ -3170,7 +3170,7 @@
     /// assert!(![1, 3, 2, 4].iter().is_sorted());
     /// assert!([0].iter().is_sorted());
     /// assert!(std::iter::empty::<i32>().is_sorted());
-    /// assert!(![0.0, 1.0, std::f32::NAN].iter().is_sorted());
+    /// assert!(![0.0, 1.0, f32::NAN].iter().is_sorted());
     /// ```
     #[inline]
     #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
@@ -3197,7 +3197,7 @@
     /// assert!(![1, 3, 2, 4].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
     /// assert!([0].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
     /// assert!(std::iter::empty::<i32>().is_sorted_by(|a, b| a.partial_cmp(b)));
-    /// assert!(![0.0, 1.0, std::f32::NAN].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
+    /// assert!(![0.0, 1.0, f32::NAN].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
     /// ```
     ///
     /// [`is_sorted`]: trait.Iterator.html#method.is_sorted
diff --git a/src/libcore/macros/mod.rs b/src/libcore/macros/mod.rs
index f67762c..9c885ef 100644
--- a/src/libcore/macros/mod.rs
+++ b/src/libcore/macros/mod.rs
@@ -1070,8 +1070,10 @@
 
     /// Includes a utf8-encoded file as a string.
     ///
-    /// The file is located relative to the current file. (similarly to how
-    /// modules are found)
+    /// The file is located relative to the current file (similarly to how
+    /// modules are found). The provided path is interpreted in a platform-specific
+    /// way at compile time. So, for instance, an invocation with a Windows path
+    /// containing backslashes `\` would not compile correctly on Unix.
     ///
     /// This macro will yield an expression of type `&'static str` which is the
     /// contents of the file.
@@ -1108,8 +1110,10 @@
 
     /// Includes a file as a reference to a byte array.
     ///
-    /// The file is located relative to the current file. (similarly to how
-    /// modules are found)
+    /// The file is located relative to the current file (similarly to how
+    /// modules are found). The provided path is interpreted in a platform-specific
+    /// way at compile time. So, for instance, an invocation with a Windows path
+    /// containing backslashes `\` would not compile correctly on Unix.
     ///
     /// This macro will yield an expression of type `&'static [u8; N]` which is
     /// the contents of the file.
@@ -1202,7 +1206,9 @@
     /// Parses a file as an expression or an item according to the context.
     ///
     /// The file is located relative to the current file (similarly to how
-    /// modules are found).
+    /// modules are found). The provided path is interpreted in a platform-specific
+    /// way at compile time. So, for instance, an invocation with a Windows path
+    /// containing backslashes `\` would not compile correctly on Unix.
     ///
     /// Using this macro is often a bad idea, because if the file is
     /// parsed as an expression, it is going to be placed in the
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 9b13766..35bceaa 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -759,7 +759,8 @@
 /// Implementations of `Copy` for primitive types.
 ///
 /// Implementations that cannot be described in Rust
-/// are implemented in `SelectionContext::copy_clone_conditions()` in librustc_middle.
+/// are implemented in `traits::SelectionContext::copy_clone_conditions()`
+/// in `rustc_trait_selection`.
 mod copy_impls {
 
     use super::Copy;
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 3fdc2ba..6be108f 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -394,9 +394,7 @@
     /// Converts radians to degrees.
     ///
     /// ```
-    /// use std::f32::consts;
-    ///
-    /// let angle = consts::PI;
+    /// let angle = std::f32::consts::PI;
     ///
     /// let abs_difference = (angle.to_degrees() - 180.0).abs();
     ///
@@ -413,11 +411,9 @@
     /// Converts degrees to radians.
     ///
     /// ```
-    /// use std::f32::consts;
-    ///
     /// let angle = 180.0f32;
     ///
-    /// let abs_difference = (angle.to_radians() - consts::PI).abs();
+    /// let abs_difference = (angle.to_radians() - std::f32::consts::PI).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
@@ -464,15 +460,13 @@
     /// assuming that the value is finite and fits in that type.
     ///
     /// ```
-    /// #![feature(float_approx_unchecked_to)]
-    ///
     /// let value = 4.6_f32;
-    /// let rounded = unsafe { value.approx_unchecked_to::<u16>() };
+    /// let rounded = unsafe { value.to_int_unchecked::<u16>() };
     /// assert_eq!(rounded, 4);
     ///
     /// let value = -128.9_f32;
-    /// let rounded = unsafe { value.approx_unchecked_to::<i8>() };
-    /// assert_eq!(rounded, std::i8::MIN);
+    /// let rounded = unsafe { value.to_int_unchecked::<i8>() };
+    /// assert_eq!(rounded, i8::MIN);
     /// ```
     ///
     /// # Safety
@@ -482,13 +476,13 @@
     /// * Not be `NaN`
     /// * Not be infinite
     /// * Be representable in the return type `Int`, after truncating off its fractional part
-    #[unstable(feature = "float_approx_unchecked_to", issue = "67058")]
+    #[stable(feature = "float_approx_unchecked_to", since = "1.44.0")]
     #[inline]
-    pub unsafe fn approx_unchecked_to<Int>(self) -> Int
+    pub unsafe fn to_int_unchecked<Int>(self) -> Int
     where
         Self: FloatToInt<Int>,
     {
-        FloatToInt::<Int>::approx_unchecked(self)
+        FloatToInt::<Int>::to_int_unchecked(self)
     }
 
     /// Raw transmutation to `u32`.
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 129df93..da22ba8 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -407,9 +407,7 @@
     /// Converts radians to degrees.
     ///
     /// ```
-    /// use std::f64::consts;
-    ///
-    /// let angle = consts::PI;
+    /// let angle = std::f64::consts::PI;
     ///
     /// let abs_difference = (angle.to_degrees() - 180.0).abs();
     ///
@@ -427,11 +425,9 @@
     /// Converts degrees to radians.
     ///
     /// ```
-    /// use std::f64::consts;
-    ///
     /// let angle = 180.0_f64;
     ///
-    /// let abs_difference = (angle.to_radians() - consts::PI).abs();
+    /// let abs_difference = (angle.to_radians() - std::f64::consts::PI).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
@@ -478,15 +474,13 @@
     /// assuming that the value is finite and fits in that type.
     ///
     /// ```
-    /// #![feature(float_approx_unchecked_to)]
-    ///
     /// let value = 4.6_f32;
-    /// let rounded = unsafe { value.approx_unchecked_to::<u16>() };
+    /// let rounded = unsafe { value.to_int_unchecked::<u16>() };
     /// assert_eq!(rounded, 4);
     ///
     /// let value = -128.9_f32;
-    /// let rounded = unsafe { value.approx_unchecked_to::<i8>() };
-    /// assert_eq!(rounded, std::i8::MIN);
+    /// let rounded = unsafe { value.to_int_unchecked::<i8>() };
+    /// assert_eq!(rounded, i8::MIN);
     /// ```
     ///
     /// # Safety
@@ -496,13 +490,13 @@
     /// * Not be `NaN`
     /// * Not be infinite
     /// * Be representable in the return type `Int`, after truncating off its fractional part
-    #[unstable(feature = "float_approx_unchecked_to", issue = "67058")]
+    #[stable(feature = "float_approx_unchecked_to", since = "1.44.0")]
     #[inline]
-    pub unsafe fn approx_unchecked_to<Int>(self) -> Int
+    pub unsafe fn to_int_unchecked<Int>(self) -> Int
     where
         Self: FloatToInt<Int>,
     {
-        FloatToInt::<Int>::approx_unchecked(self)
+        FloatToInt::<Int>::to_int_unchecked(self)
     }
 
     /// Raw transmutation to `u64`.
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 853092d..7ba4004 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -174,7 +174,7 @@
 /// let zero = Wrapping(0u32);
 /// let one = Wrapping(1u32);
 ///
-/// assert_eq!(std::u32::MAX, (zero - one).0);
+/// assert_eq!(u32::MAX, (zero - one).0);
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)]
@@ -4376,7 +4376,7 @@
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     #[inline]
     pub fn to_ascii_uppercase(&self) -> u8 {
-        // Unset the fith bit if this is a lowercase letter
+        // Unset the fifth bit if this is a lowercase letter
         *self & !((self.is_ascii_lowercase() as u8) << 5)
     }
 
@@ -4399,7 +4399,7 @@
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     #[inline]
     pub fn to_ascii_lowercase(&self) -> u8 {
-        // Set the fith bit if this is an uppercase letter
+        // Set the fifth bit if this is an uppercase letter
         *self | ((self.is_ascii_uppercase() as u8) << 5)
     }
 
diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs
index adee8ce..d4e6048 100644
--- a/src/libcore/ops/range.rs
+++ b/src/libcore/ops/range.rs
@@ -98,8 +98,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// assert!(!(3..5).contains(&2));
     /// assert!( (3..5).contains(&3));
     /// assert!( (3..5).contains(&4));
@@ -139,10 +137,9 @@
     /// ```
     /// #![feature(range_is_empty)]
     ///
-    /// use std::f32::NAN;
     /// assert!(!(3.0..5.0).is_empty());
-    /// assert!( (3.0..NAN).is_empty());
-    /// assert!( (NAN..5.0).is_empty());
+    /// assert!( (3.0..f32::NAN).is_empty());
+    /// assert!( (f32::NAN..5.0).is_empty());
     /// ```
     #[unstable(feature = "range_is_empty", reason = "recently added", issue = "48111")]
     pub fn is_empty(&self) -> bool {
@@ -199,8 +196,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// assert!(!(3..).contains(&2));
     /// assert!( (3..).contains(&3));
     /// assert!( (3..).contains(&1_000_000_000));
@@ -283,8 +278,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// assert!( (..5).contains(&-1_000_000_000));
     /// assert!( (..5).contains(&4));
     /// assert!(!(..5).contains(&5));
@@ -454,8 +447,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// assert!(!(3..=5).contains(&2));
     /// assert!( (3..=5).contains(&3));
     /// assert!( (3..=5).contains(&4));
@@ -496,10 +487,9 @@
     /// ```
     /// #![feature(range_is_empty)]
     ///
-    /// use std::f32::NAN;
     /// assert!(!(3.0..=5.0).is_empty());
-    /// assert!( (3.0..=NAN).is_empty());
-    /// assert!( (NAN..=5.0).is_empty());
+    /// assert!( (3.0..=f32::NAN).is_empty());
+    /// assert!( (f32::NAN..=5.0).is_empty());
     /// ```
     ///
     /// This method returns `true` after iteration has finished:
@@ -583,8 +573,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// assert!( (..=5).contains(&-1_000_000_000));
     /// assert!( (..=5).contains(&5));
     /// assert!(!(..=5).contains(&6));
@@ -723,8 +711,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// assert!( (3..5).contains(&4));
     /// assert!(!(3..5).contains(&2));
     ///
diff --git a/src/libcore/ptr/const_ptr.rs b/src/libcore/ptr/const_ptr.rs
index a540016..52e224d 100644
--- a/src/libcore/ptr/const_ptr.rs
+++ b/src/libcore/ptr/const_ptr.rs
@@ -659,8 +659,8 @@
     /// `align`.
     ///
     /// If it is not possible to align the pointer, the implementation returns
-    /// `usize::max_value()`. It is permissible for the implementation to *always*
-    /// return `usize::max_value()`. Only your algorithm's performance can depend
+    /// `usize::MAX`. It is permissible for the implementation to *always*
+    /// return `usize::MAX`. Only your algorithm's performance can depend
     /// on getting a usable offset here, not its correctness.
     ///
     /// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
diff --git a/src/libcore/ptr/mut_ptr.rs b/src/libcore/ptr/mut_ptr.rs
index 01d830c..9f85d78 100644
--- a/src/libcore/ptr/mut_ptr.rs
+++ b/src/libcore/ptr/mut_ptr.rs
@@ -847,8 +847,8 @@
     /// `align`.
     ///
     /// If it is not possible to align the pointer, the implementation returns
-    /// `usize::max_value()`. It is permissible for the implementation to *always*
-    /// return `usize::max_value()`. Only your algorithm's performance can depend
+    /// `usize::MAX`. It is permissible for the implementation to *always*
+    /// return `usize::MAX`. Only your algorithm's performance can depend
     /// on getting a usable offset here, not its correctness.
     ///
     /// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs
index 9bbdce9..cb0fb87 100644
--- a/src/libcore/raw.rs
+++ b/src/libcore/raw.rs
@@ -6,7 +6,8 @@
 //! They can be used as targets of transmutes in unsafe code for manipulating
 //! the raw representations directly.
 //!
-//! Their definition should always match the ABI defined in `rustc_target::abi`.
+//! Their definition should always match the ABI defined in
+//! `rustc_middle::ty::layout`.
 
 /// The representation of a trait object like `&SomeTrait`.
 ///
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 0087b92..c7b5777 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -521,14 +521,16 @@
         }
     }
 
-    /// Applies a function to the contained value (if any),
-    /// or returns the provided default (if not).
+    /// Applies a function to the contained value (if [`Ok`]),
+    /// or returns the provided default (if [`Err`]).
     ///
     /// Arguments passed to `map_or` are eagerly evaluated; if you are passing
     /// the result of a function call, it is recommended to use [`map_or_else`],
     /// which is lazily evaluated.
     ///
     /// [`map_or_else`]: #method.map_or_else
+    /// [`Ok`]: enum.Result.html#variant.Ok
+    /// [`Err`]: enum.Result.html#variant.Err
     ///
     /// # Examples
     ///
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index 2140a7b..66aad32 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -23,6 +23,7 @@
 // * The `raw` and `bytes` submodules.
 // * Boilerplate trait implementations.
 
+use crate::borrow::Borrow;
 use crate::cmp;
 use crate::cmp::Ordering::{self, Equal, Greater, Less};
 use crate::fmt;
@@ -2145,6 +2146,29 @@
         }
     }
 
+    /// Fills `self` with elements by cloning `value`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(slice_fill)]
+    ///
+    /// let mut buf = vec![0; 10];
+    /// buf.fill(1);
+    /// assert_eq!(buf, vec![1; 10]);
+    /// ```
+    #[unstable(feature = "slice_fill", issue = "70758")]
+    pub fn fill<V>(&mut self, value: V)
+    where
+        V: Borrow<T>,
+        T: Clone,
+    {
+        let value = value.borrow();
+        for el in self {
+            el.clone_from(value)
+        }
+    }
+
     /// Copies the elements from `src` into `self`.
     ///
     /// The length of `src` must be the same as `self`.
@@ -2588,7 +2612,7 @@
     /// assert!(![1, 3, 2, 4].is_sorted());
     /// assert!([0].is_sorted());
     /// assert!(empty.is_sorted());
-    /// assert!(![0.0, 1.0, std::f32::NAN].is_sorted());
+    /// assert!(![0.0, 1.0, f32::NAN].is_sorted());
     /// ```
     #[inline]
     #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
diff --git a/src/libcore/tests/fmt/num.rs b/src/libcore/tests/fmt/num.rs
index a50c2b4..275a1d0 100644
--- a/src/libcore/tests/fmt/num.rs
+++ b/src/libcore/tests/fmt/num.rs
@@ -104,7 +104,6 @@
 
 #[test]
 fn test_format_int_exp_limits() {
-    use core::{i128, i16, i32, i64, i8, u128, u16, u32, u64, u8};
     assert_eq!(format!("{:e}", i8::MIN), "-1.28e2");
     assert_eq!(format!("{:e}", i8::MAX), "1.27e2");
     assert_eq!(format!("{:e}", i16::MIN), "-3.2768e4");
@@ -125,8 +124,6 @@
 
 #[test]
 fn test_format_int_exp_precision() {
-    use core::{i128, i16, i32, i64, i8};
-
     //test that float and integer match
     let big_int: u32 = 314_159_265;
     assert_eq!(format!("{:.1e}", big_int), format!("{:.1e}", f64::from(big_int)));
@@ -214,7 +211,6 @@
 
 #[test]
 fn test_format_int_twos_complement() {
-    use core::{i16, i32, i64, i8};
     assert_eq!(format!("{}", i8::MIN), "-128");
     assert_eq!(format!("{}", i16::MIN), "-32768");
     assert_eq!(format!("{}", i32::MIN), "-2147483648");
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index 98e3eeb..e0954a6 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -3,8 +3,6 @@
 use core::cell::Cell;
 use core::convert::TryFrom;
 use core::iter::*;
-use core::usize;
-use core::{i16, i8, isize};
 
 #[test]
 fn test_lt() {
@@ -2251,62 +2249,58 @@
 
 #[test]
 fn test_range_size_hint() {
-    use core::usize::MAX as UMAX;
     assert_eq!((0..0usize).size_hint(), (0, Some(0)));
     assert_eq!((0..100usize).size_hint(), (100, Some(100)));
-    assert_eq!((0..UMAX).size_hint(), (UMAX, Some(UMAX)));
+    assert_eq!((0..usize::MAX).size_hint(), (usize::MAX, Some(usize::MAX)));
 
-    let umax = u128::try_from(UMAX).unwrap();
+    let umax = u128::try_from(usize::MAX).unwrap();
     assert_eq!((0..0u128).size_hint(), (0, Some(0)));
     assert_eq!((0..100u128).size_hint(), (100, Some(100)));
-    assert_eq!((0..umax).size_hint(), (UMAX, Some(UMAX)));
-    assert_eq!((0..umax + 1).size_hint(), (UMAX, None));
+    assert_eq!((0..umax).size_hint(), (usize::MAX, Some(usize::MAX)));
+    assert_eq!((0..umax + 1).size_hint(), (usize::MAX, None));
 
-    use core::isize::{MAX as IMAX, MIN as IMIN};
     assert_eq!((0..0isize).size_hint(), (0, Some(0)));
     assert_eq!((-100..100isize).size_hint(), (200, Some(200)));
-    assert_eq!((IMIN..IMAX).size_hint(), (UMAX, Some(UMAX)));
+    assert_eq!((isize::MIN..isize::MAX).size_hint(), (usize::MAX, Some(usize::MAX)));
 
-    let imin = i128::try_from(IMIN).unwrap();
-    let imax = i128::try_from(IMAX).unwrap();
+    let imin = i128::try_from(isize::MIN).unwrap();
+    let imax = i128::try_from(isize::MAX).unwrap();
     assert_eq!((0..0i128).size_hint(), (0, Some(0)));
     assert_eq!((-100..100i128).size_hint(), (200, Some(200)));
-    assert_eq!((imin..imax).size_hint(), (UMAX, Some(UMAX)));
-    assert_eq!((imin..imax + 1).size_hint(), (UMAX, None));
+    assert_eq!((imin..imax).size_hint(), (usize::MAX, Some(usize::MAX)));
+    assert_eq!((imin..imax + 1).size_hint(), (usize::MAX, None));
 }
 
 #[test]
 fn test_range_inclusive_size_hint() {
-    use core::usize::MAX as UMAX;
     assert_eq!((1..=0usize).size_hint(), (0, Some(0)));
     assert_eq!((0..=0usize).size_hint(), (1, Some(1)));
     assert_eq!((0..=100usize).size_hint(), (101, Some(101)));
-    assert_eq!((0..=UMAX - 1).size_hint(), (UMAX, Some(UMAX)));
-    assert_eq!((0..=UMAX).size_hint(), (UMAX, None));
+    assert_eq!((0..=usize::MAX - 1).size_hint(), (usize::MAX, Some(usize::MAX)));
+    assert_eq!((0..=usize::MAX).size_hint(), (usize::MAX, None));
 
-    let umax = u128::try_from(UMAX).unwrap();
+    let umax = u128::try_from(usize::MAX).unwrap();
     assert_eq!((1..=0u128).size_hint(), (0, Some(0)));
     assert_eq!((0..=0u128).size_hint(), (1, Some(1)));
     assert_eq!((0..=100u128).size_hint(), (101, Some(101)));
-    assert_eq!((0..=umax - 1).size_hint(), (UMAX, Some(UMAX)));
-    assert_eq!((0..=umax).size_hint(), (UMAX, None));
-    assert_eq!((0..=umax + 1).size_hint(), (UMAX, None));
+    assert_eq!((0..=umax - 1).size_hint(), (usize::MAX, Some(usize::MAX)));
+    assert_eq!((0..=umax).size_hint(), (usize::MAX, None));
+    assert_eq!((0..=umax + 1).size_hint(), (usize::MAX, None));
 
-    use core::isize::{MAX as IMAX, MIN as IMIN};
     assert_eq!((0..=-1isize).size_hint(), (0, Some(0)));
     assert_eq!((0..=0isize).size_hint(), (1, Some(1)));
     assert_eq!((-100..=100isize).size_hint(), (201, Some(201)));
-    assert_eq!((IMIN..=IMAX - 1).size_hint(), (UMAX, Some(UMAX)));
-    assert_eq!((IMIN..=IMAX).size_hint(), (UMAX, None));
+    assert_eq!((isize::MIN..=isize::MAX - 1).size_hint(), (usize::MAX, Some(usize::MAX)));
+    assert_eq!((isize::MIN..=isize::MAX).size_hint(), (usize::MAX, None));
 
-    let imin = i128::try_from(IMIN).unwrap();
-    let imax = i128::try_from(IMAX).unwrap();
+    let imin = i128::try_from(isize::MIN).unwrap();
+    let imax = i128::try_from(isize::MAX).unwrap();
     assert_eq!((0..=-1i128).size_hint(), (0, Some(0)));
     assert_eq!((0..=0i128).size_hint(), (1, Some(1)));
     assert_eq!((-100..=100i128).size_hint(), (201, Some(201)));
-    assert_eq!((imin..=imax - 1).size_hint(), (UMAX, Some(UMAX)));
-    assert_eq!((imin..=imax).size_hint(), (UMAX, None));
-    assert_eq!((imin..=imax + 1).size_hint(), (UMAX, None));
+    assert_eq!((imin..=imax - 1).size_hint(), (usize::MAX, Some(usize::MAX)));
+    assert_eq!((imin..=imax).size_hint(), (usize::MAX, None));
+    assert_eq!((imin..=imax + 1).size_hint(), (usize::MAX, None));
 }
 
 #[test]
diff --git a/src/libcore/tests/num/dec2flt/mod.rs b/src/libcore/tests/num/dec2flt/mod.rs
index a1fa555..1c172f4 100644
--- a/src/libcore/tests/num/dec2flt/mod.rs
+++ b/src/libcore/tests/num/dec2flt/mod.rs
@@ -1,7 +1,5 @@
 #![allow(overflowing_literals)]
 
-use std::{f32, f64, i64};
-
 mod parse;
 mod rawfp;
 
diff --git a/src/libcore/tests/num/flt2dec/mod.rs b/src/libcore/tests/num/flt2dec/mod.rs
index e945d9c..ae892e3 100644
--- a/src/libcore/tests/num/flt2dec/mod.rs
+++ b/src/libcore/tests/num/flt2dec/mod.rs
@@ -1,4 +1,4 @@
-use std::{f32, f64, fmt, i16, str};
+use std::{fmt, str};
 
 use core::num::flt2dec::{decode, DecodableFloat, Decoded, FullDecoded};
 use core::num::flt2dec::{round_up, Formatted, Part, Sign, MAX_SIG_DIGITS};
diff --git a/src/libcore/tests/num/flt2dec/random.rs b/src/libcore/tests/num/flt2dec/random.rs
index ecdfc4b..5b050a2 100644
--- a/src/libcore/tests/num/flt2dec/random.rs
+++ b/src/libcore/tests/num/flt2dec/random.rs
@@ -1,6 +1,5 @@
 #![cfg(not(target_arch = "wasm32"))]
 
-use std::i16;
 use std::str;
 
 use core::num::flt2dec::strategy::grisu::format_exact_opt;
diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs
index 48a4907..8396a0d 100644
--- a/src/libcore/tests/num/int_macros.rs
+++ b/src/libcore/tests/num/int_macros.rs
@@ -2,7 +2,6 @@
     ($T:ident, $T_i:ident) => {
         #[cfg(test)]
         mod tests {
-            use core::isize;
             use core::mem;
             use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
             use core::$T_i::*;
diff --git a/src/libcore/time.rs b/src/libcore/time.rs
index 2ece215..924a648 100644
--- a/src/libcore/time.rs
+++ b/src/libcore/time.rs
@@ -389,7 +389,7 @@
     /// use std::time::Duration;
     ///
     /// assert_eq!(Duration::new(0, 0).checked_add(Duration::new(0, 1)), Some(Duration::new(0, 1)));
-    /// assert_eq!(Duration::new(1, 0).checked_add(Duration::new(std::u64::MAX, 0)), None);
+    /// assert_eq!(Duration::new(1, 0).checked_add(Duration::new(u64::MAX, 0)), None);
     /// ```
     #[stable(feature = "duration_checked_ops", since = "1.16.0")]
     #[inline]
@@ -460,7 +460,7 @@
     /// use std::time::Duration;
     ///
     /// assert_eq!(Duration::new(0, 500_000_001).checked_mul(2), Some(Duration::new(1, 2)));
-    /// assert_eq!(Duration::new(std::u64::MAX - 1, 0).checked_mul(2), None);
+    /// assert_eq!(Duration::new(u64::MAX - 1, 0).checked_mul(2), None);
     /// ```
     #[stable(feature = "duration_checked_ops", since = "1.16.0")]
     #[inline]
diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs
index 0a2a0e9..f791fe8 100644
--- a/src/libpanic_unwind/lib.rs
+++ b/src/libpanic_unwind/lib.rs
@@ -47,9 +47,6 @@
     } else if #[cfg(target_os = "hermit")] {
         #[path = "hermit.rs"]
         mod real_imp;
-    } else if #[cfg(all(target_env = "msvc", target_arch = "aarch64"))] {
-        #[path = "dummy.rs"]
-        mod real_imp;
     } else if #[cfg(target_env = "msvc")] {
         #[path = "seh.rs"]
         mod real_imp;
diff --git a/src/libpanic_unwind/seh.rs b/src/libpanic_unwind/seh.rs
index 10b765a..9eff37f 100644
--- a/src/libpanic_unwind/seh.rs
+++ b/src/libpanic_unwind/seh.rs
@@ -117,7 +117,7 @@
     }
 }
 
-#[cfg(any(target_arch = "x86_64", target_arch = "arm"))]
+#[cfg(not(target_arch = "x86"))]
 #[macro_use]
 mod imp {
     pub type ptr_t = u32;
diff --git a/src/librustc_ast/ast.rs b/src/librustc_ast/ast.rs
index 6586280..f91cbe5 100644
--- a/src/librustc_ast/ast.rs
+++ b/src/librustc_ast/ast.rs
@@ -300,8 +300,8 @@
 impl GenericBound {
     pub fn span(&self) -> Span {
         match self {
-            &GenericBound::Trait(ref t, ..) => t.span,
-            &GenericBound::Outlives(ref l) => l.ident.span,
+            GenericBound::Trait(ref t, ..) => t.span,
+            GenericBound::Outlives(ref l) => l.ident.span,
         }
     }
 }
diff --git a/src/librustc_ast/util/comments.rs b/src/librustc_ast/util/comments.rs
index 0e42ae1..5f5d481 100644
--- a/src/librustc_ast/util/comments.rs
+++ b/src/librustc_ast/util/comments.rs
@@ -5,7 +5,6 @@
 use rustc_span::{BytePos, CharPos, FileName, Pos};
 
 use log::debug;
-use std::usize;
 
 #[cfg(test)]
 mod tests;
diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs
index b319ee7..6005b60 100644
--- a/src/librustc_ast_lowering/item.rs
+++ b/src/librustc_ast_lowering/item.rs
@@ -972,8 +972,10 @@
         f: impl FnOnce(&mut Self) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>),
     ) -> hir::BodyId {
         let prev_gen_kind = self.generator_kind.take();
+        let task_context = self.task_context.take();
         let (parameters, result) = f(self);
         let body_id = self.record_body(parameters, result);
+        self.task_context = task_context;
         self.generator_kind = prev_gen_kind;
         body_id
     }
diff --git a/src/librustc_ast_passes/Cargo.toml b/src/librustc_ast_passes/Cargo.toml
index 5d096e4..e4d1d79 100644
--- a/src/librustc_ast_passes/Cargo.toml
+++ b/src/librustc_ast_passes/Cargo.toml
@@ -9,6 +9,7 @@
 path = "lib.rs"
 
 [dependencies]
+itertools = "0.8"
 log = "0.4"
 rustc_ast_pretty = { path = "../librustc_ast_pretty" }
 rustc_attr = { path = "../librustc_attr" }
diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs
index de7ae10..9563325f 100644
--- a/src/librustc_ast_passes/ast_validation.rs
+++ b/src/librustc_ast_passes/ast_validation.rs
@@ -6,6 +6,7 @@
 // This pass is supposed to perform only simple checks not requiring name resolution
 // or type checking or some other kind of complex analysis.
 
+use itertools::{Either, Itertools};
 use rustc_ast::ast::*;
 use rustc_ast::attr;
 use rustc_ast::expand::is_proc_macro_attr;
@@ -14,7 +15,7 @@
 use rustc_ast::walk_list;
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{error_code, struct_span_err, Applicability};
+use rustc_errors::{error_code, pluralize, struct_span_err, Applicability};
 use rustc_parse::validate_attr;
 use rustc_session::lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY;
 use rustc_session::lint::LintBuffer;
@@ -640,6 +641,33 @@
         }
     }
 
+    fn correct_generic_order_suggestion(&self, data: &AngleBracketedArgs) -> String {
+        // Lifetimes always come first.
+        let lt_sugg = data.args.iter().filter_map(|arg| match arg {
+            AngleBracketedArg::Arg(lt @ GenericArg::Lifetime(_)) => {
+                Some(pprust::to_string(|s| s.print_generic_arg(lt)))
+            }
+            _ => None,
+        });
+        let args_sugg = data.args.iter().filter_map(|a| match a {
+            AngleBracketedArg::Arg(GenericArg::Lifetime(_)) | AngleBracketedArg::Constraint(_) => {
+                None
+            }
+            AngleBracketedArg::Arg(arg) => Some(pprust::to_string(|s| s.print_generic_arg(arg))),
+        });
+        // Constraints always come last.
+        let constraint_sugg = data.args.iter().filter_map(|a| match a {
+            AngleBracketedArg::Arg(_) => None,
+            AngleBracketedArg::Constraint(c) => {
+                Some(pprust::to_string(|s| s.print_assoc_constraint(c)))
+            }
+        });
+        format!(
+            "<{}>",
+            lt_sugg.chain(args_sugg).chain(constraint_sugg).collect::<Vec<String>>().join(", ")
+        )
+    }
+
     /// Enforce generic args coming before constraints in `<...>` of a path segment.
     fn check_generic_args_before_constraints(&self, data: &AngleBracketedArgs) {
         // Early exit in case it's partitioned as it should be.
@@ -647,24 +675,36 @@
             return;
         }
         // Find all generic argument coming after the first constraint...
-        let mut misplaced_args = Vec::new();
-        let mut first = None;
-        for arg in &data.args {
-            match (arg, first) {
-                (AngleBracketedArg::Arg(a), Some(_)) => misplaced_args.push(a.span()),
-                (AngleBracketedArg::Constraint(c), None) => first = Some(c.span),
-                (AngleBracketedArg::Arg(_), None) | (AngleBracketedArg::Constraint(_), Some(_)) => {
-                }
-            }
-        }
+        let (constraint_spans, arg_spans): (Vec<Span>, Vec<Span>) =
+            data.args.iter().partition_map(|arg| match arg {
+                AngleBracketedArg::Constraint(c) => Either::Left(c.span),
+                AngleBracketedArg::Arg(a) => Either::Right(a.span()),
+            });
+        let args_len = arg_spans.len();
+        let constraint_len = constraint_spans.len();
         // ...and then error:
         self.err_handler()
             .struct_span_err(
-                misplaced_args.clone(),
+                arg_spans.clone(),
                 "generic arguments must come before the first constraint",
             )
-            .span_label(first.unwrap(), "the first constraint is provided here")
-            .span_labels(misplaced_args, "generic argument")
+            .span_label(constraint_spans[0], &format!("constraint{}", pluralize!(constraint_len)))
+            .span_label(
+                *arg_spans.iter().last().unwrap(),
+                &format!("generic argument{}", pluralize!(args_len)),
+            )
+            .span_labels(constraint_spans, "")
+            .span_labels(arg_spans, "")
+            .span_suggestion_verbose(
+                data.span,
+                &format!(
+                    "move the constraint{} after the generic argument{}",
+                    pluralize!(constraint_len),
+                    pluralize!(args_len)
+                ),
+                self.correct_generic_order_suggestion(&data),
+                Applicability::MachineApplicable,
+            )
             .emit();
     }
 }
diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs
index 6541ac1..f688686 100644
--- a/src/librustc_ast_pretty/pprust.rs
+++ b/src/librustc_ast_pretty/pprust.rs
@@ -869,7 +869,7 @@
         }
     }
 
-    fn print_assoc_constraint(&mut self, constraint: &ast::AssocTyConstraint) {
+    pub fn print_assoc_constraint(&mut self, constraint: &ast::AssocTyConstraint) {
         self.print_ident(constraint.ident);
         self.s.space();
         match &constraint.kind {
@@ -883,7 +883,7 @@
         }
     }
 
-    crate fn print_generic_arg(&mut self, generic_arg: &GenericArg) {
+    pub fn print_generic_arg(&mut self, generic_arg: &GenericArg) {
         match generic_arg {
             GenericArg::Lifetime(lt) => self.print_lifetime(*lt),
             GenericArg::Type(ty) => self.print_type(ty),
diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs
index 064ca53..8e9c5f2 100644
--- a/src/librustc_codegen_llvm/abi.rs
+++ b/src/librustc_codegen_llvm/abi.rs
@@ -10,17 +10,15 @@
 use rustc_codegen_ssa::traits::*;
 use rustc_codegen_ssa::MemFlags;
 use rustc_middle::bug;
-use rustc_middle::ty::layout::{self};
+pub use rustc_middle::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
 use rustc_middle::ty::Ty;
 use rustc_target::abi::call::ArgAbi;
-use rustc_target::abi::{HasDataLayout, LayoutOf};
+pub use rustc_target::abi::call::*;
+use rustc_target::abi::{self, HasDataLayout, Int, LayoutOf};
+pub use rustc_target::spec::abi::Abi;
 
 use libc::c_uint;
 
-pub use rustc_middle::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
-pub use rustc_target::abi::call::*;
-pub use rustc_target::spec::abi::Abi;
-
 macro_rules! for_each_kind {
     ($flags: ident, $f: ident, $($kind: ident),+) => ({
         $(if $flags.contains(ArgAttribute::$kind) { $f(llvm::Attribute::$kind) })+
@@ -450,11 +448,11 @@
             PassMode::Indirect(ref attrs, _) => apply(attrs, Some(self.ret.layout.llvm_type(bx))),
             _ => {}
         }
-        if let layout::Abi::Scalar(ref scalar) = self.ret.layout.abi {
+        if let abi::Abi::Scalar(ref scalar) = self.ret.layout.abi {
             // If the value is a boolean, the range is 0..2 and that ultimately
             // become 0..0 when the type becomes i1, which would be rejected
             // by the LLVM verifier.
-            if let layout::Int(..) = scalar.value {
+            if let Int(..) = scalar.value {
                 if !scalar.is_bool() {
                     let range = scalar.valid_range_exclusive(bx);
                     if range.start != range.end {
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index 35946fb..da9060f 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -16,9 +16,10 @@
 use rustc_data_structures::const_cstr;
 use rustc_data_structures::small_c_str::SmallCStr;
 use rustc_hir::def_id::DefId;
-use rustc_middle::ty::layout::{self, Align, Size, TyAndLayout};
+use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::config::{self, Sanitizer};
+use rustc_target::abi::{self, Align, Size};
 use rustc_target::spec::{HasTargetSpec, Target};
 use std::borrow::Cow;
 use std::ffi::CStr;
@@ -60,8 +61,8 @@
     type DIVariable = <CodegenCx<'ll, 'tcx> as BackendTypes>::DIVariable;
 }
 
-impl ty::layout::HasDataLayout for Builder<'_, '_, '_> {
-    fn data_layout(&self) -> &ty::layout::TargetDataLayout {
+impl abi::HasDataLayout for Builder<'_, '_, '_> {
+    fn data_layout(&self) -> &abi::TargetDataLayout {
         self.cx.data_layout()
     }
 }
@@ -84,7 +85,7 @@
     }
 }
 
-impl ty::layout::LayoutOf for Builder<'_, '_, 'tcx> {
+impl abi::LayoutOf for Builder<'_, '_, 'tcx> {
     type Ty = Ty<'tcx>;
     type TyAndLayout = TyAndLayout<'tcx>;
 
@@ -435,17 +436,17 @@
         fn scalar_load_metadata<'a, 'll, 'tcx>(
             bx: &mut Builder<'a, 'll, 'tcx>,
             load: &'ll Value,
-            scalar: &layout::Scalar,
+            scalar: &abi::Scalar,
         ) {
             let vr = scalar.valid_range.clone();
             match scalar.value {
-                layout::Int(..) => {
+                abi::Int(..) => {
                     let range = scalar.valid_range_exclusive(bx);
                     if range.start != range.end {
                         bx.range_metadata(load, range);
                     }
                 }
-                layout::Pointer if vr.start() < vr.end() && !vr.contains(&0) => {
+                abi::Pointer if vr.start() < vr.end() && !vr.contains(&0) => {
                     bx.nonnull_metadata(load);
                 }
                 _ => {}
@@ -465,16 +466,16 @@
             }
             let llval = const_llval.unwrap_or_else(|| {
                 let load = self.load(place.llval, place.align);
-                if let layout::Abi::Scalar(ref scalar) = place.layout.abi {
+                if let abi::Abi::Scalar(ref scalar) = place.layout.abi {
                     scalar_load_metadata(self, load, scalar);
                 }
                 load
             });
             OperandValue::Immediate(to_immediate(self, llval, place.layout))
-        } else if let layout::Abi::ScalarPair(ref a, ref b) = place.layout.abi {
+        } else if let abi::Abi::ScalarPair(ref a, ref b) = place.layout.abi {
             let b_offset = a.value.size(self).align_to(b.value.align(self).abi);
 
-            let mut load = |i, scalar: &layout::Scalar, align| {
+            let mut load = |i, scalar: &abi::Scalar, align| {
                 let llptr = self.struct_gep(place.llval, i as u64);
                 let load = self.load(llptr, align);
                 scalar_load_metadata(self, load, scalar);
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs
index 01c8e02..1415fed 100644
--- a/src/librustc_codegen_llvm/common.rs
+++ b/src/librustc_codegen_llvm/common.rs
@@ -2,26 +2,24 @@
 
 //! Code that is useful in various codegen modules.
 
-use crate::consts;
+use crate::consts::{self, const_alloc_to_llvm};
+pub use crate::context::CodegenCx;
 use crate::llvm::{self, BasicBlock, Bool, ConstantInt, False, OperandBundleDef, True};
 use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
-use log::debug;
-use rustc_codegen_ssa::traits::*;
-use rustc_middle::bug;
-
-use crate::consts::const_alloc_to_llvm;
-use rustc_codegen_ssa::mir::place::PlaceRef;
-use rustc_middle::mir::interpret::{Allocation, GlobalAlloc, Scalar};
-use rustc_middle::ty::layout::{self, HasDataLayout, LayoutOf, Size, TyAndLayout};
-
-use libc::{c_char, c_uint};
 
 use rustc_ast::ast::Mutability;
+use rustc_codegen_ssa::mir::place::PlaceRef;
+use rustc_codegen_ssa::traits::*;
+use rustc_middle::bug;
+use rustc_middle::mir::interpret::{Allocation, GlobalAlloc, Scalar};
+use rustc_middle::ty::layout::TyAndLayout;
 use rustc_span::symbol::Symbol;
+use rustc_target::abi::{self, HasDataLayout, LayoutOf, Pointer, Size};
 
-pub use crate::context::CodegenCx;
+use libc::{c_char, c_uint};
+use log::debug;
 
 /*
 * A note on nomenclature of linking: "extern", "foreign", and "upcall".
@@ -229,12 +227,7 @@
         })
     }
 
-    fn scalar_to_backend(
-        &self,
-        cv: Scalar,
-        layout: &layout::Scalar,
-        llty: &'ll Type,
-    ) -> &'ll Value {
+    fn scalar_to_backend(&self, cv: Scalar, layout: &abi::Scalar, llty: &'ll Type) -> &'ll Value {
         let bitsize = if layout.is_bool() { 1 } else { layout.value.size(self).bits() };
         match cv {
             Scalar::Raw { size: 0, .. } => {
@@ -244,7 +237,7 @@
             Scalar::Raw { data, size } => {
                 assert_eq!(size as u64, layout.value.size(self).bytes());
                 let llval = self.const_uint_big(self.type_ix(bitsize), data);
-                if layout.value == layout::Pointer {
+                if layout.value == Pointer {
                     unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
                 } else {
                     self.const_bitcast(llval, llty)
@@ -278,7 +271,7 @@
                         1,
                     )
                 };
-                if layout.value != layout::Pointer {
+                if layout.value != Pointer {
                     unsafe { llvm::LLVMConstPtrToInt(llval, llty) }
                 } else {
                     self.const_bitcast(llval, llty)
diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index db92f3d..9fd22c8 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -16,12 +16,11 @@
     read_target_uint, Allocation, ConstValue, ErrorHandled, Pointer,
 };
 use rustc_middle::mir::mono::MonoItem;
-use rustc_middle::ty::layout::{self, Align, LayoutOf, Size};
 use rustc_middle::ty::{self, Instance, Ty};
 use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
-use rustc_target::abi::HasDataLayout;
+use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Primitive, Scalar, Size};
 
 use std::ffi::CStr;
 
@@ -56,7 +55,7 @@
             as u64;
         llvals.push(cx.scalar_to_backend(
             Pointer::new(alloc_id, Size::from_bytes(ptr_offset)).into(),
-            &layout::Scalar { value: layout::Primitive::Pointer, valid_range: 0..=!0 },
+            &Scalar { value: Primitive::Pointer, valid_range: 0..=!0 },
             cx.type_i8p(),
         ));
         next_offset = offset + pointer_size;
@@ -437,24 +436,21 @@
                 //
                 // We could remove this hack whenever we decide to drop macOS 10.10 support.
                 if self.tcx.sess.target.target.options.is_like_osx {
-                    assert_eq!(alloc.relocations().len(), 0);
-
-                    let is_zeroed = {
-                        // Treats undefined bytes as if they were defined with the byte value that
-                        // happens to be currently assigned in mir. This is valid since reading
-                        // undef bytes may yield arbitrary values.
-                        //
-                        // FIXME: ignore undef bytes even with representation `!= 0`.
-                        //
-                        // The `inspect` method is okay here because we checked relocations, and
-                        // because we are doing this access to inspect the final interpreter state
-                        // (not as part of the interpreter execution).
-                        alloc
+                    // The `inspect` method is okay here because we checked relocations, and
+                    // because we are doing this access to inspect the final interpreter state
+                    // (not as part of the interpreter execution).
+                    //
+                    // FIXME: This check requires that the (arbitrary) value of undefined bytes
+                    // happens to be zero. Instead, we should only check the value of defined bytes
+                    // and set all undefined bytes to zero if this allocation is headed for the
+                    // BSS.
+                    let all_bytes_are_zero = alloc.relocations().is_empty()
+                        && alloc
                             .inspect_with_undef_and_ptr_outside_interpreter(0..alloc.len())
                             .iter()
-                            .all(|b| *b == 0)
-                    };
-                    let sect_name = if is_zeroed {
+                            .all(|&byte| byte == 0);
+
+                    let sect_name = if all_bytes_are_zero {
                         CStr::from_bytes_with_nul_unchecked(b"__DATA,__thread_bss\0")
                     } else {
                         CStr::from_bytes_with_nul_unchecked(b"__DATA,__thread_data\0")
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index add1f46..99a8258 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -14,14 +14,13 @@
 use rustc_data_structures::small_c_str::SmallCStr;
 use rustc_middle::bug;
 use rustc_middle::mir::mono::CodegenUnit;
-use rustc_middle::ty::layout::{
-    HasParamEnv, LayoutError, LayoutOf, PointeeInfo, Size, TyAndLayout, VariantIdx,
-};
+use rustc_middle::ty::layout::{HasParamEnv, LayoutError, TyAndLayout};
 use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
 use rustc_session::config::{self, CFGuard, DebugInfo};
 use rustc_session::Session;
 use rustc_span::source_map::{Span, DUMMY_SP};
 use rustc_span::symbol::Symbol;
+use rustc_target::abi::{HasDataLayout, LayoutOf, PointeeInfo, Size, TargetDataLayout, VariantIdx};
 use rustc_target::spec::{HasTargetSpec, Target};
 
 use std::cell::{Cell, RefCell};
@@ -817,8 +816,8 @@
     }
 }
 
-impl ty::layout::HasDataLayout for CodegenCx<'ll, 'tcx> {
-    fn data_layout(&self) -> &ty::layout::TargetDataLayout {
+impl HasDataLayout for CodegenCx<'ll, 'tcx> {
+    fn data_layout(&self) -> &TargetDataLayout {
         &self.tcx.data_layout
     }
 }
diff --git a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs
index e2eae4a..7f47b61 100644
--- a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs
+++ b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs
@@ -76,7 +76,7 @@
     }
 
     let loc = cx.lookup_debug_loc(scope_data.span.lo());
-    let file_metadata = file_metadata(cx, &loc.file.name, debug_context.defining_crate);
+    let file_metadata = file_metadata(cx, &loc.file, debug_context.defining_crate);
 
     let scope_metadata = unsafe {
         Some(llvm::LLVMRustDIBuilderCreateLexicalBlock(
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index b90c7e5..82cd85893 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -34,17 +34,17 @@
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir::interpret::truncate;
 use rustc_middle::mir::{self, Field, GeneratorLayout};
-use rustc_middle::ty::layout::{
-    self, Align, Integer, IntegerExt, LayoutOf, PrimitiveExt, Size, TyAndLayout, VariantIdx,
-};
+use rustc_middle::ty::layout::{self, IntegerExt, PrimitiveExt, TyAndLayout};
 use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
 use rustc_middle::ty::Instance;
 use rustc_middle::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_session::config::{self, DebugInfo};
 use rustc_span::symbol::{Interner, Symbol};
-use rustc_span::{self, FileName, Span};
-use rustc_target::abi::HasDataLayout;
+use rustc_span::{self, SourceFile, SourceFileHash, Span};
+use rustc_target::abi::{Abi, Align, DiscriminantKind, HasDataLayout, Integer, LayoutOf};
+use rustc_target::abi::{Int, Pointer, F32, F64};
+use rustc_target::abi::{Primitive, Size, VariantIdx, Variants};
 
 use libc::{c_longlong, c_uint};
 use std::collections::hash_map::Entry;
@@ -751,14 +751,23 @@
     metadata
 }
 
+fn hex_encode(data: &[u8]) -> String {
+    let mut hex_string = String::with_capacity(data.len() * 2);
+    for byte in data.iter() {
+        write!(&mut hex_string, "{:02x}", byte).unwrap();
+    }
+    hex_string
+}
+
 pub fn file_metadata(
     cx: &CodegenCx<'ll, '_>,
-    file_name: &FileName,
+    source_file: &SourceFile,
     defining_crate: CrateNum,
 ) -> &'ll DIFile {
-    debug!("file_metadata: file_name: {}, defining_crate: {}", file_name, defining_crate);
+    debug!("file_metadata: file_name: {}, defining_crate: {}", source_file.name, defining_crate);
 
-    let file_name = Some(file_name.to_string());
+    let hash = Some(&source_file.src_hash);
+    let file_name = Some(source_file.name.to_string());
     let directory = if defining_crate == LOCAL_CRATE {
         Some(cx.sess().working_dir.0.to_string_lossy().to_string())
     } else {
@@ -766,17 +775,18 @@
         // independent of the compiler's working directory one way or another.
         None
     };
-    file_metadata_raw(cx, file_name, directory)
+    file_metadata_raw(cx, file_name, directory, hash)
 }
 
 pub fn unknown_file_metadata(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
-    file_metadata_raw(cx, None, None)
+    file_metadata_raw(cx, None, None, None)
 }
 
 fn file_metadata_raw(
     cx: &CodegenCx<'ll, '_>,
     file_name: Option<String>,
     directory: Option<String>,
+    hash: Option<&SourceFileHash>,
 ) -> &'ll DIFile {
     let key = (file_name, directory);
 
@@ -789,6 +799,17 @@
             let file_name = file_name.as_deref().unwrap_or("<unknown>");
             let directory = directory.as_deref().unwrap_or("");
 
+            let (hash_kind, hash_value) = match hash {
+                Some(hash) => {
+                    let kind = match hash.kind {
+                        rustc_span::SourceFileHashAlgorithm::Md5 => llvm::ChecksumKind::MD5,
+                        rustc_span::SourceFileHashAlgorithm::Sha1 => llvm::ChecksumKind::SHA1,
+                    };
+                    (kind, hex_encode(hash.hash_bytes()))
+                }
+                None => (llvm::ChecksumKind::None, String::new()),
+            };
+
             let file_metadata = unsafe {
                 llvm::LLVMRustDIBuilderCreateFile(
                     DIB(cx),
@@ -796,6 +817,9 @@
                     file_name.len(),
                     directory.as_ptr().cast(),
                     directory.len(),
+                    hash_kind,
+                    hash_value.as_ptr().cast(),
+                    hash_value.len(),
                 )
             };
 
@@ -920,6 +944,9 @@
             name_in_debuginfo.len(),
             work_dir.as_ptr().cast(),
             work_dir.len(),
+            llvm::ChecksumKind::None,
+            ptr::null(),
+            0,
         );
 
         let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
@@ -1364,7 +1391,7 @@
         };
 
         match self.layout.variants {
-            layout::Variants::Single { index } => {
+            Variants::Single { index } => {
                 if let ty::Adt(adt, _) = &self.enum_type.kind {
                     if adt.variants.is_empty() {
                         return vec![];
@@ -1399,8 +1426,8 @@
                     discriminant: None,
                 }]
             }
-            layout::Variants::Multiple {
-                discr_kind: layout::DiscriminantKind::Tag,
+            Variants::Multiple {
+                discr_kind: DiscriminantKind::Tag,
                 discr_index,
                 ref variants,
                 ..
@@ -1457,9 +1484,9 @@
                     })
                     .collect()
             }
-            layout::Variants::Multiple {
+            Variants::Multiple {
                 discr_kind:
-                    layout::DiscriminantKind::Niche { ref niche_variants, niche_start, dataful_variant },
+                    DiscriminantKind::Niche { ref niche_variants, niche_start, dataful_variant },
                 ref discr,
                 ref variants,
                 discr_index,
@@ -1592,7 +1619,7 @@
 // Creates `MemberDescription`s for the fields of a single enum variant.
 struct VariantMemberDescriptionFactory<'ll, 'tcx> {
     /// Cloned from the `layout::Struct` describing the variant.
-    offsets: Vec<layout::Size>,
+    offsets: Vec<Size>,
     args: Vec<(String, Ty<'tcx>)>,
     discriminant_type_metadata: Option<&'ll DIType>,
     span: Span,
@@ -1777,7 +1804,7 @@
     // <unknown>
     let file_metadata = unknown_file_metadata(cx);
 
-    let discriminant_type_metadata = |discr: layout::Primitive| {
+    let discriminant_type_metadata = |discr: Primitive| {
         let enumerators_metadata: Vec<_> = match enum_type.kind {
             ty::Adt(def, _) => def
                 .discriminants(cx.tcx)
@@ -1870,10 +1897,8 @@
     let layout = cx.layout_of(enum_type);
 
     if let (
-        &layout::Abi::Scalar(_),
-        &layout::Variants::Multiple {
-            discr_kind: layout::DiscriminantKind::Tag, ref discr, ..
-        },
+        &Abi::Scalar(_),
+        &Variants::Multiple { discr_kind: DiscriminantKind::Tag, ref discr, .. },
     ) = (&layout.abi, &layout.variants)
     {
         return FinalMetadata(discriminant_type_metadata(discr.value));
@@ -1881,16 +1906,11 @@
 
     if use_enum_fallback(cx) {
         let discriminant_type_metadata = match layout.variants {
-            layout::Variants::Single { .. }
-            | layout::Variants::Multiple {
-                discr_kind: layout::DiscriminantKind::Niche { .. },
-                ..
-            } => None,
-            layout::Variants::Multiple {
-                discr_kind: layout::DiscriminantKind::Tag,
-                ref discr,
-                ..
-            } => Some(discriminant_type_metadata(discr.value)),
+            Variants::Single { .. }
+            | Variants::Multiple { discr_kind: DiscriminantKind::Niche { .. }, .. } => None,
+            Variants::Multiple { discr_kind: DiscriminantKind::Tag, ref discr, .. } => {
+                Some(discriminant_type_metadata(discr.value))
+            }
         };
 
         let enum_metadata = {
@@ -1938,10 +1958,10 @@
     };
     let discriminator_metadata = match layout.variants {
         // A single-variant enum has no discriminant.
-        layout::Variants::Single { .. } => None,
+        Variants::Single { .. } => None,
 
-        layout::Variants::Multiple {
-            discr_kind: layout::DiscriminantKind::Niche { .. },
+        Variants::Multiple {
+            discr_kind: DiscriminantKind::Niche { .. },
             ref discr,
             discr_index,
             ..
@@ -1951,10 +1971,10 @@
             let align = discr.value.align(cx);
 
             let discr_type = match discr.value {
-                layout::Int(t, _) => t,
-                layout::F32 => Integer::I32,
-                layout::F64 => Integer::I64,
-                layout::Pointer => cx.data_layout().ptr_sized_integer(),
+                Int(t, _) => t,
+                F32 => Integer::I32,
+                F64 => Integer::I64,
+                Pointer => cx.data_layout().ptr_sized_integer(),
             }
             .to_ty(cx.tcx, false);
 
@@ -1976,11 +1996,8 @@
             }
         }
 
-        layout::Variants::Multiple {
-            discr_kind: layout::DiscriminantKind::Tag,
-            ref discr,
-            discr_index,
-            ..
+        Variants::Multiple {
+            discr_kind: DiscriminantKind::Tag, ref discr, discr_index, ..
         } => {
             let discr_type = discr.value.to_ty(cx.tcx);
             let (size, align) = cx.size_and_align_of(discr_type);
@@ -2005,8 +2022,8 @@
     };
 
     let mut outer_fields = match layout.variants {
-        layout::Variants::Single { .. } => vec![],
-        layout::Variants::Multiple { .. } => {
+        Variants::Single { .. } => vec![],
+        Variants::Multiple { .. } => {
             let tuple_mdf = TupleMemberDescriptionFactory {
                 ty: enum_type,
                 component_types: outer_field_tys,
@@ -2313,7 +2330,7 @@
 
     let (file_metadata, line_number) = if !span.is_dummy() {
         let loc = cx.lookup_debug_loc(span.lo());
-        (file_metadata(cx, &loc.file.name, LOCAL_CRATE), loc.line)
+        (file_metadata(cx, &loc.file, LOCAL_CRATE), loc.line)
     } else {
         (unknown_file_metadata(cx), None)
     };
@@ -2422,6 +2439,6 @@
     file: &rustc_span::SourceFile,
     defining_crate: CrateNum,
 ) -> &'ll DILexicalBlock {
-    let file_metadata = file_metadata(cx, &file.name, defining_crate);
+    let file_metadata = file_metadata(cx, &file, defining_crate);
     unsafe { llvm::LLVMRustDIBuilderCreateLexicalBlockFile(DIB(cx), scope_metadata, file_metadata) }
 }
diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs
index 848c973..37f502c 100644
--- a/src/librustc_codegen_llvm/debuginfo/mod.rs
+++ b/src/librustc_codegen_llvm/debuginfo/mod.rs
@@ -8,35 +8,35 @@
 use self::type_names::compute_debuginfo_type_name;
 use self::utils::{create_DIArray, is_node_local_to_unit, DIB};
 
+use crate::abi::FnAbi;
+use crate::builder::Builder;
+use crate::common::CodegenCx;
 use crate::llvm;
 use crate::llvm::debuginfo::{
     DIArray, DIBuilder, DIFile, DIFlags, DILexicalBlock, DISPFlags, DIScope, DIType, DIVariable,
 };
-use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE};
-use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
-
-use crate::abi::FnAbi;
-use crate::builder::Builder;
-use crate::common::CodegenCx;
 use crate::value::Value;
+
+use rustc_ast::ast;
 use rustc_codegen_ssa::debuginfo::type_names;
 use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext, VariableKind};
+use rustc_codegen_ssa::traits::*;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE};
 use rustc_index::vec::IndexVec;
 use rustc_middle::mir;
+use rustc_middle::ty::layout::HasTyCtxt;
+use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
 use rustc_middle::ty::{self, Instance, ParamEnv, Ty};
 use rustc_session::config::{self, DebugInfo};
+use rustc_span::symbol::Symbol;
+use rustc_span::{self, BytePos, Span};
+use rustc_target::abi::{LayoutOf, Primitive, Size};
 
 use libc::c_uint;
 use log::debug;
-use std::cell::RefCell;
-
-use rustc_ast::ast;
-use rustc_codegen_ssa::traits::*;
-use rustc_middle::ty::layout::{self, HasTyCtxt, LayoutOf, Size};
-use rustc_span::symbol::Symbol;
-use rustc_span::{self, BytePos, Span};
 use smallvec::SmallVec;
+use std::cell::RefCell;
 
 mod create_scope_map;
 pub mod gdb;
@@ -60,7 +60,7 @@
     llmod: &'a llvm::Module,
     builder: &'a mut DIBuilder<'a>,
     created_files: RefCell<FxHashMap<(Option<String>, Option<String>), &'a DIFile>>,
-    created_enum_disr_types: RefCell<FxHashMap<(DefId, layout::Primitive), &'a DIType>>,
+    created_enum_disr_types: RefCell<FxHashMap<(DefId, Primitive), &'a DIType>>,
 
     type_map: RefCell<TypeMap<'a, 'tcx>>,
     namespace_map: RefCell<DefIdMap<&'a DIScope>>,
@@ -249,7 +249,7 @@
         let def_id = instance.def_id();
         let containing_scope = get_containing_scope(self, instance);
         let loc = self.lookup_debug_loc(span.lo());
-        let file_metadata = file_metadata(self, &loc.file.name, def_id.krate);
+        let file_metadata = file_metadata(self, &loc.file, def_id.krate);
 
         let function_type_metadata = unsafe {
             let fn_signature = get_function_signature(self, fn_abi);
@@ -536,7 +536,7 @@
         span: Span,
     ) -> &'ll DIVariable {
         let loc = self.lookup_debug_loc(span.lo());
-        let file_metadata = file_metadata(self, &loc.file.name, dbg_context.defining_crate);
+        let file_metadata = file_metadata(self, &loc.file, dbg_context.defining_crate);
 
         let type_metadata = type_metadata(self, variable_type, span);
 
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index 23f6c0a..63730c5 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -7,26 +7,25 @@
 use crate::type_of::LayoutLlvmExt;
 use crate::va_arg::emit_va_arg;
 use crate::value::Value;
+
 use rustc_ast::ast;
 use rustc_codegen_ssa::base::{compare_simd_types, to_immediate, wants_msvc_seh};
+use rustc_codegen_ssa::common::span_invalid_monomorphization_error;
 use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
 use rustc_codegen_ssa::glue;
 use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
 use rustc_codegen_ssa::mir::place::PlaceRef;
+use rustc_codegen_ssa::traits::*;
 use rustc_codegen_ssa::MemFlags;
 use rustc_hir as hir;
-use rustc_middle::ty::layout::{self, FnAbiExt, HasTyCtxt, LayoutOf, Primitive};
+use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt};
 use rustc_middle::ty::{self, Ty};
 use rustc_middle::{bug, span_bug};
-use rustc_target::abi::HasDataLayout;
-
-use rustc_codegen_ssa::common::span_invalid_monomorphization_error;
-use rustc_codegen_ssa::traits::*;
-
 use rustc_span::Span;
+use rustc_target::abi::{self, HasDataLayout, LayoutOf, Primitive};
 
 use std::cmp::Ordering;
-use std::{i128, iter, u128};
+use std::iter;
 
 fn get_simple_intrinsic(cx: &CodegenCx<'ll, '_>, name: &str) -> Option<&'ll Value> {
     let llvm_name = match name {
@@ -145,7 +144,7 @@
             }
             "va_arg" => {
                 match fn_abi.ret.layout.abi {
-                    layout::Abi::Scalar(ref scalar) => {
+                    abi::Abi::Scalar(ref scalar) => {
                         match scalar.value {
                             Primitive::Int(..) => {
                                 if self.cx().size_of(ret_ty).bytes() < 4 {
@@ -544,13 +543,13 @@
                 }
             }
 
-            "float_to_int_approx_unchecked" => {
+            "float_to_int_unchecked" => {
                 if float_type_width(arg_tys[0]).is_none() {
                     span_invalid_monomorphization_error(
                         tcx.sess,
                         span,
                         &format!(
-                            "invalid monomorphization of `float_to_int_approx_unchecked` \
+                            "invalid monomorphization of `float_to_int_unchecked` \
                                   intrinsic: expected basic float type, \
                                   found `{}`",
                             arg_tys[0]
@@ -571,7 +570,7 @@
                             tcx.sess,
                             span,
                             &format!(
-                                "invalid monomorphization of `float_to_int_approx_unchecked` \
+                                "invalid monomorphization of `float_to_int_unchecked` \
                                       intrinsic:  expected basic integer type, \
                                       found `{}`",
                                 ret_ty
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index 8a16d09..939f9e9 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -23,11 +23,10 @@
 use rustc_codegen_ssa::traits::*;
 use rustc_codegen_ssa::ModuleCodegen;
 use rustc_codegen_ssa::{CodegenResults, CompiledModule};
-use rustc_errors::{FatalError, Handler};
+use rustc_errors::{ErrorReported, FatalError, Handler};
 use rustc_middle::dep_graph::{DepGraph, WorkProduct};
 use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
 use rustc_middle::ty::{self, TyCtxt};
-use rustc_middle::util::common::ErrorReported;
 use rustc_serialize::json;
 use rustc_session::config::{self, OptLevel, OutputFilenames, PrintRequest};
 use rustc_session::Session;
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index 1d61d95..aeb34e5 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -546,6 +546,15 @@
     LocalExec,
 }
 
+/// LLVMRustChecksumKind
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub enum ChecksumKind {
+    None,
+    MD5,
+    SHA1,
+}
+
 extern "C" {
     type Opaque;
 }
@@ -1640,6 +1649,9 @@
         FilenameLen: size_t,
         Directory: *const c_char,
         DirectoryLen: size_t,
+        CSKind: ChecksumKind,
+        Checksum: *const c_char,
+        ChecksumLen: size_t,
     ) -> &'a DIFile;
 
     pub fn LLVMRustDIBuilderCreateSubroutineType(
diff --git a/src/librustc_codegen_llvm/mono_item.rs b/src/librustc_codegen_llvm/mono_item.rs
index a7a9d0c..29389b4 100644
--- a/src/librustc_codegen_llvm/mono_item.rs
+++ b/src/librustc_codegen_llvm/mono_item.rs
@@ -7,11 +7,11 @@
 use log::debug;
 use rustc_codegen_ssa::traits::*;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
-use rustc_middle::mir::mono::{Linkage, Visibility};
-use rustc_middle::ty::layout::{FnAbiExt, LayoutOf};
-use rustc_middle::ty::{Instance, TypeFoldable};
-
 pub use rustc_middle::mir::mono::MonoItem;
+use rustc_middle::mir::mono::{Linkage, Visibility};
+use rustc_middle::ty::layout::FnAbiExt;
+use rustc_middle::ty::{Instance, TypeFoldable};
+use rustc_target::abi::LayoutOf;
 
 impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
     fn predefine_static(
diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs
index c06d2e6..854eff3 100644
--- a/src/librustc_codegen_llvm/type_.rs
+++ b/src/librustc_codegen_llvm/type_.rs
@@ -12,9 +12,10 @@
 use rustc_codegen_ssa::traits::*;
 use rustc_data_structures::small_c_str::SmallCStr;
 use rustc_middle::bug;
-use rustc_middle::ty::layout::{self, Align, Size, TyAndLayout};
+use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::ty::Ty;
 use rustc_target::abi::call::{CastTarget, FnAbi, Reg};
+use rustc_target::abi::{Align, Integer, Size};
 
 use std::fmt;
 use std::ptr;
@@ -114,14 +115,14 @@
 
     crate fn type_pointee_for_align(&self, align: Align) -> &'ll Type {
         // FIXME(eddyb) We could find a better approximation if ity.align < align.
-        let ity = layout::Integer::approximate_align(self, align);
+        let ity = Integer::approximate_align(self, align);
         self.type_from_integer(ity)
     }
 
     /// Return a LLVM type that has at most the required alignment,
     /// and exactly the required size, as a best-effort padding array.
     crate fn type_padding_filler(&self, size: Size, align: Align) -> &'ll Type {
-        let unit = layout::Integer::approximate_align(self, align);
+        let unit = Integer::approximate_align(self, align);
         let size = size.bytes();
         let unit_size = unit.size().bytes();
         assert_eq!(size % unit_size, 0);
diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs
index 6501ba0..f475ea7 100644
--- a/src/librustc_codegen_llvm/type_of.rs
+++ b/src/librustc_codegen_llvm/type_of.rs
@@ -4,10 +4,12 @@
 use log::debug;
 use rustc_codegen_ssa::traits::*;
 use rustc_middle::bug;
-use rustc_middle::ty::layout::{self, Align, FnAbiExt, LayoutOf, PointeeInfo, Size, TyAndLayout};
+use rustc_middle::ty::layout::{FnAbiExt, TyAndLayout};
 use rustc_middle::ty::print::obsolete::DefPathBasedNames;
 use rustc_middle::ty::{self, Ty, TypeFoldable};
-use rustc_target::abi::TyAndLayoutMethods;
+use rustc_target::abi::{Abi, Align, FieldsShape};
+use rustc_target::abi::{Int, Pointer, F32, F64};
+use rustc_target::abi::{LayoutOf, PointeeInfo, Scalar, Size, TyAndLayoutMethods, Variants};
 
 use std::fmt::Write;
 
@@ -17,8 +19,8 @@
     defer: &mut Option<(&'a Type, TyAndLayout<'tcx>)>,
 ) -> &'a Type {
     match layout.abi {
-        layout::Abi::Scalar(_) => bug!("handled elsewhere"),
-        layout::Abi::Vector { ref element, count } => {
+        Abi::Scalar(_) => bug!("handled elsewhere"),
+        Abi::Vector { ref element, count } => {
             // LLVM has a separate type for 64-bit SIMD vectors on X86 called
             // `x86_mmx` which is needed for some SIMD operations. As a bit of a
             // hack (all SIMD definitions are super unstable anyway) we
@@ -37,7 +39,7 @@
                 return cx.type_vector(element, count);
             }
         }
-        layout::Abi::ScalarPair(..) => {
+        Abi::ScalarPair(..) => {
             return cx.type_struct(
                 &[
                     layout.scalar_pair_element_llvm_type(cx, 0, false),
@@ -46,7 +48,7 @@
                 false,
             );
         }
-        layout::Abi::Uninhabited | layout::Abi::Aggregate { .. } => {}
+        Abi::Uninhabited | Abi::Aggregate { .. } => {}
     }
 
     let name = match layout.ty.kind {
@@ -61,14 +63,14 @@
             let mut name = String::with_capacity(32);
             let printer = DefPathBasedNames::new(cx.tcx, true, true);
             printer.push_type_name(layout.ty, &mut name, false);
-            if let (&ty::Adt(def, _), &layout::Variants::Single { index })
+            if let (&ty::Adt(def, _), &Variants::Single { index })
                  = (&layout.ty.kind, &layout.variants)
             {
                 if def.is_enum() && !def.variants.is_empty() {
                     write!(&mut name, "::{}", def.variants[index].ident).unwrap();
                 }
             }
-            if let (&ty::Generator(_, substs, _), &layout::Variants::Single { index })
+            if let (&ty::Generator(_, substs, _), &Variants::Single { index })
                  = (&layout.ty.kind, &layout.variants)
             {
                 write!(&mut name, "::{}", substs.as_generator().variant_name(index)).unwrap();
@@ -79,7 +81,7 @@
     };
 
     match layout.fields {
-        layout::FieldsShape::Union(_) => {
+        FieldsShape::Union(_) => {
             let fill = cx.type_padding_filler(layout.size, layout.align.abi);
             let packed = false;
             match name {
@@ -91,10 +93,8 @@
                 }
             }
         }
-        layout::FieldsShape::Array { count, .. } => {
-            cx.type_array(layout.field(cx, 0).llvm_type(cx), count)
-        }
-        layout::FieldsShape::Arbitrary { .. } => match name {
+        FieldsShape::Array { count, .. } => cx.type_array(layout.field(cx, 0).llvm_type(cx), count),
+        FieldsShape::Arbitrary { .. } => match name {
             None => {
                 let (llfields, packed) = struct_llfields(cx, layout);
                 cx.type_struct(&llfields, packed)
@@ -189,7 +189,7 @@
     fn scalar_llvm_type_at<'a>(
         &self,
         cx: &CodegenCx<'a, 'tcx>,
-        scalar: &layout::Scalar,
+        scalar: &Scalar,
         offset: Size,
     ) -> &'a Type;
     fn scalar_pair_element_llvm_type<'a>(
@@ -205,19 +205,16 @@
 impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
     fn is_llvm_immediate(&self) -> bool {
         match self.abi {
-            layout::Abi::Scalar(_) | layout::Abi::Vector { .. } => true,
-            layout::Abi::ScalarPair(..) => false,
-            layout::Abi::Uninhabited | layout::Abi::Aggregate { .. } => self.is_zst(),
+            Abi::Scalar(_) | Abi::Vector { .. } => true,
+            Abi::ScalarPair(..) => false,
+            Abi::Uninhabited | Abi::Aggregate { .. } => self.is_zst(),
         }
     }
 
     fn is_llvm_scalar_pair(&self) -> bool {
         match self.abi {
-            layout::Abi::ScalarPair(..) => true,
-            layout::Abi::Uninhabited
-            | layout::Abi::Scalar(_)
-            | layout::Abi::Vector { .. }
-            | layout::Abi::Aggregate { .. } => false,
+            Abi::ScalarPair(..) => true,
+            Abi::Uninhabited | Abi::Scalar(_) | Abi::Vector { .. } | Abi::Aggregate { .. } => false,
         }
     }
 
@@ -233,7 +230,7 @@
     /// of that field's type - this is useful for taking the address of
     /// that field and ensuring the struct has the right alignment.
     fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
-        if let layout::Abi::Scalar(ref scalar) = self.abi {
+        if let Abi::Scalar(ref scalar) = self.abi {
             // Use a different cache for scalars because pointers to DSTs
             // can be either fat or thin (data pointers of fat pointers).
             if let Some(&llty) = cx.scalar_lltypes.borrow().get(&self.ty) {
@@ -255,7 +252,7 @@
 
         // Check the cache.
         let variant_index = match self.variants {
-            layout::Variants::Single { index } => Some(index),
+            Variants::Single { index } => Some(index),
             _ => None,
         };
         if let Some(&llty) = cx.lltypes.borrow().get(&(self.ty, variant_index)) {
@@ -293,7 +290,7 @@
     }
 
     fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
-        if let layout::Abi::Scalar(ref scalar) = self.abi {
+        if let Abi::Scalar(ref scalar) = self.abi {
             if scalar.is_bool() {
                 return cx.type_i1();
             }
@@ -304,14 +301,14 @@
     fn scalar_llvm_type_at<'a>(
         &self,
         cx: &CodegenCx<'a, 'tcx>,
-        scalar: &layout::Scalar,
+        scalar: &Scalar,
         offset: Size,
     ) -> &'a Type {
         match scalar.value {
-            layout::Int(i, _) => cx.type_from_integer(i),
-            layout::F32 => cx.type_f32(),
-            layout::F64 => cx.type_f64(),
-            layout::Pointer => {
+            Int(i, _) => cx.type_from_integer(i),
+            F32 => cx.type_f32(),
+            F64 => cx.type_f64(),
+            Pointer => {
                 // If we know the alignment, pick something better than i8.
                 let pointee = if let Some(pointee) = self.pointee_info_at(cx, offset) {
                     cx.type_pointee_for_align(pointee.align)
@@ -343,7 +340,7 @@
         }
 
         let (a, b) = match self.abi {
-            layout::Abi::ScalarPair(ref a, ref b) => (a, b),
+            Abi::ScalarPair(ref a, ref b) => (a, b),
             _ => bug!("TyAndLayout::scalar_pair_element_llty({:?}): not applicable", self),
         };
         let scalar = [a, b][index];
@@ -365,21 +362,19 @@
 
     fn llvm_field_index(&self, index: usize) -> u64 {
         match self.abi {
-            layout::Abi::Scalar(_) | layout::Abi::ScalarPair(..) => {
+            Abi::Scalar(_) | Abi::ScalarPair(..) => {
                 bug!("TyAndLayout::llvm_field_index({:?}): not applicable", self)
             }
             _ => {}
         }
         match self.fields {
-            layout::FieldsShape::Union(_) => {
+            FieldsShape::Union(_) => {
                 bug!("TyAndLayout::llvm_field_index({:?}): not applicable", self)
             }
 
-            layout::FieldsShape::Array { .. } => index as u64,
+            FieldsShape::Array { .. } => index as u64,
 
-            layout::FieldsShape::Arbitrary { .. } => {
-                1 + (self.fields.memory_index(index) as u64) * 2
-            }
+            FieldsShape::Arbitrary { .. } => 1 + (self.fields.memory_index(index) as u64) * 2,
         }
     }
 
diff --git a/src/librustc_codegen_llvm/va_arg.rs b/src/librustc_codegen_llvm/va_arg.rs
index 42e9f60..8bc3579 100644
--- a/src/librustc_codegen_llvm/va_arg.rs
+++ b/src/librustc_codegen_llvm/va_arg.rs
@@ -6,8 +6,9 @@
 use rustc_codegen_ssa::traits::{
     BaseTypeMethods, BuilderMethods, ConstMethods, DerivedTypeMethods,
 };
-use rustc_middle::ty::layout::{Align, HasDataLayout, HasTyCtxt, LayoutOf, Size};
+use rustc_middle::ty::layout::HasTyCtxt;
 use rustc_middle::ty::Ty;
+use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size};
 
 #[allow(dead_code)]
 fn round_pointer_up_to_alignment(
diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index 1e780c5..49786bc 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -505,10 +505,7 @@
             cmd.args(args);
         }
     }
-    if let Some(ref args) = sess.opts.debugging_opts.pre_link_args {
-        cmd.args(args);
-    }
-    cmd.args(&sess.opts.debugging_opts.pre_link_arg);
+    cmd.args(&sess.opts.debugging_opts.pre_link_args);
 
     if sess.target.target.options.is_like_fuchsia {
         let prefix = match sess.opts.debugging_opts.sanitizer {
@@ -1302,18 +1299,17 @@
         cmd.gc_sections(keep_metadata);
     }
 
-    let used_link_args = &codegen_results.crate_info.link_args;
+    let attr_link_args = codegen_results.crate_info.link_args.iter();
+    let user_link_args: Vec<_> =
+        sess.opts.cg.link_args.iter().chain(attr_link_args).cloned().collect();
 
     if crate_type == config::CrateType::Executable {
         let mut position_independent_executable = false;
 
         if t.options.position_independent_executables {
-            let empty_vec = Vec::new();
-            let args = sess.opts.cg.link_args.as_ref().unwrap_or(&empty_vec);
-            let more_args = &sess.opts.cg.link_arg;
-            let mut args = args.iter().chain(more_args.iter()).chain(used_link_args.iter());
-
-            if is_pic(sess) && !sess.crt_static(Some(crate_type)) && !args.any(|x| *x == "-static")
+            if is_pic(sess)
+                && !sess.crt_static(Some(crate_type))
+                && !user_link_args.iter().any(|x| x == "-static")
             {
                 position_independent_executable = true;
             }
@@ -1444,11 +1440,7 @@
 
     // Finally add all the linker arguments provided on the command line along
     // with any #[link_args] attributes found inside the crate
-    if let Some(ref args) = sess.opts.cg.link_args {
-        cmd.args(args);
-    }
-    cmd.args(&sess.opts.cg.link_arg);
-    cmd.args(&used_link_args);
+    cmd.args(&user_link_args);
 }
 
 // # Native library linking
diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs
index 9e6a3b2..0297415 100644
--- a/src/librustc_codegen_ssa/base.rs
+++ b/src/librustc_codegen_ssa/base.rs
@@ -31,14 +31,14 @@
 use rustc_data_structures::sync::{par_iter, Lock, ParallelIterator};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
+use rustc_hir::lang_items::StartFnLangItem;
 use rustc_index::vec::Idx;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
 use rustc_middle::middle::cstore::EncodedMetadata;
 use rustc_middle::middle::cstore::{self, LinkagePreference};
 use rustc_middle::middle::lang_items;
-use rustc_middle::middle::lang_items::StartFnLangItem;
 use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem};
-use rustc_middle::ty::layout::{self, Align, HasTyCtxt, LayoutOf, TyAndLayout, VariantIdx};
+use rustc_middle::ty::layout::{self, HasTyCtxt, TyAndLayout};
 use rustc_middle::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
@@ -47,6 +47,7 @@
 use rustc_session::Session;
 use rustc_span::Span;
 use rustc_symbol_mangling::test as symbol_names_test;
+use rustc_target::abi::{Abi, Align, LayoutOf, Scalar, VariantIdx};
 
 use std::cmp;
 use std::ops::{Deref, DerefMut};
@@ -343,7 +344,7 @@
     val: Bx::Value,
     layout: layout::TyAndLayout<'_>,
 ) -> Bx::Value {
-    if let layout::Abi::Scalar(ref scalar) = layout.abi {
+    if let Abi::Scalar(ref scalar) = layout.abi {
         return to_immediate_scalar(bx, val, scalar);
     }
     val
@@ -352,7 +353,7 @@
 pub fn to_immediate_scalar<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     bx: &mut Bx,
     val: Bx::Value,
-    scalar: &layout::Scalar,
+    scalar: &Scalar,
 ) -> Bx::Value {
     if scalar.is_bool() {
         return bx.trunc(val, bx.cx().type_i1());
diff --git a/src/librustc_codegen_ssa/common.rs b/src/librustc_codegen_ssa/common.rs
index 8de04b7..0d0321e 100644
--- a/src/librustc_codegen_ssa/common.rs
+++ b/src/librustc_codegen_ssa/common.rs
@@ -1,17 +1,16 @@
 #![allow(non_camel_case_types, non_snake_case)]
 
 use rustc_errors::struct_span_err;
+use rustc_hir as hir;
+use rustc_hir::def_id::DefId;
+use rustc_hir::LangItem;
 use rustc_middle::ty::{Ty, TyCtxt};
 use rustc_session::Session;
 use rustc_span::Span;
 
 use crate::base;
-use crate::traits::*;
-use rustc_hir::def_id::DefId;
-use rustc_middle::middle::lang_items::LangItem;
-
 use crate::traits::BuilderMethods;
-use rustc_hir as hir;
+use crate::traits::*;
 
 pub enum IntPredicate {
     IntEQ,
diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs
index bf2f92a..bf84415 100644
--- a/src/librustc_codegen_ssa/lib.rs
+++ b/src/librustc_codegen_ssa/lib.rs
@@ -21,10 +21,10 @@
 use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::Lrc;
 use rustc_hir::def_id::CrateNum;
+use rustc_hir::LangItem;
 use rustc_middle::dep_graph::WorkProduct;
 use rustc_middle::middle::cstore::{CrateSource, LibSource, NativeLibrary};
 use rustc_middle::middle::dependency_format::Dependencies;
-use rustc_middle::middle::lang_items::LangItem;
 use rustc_middle::ty::query::Providers;
 use rustc_session::config::{OutputFilenames, OutputType, RUST_CGU_EXT};
 use rustc_span::symbol::Symbol;
diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs
index ec3de27..221f36f 100644
--- a/src/librustc_codegen_ssa/mir/analyze.rs
+++ b/src/librustc_codegen_ssa/mir/analyze.rs
@@ -12,7 +12,8 @@
 };
 use rustc_middle::mir::{self, Location, TerminatorKind};
 use rustc_middle::ty;
-use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
+use rustc_middle::ty::layout::HasTyCtxt;
+use rustc_target::abi::LayoutOf;
 
 pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     fx: &FunctionCx<'a, 'tcx, Bx>,
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index 931fab6..219d5aa 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -9,14 +9,15 @@
 use crate::traits::*;
 use crate::MemFlags;
 
+use rustc_hir::lang_items;
 use rustc_index::vec::Idx;
-use rustc_middle::middle::lang_items;
 use rustc_middle::mir;
 use rustc_middle::mir::AssertKind;
-use rustc_middle::ty::layout::{self, FnAbiExt, HasTyCtxt, LayoutOf};
+use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt};
 use rustc_middle::ty::{self, Instance, Ty, TypeFoldable};
 use rustc_span::{source_map::Span, symbol::Symbol};
 use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode};
+use rustc_target::abi::{self, LayoutOf};
 use rustc_target::spec::abi::Abi;
 
 use std::borrow::Cow;
@@ -591,7 +592,7 @@
                 // we can do what we like. Here, we declare that transmuting
                 // into an uninhabited type is impossible, so anything following
                 // it must be unreachable.
-                assert_eq!(fn_abi.ret.layout.abi, layout::Abi::Uninhabited);
+                assert_eq!(fn_abi.ret.layout.abi, abi::Abi::Uninhabited);
                 bx.unreachable();
             }
             return;
@@ -994,7 +995,7 @@
                 // the load would just produce `OperandValue::Ref` instead
                 // of the `OperandValue::Immediate` we need for the call.
                 llval = bx.load(llval, align);
-                if let layout::Abi::Scalar(ref scalar) = arg.layout.abi {
+                if let abi::Abi::Scalar(ref scalar) = arg.layout.abi {
                     if scalar.is_bool() {
                         bx.range_metadata(llval, 0..2);
                     }
diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs
index 9770d04..298aa25 100644
--- a/src/librustc_codegen_ssa/mir/constant.rs
+++ b/src/librustc_codegen_ssa/mir/constant.rs
@@ -3,9 +3,10 @@
 use rustc_index::vec::Idx;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{ConstValue, ErrorHandled};
-use rustc_middle::ty::layout::{self, HasTyCtxt};
+use rustc_middle::ty::layout::HasTyCtxt;
 use rustc_middle::ty::{self, Ty};
 use rustc_span::source_map::Span;
+use rustc_target::abi::Abi;
 
 use super::FunctionCx;
 
@@ -87,7 +88,7 @@
                         if let Some(prim) = field.try_to_scalar() {
                             let layout = bx.layout_of(field_ty);
                             let scalar = match layout.abi {
-                                layout::Abi::Scalar(ref x) => x,
+                                Abi::Scalar(ref x) => x,
                                 _ => bug!("from_const: invalid ByVal layout: {:#?}", layout),
                             };
                             bx.scalar_to_backend(prim, scalar, bx.immediate_backend_type(layout))
diff --git a/src/librustc_codegen_ssa/mir/debuginfo.rs b/src/librustc_codegen_ssa/mir/debuginfo.rs
index 4eefb37b..5501ed5 100644
--- a/src/librustc_codegen_ssa/mir/debuginfo.rs
+++ b/src/librustc_codegen_ssa/mir/debuginfo.rs
@@ -3,11 +3,10 @@
 use rustc_index::vec::IndexVec;
 use rustc_middle::mir;
 use rustc_middle::ty;
-use rustc_middle::ty::layout::{LayoutOf, Size};
 use rustc_session::config::DebugInfo;
-
 use rustc_span::symbol::{kw, Symbol};
 use rustc_span::{BytePos, Span};
+use rustc_target::abi::{LayoutOf, Size};
 
 use super::operand::OperandValue;
 use super::place::PlaceRef;
diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs
index 7545882..69f11ed 100644
--- a/src/librustc_codegen_ssa/mir/operand.rs
+++ b/src/librustc_codegen_ssa/mir/operand.rs
@@ -8,8 +8,9 @@
 
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{ConstValue, ErrorHandled, Pointer, Scalar};
-use rustc_middle::ty::layout::{self, Align, LayoutOf, Size, TyAndLayout};
+use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::ty::Ty;
+use rustc_target::abi::{Abi, Align, LayoutOf, Size};
 
 use std::fmt;
 
@@ -78,7 +79,7 @@
         let val = match val {
             ConstValue::Scalar(x) => {
                 let scalar = match layout.abi {
-                    layout::Abi::Scalar(ref x) => x,
+                    Abi::Scalar(ref x) => x,
                     _ => bug!("from_const: invalid ByVal layout: {:#?}", layout),
                 };
                 let llval = bx.scalar_to_backend(x, scalar, bx.immediate_backend_type(layout));
@@ -86,7 +87,7 @@
             }
             ConstValue::Slice { data, start, end } => {
                 let a_scalar = match layout.abi {
-                    layout::Abi::ScalarPair(ref a, _) => a,
+                    Abi::ScalarPair(ref a, _) => a,
                     _ => bug!("from_const: invalid ScalarPair layout: {:#?}", layout),
                 };
                 let a = Scalar::from(Pointer::new(
@@ -161,7 +162,7 @@
         llval: V,
         layout: TyAndLayout<'tcx>,
     ) -> Self {
-        let val = if let layout::Abi::ScalarPair(ref a, ref b) = layout.abi {
+        let val = if let Abi::ScalarPair(ref a, ref b) = layout.abi {
             debug!("Operand::from_immediate_or_packed_pair: unpacking {:?} @ {:?}", llval, layout);
 
             // Deconstruct the immediate aggregate.
@@ -199,7 +200,7 @@
             }
 
             // Extract a scalar component from a pair.
-            (OperandValue::Pair(a_llval, b_llval), &layout::Abi::ScalarPair(ref a, ref b)) => {
+            (OperandValue::Pair(a_llval, b_llval), &Abi::ScalarPair(ref a, ref b)) => {
                 if offset.bytes() == 0 {
                     assert_eq!(field.size, a.value.size(bx.cx()));
                     OperandValue::Immediate(a_llval)
@@ -211,7 +212,7 @@
             }
 
             // `#[repr(simd)]` types are also immediate.
-            (OperandValue::Immediate(llval), &layout::Abi::Vector { .. }) => {
+            (OperandValue::Immediate(llval), &Abi::Vector { .. }) => {
                 OperandValue::Immediate(bx.extract_element(llval, bx.cx().const_usize(i as u64)))
             }
 
@@ -305,7 +306,7 @@
             }
             OperandValue::Pair(a, b) => {
                 let (a_scalar, b_scalar) = match dest.layout.abi {
-                    layout::Abi::ScalarPair(ref a, ref b) => (a, b),
+                    Abi::ScalarPair(ref a, ref b) => (a, b),
                     _ => bug!("store_with_flags: invalid ScalarPair layout: {:#?}", dest.layout),
                 };
                 let b_offset = a_scalar.value.size(bx).align_to(b_scalar.value.align(bx).abi);
diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs
index eca66a5..4616951 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/src/librustc_codegen_ssa/mir/place.rs
@@ -8,8 +8,10 @@
 
 use rustc_middle::mir;
 use rustc_middle::mir::tcx::PlaceTy;
-use rustc_middle::ty::layout::{self, Align, HasTyCtxt, LayoutOf, TyAndLayout, VariantIdx};
+use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout};
 use rustc_middle::ty::{self, Ty};
+use rustc_target::abi::{Abi, Align, DiscriminantKind, FieldsShape, Int};
+use rustc_target::abi::{LayoutOf, VariantIdx, Variants};
 
 #[derive(Copy, Clone, Debug)]
 pub struct PlaceRef<'tcx, V> {
@@ -66,7 +68,7 @@
     }
 
     pub fn len<Cx: ConstMethods<'tcx, Value = V>>(&self, cx: &Cx) -> V {
-        if let layout::FieldsShape::Array { count, .. } = self.layout.fields {
+        if let FieldsShape::Array { count, .. } = self.layout.fields {
             if self.layout.is_unsized() {
                 assert_eq!(count, 0);
                 self.llextra.unwrap()
@@ -94,7 +96,7 @@
             // Unions and newtypes only use an offset of 0.
             let llval = if offset.bytes() == 0 {
                 self.llval
-            } else if let layout::Abi::ScalarPair(ref a, ref b) = self.layout.abi {
+            } else if let Abi::ScalarPair(ref a, ref b) = self.layout.abi {
                 // Offsets have to match either first or second field.
                 assert_eq!(offset, a.value.size(bx.cx()).align_to(b.value.align(bx.cx()).abi));
                 bx.struct_gep(self.llval, 1)
@@ -198,7 +200,7 @@
             return bx.cx().const_undef(cast_to);
         }
         let (discr_scalar, discr_kind, discr_index) = match self.layout.variants {
-            layout::Variants::Single { index } => {
+            Variants::Single { index } => {
                 let discr_val = self
                     .layout
                     .ty
@@ -206,7 +208,7 @@
                     .map_or(index.as_u32() as u128, |discr| discr.val);
                 return bx.cx().const_uint_big(cast_to, discr_val);
             }
-            layout::Variants::Multiple { ref discr, ref discr_kind, discr_index, .. } => {
+            Variants::Multiple { ref discr, ref discr_kind, discr_index, .. } => {
                 (discr, discr_kind, discr_index)
             }
         };
@@ -217,22 +219,18 @@
 
         // Decode the discriminant (specifically if it's niche-encoded).
         match *discr_kind {
-            layout::DiscriminantKind::Tag => {
+            DiscriminantKind::Tag => {
                 let signed = match discr_scalar.value {
                     // We use `i1` for bytes that are always `0` or `1`,
                     // e.g., `#[repr(i8)] enum E { A, B }`, but we can't
                     // let LLVM interpret the `i1` as signed, because
                     // then `i1 1` (i.e., `E::B`) is effectively `i8 -1`.
-                    layout::Int(_, signed) => !discr_scalar.is_bool() && signed,
+                    Int(_, signed) => !discr_scalar.is_bool() && signed,
                     _ => false,
                 };
                 bx.intcast(encoded_discr.immediate(), cast_to, signed)
             }
-            layout::DiscriminantKind::Niche {
-                dataful_variant,
-                ref niche_variants,
-                niche_start,
-            } => {
+            DiscriminantKind::Niche { dataful_variant, ref niche_variants, niche_start } => {
                 // Rebase from niche values to discriminants, and check
                 // whether the result is in range for the niche variants.
                 let niche_llty = bx.cx().immediate_backend_type(encoded_discr.layout);
@@ -311,14 +309,10 @@
             return;
         }
         match self.layout.variants {
-            layout::Variants::Single { index } => {
+            Variants::Single { index } => {
                 assert_eq!(index, variant_index);
             }
-            layout::Variants::Multiple {
-                discr_kind: layout::DiscriminantKind::Tag,
-                discr_index,
-                ..
-            } => {
+            Variants::Multiple { discr_kind: DiscriminantKind::Tag, discr_index, .. } => {
                 let ptr = self.project_field(bx, discr_index);
                 let to =
                     self.layout.ty.discriminant_for_variant(bx.tcx(), variant_index).unwrap().val;
@@ -328,9 +322,9 @@
                     ptr.align,
                 );
             }
-            layout::Variants::Multiple {
+            Variants::Multiple {
                 discr_kind:
-                    layout::DiscriminantKind::Niche { dataful_variant, ref niche_variants, niche_start },
+                    DiscriminantKind::Niche { dataful_variant, ref niche_variants, niche_start },
                 discr_index,
                 ..
             } => {
diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs
index ce681c7..57fe7b0 100644
--- a/src/librustc_codegen_ssa/mir/rvalue.rs
+++ b/src/librustc_codegen_ssa/mir/rvalue.rs
@@ -8,15 +8,14 @@
 use crate::MemFlags;
 
 use rustc_apfloat::{ieee, Float, Round, Status};
-use rustc_middle::middle::lang_items::ExchangeMallocFnLangItem;
+use rustc_hir::lang_items::ExchangeMallocFnLangItem;
 use rustc_middle::mir;
 use rustc_middle::ty::cast::{CastTy, IntTy};
-use rustc_middle::ty::layout::{self, HasTyCtxt, LayoutOf};
+use rustc_middle::ty::layout::HasTyCtxt;
 use rustc_middle::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt};
 use rustc_span::source_map::{Span, DUMMY_SP};
 use rustc_span::symbol::sym;
-
-use std::{i128, u128};
+use rustc_target::abi::{Abi, Int, LayoutOf, Variants};
 
 impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     pub fn codegen_rvalue(
@@ -292,7 +291,7 @@
                         let r_t_out = CastTy::from_ty(cast.ty).expect("bad output type for cast");
                         let ll_t_in = bx.cx().immediate_backend_type(operand.layout);
                         match operand.layout.variants {
-                            layout::Variants::Single { index } => {
+                            Variants::Single { index } => {
                                 if let Some(discr) =
                                     operand.layout.ty.discriminant_for_variant(bx.tcx(), index)
                                 {
@@ -311,13 +310,13 @@
                                     );
                                 }
                             }
-                            layout::Variants::Multiple { .. } => {}
+                            Variants::Multiple { .. } => {}
                         }
                         let llval = operand.immediate();
 
                         let mut signed = false;
-                        if let layout::Abi::Scalar(ref scalar) = operand.layout.abi {
-                            if let layout::Int(_, s) = scalar.value {
+                        if let Abi::Scalar(ref scalar) = operand.layout.abi {
+                            if let Int(_, s) = scalar.value {
                                 // We use `i1` for bytes that are always `0` or `1`,
                                 // e.g., `#[repr(i8)] enum E { A, B }`, but we can't
                                 // let LLVM interpret the `i1` as signed, because
diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs
index 1474edd..91be123 100644
--- a/src/librustc_codegen_ssa/traits/backend.rs
+++ b/src/librustc_codegen_ssa/traits/backend.rs
@@ -3,17 +3,18 @@
 use crate::ModuleCodegen;
 
 use rustc_ast::expand::allocator::AllocatorKind;
+use rustc_errors::ErrorReported;
 use rustc_middle::dep_graph::DepGraph;
 use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
-use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
+use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout};
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{Ty, TyCtxt};
-use rustc_middle::util::common::ErrorReported;
 use rustc_session::{
     config::{self, OutputFilenames, PrintRequest},
     Session,
 };
 use rustc_span::symbol::Symbol;
+use rustc_target::abi::LayoutOf;
 
 pub use rustc_data_structures::sync::MetadataRef;
 
diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs
index d59ea38..caba7eb 100644
--- a/src/librustc_codegen_ssa/traits/builder.rs
+++ b/src/librustc_codegen_ssa/traits/builder.rs
@@ -12,8 +12,9 @@
 use crate::mir::place::PlaceRef;
 use crate::MemFlags;
 
-use rustc_middle::ty::layout::{Align, HasParamEnv, Size};
+use rustc_middle::ty::layout::HasParamEnv;
 use rustc_middle::ty::Ty;
+use rustc_target::abi::{Align, Size};
 use rustc_target::spec::HasTargetSpec;
 
 use std::iter::TrustedLen;
diff --git a/src/librustc_codegen_ssa/traits/consts.rs b/src/librustc_codegen_ssa/traits/consts.rs
index e5e1aa6..6b58dea 100644
--- a/src/librustc_codegen_ssa/traits/consts.rs
+++ b/src/librustc_codegen_ssa/traits/consts.rs
@@ -1,9 +1,9 @@
 use super::BackendTypes;
 use crate::mir::place::PlaceRef;
-use rustc_middle::mir::interpret::Allocation;
-use rustc_middle::mir::interpret::Scalar;
-use rustc_middle::ty::layout;
+use rustc_middle::mir::interpret::{Allocation, Scalar};
+use rustc_middle::ty::layout::TyAndLayout;
 use rustc_span::Symbol;
+use rustc_target::abi::{self, Size};
 
 pub trait ConstMethods<'tcx>: BackendTypes {
     // Constant constructors
@@ -26,17 +26,12 @@
     fn const_to_opt_uint(&self, v: Self::Value) -> Option<u64>;
     fn const_to_opt_u128(&self, v: Self::Value, sign_ext: bool) -> Option<u128>;
 
-    fn scalar_to_backend(
-        &self,
-        cv: Scalar,
-        layout: &layout::Scalar,
-        llty: Self::Type,
-    ) -> Self::Value;
+    fn scalar_to_backend(&self, cv: Scalar, layout: &abi::Scalar, llty: Self::Type) -> Self::Value;
     fn from_const_alloc(
         &self,
-        layout: layout::TyAndLayout<'tcx>,
+        layout: TyAndLayout<'tcx>,
         alloc: &Allocation,
-        offset: layout::Size,
+        offset: Size,
     ) -> PlaceRef<'tcx, Self::Value>;
 
     fn const_ptrcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value;
diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs
index 4e84c09..34be1cf 100644
--- a/src/librustc_codegen_ssa/traits/debuginfo.rs
+++ b/src/librustc_codegen_ssa/traits/debuginfo.rs
@@ -3,10 +3,10 @@
 use rustc_ast::ast::Name;
 use rustc_hir::def_id::CrateNum;
 use rustc_middle::mir;
-use rustc_middle::ty::layout::Size;
 use rustc_middle::ty::{Instance, Ty};
 use rustc_span::{SourceFile, Span};
 use rustc_target::abi::call::FnAbi;
+use rustc_target::abi::Size;
 
 pub trait DebugInfoMethods<'tcx>: BackendTypes {
     fn create_vtable_metadata(&self, ty: Ty<'tcx>, vtable: Self::Value);
diff --git a/src/librustc_codegen_ssa/traits/statics.rs b/src/librustc_codegen_ssa/traits/statics.rs
index 50df086..a6462b3 100644
--- a/src/librustc_codegen_ssa/traits/statics.rs
+++ b/src/librustc_codegen_ssa/traits/statics.rs
@@ -1,6 +1,6 @@
 use super::BackendTypes;
 use rustc_hir::def_id::DefId;
-use rustc_middle::ty::layout::Align;
+use rustc_target::abi::Align;
 
 pub trait StaticMethods: BackendTypes {
     fn static_addr_of(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value;
diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/src/librustc_codegen_ssa/traits/type_.rs
index 383be6d..703479b 100644
--- a/src/librustc_codegen_ssa/traits/type_.rs
+++ b/src/librustc_codegen_ssa/traits/type_.rs
@@ -3,10 +3,11 @@
 use super::HasCodegen;
 use crate::common::TypeKind;
 use crate::mir::place::PlaceRef;
-use rustc_middle::ty::layout::{self, TyAndLayout};
+use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::ty::{self, Ty};
 use rustc_span::DUMMY_SP;
 use rustc_target::abi::call::{ArgAbi, CastTarget, FnAbi, Reg};
+use rustc_target::abi::Integer;
 
 // This depends on `Backend` and not `BackendTypes`, because consumers will probably want to use
 // `LayoutOf` or `HasTyCtxt`. This way, they don't have to add a constraint on it themselves.
@@ -53,8 +54,8 @@
         }
     }
 
-    fn type_from_integer(&self, i: layout::Integer) -> Self::Type {
-        use rustc_middle::ty::layout::Integer::*;
+    fn type_from_integer(&self, i: Integer) -> Self::Type {
+        use Integer::*;
         match i {
             I8 => self.type_i8(),
             I16 => self.type_i16(),
diff --git a/src/librustc_data_structures/graph/implementation/mod.rs b/src/librustc_data_structures/graph/implementation/mod.rs
index f705c2f..1aa7ac0 100644
--- a/src/librustc_data_structures/graph/implementation/mod.rs
+++ b/src/librustc_data_structures/graph/implementation/mod.rs
@@ -23,7 +23,6 @@
 use crate::snapshot_vec::{SnapshotVec, SnapshotVecDelegate};
 use rustc_index::bit_set::BitSet;
 use std::fmt::Debug;
-use std::usize;
 
 #[cfg(test)]
 mod tests;
diff --git a/src/librustc_data_structures/profiling.rs b/src/librustc_data_structures/profiling.rs
index a7cdc48..23f3558 100644
--- a/src/librustc_data_structures/profiling.rs
+++ b/src/librustc_data_structures/profiling.rs
@@ -93,7 +93,6 @@
 use std::process;
 use std::sync::Arc;
 use std::time::{Duration, Instant};
-use std::u32;
 
 use measureme::{EventId, EventIdBuilder, SerializableString, StringId};
 use parking_lot::RwLock;
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 8f8c2ea..acf8f1a 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -22,10 +22,8 @@
 use rustc_codegen_ssa::{traits::CodegenBackend, CodegenResults};
 use rustc_data_structures::profiling::print_time_passes_entry;
 use rustc_data_structures::sync::SeqCst;
-use rustc_errors::{
-    registry::{InvalidErrorCode, Registry},
-    PResult,
-};
+use rustc_errors::registry::{InvalidErrorCode, Registry};
+use rustc_errors::{ErrorReported, PResult};
 use rustc_feature::{find_gated_cfg, UnstableFeatures};
 use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_interface::util::{collect_crate_types, get_builtin_codegen_backend};
@@ -34,7 +32,6 @@
 use rustc_metadata::locator;
 use rustc_middle::middle::cstore::MetadataLoader;
 use rustc_middle::ty::TyCtxt;
-use rustc_middle::util::common::ErrorReported;
 use rustc_save_analysis as save;
 use rustc_save_analysis::DumpHandler;
 use rustc_serialize::json::{self, ToJson};
@@ -139,7 +136,6 @@
 }
 
 // Parse args and run the compiler. This is the primary entry point for rustc.
-// See comments on CompilerCalls below for details about the callbacks argument.
 // The FileLoader provides a way to load files from sources other than the file system.
 pub fn run_compiler(
     at_args: &[String],
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 87777bd..78a2718 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -2,12 +2,12 @@
 
 use rustc_ast::ast;
 use rustc_ast_pretty::pprust;
+use rustc_errors::ErrorReported;
 use rustc_hir as hir;
 use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_hir_pretty as pprust_hir;
 use rustc_middle::hir::map as hir_map;
 use rustc_middle::ty::{self, TyCtxt};
-use rustc_middle::util::common::ErrorReported;
 use rustc_mir::util::{write_mir_graphviz, write_mir_pretty};
 use rustc_session::config::{Input, PpMode, PpSourceMode};
 use rustc_session::Session;
diff --git a/src/librustc_error_codes/error_codes/E0502.md b/src/librustc_error_codes/error_codes/E0502.md
index f15c05d..b90c59f 100644
--- a/src/librustc_error_codes/error_codes/E0502.md
+++ b/src/librustc_error_codes/error_codes/E0502.md
@@ -1,5 +1,4 @@
-This error indicates that you are trying to borrow a variable as mutable when it
-has already been borrowed as immutable.
+A variable already borrowed as immutable was borrowed as mutable.
 
 Erroneous code example:
 
diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs
index fffae0b..2dbd9f4 100644
--- a/src/librustc_errors/diagnostic_builder.rs
+++ b/src/librustc_errors/diagnostic_builder.rs
@@ -315,6 +315,20 @@
         self
     }
 
+    pub fn span_suggestion_verbose(
+        &mut self,
+        sp: Span,
+        msg: &str,
+        suggestion: String,
+        applicability: Applicability,
+    ) -> &mut Self {
+        if !self.0.allow_suggestions {
+            return self;
+        }
+        self.0.diagnostic.span_suggestion_verbose(sp, msg, suggestion, applicability);
+        self
+    }
+
     pub fn span_suggestion_hidden(
         &mut self,
         sp: Span,
diff --git a/src/librustc_expand/mbe/macro_parser.rs b/src/librustc_expand/mbe/macro_parser.rs
index e868b7e..5fb8009 100644
--- a/src/librustc_expand/mbe/macro_parser.rs
+++ b/src/librustc_expand/mbe/macro_parser.rs
@@ -768,7 +768,7 @@
     /// Checks whether the non-terminal may contain a single (non-keyword) identifier.
     fn may_be_ident(nt: &token::Nonterminal) -> bool {
         match *nt {
-            token::NtItem(_) | token::NtBlock(_) | token::NtVis(_) => false,
+            token::NtItem(_) | token::NtBlock(_) | token::NtVis(_) | token::NtLifetime(_) => false,
             _ => true,
         }
     }
diff --git a/src/librustc_index/vec.rs b/src/librustc_index/vec.rs
index d8c67f6..a84f89c 100644
--- a/src/librustc_index/vec.rs
+++ b/src/librustc_index/vec.rs
@@ -7,7 +7,6 @@
 use std::marker::PhantomData;
 use std::ops::{Index, IndexMut, Range, RangeBounds};
 use std::slice;
-use std::u32;
 use std::vec;
 
 /// Represents some newtyped `usize` wrapper.
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs
index 3836bd9..d206a30 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs
@@ -5,9 +5,8 @@
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
 use crate::infer::lexical_region_resolve::RegionResolutionError;
 use crate::infer::SubregionOrigin;
-use rustc_middle::util::common::ErrorReported;
 
-use rustc_errors::struct_span_err;
+use rustc_errors::{struct_span_err, ErrorReported};
 
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     /// Print the error message for lifetime errors when both the concerned regions are anonymous.
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs
index 4613c43..2aed3d9 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs
@@ -1,9 +1,8 @@
 use crate::infer::lexical_region_resolve::RegionResolutionError;
 use crate::infer::lexical_region_resolve::RegionResolutionError::*;
 use crate::infer::InferCtxt;
-use rustc_errors::DiagnosticBuilder;
+use rustc_errors::{DiagnosticBuilder, ErrorReported};
 use rustc_middle::ty::{self, TyCtxt};
-use rustc_middle::util::common::ErrorReported;
 use rustc_span::source_map::Span;
 
 mod different_lifetimes;
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/outlives_closure.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/outlives_closure.rs
index 028148b..70c3027 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/outlives_closure.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/outlives_closure.rs
@@ -4,9 +4,9 @@
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
 use crate::infer::lexical_region_resolve::RegionResolutionError::SubSupConflict;
 use crate::infer::SubregionOrigin;
+use rustc_errors::ErrorReported;
 use rustc_hir::{Expr, ExprKind::Closure, Node};
 use rustc_middle::ty::RegionKind;
-use rustc_middle::util::common::ErrorReported;
 
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     /// Print the error message for lifetime errors when binding escapes a closure.
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
index 34653f2..7f3ec85 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -3,9 +3,8 @@
 use crate::infer::error_reporting::msg_span_from_free_region;
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
 use crate::infer::lexical_region_resolve::RegionResolutionError;
-use rustc_errors::Applicability;
+use rustc_errors::{Applicability, ErrorReported};
 use rustc_middle::ty::{BoundRegion, FreeRegion, RegionKind};
-use rustc_middle::util::common::ErrorReported;
 
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     /// Print the error message for lifetime errors when the return type is a static impl Trait.
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs
index a2cd54b..695f3e4 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs
@@ -4,8 +4,8 @@
 use crate::infer::lexical_region_resolve::RegionResolutionError;
 use crate::infer::{Subtype, ValuePairs};
 use crate::traits::ObligationCauseCode::CompareImplMethodObligation;
+use rustc_errors::ErrorReported;
 use rustc_middle::ty::Ty;
-use rustc_middle::util::common::ErrorReported;
 use rustc_span::Span;
 
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
diff --git a/src/librustc_infer/infer/lexical_region_resolve/graphviz.rs b/src/librustc_infer/infer/lexical_region_resolve/graphviz.rs
index c43d810..141424f 100644
--- a/src/librustc_infer/infer/lexical_region_resolve/graphviz.rs
+++ b/src/librustc_infer/infer/lexical_region_resolve/graphviz.rs
@@ -1,5 +1,5 @@
 //! This module provides linkage between libgraphviz traits and
-//! `rustc_middle::middle::typeck::infer::region_constraints`, generating a
+//! `rustc_trait_selection::infer::region_constraints`, generating a
 //! rendering of the graph represented by the list of `Constraint`
 //! instances (which make up the edges of the graph), as well as the
 //! origin for each constraint (which are attached to the labels on
diff --git a/src/librustc_infer/infer/type_variable.rs b/src/librustc_infer/infer/type_variable.rs
index 8e4199f..1de820c 100644
--- a/src/librustc_infer/infer/type_variable.rs
+++ b/src/librustc_infer/infer/type_variable.rs
@@ -8,7 +8,6 @@
 use std::cmp;
 use std::marker::PhantomData;
 use std::ops::Range;
-use std::u32;
 
 pub struct TypeVariableTable<'tcx> {
     values: sv::SnapshotVec<Delegate>,
diff --git a/src/librustc_infer/traits/mod.rs b/src/librustc_infer/traits/mod.rs
index 0c45199..758a0b3 100644
--- a/src/librustc_infer/traits/mod.rs
+++ b/src/librustc_infer/traits/mod.rs
@@ -6,7 +6,7 @@
 pub mod error_reporting;
 mod project;
 mod structural_impls;
-mod util;
+pub mod util;
 
 use rustc_hir as hir;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
diff --git a/src/librustc_infer/traits/util.rs b/src/librustc_infer/traits/util.rs
index 80a1e28..4fa74f9 100644
--- a/src/librustc_infer/traits/util.rs
+++ b/src/librustc_infer/traits/util.rs
@@ -2,9 +2,12 @@
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::ty::outlives::Component;
-use rustc_middle::ty::{self, ToPolyTraitRef, TyCtxt};
+use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, TyCtxt, WithConstness};
 
-fn anonymize_predicate<'tcx>(tcx: TyCtxt<'tcx>, pred: &ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
+pub fn anonymize_predicate<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    pred: &ty::Predicate<'tcx>,
+) -> ty::Predicate<'tcx> {
     match *pred {
         ty::Predicate::Trait(ref data, constness) => {
             ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data), constness)
@@ -88,6 +91,21 @@
     visited: PredicateSet<'tcx>,
 }
 
+pub fn elaborate_trait_ref<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    trait_ref: ty::PolyTraitRef<'tcx>,
+) -> Elaborator<'tcx> {
+    elaborate_predicates(tcx, vec![trait_ref.without_const().to_predicate()])
+}
+
+pub fn elaborate_trait_refs<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
+) -> Elaborator<'tcx> {
+    let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate()).collect();
+    elaborate_predicates(tcx, predicates)
+}
+
 pub fn elaborate_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
     mut predicates: Vec<ty::Predicate<'tcx>>,
@@ -98,6 +116,10 @@
 }
 
 impl Elaborator<'tcx> {
+    pub fn filter_to_traits(self) -> FilterToTraits<Self> {
+        FilterToTraits::new(self)
+    }
+
     fn elaborate(&mut self, predicate: &ty::Predicate<'tcx>) {
         let tcx = self.visited.tcx;
         match *predicate {
@@ -223,3 +245,57 @@
         }
     }
 }
+
+///////////////////////////////////////////////////////////////////////////
+// Supertrait iterator
+///////////////////////////////////////////////////////////////////////////
+
+pub type Supertraits<'tcx> = FilterToTraits<Elaborator<'tcx>>;
+
+pub fn supertraits<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    trait_ref: ty::PolyTraitRef<'tcx>,
+) -> Supertraits<'tcx> {
+    elaborate_trait_ref(tcx, trait_ref).filter_to_traits()
+}
+
+pub fn transitive_bounds<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
+) -> Supertraits<'tcx> {
+    elaborate_trait_refs(tcx, bounds).filter_to_traits()
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Other
+///////////////////////////////////////////////////////////////////////////
+
+/// A filter around an iterator of predicates that makes it yield up
+/// just trait references.
+pub struct FilterToTraits<I> {
+    base_iterator: I,
+}
+
+impl<I> FilterToTraits<I> {
+    fn new(base: I) -> FilterToTraits<I> {
+        FilterToTraits { base_iterator: base }
+    }
+}
+
+impl<'tcx, I: Iterator<Item = ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> {
+    type Item = ty::PolyTraitRef<'tcx>;
+
+    fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
+        while let Some(pred) = self.base_iterator.next() {
+            if let ty::Predicate::Trait(data, _) = pred {
+                return Some(data.to_poly_trait_ref());
+            }
+        }
+        None
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let (_, upper) = self.base_iterator.size_hint();
+        (0, upper)
+    }
+}
diff --git a/src/librustc_interface/callbacks.rs b/src/librustc_interface/callbacks.rs
index 88c3d0e..913c67d 100644
--- a/src/librustc_interface/callbacks.rs
+++ b/src/librustc_interface/callbacks.rs
@@ -58,5 +58,4 @@
     rustc_span::SPAN_DEBUG.swap(&(span_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
     rustc_hir::def_id::DEF_ID_DEBUG.swap(&(def_id_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
     TRACK_DIAGNOSTICS.swap(&(track_diagnostic as fn(&_)));
-    rustc_middle::ty::RESOLVE_INSTANCE.swap(&(rustc_ty::instance::resolve_instance as _));
 }
diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs
index a50e802..8e929b7 100644
--- a/src/librustc_interface/interface.rs
+++ b/src/librustc_interface/interface.rs
@@ -8,9 +8,9 @@
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::OnDrop;
 use rustc_errors::registry::Registry;
+use rustc_errors::ErrorReported;
 use rustc_lint::LintStore;
 use rustc_middle::ty;
-use rustc_middle::util::common::ErrorReported;
 use rustc_parse::new_parser_from_source_str;
 use rustc_session::config::{self, ErrorOutputType, Input, OutputFilenames};
 use rustc_session::early_error;
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index e3fc4fa..609c80a 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -9,7 +9,7 @@
 use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_data_structures::sync::{par_iter, Lrc, Once, ParallelIterator, WorkerLocal};
 use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel};
-use rustc_errors::PResult;
+use rustc_errors::{ErrorReported, PResult};
 use rustc_expand::base::ExtCtxt;
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_hir::definitions::Definitions;
@@ -21,7 +21,6 @@
 use rustc_middle::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn};
 use rustc_middle::ty::steal::Steal;
 use rustc_middle::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt};
-use rustc_middle::util::common::ErrorReported;
 use rustc_mir as mir;
 use rustc_mir_build as mir_build;
 use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str};
diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs
index 9957765..6a62d75 100644
--- a/src/librustc_interface/queries.rs
+++ b/src/librustc_interface/queries.rs
@@ -4,6 +4,7 @@
 use rustc_ast::{self, ast};
 use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_data_structures::sync::{Lrc, Once, WorkerLocal};
+use rustc_errors::ErrorReported;
 use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_hir::Crate;
 use rustc_incremental::DepGraphFuture;
@@ -12,7 +13,6 @@
 use rustc_middle::dep_graph::DepGraph;
 use rustc_middle::ty::steal::Steal;
 use rustc_middle::ty::{GlobalCtxt, ResolverOutputs, TyCtxt};
-use rustc_middle::util::common::ErrorReported;
 use rustc_session::config::{OutputFilenames, OutputType};
 use rustc_session::{output::find_crate_name, Session};
 use rustc_span::symbol::sym;
diff --git a/src/librustc_interface/tests.rs b/src/librustc_interface/tests.rs
index f58c5cc..b452ccf 100644
--- a/src/librustc_interface/tests.rs
+++ b/src/librustc_interface/tests.rs
@@ -382,7 +382,7 @@
     opts.cg.linker = Some(PathBuf::from("linker"));
     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
 
-    opts.cg.link_args = Some(vec![String::from("abc"), String::from("def")]);
+    opts.cg.link_args = vec![String::from("abc"), String::from("def")];
     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
 
     opts.cg.link_dead_code = true;
diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs
index a8cc34e..02bf1ad 100644
--- a/src/librustc_interface/util.rs
+++ b/src/librustc_interface/util.rs
@@ -22,7 +22,7 @@
 use rustc_session::CrateDisambiguator;
 use rustc_session::{config, early_error, filesearch, output, DiagnosticOutput, Session};
 use rustc_span::edition::Edition;
-use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMap};
+use rustc_span::source_map::{FileLoader, SourceMap};
 use rustc_span::symbol::{sym, Symbol};
 use smallvec::SmallVec;
 use std::env;
@@ -62,15 +62,13 @@
     lint_caps: FxHashMap<lint::LintId, lint::Level>,
     descriptions: Registry,
 ) -> (Lrc<Session>, Lrc<Box<dyn CodegenBackend>>, Lrc<SourceMap>) {
-    let loader = file_loader.unwrap_or(box RealFileLoader);
-    let source_map = Lrc::new(SourceMap::with_file_loader(loader, sopts.file_path_mapping()));
-    let mut sess = session::build_session_with_source_map(
+    let (mut sess, source_map) = session::build_session_with_source_map(
         sopts,
         input_path,
         descriptions,
-        source_map.clone(),
         diagnostic_output,
         lint_caps,
+        file_loader,
     );
 
     let codegen_backend = get_codegen_backend(&sess);
diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs
index fcb7475..5ccfc1b 100644
--- a/src/librustc_lexer/src/lib.rs
+++ b/src/librustc_lexer/src/lib.rs
@@ -148,6 +148,10 @@
 pub struct UnvalidatedRawStr {
     /// The prefix (`r###"`) is valid
     valid_start: bool,
+
+    /// The postfix (`"###`) is valid
+    valid_end: bool,
+
     /// The number of leading `#`
     n_start_hashes: usize,
     /// The number of trailing `#`. `n_end_hashes` <= `n_start_hashes`
@@ -197,7 +201,7 @@
         let n_start_safe: u16 =
             self.n_start_hashes.try_into().map_err(|_| LexRawStrError::TooManyDelimiters)?;
 
-        if self.n_start_hashes > self.n_end_hashes {
+        if self.n_start_hashes > self.n_end_hashes || !self.valid_end {
             Err(LexRawStrError::NoTerminator {
                 expected: self.n_start_hashes,
                 found: self.n_end_hashes,
@@ -687,6 +691,7 @@
             _ => {
                 return UnvalidatedRawStr {
                     valid_start,
+                    valid_end: false,
                     n_start_hashes,
                     n_end_hashes: 0,
                     possible_terminator_offset,
@@ -702,6 +707,7 @@
             if self.is_eof() {
                 return UnvalidatedRawStr {
                     valid_start,
+                    valid_end: false,
                     n_start_hashes,
                     n_end_hashes: max_hashes,
                     possible_terminator_offset,
@@ -727,6 +733,7 @@
             if n_end_hashes == n_start_hashes {
                 return UnvalidatedRawStr {
                     valid_start,
+                    valid_end: true,
                     n_start_hashes,
                     n_end_hashes,
                     possible_terminator_offset: None,
diff --git a/src/librustc_lexer/src/tests.rs b/src/librustc_lexer/src/tests.rs
index 4af4355..06fc159 100644
--- a/src/librustc_lexer/src/tests.rs
+++ b/src/librustc_lexer/src/tests.rs
@@ -23,6 +23,7 @@
                 n_start_hashes: 0,
                 n_end_hashes: 0,
                 valid_start: true,
+                valid_end: true,
                 possible_terminator_offset: None,
             },
             Ok(ValidatedRawStr { n_hashes: 0 }),
@@ -37,6 +38,7 @@
                 n_start_hashes: 0,
                 n_end_hashes: 0,
                 valid_start: true,
+                valid_end: true,
                 possible_terminator_offset: None,
             },
             Ok(ValidatedRawStr { n_hashes: 0 }),
@@ -51,6 +53,7 @@
             UnvalidatedRawStr {
                 n_start_hashes: 1,
                 n_end_hashes: 1,
+                valid_end: true,
                 valid_start: true,
                 possible_terminator_offset: None,
             },
@@ -65,6 +68,7 @@
             UnvalidatedRawStr {
                 n_start_hashes: 1,
                 n_end_hashes: 0,
+                valid_end: false,
                 valid_start: true,
                 possible_terminator_offset: None,
             },
@@ -80,6 +84,7 @@
                 n_start_hashes: 2,
                 n_end_hashes: 1,
                 valid_start: true,
+                valid_end: false,
                 possible_terminator_offset: Some(7),
             },
             Err(LexRawStrError::NoTerminator {
@@ -95,6 +100,7 @@
                 n_start_hashes: 2,
                 n_end_hashes: 0,
                 valid_start: true,
+                valid_end: false,
                 possible_terminator_offset: None,
             },
             Err(LexRawStrError::NoTerminator {
@@ -113,9 +119,30 @@
                 n_start_hashes: 1,
                 n_end_hashes: 0,
                 valid_start: false,
+                valid_end: false,
                 possible_terminator_offset: None,
             },
             Err(LexRawStrError::InvalidStarter),
         );
     }
+
+    #[test]
+    fn test_unterminated_no_pound() {
+        // https://github.com/rust-lang/rust/issues/70677
+        check_raw_str(
+            r#"""#,
+            UnvalidatedRawStr {
+                n_start_hashes: 0,
+                n_end_hashes: 0,
+                valid_start: true,
+                valid_end: false,
+                possible_terminator_offset: None,
+            },
+            Err(LexRawStrError::NoTerminator {
+                expected: 0,
+                found: 0,
+                possible_terminator_offset: None,
+            }),
+        );
+    }
 }
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 646febe..cff86e8 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -36,12 +36,13 @@
 use rustc_hir::{GenericParamKind, PatKind};
 use rustc_hir::{HirIdSet, Node};
 use rustc_middle::lint::LintDiagnosticBuilder;
-use rustc_middle::ty::{self, layout::VariantIdx, Ty, TyCtxt};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::lint::FutureIncompatibleInfo;
 use rustc_span::edition::Edition;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::{BytePos, Span};
+use rustc_target::abi::VariantIdx;
 use rustc_trait_selection::traits::misc::can_type_implement_copy;
 
 use crate::nonstandard_style::{method_context, MethodLateContext};
diff --git a/src/librustc_lint/context.rs b/src/librustc_lint/context.rs
index 12543cf..1747a78 100644
--- a/src/librustc_lint/context.rs
+++ b/src/librustc_lint/context.rs
@@ -29,12 +29,13 @@
 use rustc_middle::lint::LintDiagnosticBuilder;
 use rustc_middle::middle::privacy::AccessLevels;
 use rustc_middle::middle::stability;
-use rustc_middle::ty::layout::{LayoutError, LayoutOf, TyAndLayout};
+use rustc_middle::ty::layout::{LayoutError, TyAndLayout};
 use rustc_middle::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt};
 use rustc_session::lint::{add_elided_lifetime_in_path_suggestion, BuiltinLintDiagnostics};
 use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
 use rustc_session::Session;
 use rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP};
+use rustc_target::abi::LayoutOf;
 
 use std::slice;
 
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index 52ec8cd..aa805a2 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -10,17 +10,17 @@
 use rustc_hir::{is_range_literal, ExprKind, Node};
 use rustc_index::vec::Idx;
 use rustc_middle::mir::interpret::{sign_extend, truncate};
-use rustc_middle::ty::layout::{self, IntegerExt, LayoutOf, SizeSkeleton, VariantIdx};
+use rustc_middle::ty::layout::{IntegerExt, SizeSkeleton};
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
 use rustc_span::source_map;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
+use rustc_target::abi::{DiscriminantKind, Integer, LayoutOf, VariantIdx, Variants};
 use rustc_target::spec::abi::Abi;
 
 use log::debug;
 use std::cmp;
-use std::{f32, f64, i16, i32, i64, i8, u16, u32, u64, u8};
 
 declare_lint! {
     UNUSED_COMPARISONS,
@@ -150,7 +150,7 @@
     val: u128,
     negative: bool,
 ) {
-    let size = layout::Integer::from_attr(&cx.tcx, ty).size();
+    let size = Integer::from_attr(&cx.tcx, ty).size();
     cx.struct_span_lint(OVERFLOWING_LITERALS, expr.span, |lint| {
         let (t, actually) = match ty {
             attr::IntType::SignedInt(t) => {
@@ -1034,8 +1034,8 @@
                 | Err(ty::layout::LayoutError::SizeOverflow(_)) => return,
             };
             let (variants, tag) = match layout.variants {
-                layout::Variants::Multiple {
-                    discr_kind: layout::DiscriminantKind::Tag,
+                Variants::Multiple {
+                    discr_kind: DiscriminantKind::Tag,
                     ref discr,
                     ref variants,
                     ..
diff --git a/src/librustc_metadata/build.rs b/src/librustc_metadata/build.rs
index d230ba9..7d5c58e 100644
--- a/src/librustc_metadata/build.rs
+++ b/src/librustc_metadata/build.rs
@@ -1,4 +1,5 @@
 fn main() {
     println!("cargo:rerun-if-changed=build.rs");
     println!("cargo:rerun-if-env-changed=CFG_VERSION");
+    println!("cargo:rerun-if-env-changed=CFG_VIRTUAL_RUST_SOURCE_BASE_DIR");
 }
diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs
index e952051..4b92a22 100644
--- a/src/librustc_metadata/native_libs.rs
+++ b/src/librustc_metadata/native_libs.rs
@@ -162,8 +162,13 @@
             }
         }
         if lib.cfg.is_some() && !self.tcx.features().link_cfg {
-            feature_err(&self.tcx.sess.parse_sess, sym::link_cfg, span.unwrap(), "is unstable")
-                .emit();
+            feature_err(
+                &self.tcx.sess.parse_sess,
+                sym::link_cfg,
+                span.unwrap(),
+                "kind=\"link_cfg\" is unstable",
+            )
+            .emit();
         }
         if lib.kind == cstore::NativeStaticNobundle && !self.tcx.features().static_nobundle {
             feature_err(
diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs
index 004c5f2..29a4254 100644
--- a/src/librustc_metadata/rmeta/decoder.rs
+++ b/src/librustc_metadata/rmeta/decoder.rs
@@ -18,13 +18,13 @@
 use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::definitions::DefPathTable;
 use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
+use rustc_hir::lang_items;
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_middle::dep_graph::{self, DepNode, DepNodeExt, DepNodeIndex};
 use rustc_middle::hir::exports::Export;
 use rustc_middle::middle::cstore::{CrateSource, ExternCrate};
 use rustc_middle::middle::cstore::{ForeignModule, LinkagePreference, NativeLibrary};
 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
-use rustc_middle::middle::lang_items;
 use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
 use rustc_middle::mir::{self, interpret, BodyAndCache, Promoted};
 use rustc_middle::ty::codec::TyDecoder;
@@ -32,7 +32,7 @@
 use rustc_middle::util::common::record_time;
 use rustc_serialize::{opaque, Decodable, Decoder, SpecializedDecoder};
 use rustc_session::Session;
-use rustc_span::source_map::{self, respan, Spanned};
+use rustc_span::source_map::{respan, Spanned};
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{self, hygiene::MacroKind, BytePos, Pos, Span, DUMMY_SP};
 
@@ -41,7 +41,7 @@
 use std::io;
 use std::mem;
 use std::num::NonZeroUsize;
-use std::u32;
+use std::path::Path;
 
 pub use cstore_impl::{provide, provide_extern};
 
@@ -427,7 +427,7 @@
         // we can call `imported_source_files` for the proper crate, and binary search
         // through the returned slice using our span.
         let imported_source_files = if tag == TAG_VALID_SPAN_LOCAL {
-            self.cdata().imported_source_files(sess.source_map())
+            self.cdata().imported_source_files(sess)
         } else {
             // FIXME: We don't decode dependencies of proc-macros.
             // Remove this once #69976 is merged
@@ -457,7 +457,7 @@
             self.last_source_file_index = 0;
 
             let foreign_data = self.cdata().cstore.get_crate_data(cnum);
-            foreign_data.imported_source_files(sess.source_map())
+            foreign_data.imported_source_files(sess)
         };
 
         let source_file = {
@@ -633,7 +633,7 @@
     }
 
     fn maybe_kind(&self, item_id: DefIndex) -> Option<EntryKind> {
-        self.root.per_def.kind.get(self, item_id).map(|k| k.decode(self))
+        self.root.tables.kind.get(self, item_id).map(|k| k.decode(self))
     }
 
     fn kind(&self, item_id: DefIndex) -> EntryKind {
@@ -665,7 +665,7 @@
                 .expect("no name in item_ident");
             let span = self
                 .root
-                .per_def
+                .tables
                 .ident_span
                 .get(self, item_index)
                 .map(|data| data.decode((self, sess)))
@@ -688,7 +688,7 @@
     }
 
     fn get_span(&self, index: DefIndex, sess: &Session) -> Span {
-        self.root.per_def.span.get(self, index).unwrap().decode((self, sess))
+        self.root.tables.span.get(self, index).unwrap().decode((self, sess))
     }
 
     fn load_proc_macro(&self, id: DefIndex, sess: &Session) -> SyntaxExtension {
@@ -781,7 +781,7 @@
             ctor_did,
             data.discr,
             self.root
-                .per_def
+                .tables
                 .children
                 .get(self, index)
                 .unwrap_or(Lazy::empty())
@@ -812,7 +812,7 @@
 
         let variants = if let ty::AdtKind::Enum = adt_kind {
             self.root
-                .per_def
+                .tables
                 .children
                 .get(self, item_id)
                 .unwrap_or(Lazy::empty())
@@ -831,7 +831,7 @@
         item_id: DefIndex,
         tcx: TyCtxt<'tcx>,
     ) -> ty::GenericPredicates<'tcx> {
-        self.root.per_def.explicit_predicates.get(self, item_id).unwrap().decode((self, tcx))
+        self.root.tables.explicit_predicates.get(self, item_id).unwrap().decode((self, tcx))
     }
 
     fn get_inferred_outlives(
@@ -840,7 +840,7 @@
         tcx: TyCtxt<'tcx>,
     ) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
         self.root
-            .per_def
+            .tables
             .inferred_outlives
             .get(self, item_id)
             .map(|predicates| predicates.decode((self, tcx)))
@@ -852,31 +852,31 @@
         item_id: DefIndex,
         tcx: TyCtxt<'tcx>,
     ) -> ty::GenericPredicates<'tcx> {
-        self.root.per_def.super_predicates.get(self, item_id).unwrap().decode((self, tcx))
+        self.root.tables.super_predicates.get(self, item_id).unwrap().decode((self, tcx))
     }
 
     fn get_generics(&self, item_id: DefIndex, sess: &Session) -> ty::Generics {
-        self.root.per_def.generics.get(self, item_id).unwrap().decode((self, sess))
+        self.root.tables.generics.get(self, item_id).unwrap().decode((self, sess))
     }
 
     fn get_type(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        self.root.per_def.ty.get(self, id).unwrap().decode((self, tcx))
+        self.root.tables.ty.get(self, id).unwrap().decode((self, tcx))
     }
 
     fn get_stability(&self, id: DefIndex) -> Option<attr::Stability> {
         match self.is_proc_macro(id) {
             true => self.root.proc_macro_stability,
-            false => self.root.per_def.stability.get(self, id).map(|stab| stab.decode(self)),
+            false => self.root.tables.stability.get(self, id).map(|stab| stab.decode(self)),
         }
     }
 
     fn get_const_stability(&self, id: DefIndex) -> Option<attr::ConstStability> {
-        self.root.per_def.const_stability.get(self, id).map(|stab| stab.decode(self))
+        self.root.tables.const_stability.get(self, id).map(|stab| stab.decode(self))
     }
 
     fn get_deprecation(&self, id: DefIndex) -> Option<attr::Deprecation> {
         self.root
-            .per_def
+            .tables
             .deprecation
             .get(self, id)
             .filter(|_| !self.is_proc_macro(id))
@@ -886,7 +886,7 @@
     fn get_visibility(&self, id: DefIndex) -> ty::Visibility {
         match self.is_proc_macro(id) {
             true => ty::Visibility::Public,
-            false => self.root.per_def.visibility.get(self, id).unwrap().decode(self),
+            false => self.root.tables.visibility.get(self, id).unwrap().decode(self),
         }
     }
 
@@ -914,7 +914,7 @@
     }
 
     fn get_impl_trait(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Option<ty::TraitRef<'tcx>> {
-        self.root.per_def.impl_trait_ref.get(self, id).map(|tr| tr.decode((self, tcx)))
+        self.root.tables.impl_trait_ref.get(self, id).map(|tr| tr.decode((self, tcx)))
     }
 
     /// Iterates over all the stability attributes in the given crate.
@@ -984,7 +984,7 @@
 
         // Iterate over all children.
         let macros_only = self.dep_kind.lock().macros_only();
-        let children = self.root.per_def.children.get(self, id).unwrap_or(Lazy::empty());
+        let children = self.root.tables.children.get(self, id).unwrap_or(Lazy::empty());
         for child_index in children.decode((self, sess)) {
             if macros_only {
                 continue;
@@ -1004,7 +1004,7 @@
                     EntryKind::ForeignMod => {
                         let child_children = self
                             .root
-                            .per_def
+                            .tables
                             .children
                             .get(self, child_index)
                             .unwrap_or(Lazy::empty());
@@ -1016,7 +1016,7 @@
                                     vis: self.get_visibility(child_index),
                                     span: self
                                         .root
-                                        .per_def
+                                        .tables
                                         .span
                                         .get(self, child_index)
                                         .unwrap()
@@ -1096,13 +1096,13 @@
     }
 
     fn is_item_mir_available(&self, id: DefIndex) -> bool {
-        !self.is_proc_macro(id) && self.root.per_def.mir.get(self, id).is_some()
+        !self.is_proc_macro(id) && self.root.tables.mir.get(self, id).is_some()
     }
 
     fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> BodyAndCache<'tcx> {
         let mut cache = self
             .root
-            .per_def
+            .tables
             .mir
             .get(self, id)
             .filter(|_| !self.is_proc_macro(id))
@@ -1121,7 +1121,7 @@
     ) -> IndexVec<Promoted, BodyAndCache<'tcx>> {
         let mut cache = self
             .root
-            .per_def
+            .tables
             .promoted_mir
             .get(self, id)
             .filter(|_| !self.is_proc_macro(id))
@@ -1172,7 +1172,7 @@
     }
 
     fn get_item_variances(&self, id: DefIndex) -> Vec<ty::Variance> {
-        self.root.per_def.variances.get(self, id).unwrap_or(Lazy::empty()).decode(self).collect()
+        self.root.tables.variances.get(self, id).unwrap_or(Lazy::empty()).decode(self).collect()
     }
 
     fn get_ctor_kind(&self, node_id: DefIndex) -> CtorKind {
@@ -1209,7 +1209,7 @@
 
         Lrc::from(
             self.root
-                .per_def
+                .tables
                 .attributes
                 .get(self, item_id)
                 .unwrap_or(Lazy::empty())
@@ -1220,7 +1220,7 @@
 
     fn get_struct_field_names(&self, id: DefIndex, sess: &Session) -> Vec<Spanned<ast::Name>> {
         self.root
-            .per_def
+            .tables
             .children
             .get(self, id)
             .unwrap_or(Lazy::empty())
@@ -1236,7 +1236,7 @@
     ) -> &'tcx [DefId] {
         tcx.arena.alloc_from_iter(
             self.root
-                .per_def
+                .tables
                 .inherent_impls
                 .get(self, id)
                 .unwrap_or(Lazy::empty())
@@ -1416,7 +1416,7 @@
     }
 
     fn fn_sig(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
-        self.root.per_def.fn_sig.get(self, id).unwrap().decode((self, tcx))
+        self.root.tables.fn_sig.get(self, id).unwrap().decode((self, tcx))
     }
 
     #[inline]
@@ -1460,10 +1460,45 @@
     ///
     /// Proc macro crates don't currently export spans, so this function does not have
     /// to work for them.
-    fn imported_source_files(
-        &self,
-        local_source_map: &source_map::SourceMap,
-    ) -> &'a [ImportedSourceFile] {
+    fn imported_source_files(&self, sess: &Session) -> &'a [ImportedSourceFile] {
+        // Translate the virtual `/rustc/$hash` prefix back to a real directory
+        // that should hold actual sources, where possible.
+        let virtual_rust_source_base_dir = option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR")
+            .map(Path::new)
+            .filter(|_| {
+                // Only spend time on further checks if we have what to translate *to*.
+                sess.real_rust_source_base_dir.is_some()
+            })
+            .filter(|virtual_dir| {
+                // Don't translate away `/rustc/$hash` if we're still remapping to it,
+                // since that means we're still building `std`/`rustc` that need it,
+                // and we don't want the real path to leak into codegen/debuginfo.
+                !sess.opts.remap_path_prefix.iter().any(|(_from, to)| to == virtual_dir)
+            });
+        let try_to_translate_virtual_to_real = |name: &mut rustc_span::FileName| {
+            debug!(
+                "try_to_translate_virtual_to_real(name={:?}): \
+                 virtual_rust_source_base_dir={:?}, real_rust_source_base_dir={:?}",
+                name, virtual_rust_source_base_dir, sess.real_rust_source_base_dir,
+            );
+
+            if let Some(virtual_dir) = virtual_rust_source_base_dir {
+                if let Some(real_dir) = &sess.real_rust_source_base_dir {
+                    if let rustc_span::FileName::Real(path) = name {
+                        if let Ok(rest) = path.strip_prefix(virtual_dir) {
+                            let new_path = real_dir.join(rest);
+                            debug!(
+                                "try_to_translate_virtual_to_real: `{}` -> `{}`",
+                                path.display(),
+                                new_path.display(),
+                            );
+                            *path = new_path;
+                        }
+                    }
+                }
+            }
+        };
+
         self.cdata.source_map_import_info.init_locking(|| {
             let external_source_map = self.root.source_map.decode(self);
 
@@ -1472,7 +1507,7 @@
                     // We can't reuse an existing SourceFile, so allocate a new one
                     // containing the information we need.
                     let rustc_span::SourceFile {
-                        name,
+                        mut name,
                         name_was_remapped,
                         src_hash,
                         start_pos,
@@ -1485,6 +1520,13 @@
                         ..
                     } = source_file_to_import;
 
+                    // If this file's path has been remapped to `/rustc/$hash`,
+                    // we might be able to reverse that (also see comments above,
+                    // on `try_to_translate_virtual_to_real`).
+                    // FIXME(eddyb) we could check `name_was_remapped` here,
+                    // but in practice it seems to be always `false`.
+                    try_to_translate_virtual_to_real(&mut name);
+
                     let source_length = (end_pos - start_pos).to_usize();
 
                     // Translate line-start positions and multibyte character
@@ -1505,7 +1547,7 @@
                         np.pos = np.pos - start_pos;
                     }
 
-                    let local_version = local_source_map.new_imported_source_file(
+                    let local_version = sess.source_map().new_imported_source_file(
                         name,
                         name_was_remapped,
                         src_hash,
diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs
index f6e2730..d75298f 100644
--- a/src/librustc_metadata/rmeta/encoder.rs
+++ b/src/librustc_metadata/rmeta/encoder.rs
@@ -15,6 +15,7 @@
 use rustc_hir::definitions::DefPathTable;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::itemlikevisit::{ItemLikeVisitor, ParItemLikeVisitor};
+use rustc_hir::lang_items;
 use rustc_hir::{AnonConst, GenericParamKind};
 use rustc_index::vec::Idx;
 use rustc_middle::hir::map::Map;
@@ -25,27 +26,25 @@
 use rustc_middle::middle::exported_symbols::{
     metadata_symbol_name, ExportedSymbol, SymbolExportLevel,
 };
-use rustc_middle::middle::lang_items;
 use rustc_middle::mir::{self, interpret};
 use rustc_middle::traits::specialization_graph;
 use rustc_middle::ty::codec::{self as ty_codec, TyEncoder};
-use rustc_middle::ty::layout::VariantIdx;
 use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
 use rustc_serialize::{opaque, Encodable, Encoder, SpecializedEncoder};
 use rustc_session::config::{self, CrateType};
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::{self, ExternalSource, FileName, SourceFile, Span};
+use rustc_target::abi::VariantIdx;
 use std::hash::Hash;
 use std::num::NonZeroUsize;
 use std::path::Path;
-use std::u32;
 
 struct EncodeContext<'tcx> {
     opaque: opaque::Encoder,
     tcx: TyCtxt<'tcx>,
 
-    per_def: PerDefTableBuilders<'tcx>,
+    tables: TableBuilders<'tcx>,
 
     lazy_state: LazyState,
     type_shorthands: FxHashMap<Ty<'tcx>, usize>,
@@ -497,8 +496,8 @@
         };
 
         i = self.position();
-        let per_def = self.per_def.encode(&mut self.opaque);
-        let per_def_bytes = self.position() - i;
+        let tables = self.tables.encode(&mut self.opaque);
+        let tables_bytes = self.position() - i;
 
         // Encode the proc macro data
         i = self.position();
@@ -560,7 +559,7 @@
             impls,
             exported_symbols,
             interpret_alloc_index,
-            per_def,
+            tables,
         });
 
         let total_bytes = self.position();
@@ -585,7 +584,7 @@
             println!("  def-path table bytes: {}", def_path_table_bytes);
             println!(" proc-macro-data-bytes: {}", proc_macro_data_bytes);
             println!("            item bytes: {}", item_bytes);
-            println!("   per-def table bytes: {}", per_def_bytes);
+            println!("           table bytes: {}", tables_bytes);
             println!("            zero bytes: {}", zero_bytes);
             println!("           total bytes: {}", total_bytes);
         }
@@ -597,12 +596,12 @@
 impl EncodeContext<'tcx> {
     fn encode_variances_of(&mut self, def_id: DefId) {
         debug!("EncodeContext::encode_variances_of({:?})", def_id);
-        record!(self.per_def.variances[def_id] <- &self.tcx.variances_of(def_id)[..]);
+        record!(self.tables.variances[def_id] <- &self.tcx.variances_of(def_id)[..]);
     }
 
     fn encode_item_type(&mut self, def_id: DefId) {
         debug!("EncodeContext::encode_item_type({:?})", def_id);
-        record!(self.per_def.ty[def_id] <- self.tcx.type_of(def_id));
+        record!(self.tables.ty[def_id] <- self.tcx.type_of(def_id));
     }
 
     fn encode_enum_variant_info(&mut self, enum_did: DefId, index: VariantIdx) {
@@ -621,12 +620,12 @@
         let enum_id = tcx.hir().as_local_hir_id(enum_did).unwrap();
         let enum_vis = &tcx.hir().expect_item(enum_id).vis;
 
-        record!(self.per_def.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
-        record!(self.per_def.visibility[def_id] <-
+        record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
+        record!(self.tables.visibility[def_id] <-
             ty::Visibility::from_hir(enum_vis, enum_id, self.tcx));
-        record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id));
-        record!(self.per_def.attributes[def_id] <- &self.tcx.get_attrs(def_id)[..]);
-        record!(self.per_def.children[def_id] <- variant.fields.iter().map(|f| {
+        record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
+        record!(self.tables.attributes[def_id] <- &self.tcx.get_attrs(def_id)[..]);
+        record!(self.tables.children[def_id] <- variant.fields.iter().map(|f| {
             assert!(f.did.is_local());
             f.did.index
         }));
@@ -637,7 +636,7 @@
         if variant.ctor_kind == CtorKind::Fn {
             // FIXME(eddyb) encode signature only in `encode_enum_variant_ctor`.
             if let Some(ctor_def_id) = variant.ctor_def_id {
-                record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(ctor_def_id));
+                record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(ctor_def_id));
             }
             // FIXME(eddyb) is this ever used?
             self.encode_variances_of(def_id);
@@ -672,14 +671,14 @@
             ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
         }
 
-        record!(self.per_def.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
-        record!(self.per_def.visibility[def_id] <- ctor_vis);
-        record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id));
+        record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
+        record!(self.tables.visibility[def_id] <- ctor_vis);
+        record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
         self.encode_stability(def_id);
         self.encode_deprecation(def_id);
         self.encode_item_type(def_id);
         if variant.ctor_kind == CtorKind::Fn {
-            record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id));
+            record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
             self.encode_variances_of(def_id);
         }
         self.encode_generics(def_id);
@@ -707,11 +706,11 @@
             },
         };
 
-        record!(self.per_def.kind[def_id] <- EntryKind::Mod(self.lazy(data)));
-        record!(self.per_def.visibility[def_id] <- ty::Visibility::from_hir(vis, id, self.tcx));
-        record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id));
-        record!(self.per_def.attributes[def_id] <- attrs);
-        record!(self.per_def.children[def_id] <- md.item_ids.iter().map(|item_id| {
+        record!(self.tables.kind[def_id] <- EntryKind::Mod(self.lazy(data)));
+        record!(self.tables.visibility[def_id] <- ty::Visibility::from_hir(vis, id, self.tcx));
+        record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
+        record!(self.tables.attributes[def_id] <- attrs);
+        record!(self.tables.children[def_id] <- md.item_ids.iter().map(|item_id| {
             tcx.hir().local_def_id(item_id.id).index
         }));
         self.encode_stability(def_id);
@@ -729,10 +728,10 @@
         let variant_id = tcx.hir().as_local_hir_id(variant.def_id).unwrap();
         let variant_data = tcx.hir().expect_variant_data(variant_id);
 
-        record!(self.per_def.kind[def_id] <- EntryKind::Field);
-        record!(self.per_def.visibility[def_id] <- field.vis);
-        record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id));
-        record!(self.per_def.attributes[def_id] <- variant_data.fields()[field_index].attrs);
+        record!(self.tables.kind[def_id] <- EntryKind::Field);
+        record!(self.tables.visibility[def_id] <- field.vis);
+        record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
+        record!(self.tables.attributes[def_id] <- variant_data.fields()[field_index].attrs);
         self.encode_ident_span(def_id, field.ident);
         self.encode_stability(def_id);
         self.encode_deprecation(def_id);
@@ -771,14 +770,14 @@
             ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
         }
 
-        record!(self.per_def.kind[def_id] <- EntryKind::Struct(self.lazy(data), adt_def.repr));
-        record!(self.per_def.visibility[def_id] <- ctor_vis);
-        record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id));
+        record!(self.tables.kind[def_id] <- EntryKind::Struct(self.lazy(data), adt_def.repr));
+        record!(self.tables.visibility[def_id] <- ctor_vis);
+        record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
         self.encode_stability(def_id);
         self.encode_deprecation(def_id);
         self.encode_item_type(def_id);
         if variant.ctor_kind == CtorKind::Fn {
-            record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id));
+            record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
             self.encode_variances_of(def_id);
         }
         self.encode_generics(def_id);
@@ -790,12 +789,12 @@
 
     fn encode_generics(&mut self, def_id: DefId) {
         debug!("EncodeContext::encode_generics({:?})", def_id);
-        record!(self.per_def.generics[def_id] <- self.tcx.generics_of(def_id));
+        record!(self.tables.generics[def_id] <- self.tcx.generics_of(def_id));
     }
 
     fn encode_explicit_predicates(&mut self, def_id: DefId) {
         debug!("EncodeContext::encode_explicit_predicates({:?})", def_id);
-        record!(self.per_def.explicit_predicates[def_id] <-
+        record!(self.tables.explicit_predicates[def_id] <-
             self.tcx.explicit_predicates_of(def_id));
     }
 
@@ -803,13 +802,13 @@
         debug!("EncodeContext::encode_inferred_outlives({:?})", def_id);
         let inferred_outlives = self.tcx.inferred_outlives_of(def_id);
         if !inferred_outlives.is_empty() {
-            record!(self.per_def.inferred_outlives[def_id] <- inferred_outlives);
+            record!(self.tables.inferred_outlives[def_id] <- inferred_outlives);
         }
     }
 
     fn encode_super_predicates(&mut self, def_id: DefId) {
         debug!("EncodeContext::encode_super_predicates({:?})", def_id);
-        record!(self.per_def.super_predicates[def_id] <- self.tcx.super_predicates_of(def_id));
+        record!(self.tables.super_predicates[def_id] <- self.tcx.super_predicates_of(def_id));
     }
 
     fn encode_info_for_trait_item(&mut self, def_id: DefId) {
@@ -826,7 +825,7 @@
             hir::Defaultness::Final => span_bug!(ast_item.span, "traits cannot have final items"),
         };
 
-        record!(self.per_def.kind[def_id] <- match trait_item.kind {
+        record!(self.tables.kind[def_id] <- match trait_item.kind {
             ty::AssocKind::Const => {
                 let rendered = rustc_hir_pretty::to_string(
                     &(&self.tcx.hir() as &dyn intravisit::Map<'_>),
@@ -867,9 +866,9 @@
             ty::AssocKind::Type => EntryKind::AssocType(container),
             ty::AssocKind::OpaqueTy => span_bug!(ast_item.span, "opaque type in trait"),
         });
-        record!(self.per_def.visibility[def_id] <- trait_item.vis);
-        record!(self.per_def.span[def_id] <- ast_item.span);
-        record!(self.per_def.attributes[def_id] <- ast_item.attrs);
+        record!(self.tables.visibility[def_id] <- trait_item.vis);
+        record!(self.tables.span[def_id] <- ast_item.span);
+        record!(self.tables.attributes[def_id] <- ast_item.attrs);
         self.encode_ident_span(def_id, ast_item.ident);
         self.encode_stability(def_id);
         self.encode_const_stability(def_id);
@@ -886,7 +885,7 @@
             ty::AssocKind::OpaqueTy => unreachable!(),
         }
         if trait_item.kind == ty::AssocKind::Method {
-            record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id));
+            record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
             self.encode_variances_of(def_id);
         }
         self.encode_generics(def_id);
@@ -919,7 +918,7 @@
             }
         };
 
-        record!(self.per_def.kind[def_id] <- match impl_item.kind {
+        record!(self.tables.kind[def_id] <- match impl_item.kind {
             ty::AssocKind::Const => {
                 if let hir::ImplItemKind::Const(_, body_id) = ast_item.kind {
                     let qualifs = self.tcx.at(ast_item.span).mir_const_qualif(def_id);
@@ -951,16 +950,16 @@
             ty::AssocKind::OpaqueTy => EntryKind::AssocOpaqueTy(container),
             ty::AssocKind::Type => EntryKind::AssocType(container)
         });
-        record!(self.per_def.visibility[def_id] <- impl_item.vis);
-        record!(self.per_def.span[def_id] <- ast_item.span);
-        record!(self.per_def.attributes[def_id] <- ast_item.attrs);
+        record!(self.tables.visibility[def_id] <- impl_item.vis);
+        record!(self.tables.span[def_id] <- ast_item.span);
+        record!(self.tables.attributes[def_id] <- ast_item.attrs);
         self.encode_ident_span(def_id, impl_item.ident);
         self.encode_stability(def_id);
         self.encode_const_stability(def_id);
         self.encode_deprecation(def_id);
         self.encode_item_type(def_id);
         if impl_item.kind == ty::AssocKind::Method {
-            record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id));
+            record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
             self.encode_variances_of(def_id);
         }
         self.encode_generics(def_id);
@@ -1005,14 +1004,14 @@
     fn encode_optimized_mir(&mut self, def_id: DefId) {
         debug!("EntryBuilder::encode_mir({:?})", def_id);
         if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) {
-            record!(self.per_def.mir[def_id] <- self.tcx.optimized_mir(def_id));
+            record!(self.tables.mir[def_id] <- self.tcx.optimized_mir(def_id));
         }
     }
 
     fn encode_promoted_mir(&mut self, def_id: DefId) {
         debug!("EncodeContext::encode_promoted_mir({:?})", def_id);
         if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) {
-            record!(self.per_def.promoted_mir[def_id] <- self.tcx.promoted_mir(def_id));
+            record!(self.tables.promoted_mir[def_id] <- self.tcx.promoted_mir(def_id));
         }
     }
 
@@ -1021,7 +1020,7 @@
         debug!("EncodeContext::encode_inherent_implementations({:?})", def_id);
         let implementations = self.tcx.inherent_impls(def_id);
         if !implementations.is_empty() {
-            record!(self.per_def.inherent_impls[def_id] <- implementations.iter().map(|&def_id| {
+            record!(self.tables.inherent_impls[def_id] <- implementations.iter().map(|&def_id| {
                 assert!(def_id.is_local());
                 def_id.index
             }));
@@ -1031,21 +1030,21 @@
     fn encode_stability(&mut self, def_id: DefId) {
         debug!("EncodeContext::encode_stability({:?})", def_id);
         if let Some(stab) = self.tcx.lookup_stability(def_id) {
-            record!(self.per_def.stability[def_id] <- stab)
+            record!(self.tables.stability[def_id] <- stab)
         }
     }
 
     fn encode_const_stability(&mut self, def_id: DefId) {
         debug!("EncodeContext::encode_const_stability({:?})", def_id);
         if let Some(stab) = self.tcx.lookup_const_stability(def_id) {
-            record!(self.per_def.const_stability[def_id] <- stab)
+            record!(self.tables.const_stability[def_id] <- stab)
         }
     }
 
     fn encode_deprecation(&mut self, def_id: DefId) {
         debug!("EncodeContext::encode_deprecation({:?})", def_id);
         if let Some(depr) = self.tcx.lookup_deprecation(def_id) {
-            record!(self.per_def.deprecation[def_id] <- depr);
+            record!(self.tables.deprecation[def_id] <- depr);
         }
     }
 
@@ -1066,7 +1065,7 @@
 
         self.encode_ident_span(def_id, item.ident);
 
-        record!(self.per_def.kind[def_id] <- match item.kind {
+        record!(self.tables.kind[def_id] <- match item.kind {
             hir::ItemKind::Static(_, hir::Mutability::Mut, _) => EntryKind::MutStatic,
             hir::ItemKind::Static(_, hir::Mutability::Not, _) => EntryKind::ImmStatic,
             hir::ItemKind::Const(_, body_id) => {
@@ -1172,26 +1171,26 @@
             hir::ItemKind::ExternCrate(_) |
             hir::ItemKind::Use(..) => bug!("cannot encode info for item {:?}", item),
         });
-        record!(self.per_def.visibility[def_id] <-
+        record!(self.tables.visibility[def_id] <-
             ty::Visibility::from_hir(&item.vis, item.hir_id, tcx));
-        record!(self.per_def.span[def_id] <- item.span);
-        record!(self.per_def.attributes[def_id] <- item.attrs);
+        record!(self.tables.span[def_id] <- item.span);
+        record!(self.tables.attributes[def_id] <- item.attrs);
         // FIXME(eddyb) there should be a nicer way to do this.
         match item.kind {
-            hir::ItemKind::ForeignMod(ref fm) => record!(self.per_def.children[def_id] <-
+            hir::ItemKind::ForeignMod(ref fm) => record!(self.tables.children[def_id] <-
                 fm.items
                     .iter()
                     .map(|foreign_item| tcx.hir().local_def_id(
                         foreign_item.hir_id).index)
             ),
-            hir::ItemKind::Enum(..) => record!(self.per_def.children[def_id] <-
+            hir::ItemKind::Enum(..) => record!(self.tables.children[def_id] <-
                 self.tcx.adt_def(def_id).variants.iter().map(|v| {
                     assert!(v.def_id.is_local());
                     v.def_id.index
                 })
             ),
             hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
-                record!(self.per_def.children[def_id] <-
+                record!(self.tables.children[def_id] <-
                     self.tcx.adt_def(def_id).non_enum_variant().fields.iter().map(|f| {
                         assert!(f.did.is_local());
                         f.did.index
@@ -1200,7 +1199,7 @@
             }
             hir::ItemKind::Impl { .. } | hir::ItemKind::Trait(..) => {
                 let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id);
-                record!(self.per_def.children[def_id] <-
+                record!(self.tables.children[def_id] <-
                     associated_item_def_ids.iter().map(|&def_id| {
                         assert!(def_id.is_local());
                         def_id.index
@@ -1225,11 +1224,11 @@
             _ => {}
         }
         if let hir::ItemKind::Fn(..) = item.kind {
-            record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id));
+            record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
         }
         if let hir::ItemKind::Impl { .. } = item.kind {
             if let Some(trait_ref) = self.tcx.impl_trait_ref(def_id) {
-                record!(self.per_def.impl_trait_ref[def_id] <- trait_ref);
+                record!(self.tables.impl_trait_ref[def_id] <- trait_ref);
             }
         }
         self.encode_inherent_implementations(def_id);
@@ -1288,19 +1287,19 @@
     /// Serialize the text of exported macros
     fn encode_info_for_macro_def(&mut self, macro_def: &hir::MacroDef<'_>) {
         let def_id = self.tcx.hir().local_def_id(macro_def.hir_id);
-        record!(self.per_def.kind[def_id] <- EntryKind::MacroDef(self.lazy(macro_def.ast.clone())));
-        record!(self.per_def.visibility[def_id] <- ty::Visibility::Public);
-        record!(self.per_def.span[def_id] <- macro_def.span);
-        record!(self.per_def.attributes[def_id] <- macro_def.attrs);
+        record!(self.tables.kind[def_id] <- EntryKind::MacroDef(self.lazy(macro_def.ast.clone())));
+        record!(self.tables.visibility[def_id] <- ty::Visibility::Public);
+        record!(self.tables.span[def_id] <- macro_def.span);
+        record!(self.tables.attributes[def_id] <- macro_def.attrs);
         self.encode_ident_span(def_id, macro_def.ident);
         self.encode_stability(def_id);
         self.encode_deprecation(def_id);
     }
 
     fn encode_info_for_generic_param(&mut self, def_id: DefId, kind: EntryKind, encode_type: bool) {
-        record!(self.per_def.kind[def_id] <- kind);
-        record!(self.per_def.visibility[def_id] <- ty::Visibility::Public);
-        record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id));
+        record!(self.tables.kind[def_id] <- kind);
+        record!(self.tables.visibility[def_id] <- ty::Visibility::Public);
+        record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
         if encode_type {
             self.encode_item_type(def_id);
         }
@@ -1314,7 +1313,7 @@
         let hir_id = self.tcx.hir().as_local_hir_id(def_id).unwrap();
         let ty = self.tcx.typeck_tables_of(def_id).node_type(hir_id);
 
-        record!(self.per_def.kind[def_id] <- match ty.kind {
+        record!(self.tables.kind[def_id] <- match ty.kind {
             ty::Generator(..) => {
                 let data = self.tcx.generator_kind(def_id).unwrap();
                 EntryKind::Generator(data)
@@ -1324,12 +1323,12 @@
 
             _ => bug!("closure that is neither generator nor closure"),
         });
-        record!(self.per_def.visibility[def_id] <- ty::Visibility::Public);
-        record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id));
-        record!(self.per_def.attributes[def_id] <- &self.tcx.get_attrs(def_id)[..]);
+        record!(self.tables.visibility[def_id] <- ty::Visibility::Public);
+        record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
+        record!(self.tables.attributes[def_id] <- &self.tcx.get_attrs(def_id)[..]);
         self.encode_item_type(def_id);
         if let ty::Closure(def_id, substs) = ty.kind {
-            record!(self.per_def.fn_sig[def_id] <- substs.as_closure().sig());
+            record!(self.tables.fn_sig[def_id] <- substs.as_closure().sig());
         }
         self.encode_generics(def_id);
         self.encode_optimized_mir(def_id);
@@ -1343,9 +1342,9 @@
         let const_data = self.encode_rendered_const_for_body(body_id);
         let qualifs = self.tcx.mir_const_qualif(def_id);
 
-        record!(self.per_def.kind[def_id] <- EntryKind::Const(qualifs, const_data));
-        record!(self.per_def.visibility[def_id] <- ty::Visibility::Public);
-        record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id));
+        record!(self.tables.kind[def_id] <- EntryKind::Const(qualifs, const_data));
+        record!(self.tables.visibility[def_id] <- ty::Visibility::Public);
+        record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
         self.encode_item_type(def_id);
         self.encode_generics(def_id);
         self.encode_explicit_predicates(def_id);
@@ -1516,7 +1515,7 @@
 
         debug!("EncodeContext::encode_info_for_foreign_item({:?})", def_id);
 
-        record!(self.per_def.kind[def_id] <- match nitem.kind {
+        record!(self.tables.kind[def_id] <- match nitem.kind {
             hir::ForeignItemKind::Fn(_, ref names, _) => {
                 let data = FnData {
                     asyncness: hir::IsAsync::NotAsync,
@@ -1533,17 +1532,17 @@
             hir::ForeignItemKind::Static(_, hir::Mutability::Not) => EntryKind::ForeignImmStatic,
             hir::ForeignItemKind::Type => EntryKind::ForeignType,
         });
-        record!(self.per_def.visibility[def_id] <-
+        record!(self.tables.visibility[def_id] <-
             ty::Visibility::from_hir(&nitem.vis, nitem.hir_id, self.tcx));
-        record!(self.per_def.span[def_id] <- nitem.span);
-        record!(self.per_def.attributes[def_id] <- nitem.attrs);
+        record!(self.tables.span[def_id] <- nitem.span);
+        record!(self.tables.attributes[def_id] <- nitem.attrs);
         self.encode_ident_span(def_id, nitem.ident);
         self.encode_stability(def_id);
         self.encode_const_stability(def_id);
         self.encode_deprecation(def_id);
         self.encode_item_type(def_id);
         if let hir::ForeignItemKind::Fn(..) = nitem.kind {
-            record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id));
+            record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
             self.encode_variances_of(def_id);
         }
         self.encode_generics(def_id);
@@ -1630,7 +1629,7 @@
     }
 
     fn encode_ident_span(&mut self, def_id: DefId, ident: Ident) {
-        record!(self.per_def.ident_span[def_id] <- ident.span);
+        record!(self.tables.ident_span[def_id] <- ident.span);
     }
 
     /// In some cases, along with the item itself, we also
@@ -1846,7 +1845,7 @@
     let mut ecx = EncodeContext {
         opaque: encoder,
         tcx,
-        per_def: Default::default(),
+        tables: Default::default(),
         lazy_state: LazyState::NoNode,
         type_shorthands: Default::default(),
         predicate_shorthands: Default::default(),
diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs
index d0ad76b..71872d5 100644
--- a/src/librustc_metadata/rmeta/mod.rs
+++ b/src/librustc_metadata/rmeta/mod.rs
@@ -8,11 +8,11 @@
 use rustc_hir as hir;
 use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::{DefId, DefIndex};
+use rustc_hir::lang_items;
 use rustc_index::vec::IndexVec;
 use rustc_middle::hir::exports::Export;
 use rustc_middle::middle::cstore::{DepKind, ForeignModule, LinkagePreference, NativeLibrary};
 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
-use rustc_middle::middle::lang_items;
 use rustc_middle::mir;
 use rustc_middle::ty::{self, ReprOptions, Ty};
 use rustc_serialize::opaque::Encoder;
@@ -197,7 +197,7 @@
     impls: Lazy<[TraitImpls]>,
     interpret_alloc_index: Lazy<[u32]>,
 
-    per_def: LazyPerDefTables<'tcx>,
+    tables: LazyTables<'tcx>,
 
     /// The DefIndex's of any proc macros declared by this crate.
     proc_macro_data: Option<Lazy<[DefIndex]>>,
@@ -228,22 +228,22 @@
     impls: Lazy<[DefIndex]>,
 }
 
-/// Define `LazyPerDefTables` and `PerDefTableBuilders` at the same time.
-macro_rules! define_per_def_tables {
+/// Define `LazyTables` and `TableBuilders` at the same time.
+macro_rules! define_tables {
     ($($name:ident: Table<DefIndex, $T:ty>),+ $(,)?) => {
         #[derive(RustcEncodable, RustcDecodable)]
-        crate struct LazyPerDefTables<'tcx> {
+        crate struct LazyTables<'tcx> {
             $($name: Lazy!(Table<DefIndex, $T>)),+
         }
 
         #[derive(Default)]
-        struct PerDefTableBuilders<'tcx> {
+        struct TableBuilders<'tcx> {
             $($name: TableBuilder<DefIndex, $T>),+
         }
 
-        impl PerDefTableBuilders<'tcx> {
-            fn encode(&self, buf: &mut Encoder) -> LazyPerDefTables<'tcx> {
-                LazyPerDefTables {
+        impl TableBuilders<'tcx> {
+            fn encode(&self, buf: &mut Encoder) -> LazyTables<'tcx> {
+                LazyTables {
                     $($name: self.$name.encode(buf)),+
                 }
             }
@@ -251,7 +251,7 @@
     }
 }
 
-define_per_def_tables! {
+define_tables! {
     kind: Table<DefIndex, Lazy<EntryKind>>,
     visibility: Table<DefIndex, Lazy<ty::Visibility>>,
     span: Table<DefIndex, Lazy<Span>>,
diff --git a/src/librustc_middle/arena.rs b/src/librustc_middle/arena.rs
index fcf6989..e3dec59 100644
--- a/src/librustc_middle/arena.rs
+++ b/src/librustc_middle/arena.rs
@@ -11,7 +11,7 @@
 macro_rules! arena_types {
     ($macro:path, $args:tt, $tcx:lifetime) => (
         $macro!($args, [
-            [] layouts: rustc_middle::ty::layout::Layout,
+            [] layouts: rustc_target::abi::Layout,
             [] generics: rustc_middle::ty::Generics,
             [] trait_def: rustc_middle::ty::TraitDef,
             [] adt_def: rustc_middle::ty::AdtDef,
@@ -106,7 +106,7 @@
                 String
             >,
             [few] get_lib_features: rustc_middle::middle::lib_features::LibFeatures,
-            [few] defined_lib_features: rustc_middle::middle::lang_items::LanguageItems,
+            [few] defined_lib_features: rustc_hir::lang_items::LanguageItems,
             [few] visible_parent_map: rustc_hir::def_id::DefIdMap<rustc_hir::def_id::DefId>,
             [few] foreign_module: rustc_middle::middle::cstore::ForeignModule,
             [few] foreign_modules: Vec<rustc_middle::middle::cstore::ForeignModule>,
diff --git a/src/librustc_middle/ich/impls_syntax.rs b/src/librustc_middle/ich/impls_syntax.rs
index c5a4b53..300aac1 100644
--- a/src/librustc_middle/ich/impls_syntax.rs
+++ b/src/librustc_middle/ich/impls_syntax.rs
@@ -61,7 +61,7 @@
             cnum,
             // Do not hash the source as it is not encoded
             src: _,
-            src_hash,
+            ref src_hash,
             external_src: _,
             start_pos,
             end_pos: _,
diff --git a/src/librustc_middle/ich/mod.rs b/src/librustc_middle/ich/mod.rs
index 516e3ed..c8fb2bf 100644
--- a/src/librustc_middle/ich/mod.rs
+++ b/src/librustc_middle/ich/mod.rs
@@ -4,7 +4,6 @@
     hash_stable_trait_impls, NodeIdHashingMode, StableHashingContext, StableHashingContextProvider,
 };
 use rustc_span::symbol::{sym, Symbol};
-pub use rustc_span::CachingSourceMapView;
 
 mod hcx;
 
diff --git a/src/librustc_middle/middle/lang_items.rs b/src/librustc_middle/middle/lang_items.rs
index 3656037..0f98c33 100644
--- a/src/librustc_middle/middle/lang_items.rs
+++ b/src/librustc_middle/middle/lang_items.rs
@@ -7,17 +7,13 @@
 //! * Traits that represent operators; e.g., `Add`, `Sub`, `Index`.
 //! * Functions called by the compiler itself.
 
-pub use self::LangItem::*;
-
 use crate::ty::{self, TyCtxt};
 
 use rustc_hir::def_id::DefId;
+use rustc_hir::LangItem;
 use rustc_span::Span;
 use rustc_target::spec::PanicStrategy;
 
-pub use rustc_hir::weak_lang_items::link_name;
-pub use rustc_hir::{LangItem, LanguageItems};
-
 impl<'tcx> TyCtxt<'tcx> {
     /// Returns the `DefId` for a given `LangItem`.
     /// If not found, fatally aborts compilation.
diff --git a/src/librustc_middle/mir/interpret/allocation.rs b/src/librustc_middle/mir/interpret/allocation.rs
index 0e75f34..8b9f097 100644
--- a/src/librustc_middle/mir/interpret/allocation.rs
+++ b/src/librustc_middle/mir/interpret/allocation.rs
@@ -7,14 +7,12 @@
 
 use rustc_ast::ast::Mutability;
 use rustc_data_structures::sorted_map::SortedMap;
-use rustc_target::abi::HasDataLayout;
+use rustc_target::abi::{Align, HasDataLayout, Size};
 
 use super::{
     read_target_uint, write_target_uint, AllocId, InterpResult, Pointer, Scalar, ScalarMaybeUndef,
 };
 
-use crate::ty::layout::{Align, Size};
-
 // NOTE: When adding new fields, make sure to adjust the `Snapshot` impl in
 // `src/librustc_mir/interpret/snapshot.rs`.
 #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
diff --git a/src/librustc_middle/mir/interpret/error.rs b/src/librustc_middle/mir/interpret/error.rs
index d46f1bc..7844fb1 100644
--- a/src/librustc_middle/mir/interpret/error.rs
+++ b/src/librustc_middle/mir/interpret/error.rs
@@ -1,7 +1,7 @@
 use super::{AllocId, CheckInAllocMsg, Pointer, RawConst, ScalarMaybeUndef};
 
 use crate::mir::interpret::ConstValue;
-use crate::ty::layout::{Align, LayoutError, Size};
+use crate::ty::layout::LayoutError;
 use crate::ty::query::TyCtxtAt;
 use crate::ty::tls;
 use crate::ty::{self, layout, Ty};
@@ -14,6 +14,7 @@
 use rustc_macros::HashStable;
 use rustc_session::CtfeBacktrace;
 use rustc_span::{def_id::DefId, Pos, Span};
+use rustc_target::abi::{Align, Size};
 use std::{any::Any, fmt, mem};
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, RustcEncodable, RustcDecodable)]
diff --git a/src/librustc_middle/mir/interpret/mod.rs b/src/librustc_middle/mir/interpret/mod.rs
index 10c3a06..96bf694 100644
--- a/src/librustc_middle/mir/interpret/mod.rs
+++ b/src/librustc_middle/mir/interpret/mod.rs
@@ -109,10 +109,10 @@
 use rustc_hir::def_id::DefId;
 use rustc_macros::HashStable;
 use rustc_serialize::{Decodable, Encodable, Encoder};
+use rustc_target::abi::{Endian, Size};
 
 use crate::mir;
 use crate::ty::codec::TyDecoder;
-use crate::ty::layout::{self, Size};
 use crate::ty::subst::GenericArgKind;
 use crate::ty::{self, Instance, Ty, TyCtxt};
 
@@ -521,22 +521,22 @@
 
 #[inline]
 pub fn write_target_uint(
-    endianness: layout::Endian,
+    endianness: Endian,
     mut target: &mut [u8],
     data: u128,
 ) -> Result<(), io::Error> {
     let len = target.len();
     match endianness {
-        layout::Endian::Little => target.write_uint128::<LittleEndian>(data, len),
-        layout::Endian::Big => target.write_uint128::<BigEndian>(data, len),
+        Endian::Little => target.write_uint128::<LittleEndian>(data, len),
+        Endian::Big => target.write_uint128::<BigEndian>(data, len),
     }
 }
 
 #[inline]
-pub fn read_target_uint(endianness: layout::Endian, mut source: &[u8]) -> Result<u128, io::Error> {
+pub fn read_target_uint(endianness: Endian, mut source: &[u8]) -> Result<u128, io::Error> {
     match endianness {
-        layout::Endian::Little => source.read_uint128::<LittleEndian>(source.len()),
-        layout::Endian::Big => source.read_uint128::<BigEndian>(source.len()),
+        Endian::Little => source.read_uint128::<LittleEndian>(source.len()),
+        Endian::Big => source.read_uint128::<BigEndian>(source.len()),
     }
 }
 
diff --git a/src/librustc_middle/mir/interpret/pointer.rs b/src/librustc_middle/mir/interpret/pointer.rs
index d22207b..7549d90 100644
--- a/src/librustc_middle/mir/interpret/pointer.rs
+++ b/src/librustc_middle/mir/interpret/pointer.rs
@@ -1,8 +1,7 @@
 use super::{AllocId, InterpResult};
 
-use crate::ty::layout::{self, HasDataLayout, Size};
-
 use rustc_macros::HashStable;
+use rustc_target::abi::{HasDataLayout, Size};
 
 use std::convert::TryFrom;
 use std::fmt::{self, Display};
@@ -37,7 +36,7 @@
 // Pointer arithmetic
 ////////////////////////////////////////////////////////////////////////////////
 
-pub trait PointerArithmetic: layout::HasDataLayout {
+pub trait PointerArithmetic: HasDataLayout {
     // These are not supposed to be overridden.
 
     #[inline(always)]
@@ -100,7 +99,7 @@
     }
 }
 
-impl<T: layout::HasDataLayout> PointerArithmetic for T {}
+impl<T: HasDataLayout> PointerArithmetic for T {}
 
 /// `Pointer` is generic over the type that represents a reference to `Allocation`s,
 /// thus making it possible for the most convenient representation to be used in
diff --git a/src/librustc_middle/mir/interpret/value.rs b/src/librustc_middle/mir/interpret/value.rs
index bf4ee84..f3c1c87 100644
--- a/src/librustc_middle/mir/interpret/value.rs
+++ b/src/librustc_middle/mir/interpret/value.rs
@@ -6,12 +6,9 @@
     Float,
 };
 use rustc_macros::HashStable;
-use rustc_target::abi::TargetDataLayout;
+use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout};
 
-use crate::ty::{
-    layout::{HasDataLayout, Size},
-    ParamEnv, Ty, TyCtxt,
-};
+use crate::ty::{ParamEnv, Ty, TyCtxt};
 
 use super::{sign_extend, truncate, AllocId, Allocation, InterpResult, Pointer, PointerArithmetic};
 
diff --git a/src/librustc_middle/mir/mod.rs b/src/librustc_middle/mir/mod.rs
index 216fe43..b82008f 100644
--- a/src/librustc_middle/mir/mod.rs
+++ b/src/librustc_middle/mir/mod.rs
@@ -6,7 +6,6 @@
 use crate::mir::visit::MirVisitable;
 use crate::ty::adjustment::PointerCast;
 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
-use crate::ty::layout::VariantIdx;
 use crate::ty::print::{FmtPrinter, Printer};
 use crate::ty::subst::{Subst, SubstsRef};
 use crate::ty::{
@@ -16,6 +15,7 @@
 use rustc_hir::def::{CtorKind, Namespace};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{self, GeneratorKind};
+use rustc_target::abi::VariantIdx;
 
 use polonius_engine::Atom;
 pub use rustc_ast::ast::Mutability;
@@ -33,7 +33,7 @@
 use std::fmt::{self, Debug, Display, Formatter, Write};
 use std::ops::Index;
 use std::slice;
-use std::{iter, mem, option, u32};
+use std::{iter, mem, option};
 
 pub use self::cache::{BodyAndCache, ReadOnlyBodyAndCache};
 pub use self::query::*;
diff --git a/src/librustc_middle/mir/tcx.rs b/src/librustc_middle/mir/tcx.rs
index feb6631..06b27c5 100644
--- a/src/librustc_middle/mir/tcx.rs
+++ b/src/librustc_middle/mir/tcx.rs
@@ -4,11 +4,11 @@
  */
 
 use crate::mir::*;
-use crate::ty::layout::VariantIdx;
 use crate::ty::subst::Subst;
 use crate::ty::util::IntTypeExt;
 use crate::ty::{self, Ty, TyCtxt};
 use rustc_hir as hir;
+use rustc_target::abi::VariantIdx;
 
 #[derive(Copy, Clone, Debug, TypeFoldable)]
 pub struct PlaceTy<'tcx> {
diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs
index c1ece62..c26c043 100644
--- a/src/librustc_middle/query/mod.rs
+++ b/src/librustc_middle/query/mod.rs
@@ -738,7 +738,7 @@
 
         query layout_raw(
             env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
-        ) -> Result<&'tcx ty::layout::Layout, ty::layout::LayoutError<'tcx>> {
+        ) -> Result<&'tcx rustc_target::abi::Layout, ty::layout::LayoutError<'tcx>> {
             desc { "computing layout of `{}`", env.value }
         }
     }
@@ -1257,5 +1257,9 @@
             eval_always
             desc { "looking up enabled feature gates" }
         }
+
+        query resolve_instance(key: (ty::ParamEnv<'tcx>, DefId, SubstsRef<'tcx>)) -> Option<ty::Instance<'tcx>> {
+            desc { "resolving instance `{:?}` `{:?}` with {:?}", key.1, key.2, key.0 }
+        }
     }
 }
diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs
index be889f6..95d0c75 100644
--- a/src/librustc_middle/ty/context.rs
+++ b/src/librustc_middle/ty/context.rs
@@ -11,8 +11,6 @@
 use crate::middle;
 use crate::middle::cstore::CrateStoreDyn;
 use crate::middle::cstore::EncodedMetadata;
-use crate::middle::lang_items;
-use crate::middle::lang_items::PanicLocationLangItem;
 use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault};
 use crate::middle::stability;
 use crate::mir::interpret::{Allocation, ConstValue, Scalar};
@@ -21,7 +19,6 @@
 };
 use crate::traits;
 use crate::traits::{Clause, Clauses, Goal, GoalKind, Goals};
-use crate::ty::layout::{Layout, TargetDataLayout, VariantIdx};
 use crate::ty::query;
 use crate::ty::steal::Steal;
 use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
@@ -38,7 +35,6 @@
 use crate::ty::{ExistentialPredicate, InferTy, ParamTy, PolyFnSig, Predicate, ProjectionTy};
 use crate::ty::{InferConst, ParamConst};
 use crate::ty::{List, TyKind, TyS};
-use crate::util::common::ErrorReported;
 use rustc_ast::ast;
 use rustc_ast::expand::allocator::AllocatorKind;
 use rustc_ast::node_id::NodeMap;
@@ -50,10 +46,13 @@
     hash_stable_hashmap, HashStable, StableHasher, StableVec,
 };
 use rustc_data_structures::sync::{self, Lock, Lrc, WorkerLocal};
+use rustc_errors::ErrorReported;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE};
 use rustc_hir::definitions::{DefPathData, DefPathHash, Definitions};
+use rustc_hir::lang_items;
+use rustc_hir::lang_items::PanicLocationLangItem;
 use rustc_hir::{HirId, Node, TraitCandidate};
 use rustc_hir::{ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet};
 use rustc_index::vec::{Idx, IndexVec};
@@ -65,6 +64,7 @@
 use rustc_span::source_map::MultiSpan;
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::Span;
+use rustc_target::abi::{Layout, TargetDataLayout, VariantIdx};
 use rustc_target::spec::abi;
 
 use smallvec::SmallVec;
@@ -1203,7 +1203,7 @@
     }
 
     /// Obtain all lang items of this crate and all dependencies (recursively)
-    pub fn lang_items(self) -> &'tcx middle::lang_items::LanguageItems {
+    pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
         self.get_lang_items(LOCAL_CRATE)
     }
 
diff --git a/src/librustc_middle/ty/flags.rs b/src/librustc_middle/ty/flags.rs
index 5243e1fb..99a6511 100644
--- a/src/librustc_middle/ty/flags.rs
+++ b/src/librustc_middle/ty/flags.rs
@@ -1,4 +1,4 @@
-use crate::ty::subst::{GenericArgKind, SubstsRef};
+use crate::ty::subst::{GenericArg, GenericArgKind};
 use crate::ty::{self, InferConst, Ty, TypeFlags};
 
 #[derive(Debug)]
@@ -81,6 +81,7 @@
 
             &ty::Param(_) => {
                 self.add_flags(TypeFlags::HAS_TY_PARAM);
+                self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
             }
 
             &ty::Generator(_, ref substs, _) => {
@@ -99,14 +100,17 @@
 
             &ty::Bound(debruijn, _) => {
                 self.add_binder(debruijn);
+                self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
             }
 
             &ty::Placeholder(..) => {
                 self.add_flags(TypeFlags::HAS_TY_PLACEHOLDER);
+                self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
             }
 
             &ty::Infer(infer) => {
                 self.add_flags(TypeFlags::HAS_TY_INFER);
+                self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
                 match infer {
                     ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => {}
 
@@ -218,17 +222,23 @@
             }
             ty::ConstKind::Infer(infer) => {
                 self.add_flags(TypeFlags::HAS_CT_INFER);
+                self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
                 match infer {
                     InferConst::Fresh(_) => {}
                     InferConst::Var(_) => self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX),
                 }
             }
-            ty::ConstKind::Bound(debruijn, _) => self.add_binder(debruijn),
+            ty::ConstKind::Bound(debruijn, _) => {
+                self.add_binder(debruijn);
+                self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
+            }
             ty::ConstKind::Param(_) => {
                 self.add_flags(TypeFlags::HAS_CT_PARAM);
+                self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
             }
             ty::ConstKind::Placeholder(_) => {
                 self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER);
+                self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
             }
             ty::ConstKind::Value(_) => {}
         }
@@ -243,7 +253,7 @@
         self.add_substs(projection_ty.substs);
     }
 
-    fn add_substs(&mut self, substs: SubstsRef<'_>) {
+    fn add_substs(&mut self, substs: &[GenericArg<'_>]) {
         for kind in substs {
             match kind.unpack() {
                 GenericArgKind::Type(ty) => self.add_ty(ty),
diff --git a/src/librustc_middle/ty/fold.rs b/src/librustc_middle/ty/fold.rs
index 3f4f240..a3d611a 100644
--- a/src/librustc_middle/ty/fold.rs
+++ b/src/librustc_middle/ty/fold.rs
@@ -142,6 +142,13 @@
         self.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND)
     }
 
+    /// Indicates whether this value still has parameters/placeholders/inference variables
+    /// which could be replaced later, in a way that would change the results of `impl`
+    /// specialization.
+    fn still_further_specializable(&self) -> bool {
+        self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE)
+    }
+
     /// A visitor that does not recurse into types, works like `fn walk_shallow` in `Ty`.
     fn visit_tys_shallow(&self, visit: impl FnMut(Ty<'tcx>) -> bool) -> bool {
         pub struct Visitor<F>(F);
diff --git a/src/librustc_middle/ty/instance.rs b/src/librustc_middle/ty/instance.rs
index fcfee0f..cf02223 100644
--- a/src/librustc_middle/ty/instance.rs
+++ b/src/librustc_middle/ty/instance.rs
@@ -1,10 +1,9 @@
 use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
-use crate::middle::lang_items::DropInPlaceFnLangItem;
 use crate::ty::print::{FmtPrinter, Printer};
 use crate::ty::{self, SubstsRef, Ty, TyCtxt, TypeFoldable};
-use rustc_data_structures::AtomicRef;
 use rustc_hir::def::Namespace;
 use rustc_hir::def_id::{CrateNum, DefId};
+use rustc_hir::lang_items::DropInPlaceFnLangItem;
 use rustc_macros::HashStable;
 
 use std::fmt;
@@ -289,7 +288,9 @@
         def_id: DefId,
         substs: SubstsRef<'tcx>,
     ) -> Option<Instance<'tcx>> {
-        (*RESOLVE_INSTANCE)(tcx, param_env, def_id, substs)
+        // All regions in the result of this query are erased, so it's
+        // fine to erase all of the input regions.
+        tcx.resolve_instance((tcx.erase_regions(&param_env), def_id, tcx.erase_regions(&substs)))
     }
 
     pub fn resolve_for_fn_ptr(
@@ -440,21 +441,3 @@
         (ty::ClosureKind::FnMut, _) | (ty::ClosureKind::FnOnce, _) => Err(()),
     }
 }
-
-fn resolve_instance_default(
-    _tcx: TyCtxt<'tcx>,
-    _param_env: ty::ParamEnv<'tcx>,
-    _def_id: DefId,
-    _substs: SubstsRef<'tcx>,
-) -> Option<Instance<'tcx>> {
-    unimplemented!()
-}
-
-pub static RESOLVE_INSTANCE: AtomicRef<
-    for<'tcx> fn(
-        TyCtxt<'tcx>,
-        ty::ParamEnv<'tcx>,
-        DefId,
-        SubstsRef<'tcx>,
-    ) -> Option<Instance<'tcx>>,
-> = AtomicRef::new(&(resolve_instance_default as _));
diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs
index 727d302..5740f8c 100644
--- a/src/librustc_middle/ty/layout.rs
+++ b/src/librustc_middle/ty/layout.rs
@@ -15,7 +15,7 @@
 use rustc_target::abi::call::{
     ArgAbi, ArgAttribute, ArgAttributes, Conv, FnAbi, PassMode, Reg, RegKind,
 };
-pub use rustc_target::abi::*;
+use rustc_target::abi::*;
 use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec, PanicStrategy};
 
 use std::cmp;
@@ -285,11 +285,7 @@
 
         let mut inverse_memory_index: Vec<u32> = (0..fields.len() as u32).collect();
 
-        let mut optimize = !repr.inhibit_struct_field_reordering_opt();
-        if let StructKind::Prefixed(_, align) = kind {
-            optimize &= align.bytes() == 1;
-        }
-
+        let optimize = !repr.inhibit_struct_field_reordering_opt();
         if optimize {
             let end =
                 if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() };
@@ -307,6 +303,8 @@
                     });
                 }
                 StructKind::Prefixed(..) => {
+                    // Sort in ascending alignment so that the layout stay optimal
+                    // regardless of the prefix
                     optimizing.sort_by_key(|&x| field_align(&fields[x as usize]));
                 }
             }
diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs
index 4398243..0ebd55a 100644
--- a/src/librustc_middle/ty/mod.rs
+++ b/src/librustc_middle/ty/mod.rs
@@ -11,14 +11,12 @@
 use crate::ich::StableHashingContext;
 use crate::infer::canonical::Canonical;
 use crate::middle::cstore::CrateStoreDyn;
-use crate::middle::lang_items::{FnMutTraitLangItem, FnOnceTraitLangItem, FnTraitLangItem};
 use crate::middle::resolve_lifetime::ObjectLifetimeDefault;
 use crate::mir::interpret::ErrorHandled;
 use crate::mir::GeneratorLayout;
 use crate::mir::ReadOnlyBodyAndCache;
 use crate::traits::{self, Reveal};
 use crate::ty;
-use crate::ty::layout::VariantIdx;
 use crate::ty::subst::{InternalSubsts, Subst, SubstsRef};
 use crate::ty::util::{Discr, IntTypeExt};
 use crate::ty::walk::TypeWalker;
@@ -35,6 +33,7 @@
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX};
+use rustc_hir::lang_items::{FnMutTraitLangItem, FnOnceTraitLangItem, FnTraitLangItem};
 use rustc_hir::{Constness, GlobMap, Node, TraitMap};
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_macros::HashStable;
@@ -43,7 +42,7 @@
 use rustc_span::hygiene::ExpnId;
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::Span;
-use rustc_target::abi::Align;
+use rustc_target::abi::{Align, VariantIdx};
 
 use std::cell::RefCell;
 use std::cmp::{self, Ordering};
@@ -82,7 +81,6 @@
     CtxtInterners, GeneratorInteriorTypeCause, GlobalCtxt, Lift, TypeckTables,
 };
 
-pub use self::instance::RESOLVE_INSTANCE;
 pub use self::instance::{Instance, InstanceDef};
 
 pub use self::trait_def::TraitDef;
@@ -524,101 +522,106 @@
         // Does this have parameters? Used to determine whether substitution is
         // required.
         /// Does this have [Param]?
-        const HAS_TY_PARAM              = 1 << 0;
+        const HAS_TY_PARAM                = 1 << 0;
         /// Does this have [ReEarlyBound]?
-        const HAS_RE_PARAM              = 1 << 1;
+        const HAS_RE_PARAM                = 1 << 1;
         /// Does this have [ConstKind::Param]?
-        const HAS_CT_PARAM              = 1 << 2;
+        const HAS_CT_PARAM                = 1 << 2;
 
-        const NEEDS_SUBST               = TypeFlags::HAS_TY_PARAM.bits
-                                        | TypeFlags::HAS_RE_PARAM.bits
-                                        | TypeFlags::HAS_CT_PARAM.bits;
+        const NEEDS_SUBST                 = TypeFlags::HAS_TY_PARAM.bits
+                                          | TypeFlags::HAS_RE_PARAM.bits
+                                          | TypeFlags::HAS_CT_PARAM.bits;
 
         /// Does this have [Infer]?
-        const HAS_TY_INFER              = 1 << 3;
+        const HAS_TY_INFER                = 1 << 3;
         /// Does this have [ReVar]?
-        const HAS_RE_INFER              = 1 << 4;
+        const HAS_RE_INFER                = 1 << 4;
         /// Does this have [ConstKind::Infer]?
-        const HAS_CT_INFER              = 1 << 5;
+        const HAS_CT_INFER                = 1 << 5;
 
         /// Does this have inference variables? Used to determine whether
         /// inference is required.
-        const NEEDS_INFER               = TypeFlags::HAS_TY_INFER.bits
-                                        | TypeFlags::HAS_RE_INFER.bits
-                                        | TypeFlags::HAS_CT_INFER.bits;
+        const NEEDS_INFER                 = TypeFlags::HAS_TY_INFER.bits
+                                          | TypeFlags::HAS_RE_INFER.bits
+                                          | TypeFlags::HAS_CT_INFER.bits;
 
         /// Does this have [Placeholder]?
-        const HAS_TY_PLACEHOLDER        = 1 << 6;
+        const HAS_TY_PLACEHOLDER          = 1 << 6;
         /// Does this have [RePlaceholder]?
-        const HAS_RE_PLACEHOLDER        = 1 << 7;
+        const HAS_RE_PLACEHOLDER          = 1 << 7;
         /// Does this have [ConstKind::Placeholder]?
-        const HAS_CT_PLACEHOLDER        = 1 << 8;
+        const HAS_CT_PLACEHOLDER          = 1 << 8;
 
         /// `true` if there are "names" of regions and so forth
         /// that are local to a particular fn/inferctxt
-        const HAS_FREE_LOCAL_REGIONS    = 1 << 9;
+        const HAS_FREE_LOCAL_REGIONS      = 1 << 9;
 
         /// `true` if there are "names" of types and regions and so forth
         /// that are local to a particular fn
-        const HAS_FREE_LOCAL_NAMES      = TypeFlags::HAS_TY_PARAM.bits
-                                        | TypeFlags::HAS_CT_PARAM.bits
-                                        | TypeFlags::HAS_TY_INFER.bits
-                                        | TypeFlags::HAS_CT_INFER.bits
-                                        | TypeFlags::HAS_TY_PLACEHOLDER.bits
-                                        | TypeFlags::HAS_CT_PLACEHOLDER.bits
-                                        | TypeFlags::HAS_FREE_LOCAL_REGIONS.bits;
+        const HAS_FREE_LOCAL_NAMES        = TypeFlags::HAS_TY_PARAM.bits
+                                          | TypeFlags::HAS_CT_PARAM.bits
+                                          | TypeFlags::HAS_TY_INFER.bits
+                                          | TypeFlags::HAS_CT_INFER.bits
+                                          | TypeFlags::HAS_TY_PLACEHOLDER.bits
+                                          | TypeFlags::HAS_CT_PLACEHOLDER.bits
+                                          | TypeFlags::HAS_FREE_LOCAL_REGIONS.bits;
 
         /// Does this have [Projection] or [UnnormalizedProjection]?
-        const HAS_TY_PROJECTION         = 1 << 10;
+        const HAS_TY_PROJECTION           = 1 << 10;
         /// Does this have [Opaque]?
-        const HAS_TY_OPAQUE             = 1 << 11;
+        const HAS_TY_OPAQUE               = 1 << 11;
         /// Does this have [ConstKind::Unevaluated]?
-        const HAS_CT_PROJECTION         = 1 << 12;
+        const HAS_CT_PROJECTION           = 1 << 12;
 
         /// Could this type be normalized further?
-        const HAS_PROJECTION            = TypeFlags::HAS_TY_PROJECTION.bits
-                                        | TypeFlags::HAS_TY_OPAQUE.bits
-                                        | TypeFlags::HAS_CT_PROJECTION.bits;
+        const HAS_PROJECTION              = TypeFlags::HAS_TY_PROJECTION.bits
+                                          | TypeFlags::HAS_TY_OPAQUE.bits
+                                          | TypeFlags::HAS_CT_PROJECTION.bits;
 
         /// Present if the type belongs in a local type context.
         /// Set for placeholders and inference variables that are not "Fresh".
-        const KEEP_IN_LOCAL_TCX         = 1 << 13;
+        const KEEP_IN_LOCAL_TCX           = 1 << 13;
 
         /// Is an error type reachable?
-        const HAS_TY_ERR                = 1 << 14;
+        const HAS_TY_ERR                  = 1 << 14;
 
         /// Does this have any region that "appears free" in the type?
         /// Basically anything but [ReLateBound] and [ReErased].
-        const HAS_FREE_REGIONS          = 1 << 15;
+        const HAS_FREE_REGIONS            = 1 << 15;
 
         /// Does this have any [ReLateBound] regions? Used to check
         /// if a global bound is safe to evaluate.
-        const HAS_RE_LATE_BOUND         = 1 << 16;
+        const HAS_RE_LATE_BOUND           = 1 << 16;
 
         /// Does this have any [ReErased] regions?
-        const HAS_RE_ERASED             = 1 << 17;
+        const HAS_RE_ERASED               = 1 << 17;
+
+        /// Does this value have parameters/placeholders/inference variables which could be
+        /// replaced later, in a way that would change the results of `impl` specialization?
+        const STILL_FURTHER_SPECIALIZABLE = 1 << 18;
 
         /// Flags representing the nominal content of a type,
         /// computed by FlagsComputation. If you add a new nominal
         /// flag, it should be added here too.
-        const NOMINAL_FLAGS             = TypeFlags::HAS_TY_PARAM.bits
-                                        | TypeFlags::HAS_RE_PARAM.bits
-                                        | TypeFlags::HAS_CT_PARAM.bits
-                                        | TypeFlags::HAS_TY_INFER.bits
-                                        | TypeFlags::HAS_RE_INFER.bits
-                                        | TypeFlags::HAS_CT_INFER.bits
-                                        | TypeFlags::HAS_TY_PLACEHOLDER.bits
-                                        | TypeFlags::HAS_RE_PLACEHOLDER.bits
-                                        | TypeFlags::HAS_CT_PLACEHOLDER.bits
-                                        | TypeFlags::HAS_FREE_LOCAL_REGIONS.bits
-                                        | TypeFlags::HAS_TY_PROJECTION.bits
-                                        | TypeFlags::HAS_TY_OPAQUE.bits
-                                        | TypeFlags::HAS_CT_PROJECTION.bits
-                                        | TypeFlags::KEEP_IN_LOCAL_TCX.bits
-                                        | TypeFlags::HAS_TY_ERR.bits
-                                        | TypeFlags::HAS_FREE_REGIONS.bits
-                                        | TypeFlags::HAS_RE_LATE_BOUND.bits
-                                        | TypeFlags::HAS_RE_ERASED.bits;
+        const NOMINAL_FLAGS               = TypeFlags::HAS_TY_PARAM.bits
+                                          | TypeFlags::HAS_RE_PARAM.bits
+                                          | TypeFlags::HAS_CT_PARAM.bits
+                                          | TypeFlags::HAS_TY_INFER.bits
+                                          | TypeFlags::HAS_RE_INFER.bits
+                                          | TypeFlags::HAS_CT_INFER.bits
+                                          | TypeFlags::HAS_TY_PLACEHOLDER.bits
+                                          | TypeFlags::HAS_RE_PLACEHOLDER.bits
+                                          | TypeFlags::HAS_CT_PLACEHOLDER.bits
+                                          | TypeFlags::HAS_FREE_LOCAL_REGIONS.bits
+                                          | TypeFlags::HAS_TY_PROJECTION.bits
+                                          | TypeFlags::HAS_TY_OPAQUE.bits
+                                          | TypeFlags::HAS_CT_PROJECTION.bits
+                                          | TypeFlags::KEEP_IN_LOCAL_TCX.bits
+                                          | TypeFlags::HAS_TY_ERR.bits
+                                          | TypeFlags::HAS_FREE_REGIONS.bits
+                                          | TypeFlags::HAS_RE_LATE_BOUND.bits
+                                          | TypeFlags::HAS_RE_ERASED.bits
+                                          | TypeFlags::STILL_FURTHER_SPECIALIZABLE.bits;
     }
 }
 
@@ -1073,48 +1076,42 @@
         false
     }
 
+    pub fn param_at(&'tcx self, param_index: usize, tcx: TyCtxt<'tcx>) -> &'tcx GenericParamDef {
+        if let Some(index) = param_index.checked_sub(self.parent_count) {
+            &self.params[index]
+        } else {
+            tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
+                .param_at(param_index, tcx)
+        }
+    }
+
     pub fn region_param(
         &'tcx self,
         param: &EarlyBoundRegion,
         tcx: TyCtxt<'tcx>,
     ) -> &'tcx GenericParamDef {
-        if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
-            let param = &self.params[index as usize];
-            match param.kind {
-                GenericParamDefKind::Lifetime => param,
-                _ => bug!("expected lifetime parameter, but found another generic parameter"),
-            }
-        } else {
-            tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
-                .region_param(param, tcx)
+        let param = self.param_at(param.index as usize, tcx);
+        match param.kind {
+            GenericParamDefKind::Lifetime => param,
+            _ => bug!("expected lifetime parameter, but found another generic parameter"),
         }
     }
 
     /// Returns the `GenericParamDef` associated with this `ParamTy`.
     pub fn type_param(&'tcx self, param: &ParamTy, tcx: TyCtxt<'tcx>) -> &'tcx GenericParamDef {
-        if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
-            let param = &self.params[index as usize];
-            match param.kind {
-                GenericParamDefKind::Type { .. } => param,
-                _ => bug!("expected type parameter, but found another generic parameter"),
-            }
-        } else {
-            tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
-                .type_param(param, tcx)
+        let param = self.param_at(param.index as usize, tcx);
+        match param.kind {
+            GenericParamDefKind::Type { .. } => param,
+            _ => bug!("expected type parameter, but found another generic parameter"),
         }
     }
 
     /// Returns the `ConstParameterDef` associated with this `ParamConst`.
     pub fn const_param(&'tcx self, param: &ParamConst, tcx: TyCtxt<'tcx>) -> &GenericParamDef {
-        if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
-            let param = &self.params[index as usize];
-            match param.kind {
-                GenericParamDefKind::Const => param,
-                _ => bug!("expected const parameter, but found another generic parameter"),
-            }
-        } else {
-            tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
-                .const_param(param, tcx)
+        let param = self.param_at(param.index as usize, tcx);
+        match param.kind {
+            GenericParamDefKind::Const => param,
+            _ => bug!("expected const parameter, but found another generic parameter"),
         }
     }
 }
@@ -2078,7 +2075,7 @@
     /// The `DefId` of the struct, enum or union item.
     pub did: DefId,
     /// Variants of the ADT. If this is a struct or union, then there will be a single variant.
-    pub variants: IndexVec<self::layout::VariantIdx, VariantDef>,
+    pub variants: IndexVec<VariantIdx, VariantDef>,
     /// Flags of the ADT (e.g., is this a struct? is this non-exhaustive?).
     flags: AdtFlags,
     /// Repr options provided by the user.
diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs
index 5c365a5..a8b7b6a 100644
--- a/src/librustc_middle/ty/print/pretty.rs
+++ b/src/librustc_middle/ty/print/pretty.rs
@@ -1,7 +1,7 @@
 use crate::middle::cstore::{ExternCrate, ExternCrateSource};
 use crate::middle::region;
 use crate::mir::interpret::{sign_extend, truncate, AllocId, ConstValue, Pointer, Scalar};
-use crate::ty::layout::{Integer, IntegerExt, Size};
+use crate::ty::layout::IntegerExt;
 use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
 use crate::ty::{self, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable};
 use rustc_apfloat::ieee::{Double, Single};
@@ -13,6 +13,7 @@
 use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
 use rustc_span::symbol::{kw, Symbol};
+use rustc_target::abi::{Integer, Size};
 use rustc_target::spec::abi::Abi;
 
 use std::cell::Cell;
diff --git a/src/librustc_middle/ty/query/keys.rs b/src/librustc_middle/ty/query/keys.rs
index a261e48..438e7ed 100644
--- a/src/librustc_middle/ty/query/keys.rs
+++ b/src/librustc_middle/ty/query/keys.rs
@@ -296,3 +296,14 @@
         DUMMY_SP
     }
 }
+
+impl<'tcx> Key for (ty::ParamEnv<'tcx>, DefId, SubstsRef<'tcx>) {
+    type CacheSelector = DefaultCacheSelector;
+
+    fn query_crate(&self) -> CrateNum {
+        self.1.krate
+    }
+    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
+        tcx.def_span(self.1)
+    }
+}
diff --git a/src/librustc_middle/ty/query/mod.rs b/src/librustc_middle/ty/query/mod.rs
index 7442375..9986eb8 100644
--- a/src/librustc_middle/ty/query/mod.rs
+++ b/src/librustc_middle/ty/query/mod.rs
@@ -7,7 +7,6 @@
 use crate::middle::cstore::{CrateSource, DepKind, NativeLibraryKind};
 use crate::middle::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLibrary};
 use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
-use crate::middle::lang_items::{LangItem, LanguageItems};
 use crate::middle::lib_features::LibFeatures;
 use crate::middle::privacy::AccessLevels;
 use crate::middle::region;
@@ -34,16 +33,17 @@
 use crate::ty::subst::{GenericArg, SubstsRef};
 use crate::ty::util::AlwaysRequiresDrop;
 use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
-use crate::util::common::ErrorReported;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
 use rustc_data_structures::profiling::ProfileCategory::*;
 use rustc_data_structures::stable_hasher::StableVec;
 use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::Lrc;
+use rustc_errors::ErrorReported;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
+use rustc_hir::lang_items::{LangItem, LanguageItems};
 use rustc_hir::{Crate, HirIdSet, ItemLocalId, TraitCandidate};
 use rustc_index::vec::IndexVec;
 use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
diff --git a/src/librustc_middle/ty/structural_impls.rs b/src/librustc_middle/ty/structural_impls.rs
index 429791d..0ac4466 100644
--- a/src/librustc_middle/ty/structural_impls.rs
+++ b/src/librustc_middle/ty/structural_impls.rs
@@ -254,7 +254,7 @@
     (),
     bool,
     usize,
-    crate::ty::layout::VariantIdx,
+    ::rustc_target::abi::VariantIdx,
     u64,
     String,
     crate::middle::region::Scope,
diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs
index 57df50d..ef815aa 100644
--- a/src/librustc_middle/ty/sty.rs
+++ b/src/librustc_middle/ty/sty.rs
@@ -10,7 +10,6 @@
 use crate::mir::interpret::ConstValue;
 use crate::mir::interpret::{LitToConstInput, Scalar};
 use crate::mir::Promoted;
-use crate::ty::layout::VariantIdx;
 use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
 use crate::ty::{
     self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable, WithConstness,
@@ -24,6 +23,7 @@
 use rustc_index::vec::Idx;
 use rustc_macros::HashStable;
 use rustc_span::symbol::{kw, Symbol};
+use rustc_target::abi::{Size, VariantIdx};
 use rustc_target::spec::abi;
 use smallvec::SmallVec;
 use std::borrow::Cow;
@@ -1623,16 +1623,19 @@
                 flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
                 flags = flags | TypeFlags::HAS_RE_INFER;
                 flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
+                flags = flags | TypeFlags::STILL_FURTHER_SPECIALIZABLE;
             }
             ty::RePlaceholder(..) => {
                 flags = flags | TypeFlags::HAS_FREE_REGIONS;
                 flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
                 flags = flags | TypeFlags::HAS_RE_PLACEHOLDER;
+                flags = flags | TypeFlags::STILL_FURTHER_SPECIALIZABLE;
             }
             ty::ReEarlyBound(..) => {
                 flags = flags | TypeFlags::HAS_FREE_REGIONS;
                 flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
                 flags = flags | TypeFlags::HAS_RE_PARAM;
+                flags = flags | TypeFlags::STILL_FURTHER_SPECIALIZABLE;
             }
             ty::ReFree { .. } | ty::ReScope { .. } => {
                 flags = flags | TypeFlags::HAS_FREE_REGIONS;
@@ -2501,7 +2504,7 @@
     }
 
     #[inline]
-    pub fn try_to_bits(&self, size: ty::layout::Size) -> Option<u128> {
+    pub fn try_to_bits(&self, size: Size) -> Option<u128> {
         if let ConstKind::Value(val) = self { val.try_to_bits(size) } else { None }
     }
 }
diff --git a/src/librustc_middle/ty/util.rs b/src/librustc_middle/ty/util.rs
index dab367a..86575b0 100644
--- a/src/librustc_middle/ty/util.rs
+++ b/src/librustc_middle/ty/util.rs
@@ -2,24 +2,24 @@
 
 use crate::ich::NodeIdHashingMode;
 use crate::mir::interpret::{sign_extend, truncate};
-use crate::ty::layout::{Integer, IntegerExt, Size};
+use crate::ty::layout::IntegerExt;
 use crate::ty::query::TyCtxtAt;
 use crate::ty::subst::{GenericArgKind, InternalSubsts, Subst, SubstsRef};
 use crate::ty::TyKind::*;
 use crate::ty::{self, DefIdTree, GenericParamDefKind, Ty, TyCtxt, TypeFoldable};
-use crate::util::common::ErrorReported;
 use rustc_apfloat::Float as _;
 use rustc_ast::ast;
 use rustc_attr::{self as attr, SignedInt, UnsignedInt};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+use rustc_errors::ErrorReported;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::definitions::DefPathData;
 use rustc_macros::HashStable;
 use rustc_span::Span;
-use rustc_target::abi::TargetDataLayout;
+use rustc_target::abi::{Integer, Size, TargetDataLayout};
 use smallvec::SmallVec;
 use std::{cmp, fmt};
 
diff --git a/src/librustc_middle/util/common.rs b/src/librustc_middle/util/common.rs
index 19b43bf..1e09702 100644
--- a/src/librustc_middle/util/common.rs
+++ b/src/librustc_middle/util/common.rs
@@ -8,8 +8,6 @@
 #[cfg(test)]
 mod tests;
 
-pub use rustc_errors::ErrorReported;
-
 pub fn to_readable_str(mut val: usize) -> String {
     let mut groups = vec![];
     loop {
diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs
index 2991f29..619ae0f 100644
--- a/src/librustc_mir/borrow_check/diagnostics/mod.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs
@@ -9,10 +9,10 @@
     AggregateKind, Constant, Field, Local, LocalInfo, LocalKind, Location, Operand, Place,
     PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
 };
-use rustc_middle::ty::layout::VariantIdx;
 use rustc_middle::ty::print::Print;
 use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt};
 use rustc_span::Span;
+use rustc_target::abi::VariantIdx;
 
 use super::borrow_set::BorrowData;
 use super::MirBorrowckCtxt;
diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs
index 1251102..303f43b 100644
--- a/src/librustc_mir/borrow_check/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/region_infer/mod.rs
@@ -202,7 +202,7 @@
 ///
 /// For more information about this translation, see
 /// `InferCtxt::process_registered_region_obligations` and
-/// `InferCtxt::type_must_outlive` in `rustc_middle::infer::outlives`.
+/// `InferCtxt::type_must_outlive` in `rustc_infer::infer::InferCtxt`.
 #[derive(Clone, Debug)]
 pub struct TypeTest<'tcx> {
     /// The type `T` that must outlive the region.
diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs
index 1d66bd1..a118fe2 100644
--- a/src/librustc_mir/borrow_check/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/type_check/mod.rs
@@ -24,13 +24,13 @@
 use rustc_middle::ty::adjustment::PointerCast;
 use rustc_middle::ty::cast::CastTy;
 use rustc_middle::ty::fold::TypeFoldable;
-use rustc_middle::ty::layout::VariantIdx;
 use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef, UserSubsts};
 use rustc_middle::ty::{
     self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, RegionVid, ToPolyTraitRef, Ty,
     TyCtxt, UserType, UserTypeAnnotationIndex,
 };
 use rustc_span::{Span, DUMMY_SP};
+use rustc_target::abi::VariantIdx;
 use rustc_trait_selection::infer::InferCtxtExt as _;
 use rustc_trait_selection::opaque_types::{GenerateMemberConstraints, InferCtxtExt};
 use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
@@ -1053,7 +1053,7 @@
     /// regions which are extracted and stored as having occurred at
     /// `locations`.
     ///
-    /// **Any `rustc_middle::infer` operations that might generate region
+    /// **Any `rustc_infer::infer` operations that might generate region
     /// constraints should occur within this method so that those
     /// constraints can be properly localized!**
     fn fully_perform_op<R>(
diff --git a/src/librustc_mir/borrow_check/universal_regions.rs b/src/librustc_mir/borrow_check/universal_regions.rs
index c31f5a5..4d67d72 100644
--- a/src/librustc_mir/borrow_check/universal_regions.rs
+++ b/src/librustc_mir/borrow_check/universal_regions.rs
@@ -17,10 +17,10 @@
 use rustc_errors::DiagnosticBuilder;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_hir::lang_items;
 use rustc_hir::{BodyOwnerKind, HirId};
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_infer::infer::{InferCtxt, NLLRegionVariableOrigin};
-use rustc_middle::middle::lang_items;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
 use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs
index af79198..97cdb32 100644
--- a/src/librustc_mir/const_eval/eval_queries.rs
+++ b/src/librustc_mir/const_eval/eval_queries.rs
@@ -9,8 +9,9 @@
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{ConstEvalErr, ErrorHandled};
 use rustc_middle::traits::Reveal;
-use rustc_middle::ty::{self, layout, layout::LayoutOf, subst::Subst, TyCtxt};
+use rustc_middle::ty::{self, subst::Subst, TyCtxt};
 use rustc_span::source_map::Span;
+use rustc_target::abi::{Abi, LayoutOf};
 use std::convert::TryInto;
 
 pub fn note_on_undefined_behavior_error() -> &'static str {
@@ -105,8 +106,8 @@
     // the usual cases of extracting e.g. a `usize`, without there being a real use case for the
     // `Undef` situation.
     let try_as_immediate = match op.layout.abi {
-        layout::Abi::Scalar(..) => true,
-        layout::Abi::ScalarPair(..) => match op.layout.ty.kind {
+        Abi::Scalar(..) => true,
+        Abi::ScalarPair(..) => match op.layout.ty.kind {
             ty::Ref(_, inner, _) => match inner.kind {
                 ty::Slice(elem) => elem == ecx.tcx.types.u8,
                 ty::Str => true,
diff --git a/src/librustc_mir/const_eval/mod.rs b/src/librustc_mir/const_eval/mod.rs
index 78d1e89..e1146ef 100644
--- a/src/librustc_mir/const_eval/mod.rs
+++ b/src/librustc_mir/const_eval/mod.rs
@@ -3,9 +3,9 @@
 use std::convert::TryFrom;
 
 use rustc_middle::mir;
-use rustc_middle::ty::layout::VariantIdx;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::{source_map::DUMMY_SP, symbol::Symbol};
+use rustc_target::abi::VariantIdx;
 
 use crate::interpret::{intern_const_alloc_recursive, ConstValue, InternKind, InterpCx};
 
diff --git a/src/librustc_mir/dataflow/framework/mod.rs b/src/librustc_mir/dataflow/framework/mod.rs
index fd2a3d5..06da879 100644
--- a/src/librustc_mir/dataflow/framework/mod.rs
+++ b/src/librustc_mir/dataflow/framework/mod.rs
@@ -36,8 +36,8 @@
 use rustc_index::bit_set::{BitSet, HybridBitSet};
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_middle::mir::{self, BasicBlock, Location};
-use rustc_middle::ty::layout::VariantIdx;
 use rustc_middle::ty::{self, TyCtxt};
+use rustc_target::abi::VariantIdx;
 
 mod cursor;
 mod engine;
diff --git a/src/librustc_mir/dataflow/graphviz.rs b/src/librustc_mir/dataflow/graphviz.rs
deleted file mode 100644
index e74d27b..0000000
--- a/src/librustc_mir/dataflow/graphviz.rs
+++ /dev/null
@@ -1,277 +0,0 @@
-//! Hook into libgraphviz for rendering dataflow graphs for MIR.
-
-use rustc_hir::def_id::DefId;
-use rustc_middle::mir::{BasicBlock, Body};
-
-use std::fs;
-use std::io;
-use std::marker::PhantomData;
-use std::path::Path;
-
-use crate::util::graphviz_safe_def_name;
-
-use super::DataflowBuilder;
-use super::DebugFormatted;
-use super::{BitDenotation, DataflowState};
-
-pub trait MirWithFlowState<'tcx> {
-    type BD: BitDenotation<'tcx>;
-    fn def_id(&self) -> DefId;
-    fn body(&self) -> &Body<'tcx>;
-    fn flow_state(&self) -> &DataflowState<'tcx, Self::BD>;
-}
-
-impl<'a, 'tcx, BD> MirWithFlowState<'tcx> for DataflowBuilder<'a, 'tcx, BD>
-where
-    BD: BitDenotation<'tcx>,
-{
-    type BD = BD;
-    fn def_id(&self) -> DefId {
-        self.def_id
-    }
-    fn body(&self) -> &Body<'tcx> {
-        self.flow_state.body()
-    }
-    fn flow_state(&self) -> &DataflowState<'tcx, Self::BD> {
-        &self.flow_state.flow_state
-    }
-}
-
-struct Graph<'a, 'tcx, MWF, P>
-where
-    MWF: MirWithFlowState<'tcx>,
-{
-    mbcx: &'a MWF,
-    phantom: PhantomData<&'tcx ()>,
-    render_idx: P,
-}
-
-pub(crate) fn print_borrowck_graph_to<'a, 'tcx, BD, P>(
-    mbcx: &DataflowBuilder<'a, 'tcx, BD>,
-    path: &Path,
-    render_idx: P,
-) -> io::Result<()>
-where
-    BD: BitDenotation<'tcx>,
-    P: Fn(&BD, BD::Idx) -> DebugFormatted,
-{
-    let g = Graph { mbcx, phantom: PhantomData, render_idx };
-    let mut v = Vec::new();
-    dot::render(&g, &mut v)?;
-    debug!("print_borrowck_graph_to path: {} def_id: {:?}", path.display(), mbcx.def_id);
-    fs::write(path, v)
-}
-
-pub type Node = BasicBlock;
-
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-pub struct Edge {
-    source: BasicBlock,
-    index: usize,
-}
-
-fn outgoing(body: &Body<'_>, bb: BasicBlock) -> Vec<Edge> {
-    (0..body[bb].terminator().successors().count())
-        .map(|index| Edge { source: bb, index })
-        .collect()
-}
-
-impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P>
-where
-    MWF: MirWithFlowState<'tcx>,
-    P: Fn(&MWF::BD, <MWF::BD as BitDenotation<'tcx>>::Idx) -> DebugFormatted,
-{
-    type Node = Node;
-    type Edge = Edge;
-    fn graph_id(&self) -> dot::Id<'_> {
-        let name = graphviz_safe_def_name(self.mbcx.def_id());
-        dot::Id::new(format!("graph_for_def_id_{}", name)).unwrap()
-    }
-
-    fn node_id(&self, n: &Node) -> dot::Id<'_> {
-        dot::Id::new(format!("bb_{}", n.index())).unwrap()
-    }
-
-    fn node_label(&self, n: &Node) -> dot::LabelText<'_> {
-        // Node label is something like this:
-        // +---------+----------------------------------+------------------+------------------+
-        // | ENTRY   | MIR                              | GEN              | KILL             |
-        // +---------+----------------------------------+------------------+------------------+
-        // |         |  0: StorageLive(_7)              | bb3[2]: reserved | bb2[0]: reserved |
-        // |         |  1: StorageLive(_8)              | bb3[2]: active   | bb2[0]: active   |
-        // |         |  2: _8 = &mut _1                 |                  | bb4[2]: reserved |
-        // |         |                                  |                  | bb4[2]: active   |
-        // |         |                                  |                  | bb9[0]: reserved |
-        // |         |                                  |                  | bb9[0]: active   |
-        // |         |                                  |                  | bb10[0]: reserved|
-        // |         |                                  |                  | bb10[0]: active  |
-        // |         |                                  |                  | bb11[0]: reserved|
-        // |         |                                  |                  | bb11[0]: active  |
-        // +---------+----------------------------------+------------------+------------------+
-        // | [00-00] | _7 = const Foo::twiddle(move _8) | [0c-00]          | [f3-0f]          |
-        // +---------+----------------------------------+------------------+------------------+
-        let mut v = Vec::new();
-        self.node_label_internal(n, &mut v, *n, self.mbcx.body()).unwrap();
-        dot::LabelText::html(String::from_utf8(v).unwrap())
-    }
-
-    fn node_shape(&self, _n: &Node) -> Option<dot::LabelText<'_>> {
-        Some(dot::LabelText::label("none"))
-    }
-
-    fn edge_label(&'a self, e: &Edge) -> dot::LabelText<'a> {
-        let term = self.mbcx.body()[e.source].terminator();
-        let label = &term.kind.fmt_successor_labels()[e.index];
-        dot::LabelText::label(label.clone())
-    }
-}
-
-impl<'a, 'tcx, MWF, P> Graph<'a, 'tcx, MWF, P>
-where
-    MWF: MirWithFlowState<'tcx>,
-    P: Fn(&MWF::BD, <MWF::BD as BitDenotation<'tcx>>::Idx) -> DebugFormatted,
-{
-    /// Generate the node label
-    fn node_label_internal<W: io::Write>(
-        &self,
-        n: &Node,
-        w: &mut W,
-        block: BasicBlock,
-        body: &Body<'_>,
-    ) -> io::Result<()> {
-        // Header rows
-        const HDRS: [&str; 4] = ["ENTRY", "MIR", "BLOCK GENS", "BLOCK KILLS"];
-        const HDR_FMT: &str = "bgcolor=\"grey\"";
-        write!(w, "<table><tr><td rowspan=\"{}\">", HDRS.len())?;
-        write!(w, "{:?}", block.index())?;
-        write!(w, "</td></tr><tr>")?;
-        for hdr in &HDRS {
-            write!(w, "<td {}>{}</td>", HDR_FMT, hdr)?;
-        }
-        write!(w, "</tr>")?;
-
-        // Data row
-        self.node_label_verbose_row(n, w, block, body)?;
-        self.node_label_final_row(n, w, block, body)?;
-        write!(w, "</table>")?;
-
-        Ok(())
-    }
-
-    /// Builds the verbose row: full MIR data, and detailed gen/kill/entry sets.
-    fn node_label_verbose_row<W: io::Write>(
-        &self,
-        n: &Node,
-        w: &mut W,
-        block: BasicBlock,
-        body: &Body<'_>,
-    ) -> io::Result<()> {
-        let i = n.index();
-
-        macro_rules! dump_set_for {
-            ($set:ident, $interpret:ident) => {
-                write!(w, "<td>")?;
-
-                let flow = self.mbcx.flow_state();
-                let entry_interp =
-                    flow.$interpret(&flow.operator, flow.sets.$set(i), &self.render_idx);
-                for e in &entry_interp {
-                    write!(w, "{:?}<br/>", e)?;
-                }
-                write!(w, "</td>")?;
-            };
-        }
-
-        write!(w, "<tr>")?;
-        // Entry
-        dump_set_for!(entry_set_for, interpret_set);
-
-        // MIR statements
-        write!(w, "<td>")?;
-        {
-            let data = &body[block];
-            for (i, statement) in data.statements.iter().enumerate() {
-                write!(
-                    w,
-                    "{}<br align=\"left\"/>",
-                    dot::escape_html(&format!("{:3}: {:?}", i, statement))
-                )?;
-            }
-        }
-        write!(w, "</td>")?;
-
-        // Gen
-        dump_set_for!(gen_set_for, interpret_hybrid_set);
-
-        // Kill
-        dump_set_for!(kill_set_for, interpret_hybrid_set);
-
-        write!(w, "</tr>")?;
-
-        Ok(())
-    }
-
-    /// Builds the summary row: terminator, gen/kill/entry bit sets.
-    fn node_label_final_row<W: io::Write>(
-        &self,
-        n: &Node,
-        w: &mut W,
-        block: BasicBlock,
-        body: &Body<'_>,
-    ) -> io::Result<()> {
-        let i = n.index();
-
-        let flow = self.mbcx.flow_state();
-
-        write!(w, "<tr>")?;
-
-        // Entry
-        let set = flow.sets.entry_set_for(i);
-        write!(w, "<td>{:?}</td>", dot::escape_html(&set.to_string()))?;
-
-        // Terminator
-        write!(w, "<td>")?;
-        {
-            let data = &body[block];
-            let mut terminator_head = String::new();
-            data.terminator().kind.fmt_head(&mut terminator_head).unwrap();
-            write!(w, "{}", dot::escape_html(&terminator_head))?;
-        }
-        write!(w, "</td>")?;
-
-        // Gen/Kill
-        let trans = flow.sets.trans_for(i);
-        write!(w, "<td>{:?}</td>", dot::escape_html(&format!("{:?}", trans.gen_set)))?;
-        write!(w, "<td>{:?}</td>", dot::escape_html(&format!("{:?}", trans.kill_set)))?;
-
-        write!(w, "</tr>")?;
-
-        Ok(())
-    }
-}
-
-impl<'a, 'tcx, MWF, P> dot::GraphWalk<'a> for Graph<'a, 'tcx, MWF, P>
-where
-    MWF: MirWithFlowState<'tcx>,
-{
-    type Node = Node;
-    type Edge = Edge;
-    fn nodes(&self) -> dot::Nodes<'_, Node> {
-        self.mbcx.body().basic_blocks().indices().collect::<Vec<_>>().into()
-    }
-
-    fn edges(&self) -> dot::Edges<'_, Edge> {
-        let body = self.mbcx.body();
-
-        body.basic_blocks().indices().flat_map(|bb| outgoing(body, bb)).collect::<Vec<_>>().into()
-    }
-
-    fn source(&self, edge: &Edge) -> Node {
-        edge.source
-    }
-
-    fn target(&self, edge: &Edge) -> Node {
-        let body = self.mbcx.body();
-        *body[edge.source].terminator().successors().nth(edge.index).unwrap()
-    }
-}
diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs
index 1c85226..b5f1a2d 100644
--- a/src/librustc_mir/dataflow/impls/mod.rs
+++ b/src/librustc_mir/dataflow/impls/mod.rs
@@ -5,8 +5,8 @@
 use rustc_index::bit_set::BitSet;
 use rustc_index::vec::Idx;
 use rustc_middle::mir::{self, Body, Location};
-use rustc_middle::ty::layout::VariantIdx;
 use rustc_middle::ty::{self, TyCtxt};
+use rustc_target::abi::VariantIdx;
 
 use super::MoveDataParamEnv;
 
diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs
index 215c7bb..67696aa 100644
--- a/src/librustc_mir/interpret/cast.rs
+++ b/src/librustc_mir/interpret/cast.rs
@@ -7,10 +7,10 @@
 use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar};
 use rustc_middle::mir::CastKind;
 use rustc_middle::ty::adjustment::PointerCast;
-use rustc_middle::ty::layout::{self, Size, TyAndLayout};
+use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::ty::{self, Ty, TypeAndMut, TypeFoldable};
 use rustc_span::symbol::sym;
-use rustc_target::abi::LayoutOf;
+use rustc_target::abi::{LayoutOf, Size, Variants};
 
 impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     pub fn cast(
@@ -132,7 +132,7 @@
 
         // Handle cast from a univariant (ZST) enum.
         match src.layout.variants {
-            layout::Variants::Single { index } => {
+            Variants::Single { index } => {
                 if let Some(discr) = src.layout.ty.discriminant_for_variant(*self.tcx, index) {
                     assert!(src.layout.is_zst());
                     let discr_layout = self.layout_of(discr.ty)?;
@@ -141,7 +141,7 @@
                         .into());
                 }
             }
-            layout::Variants::Multiple { .. } => {}
+            Variants::Multiple { .. } => {}
         }
 
         // Handle casting the metadata away from a fat pointer.
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 8f24fc4..0b182d4 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -13,11 +13,12 @@
 use rustc_middle::mir::interpret::{
     sign_extend, truncate, AllocId, FrameInfo, GlobalId, InterpResult, Pointer, Scalar,
 };
-use rustc_middle::ty::layout::{self, Align, HasDataLayout, LayoutOf, Size, TyAndLayout};
-use rustc_middle::ty::query::TyCtxtAt;
-use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
+use rustc_middle::ty::layout::{self, TyAndLayout};
+use rustc_middle::ty::{
+    self, fold::BottomUpFolder, query::TyCtxtAt, subst::SubstsRef, Ty, TyCtxt, TypeFoldable,
+};
 use rustc_span::source_map::DUMMY_SP;
+use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size, TargetDataLayout};
 
 use super::{
     Immediate, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, OpTy, Operand, Place, PlaceTy,
@@ -173,7 +174,7 @@
 
 impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout for InterpCx<'mir, 'tcx, M> {
     #[inline]
-    fn data_layout(&self) -> &layout::TargetDataLayout {
+    fn data_layout(&self) -> &TargetDataLayout {
         &self.tcx.data_layout
     }
 }
@@ -209,6 +210,73 @@
     }
 }
 
+/// Test if it is valid for a MIR assignment to assign `src`-typed place to `dest`-typed value.
+/// This test should be symmetric, as it is primarily about layout compatibility.
+pub(super) fn mir_assign_valid_types<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    src: TyAndLayout<'tcx>,
+    dest: TyAndLayout<'tcx>,
+) -> bool {
+    if src.ty == dest.ty {
+        // Equal types, all is good.
+        return true;
+    }
+    if src.layout != dest.layout {
+        // Layout differs, definitely not equal.
+        // We do this here because Miri would *do the wrong thing* if we allowed layout-changing
+        // assignments.
+        return false;
+    }
+
+    // Type-changing assignments can happen for (at least) two reasons:
+    // 1. `&mut T` -> `&T` gets optimized from a reborrow to a mere assignment.
+    // 2. Subtyping is used. While all normal lifetimes are erased, higher-ranked types
+    //    with their late-bound lifetimes are still around and can lead to type differences.
+    // Normalize both of them away.
+    let normalize = |ty: Ty<'tcx>| {
+        ty.fold_with(&mut BottomUpFolder {
+            tcx,
+            // Normalize all references to immutable.
+            ty_op: |ty| match ty.kind {
+                ty::Ref(_, pointee, _) => tcx.mk_imm_ref(tcx.lifetimes.re_erased, pointee),
+                _ => ty,
+            },
+            // We just erase all late-bound lifetimes, but this is not fully correct (FIXME):
+            // lifetimes in invariant positions could matter (e.g. through associated types).
+            // We rely on the fact that layout was confirmed to be equal above.
+            lt_op: |_| tcx.lifetimes.re_erased,
+            // Leave consts unchanged.
+            ct_op: |ct| ct,
+        })
+    };
+    normalize(src.ty) == normalize(dest.ty)
+}
+
+/// Use the already known layout if given (but sanity check in debug mode),
+/// or compute the layout.
+#[cfg_attr(not(debug_assertions), inline(always))]
+pub(super) fn from_known_layout<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    known_layout: Option<TyAndLayout<'tcx>>,
+    compute: impl FnOnce() -> InterpResult<'tcx, TyAndLayout<'tcx>>,
+) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
+    match known_layout {
+        None => compute(),
+        Some(known_layout) => {
+            if cfg!(debug_assertions) {
+                let check_layout = compute()?;
+                assert!(
+                    mir_assign_valid_types(tcx, check_layout, known_layout),
+                    "expected type differs from actual type.\nexpected: {:?}\nactual: {:?}",
+                    known_layout.ty,
+                    check_layout.ty,
+                );
+            }
+            Ok(known_layout)
+        }
+    }
+}
+
 impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     pub fn new(
         tcx: TyCtxtAt<'tcx>,
@@ -376,7 +444,7 @@
         // have to support that case (mostly by skipping all caching).
         match frame.locals.get(local).and_then(|state| state.layout.get()) {
             None => {
-                let layout = crate::interpret::operand::from_known_layout(layout, || {
+                let layout = from_known_layout(self.tcx.tcx, layout, || {
                     let local_ty = frame.body.local_decls[local].ty;
                     let local_ty =
                         self.subst_from_frame_and_normalize_erasing_regions(frame, local_ty);
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index b60377f..d976df8 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -11,10 +11,10 @@
     BinOp,
 };
 use rustc_middle::ty;
-use rustc_middle::ty::layout::{LayoutOf, Primitive, Size};
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::{sym, Symbol};
+use rustc_target::abi::{Abi, LayoutOf as _, Primitive, Size};
 
 use super::{ImmTy, InterpCx, Machine, OpTy, PlaceTy};
 
@@ -134,7 +134,7 @@
                 let val = self.read_scalar(args[0])?.not_undef()?;
                 let bits = self.force_bits(val, layout_of.size)?;
                 let kind = match layout_of.abi {
-                    ty::layout::Abi::Scalar(ref scalar) => scalar.value,
+                    Abi::Scalar(ref scalar) => scalar.value,
                     _ => bug!("{} called on invalid type {:?}", intrinsic_name, ty),
                 };
                 let (nonzero, intrinsic_name) = match intrinsic_name {
diff --git a/src/librustc_mir/interpret/intrinsics/caller_location.rs b/src/librustc_mir/interpret/intrinsics/caller_location.rs
index f7e264b..754f45d 100644
--- a/src/librustc_mir/interpret/intrinsics/caller_location.rs
+++ b/src/librustc_mir/interpret/intrinsics/caller_location.rs
@@ -1,6 +1,6 @@
 use std::convert::TryFrom;
 
-use rustc_middle::middle::lang_items::PanicLocationLangItem;
+use rustc_hir::lang_items::PanicLocationLangItem;
 use rustc_middle::ty::subst::Subst;
 use rustc_span::{Span, Symbol};
 use rustc_target::abi::LayoutOf;
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 9443ae1..04a927c 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -11,11 +11,10 @@
 use std::convert::TryFrom;
 use std::ptr;
 
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_middle::ty::layout::{Align, HasDataLayout, Size, TargetDataLayout};
-use rustc_middle::ty::{self, query::TyCtxtAt, Instance, ParamEnv};
-
 use rustc_ast::ast::Mutability;
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_middle::ty::{self, query::TyCtxtAt, Instance, ParamEnv};
+use rustc_target::abi::{Align, HasDataLayout, Size, TargetDataLayout};
 
 use super::{
     AllocId, AllocMap, Allocation, AllocationExtra, CheckInAllocMsg, ErrorHandled, GlobalAlloc,
diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs
index 4e30da8..fb59a17 100644
--- a/src/librustc_mir/interpret/mod.rs
+++ b/src/librustc_mir/interpret/mod.rs
@@ -18,19 +18,13 @@
 pub use rustc_middle::mir::interpret::*; // have all the `interpret` symbols in one place: here
 
 pub use self::eval_context::{Frame, InterpCx, LocalState, LocalValue, StackPopCleanup};
-
-pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy};
-
-pub use self::memory::{AllocCheck, FnVal, Memory, MemoryKind};
-
+pub use self::intern::{intern_const_alloc_recursive, InternKind};
 pub use self::machine::{AllocMap, Machine, MayLeak, StackPopJump};
-
-pub use self::operand::{ImmTy, Immediate, OpTy, Operand, ScalarMaybeUndef};
-
+pub use self::memory::{AllocCheck, FnVal, Memory, MemoryKind};
+pub use self::operand::{ImmTy, Immediate, OpTy, Operand};
+pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy};
+pub use self::validity::RefTracking;
 pub use self::visitor::{MutValueVisitor, ValueVisitor};
 
-pub use self::validity::RefTracking;
-
-pub use self::intern::{intern_const_alloc_recursive, InternKind};
-
 crate use self::intrinsics::eval_nullary_intrinsic;
+use eval_context::{from_known_layout, mir_assign_valid_types};
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 7191198..03614b2 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -2,21 +2,21 @@
 //! All high-level functions to read from memory work on operands as sources.
 
 use std::convert::TryFrom;
+use std::fmt::Write;
 
-use super::{InterpCx, MPlaceTy, Machine, MemPlace, Place, PlaceTy};
 use rustc_hir::def::Namespace;
 use rustc_macros::HashStable;
-pub use rustc_middle::mir::interpret::ScalarMaybeUndef;
-use rustc_middle::mir::interpret::{
-    sign_extend, truncate, AllocId, ConstValue, GlobalId, InterpResult, Pointer, Scalar,
-};
-use rustc_middle::ty::layout::{
-    self, HasDataLayout, IntegerExt, LayoutOf, PrimitiveExt, Size, TyAndLayout, VariantIdx,
-};
+use rustc_middle::ty::layout::{IntegerExt, PrimitiveExt, TyAndLayout};
 use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Printer};
 use rustc_middle::ty::Ty;
 use rustc_middle::{mir, ty};
-use std::fmt::Write;
+use rustc_target::abi::{Abi, DiscriminantKind, HasDataLayout, Integer, LayoutOf, Size};
+use rustc_target::abi::{VariantIdx, Variants};
+
+use super::{
+    from_known_layout, sign_extend, truncate, AllocId, ConstValue, GlobalId, InterpCx,
+    InterpResult, MPlaceTy, Machine, MemPlace, Place, PlaceTy, Pointer, Scalar, ScalarMaybeUndef,
+};
 
 /// An `Immediate` represents a single immediate self-contained Rust value.
 ///
@@ -203,29 +203,6 @@
     }
 }
 
-// Use the existing layout if given (but sanity check in debug mode),
-// or compute the layout.
-#[inline(always)]
-pub(super) fn from_known_layout<'tcx>(
-    layout: Option<TyAndLayout<'tcx>>,
-    compute: impl FnOnce() -> InterpResult<'tcx, TyAndLayout<'tcx>>,
-) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
-    match layout {
-        None => compute(),
-        Some(layout) => {
-            if cfg!(debug_assertions) {
-                let layout2 = compute()?;
-                assert_eq!(
-                    layout.layout, layout2.layout,
-                    "mismatch in layout of supposedly equal-layout types {:?} and {:?}",
-                    layout.ty, layout2.ty
-                );
-            }
-            Ok(layout)
-        }
-    }
-}
-
 impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     /// Normalice `place.ptr` to a `Pointer` if this is a place and not a ZST.
     /// Can be helpful to avoid lots of `force_ptr` calls later, if this place is used a lot.
@@ -266,7 +243,7 @@
         };
 
         match mplace.layout.abi {
-            layout::Abi::Scalar(..) => {
+            Abi::Scalar(..) => {
                 let scalar = self.memory.get_raw(ptr.alloc_id)?.read_scalar(
                     self,
                     ptr,
@@ -274,7 +251,7 @@
                 )?;
                 Ok(Some(ImmTy { imm: scalar.into(), layout: mplace.layout }))
             }
-            layout::Abi::ScalarPair(ref a, ref b) => {
+            Abi::ScalarPair(ref a, ref b) => {
                 // We checked `ptr_align` above, so all fields will have the alignment they need.
                 // We would anyway check against `ptr_align.restrict_for_offset(b_offset)`,
                 // which `ptr.offset(b_offset)` cannot possibly fail to satisfy.
@@ -552,7 +529,7 @@
             ty::ConstKind::Value(val_val) => val_val,
         };
         // Other cases need layout.
-        let layout = from_known_layout(layout, || self.layout_of(val.ty))?;
+        let layout = from_known_layout(self.tcx.tcx, layout, || self.layout_of(val.ty))?;
         let op = match val_val {
             ConstValue::ByRef { alloc, offset } => {
                 let id = self.tcx.alloc_map.lock().create_memory_alloc(alloc);
@@ -587,7 +564,7 @@
         trace!("read_discriminant_value {:#?}", rval.layout);
 
         let (discr_layout, discr_kind, discr_index) = match rval.layout.variants {
-            layout::Variants::Single { index } => {
+            Variants::Single { index } => {
                 let discr_val = rval
                     .layout
                     .ty
@@ -595,12 +572,9 @@
                     .map_or(u128::from(index.as_u32()), |discr| discr.val);
                 return Ok((discr_val, index));
             }
-            layout::Variants::Multiple {
-                discr: ref discr_layout,
-                ref discr_kind,
-                discr_index,
-                ..
-            } => (discr_layout, discr_kind, discr_index),
+            Variants::Multiple { discr: ref discr_layout, ref discr_kind, discr_index, .. } => {
+                (discr_layout, discr_kind, discr_index)
+            }
         };
 
         // read raw discriminant value
@@ -610,7 +584,7 @@
         trace!("discr value: {:?}", raw_discr);
         // post-process
         Ok(match *discr_kind {
-            layout::DiscriminantKind::Tag => {
+            DiscriminantKind::Tag => {
                 let bits_discr = raw_discr
                     .not_undef()
                     .and_then(|raw_discr| self.force_bits(raw_discr, discr_val.layout.size))
@@ -627,7 +601,7 @@
                         .expect("tagged layout corresponds to adt")
                         .repr
                         .discr_type();
-                    let size = layout::Integer::from_attr(self, discr_ty).size();
+                    let size = Integer::from_attr(self, discr_ty).size();
                     truncate(sexted, size)
                 } else {
                     bits_discr
@@ -648,11 +622,7 @@
                 .ok_or_else(|| err_ub!(InvalidDiscriminant(raw_discr.erase_tag())))?;
                 (real_discr, index.0)
             }
-            layout::DiscriminantKind::Niche {
-                dataful_variant,
-                ref niche_variants,
-                niche_start,
-            } => {
+            DiscriminantKind::Niche { dataful_variant, ref niche_variants, niche_start } => {
                 let variants_start = niche_variants.start().as_u32();
                 let variants_end = niche_variants.end().as_u32();
                 let raw_discr = raw_discr
diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs
index e81cd8b..0aa7e98 100644
--- a/src/librustc_mir/interpret/operator.rs
+++ b/src/librustc_mir/interpret/operator.rs
@@ -4,11 +4,8 @@
 use rustc_ast::ast::FloatTy;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{InterpResult, Scalar};
-use rustc_middle::ty::{
-    self,
-    layout::{LayoutOf, TyAndLayout},
-    Ty,
-};
+use rustc_middle::ty::{self, layout::TyAndLayout, Ty};
+use rustc_target::abi::LayoutOf;
 
 use super::{ImmTy, Immediate, InterpCx, Machine, PlaceTy};
 
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index a8e65a7..716c7c7 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -7,16 +7,15 @@
 
 use rustc_macros::HashStable;
 use rustc_middle::mir;
-use rustc_middle::mir::interpret::truncate;
-use rustc_middle::ty::layout::{
-    self, Align, HasDataLayout, LayoutOf, PrimitiveExt, Size, TyAndLayout, VariantIdx,
-};
+use rustc_middle::ty::layout::{PrimitiveExt, TyAndLayout};
 use rustc_middle::ty::{self, Ty};
+use rustc_target::abi::{Abi, Align, DiscriminantKind, FieldsShape};
+use rustc_target::abi::{HasDataLayout, LayoutOf, Size, VariantIdx, Variants};
 
 use super::{
-    AllocId, AllocMap, Allocation, AllocationExtra, ImmTy, Immediate, InterpCx, InterpResult,
-    LocalValue, Machine, MemoryKind, OpTy, Operand, Pointer, PointerArithmetic, RawConst, Scalar,
-    ScalarMaybeUndef,
+    mir_assign_valid_types, truncate, AllocId, AllocMap, Allocation, AllocationExtra, ImmTy,
+    Immediate, InterpCx, InterpResult, LocalValue, Machine, MemoryKind, OpTy, Operand, Pointer,
+    PointerArithmetic, RawConst, Scalar, ScalarMaybeUndef,
 };
 
 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)]
@@ -219,7 +218,7 @@
             // Go through the layout.  There are lots of types that support a length,
             // e.g., SIMD types.
             match self.layout.fields {
-                layout::FieldsShape::Array { count, .. } => Ok(count),
+                FieldsShape::Array { count, .. } => Ok(count),
                 _ => bug!("len not supported on sized type {:?}", self.layout.ty),
             }
         }
@@ -437,7 +436,7 @@
     ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
         // Not using the layout method because we want to compute on u64
         match base.layout.fields {
-            layout::FieldsShape::Array { stride, .. } => {
+            FieldsShape::Array { stride, .. } => {
                 let len = base.len(self)?;
                 if index >= len {
                     // This can only be reached in ConstProp and non-rustc-MIR.
@@ -463,7 +462,7 @@
     {
         let len = base.len(self)?; // also asserts that we have a type where this makes sense
         let stride = match base.layout.fields {
-            layout::FieldsShape::Array { stride, .. } => stride,
+            FieldsShape::Array { stride, .. } => stride,
             _ => bug!("mplace_array_fields: expected an array layout"),
         };
         let layout = base.layout.field(self, 0)?;
@@ -493,7 +492,7 @@
         // Not using layout method because that works with usize, and does not work with slices
         // (that have count 0 in their layout).
         let from_offset = match base.layout.fields {
-            layout::FieldsShape::Array { stride, .. } => stride * from, // `Size` multiplication is checked
+            FieldsShape::Array { stride, .. } => stride * from, // `Size` multiplication is checked
             _ => bug!("Unexpected layout of index access: {:#?}", base.layout),
         };
 
@@ -802,7 +801,7 @@
         match value {
             Immediate::Scalar(scalar) => {
                 match dest.layout.abi {
-                    layout::Abi::Scalar(_) => {} // fine
+                    Abi::Scalar(_) => {} // fine
                     _ => {
                         bug!("write_immediate_to_mplace: invalid Scalar layout: {:#?}", dest.layout)
                     }
@@ -819,7 +818,7 @@
                 // We would anyway check against `ptr_align.restrict_for_offset(b_offset)`,
                 // which `ptr.offset(b_offset)` cannot possibly fail to satisfy.
                 let (a, b) = match dest.layout.abi {
-                    layout::Abi::ScalarPair(ref a, ref b) => (&a.value, &b.value),
+                    Abi::ScalarPair(ref a, ref b) => (&a.value, &b.value),
                     _ => bug!(
                         "write_immediate_to_mplace: invalid ScalarPair layout: {:#?}",
                         dest.layout
@@ -869,10 +868,10 @@
         // We do NOT compare the types for equality, because well-typed code can
         // actually "transmute" `&mut T` to `&T` in an assignment without a cast.
         assert!(
-            src.layout.layout == dest.layout.layout,
-            "Layout mismatch when copying!\nsrc: {:#?}\ndest: {:#?}",
-            src,
-            dest
+            mir_assign_valid_types(self.tcx.tcx, src.layout, dest.layout),
+            "type mismatch when copying!\nsrc: {:?},\ndest: {:?}",
+            src.layout.ty,
+            dest.layout.ty,
         );
 
         // Let us see if the layout is simple so we take a shortcut, avoid force_allocation.
@@ -923,7 +922,7 @@
         src: OpTy<'tcx, M::PointerTag>,
         dest: PlaceTy<'tcx, M::PointerTag>,
     ) -> InterpResult<'tcx> {
-        if src.layout.layout == dest.layout.layout {
+        if mir_assign_valid_types(self.tcx.tcx, src.layout, dest.layout) {
             // Fast path: Just use normal `copy_op`
             return self.copy_op(src, dest);
         }
@@ -1067,11 +1066,11 @@
         }
 
         match dest.layout.variants {
-            layout::Variants::Single { index } => {
+            Variants::Single { index } => {
                 assert_eq!(index, variant_index);
             }
-            layout::Variants::Multiple {
-                discr_kind: layout::DiscriminantKind::Tag,
+            Variants::Multiple {
+                discr_kind: DiscriminantKind::Tag,
                 discr: ref discr_layout,
                 discr_index,
                 ..
@@ -1091,9 +1090,9 @@
                 let discr_dest = self.place_field(dest, discr_index)?;
                 self.write_scalar(Scalar::from_uint(discr_val, size), discr_dest)?;
             }
-            layout::Variants::Multiple {
+            Variants::Multiple {
                 discr_kind:
-                    layout::DiscriminantKind::Niche { dataful_variant, ref niche_variants, niche_start },
+                    DiscriminantKind::Niche { dataful_variant, ref niche_variants, niche_start },
                 discr: ref discr_layout,
                 discr_index,
                 ..
diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs
index 961b0f4..407849c 100644
--- a/src/librustc_mir/interpret/step.rs
+++ b/src/librustc_mir/interpret/step.rs
@@ -4,7 +4,7 @@
 
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{InterpResult, Scalar};
-use rustc_middle::ty::layout::LayoutOf;
+use rustc_target::abi::LayoutOf;
 
 use super::{InterpCx, Machine};
 
diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs
index 6ca6f50..6ebe5b8 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/src/librustc_mir/interpret/terminator.rs
@@ -1,9 +1,10 @@
 use std::borrow::Cow;
 use std::convert::TryFrom;
 
-use rustc_middle::ty::layout::{self, LayoutOf, TyAndLayout};
+use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::ty::Instance;
 use rustc_middle::{mir, ty};
+use rustc_target::abi::{self, LayoutOf as _};
 use rustc_target::spec::abi::Abi;
 
 use super::{
@@ -74,7 +75,6 @@
             }
 
             Drop { location, target, unwind } => {
-                // FIXME(CTFE): forbid drop in const eval
                 let place = self.eval_place(location)?;
                 let ty = place.layout.ty;
                 trace!("TerminatorKind::drop: {:?}, type {}", location, ty);
@@ -142,12 +142,12 @@
             // Different valid ranges are okay (once we enforce validity,
             // that will take care to make it UB to leave the range, just
             // like for transmute).
-            (layout::Abi::Scalar(ref caller), layout::Abi::Scalar(ref callee)) => {
+            (abi::Abi::Scalar(ref caller), abi::Abi::Scalar(ref callee)) => {
                 caller.value == callee.value
             }
             (
-                layout::Abi::ScalarPair(ref caller1, ref caller2),
-                layout::Abi::ScalarPair(ref callee1, ref callee2),
+                abi::Abi::ScalarPair(ref caller1, ref caller2),
+                abi::Abi::ScalarPair(ref callee1, ref callee2),
             ) => caller1.value == callee1.value && caller2.value == callee2.value,
             // Be conservative
             _ => false,
diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs
index ed882e1..fb9401c 100644
--- a/src/librustc_mir/interpret/traits.rs
+++ b/src/librustc_mir/interpret/traits.rs
@@ -1,8 +1,8 @@
 use std::convert::TryFrom;
 
 use rustc_middle::mir::interpret::{InterpResult, Pointer, PointerArithmetic, Scalar};
-use rustc_middle::ty::layout::{Align, HasDataLayout, LayoutOf, Size};
 use rustc_middle::ty::{self, Instance, Ty, TypeFoldable};
+use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size};
 
 use super::{FnVal, InterpCx, Machine, MemoryKind};
 
diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 0ca565d..701e394 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -11,8 +11,9 @@
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_middle::ty;
-use rustc_middle::ty::layout::{self, LayoutOf, TyAndLayout, VariantIdx};
+use rustc_middle::ty::layout::TyAndLayout;
 use rustc_span::symbol::{sym, Symbol};
+use rustc_target::abi::{Abi, LayoutOf, Scalar, VariantIdx, Variants};
 
 use std::hash::Hash;
 
@@ -180,7 +181,7 @@
     fn aggregate_field_path_elem(&mut self, layout: TyAndLayout<'tcx>, field: usize) -> PathElem {
         // First, check if we are projecting to a variant.
         match layout.variants {
-            layout::Variants::Multiple { discr_index, .. } => {
+            Variants::Multiple { discr_index, .. } => {
                 if discr_index == field {
                     return match layout.ty.kind {
                         ty::Adt(def, ..) if def.is_enum() => PathElem::EnumTag,
@@ -189,7 +190,7 @@
                     };
                 }
             }
-            layout::Variants::Single { .. } => {}
+            Variants::Single { .. } => {}
         }
 
         // Now we know we are projecting to a field, so figure out which one.
@@ -226,11 +227,11 @@
             ty::Adt(def, ..) if def.is_enum() => {
                 // we might be projecting *to* a variant, or to a field *in* a variant.
                 match layout.variants {
-                    layout::Variants::Single { index } => {
+                    Variants::Single { index } => {
                         // Inside a variant
                         PathElem::Field(def.variants[index].fields[field].ident.name)
                     }
-                    layout::Variants::Multiple { .. } => bug!("we handled variants above"),
+                    Variants::Multiple { .. } => bug!("we handled variants above"),
                 }
             }
 
@@ -539,7 +540,7 @@
     fn visit_scalar(
         &mut self,
         op: OpTy<'tcx, M::PointerTag>,
-        scalar_layout: &layout::Scalar,
+        scalar_layout: &Scalar,
     ) -> InterpResult<'tcx> {
         let value = self.ecx.read_scalar(op)?;
         let valid_range = &scalar_layout.valid_range;
@@ -685,22 +686,22 @@
         // scalars, we do the same check on every "level" (e.g., first we check
         // MyNewtype and then the scalar in there).
         match op.layout.abi {
-            layout::Abi::Uninhabited => {
+            Abi::Uninhabited => {
                 throw_validation_failure!(
                     format_args!("a value of uninhabited type {:?}", op.layout.ty),
                     self.path
                 );
             }
-            layout::Abi::Scalar(ref scalar_layout) => {
+            Abi::Scalar(ref scalar_layout) => {
                 self.visit_scalar(op, scalar_layout)?;
             }
-            layout::Abi::ScalarPair { .. } | layout::Abi::Vector { .. } => {
+            Abi::ScalarPair { .. } | Abi::Vector { .. } => {
                 // These have fields that we already visited above, so we already checked
                 // all their scalar-level restrictions.
                 // There is also no equivalent to `rustc_layout_scalar_valid_range_start`
                 // that would make skipping them here an issue.
             }
-            layout::Abi::Aggregate { .. } => {
+            Abi::Aggregate { .. } => {
                 // Nothing to do.
             }
         }
diff --git a/src/librustc_mir/interpret/visitor.rs b/src/librustc_mir/interpret/visitor.rs
index 66a46c1..e03984f 100644
--- a/src/librustc_mir/interpret/visitor.rs
+++ b/src/librustc_mir/interpret/visitor.rs
@@ -3,7 +3,8 @@
 
 use rustc_middle::mir::interpret::InterpResult;
 use rustc_middle::ty;
-use rustc_middle::ty::layout::{self, TyAndLayout, VariantIdx};
+use rustc_middle::ty::layout::TyAndLayout;
+use rustc_target::abi::{FieldsShape, VariantIdx, Variants};
 
 use super::{InterpCx, MPlaceTy, Machine, OpTy};
 
@@ -207,10 +208,10 @@
 
                 // Visit the fields of this value.
                 match v.layout().fields {
-                    layout::FieldsShape::Union(fields) => {
+                    FieldsShape::Union(fields) => {
                         self.visit_union(v, fields)?;
                     },
-                    layout::FieldsShape::Arbitrary { ref offsets, .. } => {
+                    FieldsShape::Arbitrary { ref offsets, .. } => {
                         // FIXME: We collect in a vec because otherwise there are lifetime
                         // errors: Projecting to a field needs access to `ecx`.
                         let fields: Vec<InterpResult<'tcx, Self::V>> =
@@ -220,7 +221,7 @@
                             .collect();
                         self.visit_aggregate(v, fields.into_iter())?;
                     },
-                    layout::FieldsShape::Array { .. } => {
+                    FieldsShape::Array { .. } => {
                         // Let's get an mplace first.
                         let mplace = v.to_op(self.ecx())?.assert_mem_place(self.ecx());
                         // Now we can go over all the fields.
@@ -237,7 +238,7 @@
                 match v.layout().variants {
                     // If this is a multi-variant layout, find the right variant and proceed
                     // with *its* fields.
-                    layout::Variants::Multiple { .. } => {
+                    Variants::Multiple { .. } => {
                         let op = v.to_op(self.ecx())?;
                         let idx = self.ecx().read_discriminant(op)?.1;
                         let inner = v.project_downcast(self.ecx(), idx)?;
@@ -246,7 +247,7 @@
                         self.visit_variant(v, idx, inner)
                     }
                     // For single-variant layouts, we already did anything there is to do.
-                    layout::Variants::Single { .. } => Ok(())
+                    Variants::Single { .. } => Ok(())
                 }
             }
         }
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 1106eba..1032ff4 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -181,9 +181,9 @@
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, DefIdMap, LOCAL_CRATE};
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
+use rustc_hir::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
 use rustc_index::bit_set::GrowableBitSet;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
-use rustc_middle::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
 use rustc_middle::mir::interpret::{AllocId, ConstValue};
 use rustc_middle::mir::interpret::{ErrorHandled, GlobalAlloc, Scalar};
 use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs
index ba01e37..9068c05 100644
--- a/src/librustc_mir/monomorphize/partitioning.rs
+++ b/src/librustc_mir/monomorphize/partitioning.rs
@@ -107,19 +107,11 @@
 use rustc_middle::ty::print::characteristic_def_id_of_type;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, DefIdTree, InstanceDef, TyCtxt};
-use rustc_span::symbol::Symbol;
+use rustc_span::symbol::{Symbol, SymbolStr};
 
 use crate::monomorphize::collector::InliningMap;
 use crate::monomorphize::collector::{self, MonoItemCollectionMode};
 
-pub enum PartitioningStrategy {
-    /// Generates one codegen unit per source-level module.
-    PerModule,
-
-    /// Partition the whole crate into a fixed number of codegen units.
-    FixedUnitCount(usize),
-}
-
 // Anything we can't find a proper codegen unit for goes into this.
 fn fallback_cgu_name(name_builder: &mut CodegenUnitNameBuilder<'_>) -> Symbol {
     name_builder.build_cgu_name(LOCAL_CRATE, &["fallback"], Some("cgu"))
@@ -128,7 +120,7 @@
 pub fn partition<'tcx, I>(
     tcx: TyCtxt<'tcx>,
     mono_items: I,
-    strategy: PartitioningStrategy,
+    max_cgu_count: usize,
     inlining_map: &InliningMap<'tcx>,
 ) -> Vec<CodegenUnit<'tcx>>
 where
@@ -148,11 +140,10 @@
 
     debug_dump(tcx, "INITIAL PARTITIONING:", initial_partitioning.codegen_units.iter());
 
-    // If the partitioning should produce a fixed count of codegen units, merge
-    // until that count is reached.
-    if let PartitioningStrategy::FixedUnitCount(count) = strategy {
+    // Merge until we have at most `max_cgu_count` codegen units.
+    {
         let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_merge_cgus");
-        merge_codegen_units(tcx, &mut initial_partitioning, count);
+        merge_codegen_units(tcx, &mut initial_partitioning, max_cgu_count);
         debug_dump(tcx, "POST MERGING:", initial_partitioning.codegen_units.iter());
     }
 
@@ -480,6 +471,10 @@
     // the stable sort below will keep everything nice and deterministic.
     codegen_units.sort_by_cached_key(|cgu| cgu.name().as_str());
 
+    // This map keeps track of what got merged into what.
+    let mut cgu_contents: FxHashMap<Symbol, Vec<SymbolStr>> =
+        codegen_units.iter().map(|cgu| (cgu.name(), vec![cgu.name().as_str()])).collect();
+
     // Merge the two smallest codegen units until the target size is reached.
     while codegen_units.len() > target_cgu_count {
         // Sort small cgus to the back
@@ -487,20 +482,67 @@
         let mut smallest = codegen_units.pop().unwrap();
         let second_smallest = codegen_units.last_mut().unwrap();
 
+        // Move the mono-items from `smallest` to `second_smallest`
         second_smallest.modify_size_estimate(smallest.size_estimate());
         for (k, v) in smallest.items_mut().drain() {
             second_smallest.items_mut().insert(k, v);
         }
+
+        // Record that `second_smallest` now contains all the stuff that was in
+        // `smallest` before.
+        let mut consumed_cgu_names = cgu_contents.remove(&smallest.name()).unwrap();
+        cgu_contents.get_mut(&second_smallest.name()).unwrap().extend(consumed_cgu_names.drain(..));
+
         debug!(
-            "CodegenUnit {} merged in to CodegenUnit {}",
+            "CodegenUnit {} merged into CodegenUnit {}",
             smallest.name(),
             second_smallest.name()
         );
     }
 
     let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx);
-    for (index, cgu) in codegen_units.iter_mut().enumerate() {
-        cgu.set_name(numbered_codegen_unit_name(cgu_name_builder, index));
+
+    if tcx.sess.opts.incremental.is_some() {
+        // If we are doing incremental compilation, we want CGU names to
+        // reflect the path of the source level module they correspond to.
+        // For CGUs that contain the code of multiple modules because of the
+        // merging done above, we use a concatenation of the names of
+        // all contained CGUs.
+        let new_cgu_names: FxHashMap<Symbol, String> = cgu_contents
+            .into_iter()
+            // This `filter` makes sure we only update the name of CGUs that
+            // were actually modified by merging.
+            .filter(|(_, cgu_contents)| cgu_contents.len() > 1)
+            .map(|(current_cgu_name, cgu_contents)| {
+                let mut cgu_contents: Vec<&str> = cgu_contents.iter().map(|s| &s[..]).collect();
+
+                // Sort the names, so things are deterministic and easy to
+                // predict.
+                cgu_contents.sort();
+
+                (current_cgu_name, cgu_contents.join("--"))
+            })
+            .collect();
+
+        for cgu in codegen_units.iter_mut() {
+            if let Some(new_cgu_name) = new_cgu_names.get(&cgu.name()) {
+                if tcx.sess.opts.debugging_opts.human_readable_cgu_names {
+                    cgu.set_name(Symbol::intern(&new_cgu_name));
+                } else {
+                    // If we don't require CGU names to be human-readable, we
+                    // use a fixed length hash of the composite CGU name
+                    // instead.
+                    let new_cgu_name = CodegenUnit::mangle_name(&new_cgu_name);
+                    cgu.set_name(Symbol::intern(&new_cgu_name));
+                }
+            }
+        }
+    } else {
+        // If we are compiling non-incrementally we just generate simple CGU
+        // names containing an index.
+        for (index, cgu) in codegen_units.iter_mut().enumerate() {
+            cgu.set_name(numbered_codegen_unit_name(cgu_name_builder, index));
+        }
     }
 }
 
@@ -879,13 +921,7 @@
     let (codegen_units, _) = tcx.sess.time("partition_and_assert_distinct_symbols", || {
         sync::join(
             || {
-                let strategy = if tcx.sess.opts.incremental.is_some() {
-                    PartitioningStrategy::PerModule
-                } else {
-                    PartitioningStrategy::FixedUnitCount(tcx.sess.codegen_units())
-                };
-
-                partition(tcx, items.iter().cloned(), strategy, &inlining_map)
+                partition(tcx, items.iter().cloned(), tcx.sess.codegen_units(), &inlining_map)
                     .into_iter()
                     .map(Arc::new)
                     .collect::<Vec<_>>()
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 0a998bb..67de81e 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -1,10 +1,10 @@
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_middle::mir::*;
-use rustc_middle::ty::layout::VariantIdx;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::subst::{InternalSubsts, Subst};
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
+use rustc_target::abi::VariantIdx;
 
 use rustc_index::vec::{Idx, IndexVec};
 
diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs
index 649cc0a..e4a0b9c 100644
--- a/src/librustc_mir/transform/check_consts/validation.rs
+++ b/src/librustc_mir/transform/check_consts/validation.rs
@@ -1,10 +1,10 @@
 //! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations.
 
 use rustc_errors::struct_span_err;
+use rustc_hir::lang_items;
 use rustc_hir::{def_id::DefId, HirId};
 use rustc_index::bit_set::BitSet;
 use rustc_infer::infer::TyCtxtInferExt;
-use rustc_middle::middle::lang_items;
 use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::*;
 use rustc_middle::ty::cast::CastTy;
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index f4cba87..c7f63d2 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -19,13 +19,12 @@
     SourceInfo, SourceScope, SourceScopeData, Statement, StatementKind, Terminator, TerminatorKind,
     UnOp, RETURN_PLACE,
 };
-use rustc_middle::ty::layout::{
-    HasDataLayout, HasTyCtxt, LayoutError, LayoutOf, Size, TargetDataLayout, TyAndLayout,
-};
+use rustc_middle::ty::layout::{HasTyCtxt, LayoutError, TyAndLayout};
 use rustc_middle::ty::subst::{InternalSubsts, Subst};
 use rustc_middle::ty::{self, ConstKind, Instance, ParamEnv, Ty, TyCtxt, TypeFoldable};
 use rustc_session::lint;
 use rustc_span::{def_id::DefId, Span};
+use rustc_target::abi::{HasDataLayout, LayoutOf, Size, TargetDataLayout};
 use rustc_trait_selection::traits;
 
 use crate::const_eval::error_to_const_error;
diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs
index d3971c9..a7c6b5a 100644
--- a/src/librustc_mir/transform/elaborate_drops.rs
+++ b/src/librustc_mir/transform/elaborate_drops.rs
@@ -13,9 +13,9 @@
 use rustc_hir as hir;
 use rustc_index::bit_set::BitSet;
 use rustc_middle::mir::*;
-use rustc_middle::ty::layout::VariantIdx;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::Span;
+use rustc_target::abi::VariantIdx;
 use std::fmt;
 
 pub struct ElaborateDrops;
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index 390d927..53eec1f 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -63,10 +63,10 @@
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor};
 use rustc_middle::mir::*;
-use rustc_middle::ty::layout::VariantIdx;
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::GeneratorSubsts;
 use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
+use rustc_target::abi::VariantIdx;
 use std::borrow::Cow;
 use std::iter;
 
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index 34fa12e..ec0b89e 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -27,7 +27,7 @@
 use rustc_target::spec::abi::Abi;
 
 use std::cell::Cell;
-use std::{cmp, iter, mem, usize};
+use std::{cmp, iter, mem};
 
 use crate::const_eval::{is_const_fn, is_unstable_const_fn};
 use crate::transform::check_consts::{is_lang_panic_fn, qualifs, ConstKind, Item};
diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs
index faee077..c2029a2 100644
--- a/src/librustc_mir/transform/simplify.rs
+++ b/src/librustc_mir/transform/simplify.rs
@@ -368,18 +368,22 @@
             if location.statement_index != block.statements.len() {
                 let stmt = &block.statements[location.statement_index];
 
-                if let StatementKind::Assign(box (p, Rvalue::Use(Operand::Constant(c)))) =
-                    &stmt.kind
-                {
-                    match c.literal.val {
-                        // Keep assignments from unevaluated constants around, since the evaluation
-                        // may report errors, even if the use of the constant is dead code.
-                        ty::ConstKind::Unevaluated(..) => {}
-                        _ => {
-                            if !p.is_indirect() {
-                                trace!("skipping store of const value {:?} to {:?}", c, p);
-                                return;
+                if let StatementKind::Assign(box (dest, rvalue)) = &stmt.kind {
+                    if !dest.is_indirect() && dest.local == *local {
+                        if let Rvalue::Use(Operand::Constant(c)) = rvalue {
+                            match c.literal.val {
+                                // Keep assignments from unevaluated constants around, since the
+                                // evaluation may report errors, even if the use of the constant
+                                // is dead code.
+                                ty::ConstKind::Unevaluated(..) => {}
+                                _ => {
+                                    trace!("skipping store of const value {:?} to {:?}", c, dest);
+                                    return;
+                                }
                             }
+                        } else if let Rvalue::Discriminant(d) = rvalue {
+                            trace!("skipping store of discriminant value {:?} to {:?}", d, dest);
+                            return;
                         }
                     }
                 }
diff --git a/src/librustc_mir/transform/uninhabited_enum_branching.rs b/src/librustc_mir/transform/uninhabited_enum_branching.rs
index 38a9194..0a08c13 100644
--- a/src/librustc_mir/transform/uninhabited_enum_branching.rs
+++ b/src/librustc_mir/transform/uninhabited_enum_branching.rs
@@ -5,8 +5,9 @@
     BasicBlock, BasicBlockData, Body, BodyAndCache, Local, Operand, Rvalue, StatementKind,
     TerminatorKind,
 };
-use rustc_middle::ty::layout::{Abi, TyAndLayout, Variants};
+use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::ty::{Ty, TyCtxt};
+use rustc_target::abi::{Abi, Variants};
 
 pub struct UninhabitedEnumBranching;
 
diff --git a/src/librustc_mir/util/aggregate.rs b/src/librustc_mir/util/aggregate.rs
index b22dbf4..e77d264 100644
--- a/src/librustc_mir/util/aggregate.rs
+++ b/src/librustc_mir/util/aggregate.rs
@@ -1,7 +1,7 @@
 use rustc_index::vec::Idx;
 use rustc_middle::mir::*;
-use rustc_middle::ty::layout::VariantIdx;
 use rustc_middle::ty::{Ty, TyCtxt};
+use rustc_target::abi::VariantIdx;
 
 use std::iter::TrustedLen;
 
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index f6d67ab..e3a96ca 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -1,13 +1,13 @@
 use crate::util::patch::MirPatch;
 use rustc_hir as hir;
+use rustc_hir::lang_items;
 use rustc_index::vec::Idx;
-use rustc_middle::middle::lang_items;
 use rustc_middle::mir::*;
 use rustc_middle::traits::Reveal;
-use rustc_middle::ty::layout::VariantIdx;
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::util::IntTypeExt;
 use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_target::abi::VariantIdx;
 use std::fmt;
 
 use std::convert::TryInto;
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index df7df6a..a81fcb5 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -9,7 +9,8 @@
 };
 use rustc_middle::mir::visit::Visitor;
 use rustc_middle::mir::*;
-use rustc_middle::ty::{self, layout::Size, TyCtxt, TypeFoldable, TypeVisitor};
+use rustc_middle::ty::{self, TyCtxt, TypeFoldable, TypeVisitor};
+use rustc_target::abi::Size;
 use std::collections::BTreeSet;
 use std::fmt::Display;
 use std::fmt::Write as _;
diff --git a/src/librustc_mir_build/build/matches/mod.rs b/src/librustc_mir_build/build/matches/mod.rs
index a98b18c..a4a9271 100644
--- a/src/librustc_mir_build/build/matches/mod.rs
+++ b/src/librustc_mir_build/build/matches/mod.rs
@@ -16,9 +16,9 @@
 use rustc_index::bit_set::BitSet;
 use rustc_middle::middle::region;
 use rustc_middle::mir::*;
-use rustc_middle::ty::layout::VariantIdx;
 use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty};
 use rustc_span::Span;
+use rustc_target::abi::VariantIdx;
 use smallvec::{smallvec, SmallVec};
 
 // helper functions, broken out by category:
diff --git a/src/librustc_mir_build/build/matches/simplify.rs b/src/librustc_mir_build/build/matches/simplify.rs
index 664f56a..d74d8b5 100644
--- a/src/librustc_mir_build/build/matches/simplify.rs
+++ b/src/librustc_mir_build/build/matches/simplify.rs
@@ -15,12 +15,13 @@
 use crate::build::matches::{Ascription, Binding, Candidate, MatchPair};
 use crate::build::Builder;
 use crate::hair::{self, *};
+use rustc_attr::{SignedInt, UnsignedInt};
+use rustc_hir::RangeEnd;
 use rustc_middle::mir::interpret::truncate;
 use rustc_middle::mir::Place;
 use rustc_middle::ty;
-use rustc_middle::ty::layout::{Integer, IntegerExt, Size};
-use rustc_attr::{SignedInt, UnsignedInt};
-use rustc_hir::RangeEnd;
+use rustc_middle::ty::layout::IntegerExt;
+use rustc_target::abi::{Integer, Size};
 
 use std::mem;
 
diff --git a/src/librustc_mir_build/build/matches/test.rs b/src/librustc_mir_build/build/matches/test.rs
index 450bb0a..c049842 100644
--- a/src/librustc_mir_build/build/matches/test.rs
+++ b/src/librustc_mir_build/build/matches/test.rs
@@ -9,14 +9,14 @@
 use crate::build::Builder;
 use crate::hair::pattern::compare_const_vals;
 use crate::hair::*;
-use rustc_middle::mir::*;
-use rustc_middle::ty::layout::VariantIdx;
-use rustc_middle::ty::util::IntTypeExt;
-use rustc_middle::ty::{self, adjustment::PointerCast, Ty};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::RangeEnd;
 use rustc_index::bit_set::BitSet;
+use rustc_middle::mir::*;
+use rustc_middle::ty::util::IntTypeExt;
+use rustc_middle::ty::{self, adjustment::PointerCast, Ty};
 use rustc_span::symbol::sym;
+use rustc_target::abi::VariantIdx;
 
 use std::cmp::Ordering;
 
@@ -362,7 +362,7 @@
         place: Place<'tcx>,
         mut ty: Ty<'tcx>,
     ) {
-        use rustc_middle::middle::lang_items::EqTraitLangItem;
+        use rustc_hir::lang_items::EqTraitLangItem;
 
         let mut expect = self.literal_operand(source_info.span, value);
         let mut val = Operand::Copy(place);
diff --git a/src/librustc_mir_build/build/matches/util.rs b/src/librustc_mir_build/build/matches/util.rs
index 967a44b..393af10 100644
--- a/src/librustc_mir_build/build/matches/util.rs
+++ b/src/librustc_mir_build/build/matches/util.rs
@@ -5,7 +5,6 @@
 use rustc_middle::ty;
 use smallvec::SmallVec;
 use std::convert::TryInto;
-use std::u32;
 
 impl<'a, 'tcx> Builder<'a, 'tcx> {
     crate fn field_match_pairs<'pat>(
diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs
index cec7e5b..04cb509 100644
--- a/src/librustc_mir_build/build/mod.rs
+++ b/src/librustc_mir_build/build/mod.rs
@@ -2,22 +2,21 @@
 use crate::build::scope::DropKind;
 use crate::hair::cx::Cx;
 use crate::hair::{BindingMode, LintLevel, PatKind};
-use rustc_middle::middle::lang_items;
+use rustc_attr::{self as attr, UnwindAttr};
+use rustc_hir as hir;
+use rustc_hir::def_id::DefId;
+use rustc_hir::lang_items;
+use rustc_hir::{GeneratorKind, HirIdMap, Node};
+use rustc_index::vec::{Idx, IndexVec};
+use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::middle::region;
 use rustc_middle::mir::*;
 use rustc_middle::ty::subst::Subst;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
-use rustc_attr::{self as attr, UnwindAttr};
-use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
-use rustc_hir::{GeneratorKind, HirIdMap, Node};
-use rustc_index::vec::{Idx, IndexVec};
-use rustc_infer::infer::TyCtxtInferExt;
 use rustc_span::symbol::kw;
 use rustc_span::Span;
 use rustc_target::spec::abi::Abi;
 use rustc_target::spec::PanicStrategy;
-use std::u32;
 
 use super::lints;
 
diff --git a/src/librustc_mir_build/hair/constant.rs b/src/librustc_mir_build/hair/constant.rs
index 667f293..e5af0b5 100644
--- a/src/librustc_mir_build/hair/constant.rs
+++ b/src/librustc_mir_build/hair/constant.rs
@@ -2,8 +2,9 @@
 use rustc_middle::mir::interpret::{
     truncate, Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar,
 };
-use rustc_middle::ty::{self, layout::Size, ParamEnv, TyCtxt, TyS};
+use rustc_middle::ty::{self, ParamEnv, TyCtxt, TyS};
 use rustc_span::symbol::Symbol;
+use rustc_target::abi::Size;
 
 crate fn lit_to_const<'tcx>(
     tcx: TyCtxt<'tcx>,
diff --git a/src/librustc_mir_build/hair/cx/mod.rs b/src/librustc_mir_build/hair/cx/mod.rs
index 13a4767..503bd26 100644
--- a/src/librustc_mir_build/hair/cx/mod.rs
+++ b/src/librustc_mir_build/hair/cx/mod.rs
@@ -14,11 +14,11 @@
 use rustc_infer::infer::InferCtxt;
 use rustc_middle::middle::region;
 use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
-use rustc_middle::ty::layout::VariantIdx;
 use rustc_middle::ty::subst::Subst;
 use rustc_middle::ty::subst::{GenericArg, InternalSubsts};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::symbol::{sym, Symbol};
+use rustc_target::abi::VariantIdx;
 use rustc_trait_selection::infer::InferCtxtExt;
 
 #[derive(Clone)]
diff --git a/src/librustc_mir_build/hair/mod.rs b/src/librustc_mir_build/hair/mod.rs
index fadfc76..601e441 100644
--- a/src/librustc_mir_build/hair/mod.rs
+++ b/src/librustc_mir_build/hair/mod.rs
@@ -11,10 +11,10 @@
 use rustc_middle::middle::region;
 use rustc_middle::mir::{BinOp, BorrowKind, Field, UnOp};
 use rustc_middle::ty::adjustment::PointerCast;
-use rustc_middle::ty::layout::VariantIdx;
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::{AdtDef, Const, Ty, UpvarSubsts, UserType};
 use rustc_span::Span;
+use rustc_target::abi::VariantIdx;
 
 crate mod constant;
 crate mod cx;
diff --git a/src/librustc_mir_build/hair/pattern/_match.rs b/src/librustc_mir_build/hair/pattern/_match.rs
index 03f668d..51ba844 100644
--- a/src/librustc_mir_build/hair/pattern/_match.rs
+++ b/src/librustc_mir_build/hair/pattern/_match.rs
@@ -236,15 +236,16 @@
 use super::{FieldPat, Pat, PatKind, PatRange};
 
 use rustc_attr::{SignedInt, UnsignedInt};
+use rustc_errors::ErrorReported;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{HirId, RangeEnd};
 use rustc_middle::mir::interpret::{truncate, AllocId, ConstValue, Pointer, Scalar};
 use rustc_middle::mir::Field;
-use rustc_middle::ty::layout::{Integer, IntegerExt, Size, VariantIdx};
+use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeFoldable, VariantDef};
-use rustc_middle::util::common::ErrorReported;
 use rustc_session::lint;
 use rustc_span::{Span, DUMMY_SP};
+use rustc_target::abi::{Integer, Size, VariantIdx};
 
 use arena::TypedArena;
 
@@ -255,7 +256,6 @@
 use std::fmt;
 use std::iter::{FromIterator, IntoIterator};
 use std::ops::RangeInclusive;
-use std::u128;
 
 crate fn expand_pattern<'a, 'tcx>(cx: &MatchCheckCtxt<'a, 'tcx>, pat: Pat<'tcx>) -> Pat<'tcx> {
     LiteralExpander { tcx: cx.tcx, param_env: cx.param_env }.fold_pattern(&pat)
diff --git a/src/librustc_mir_build/hair/pattern/mod.rs b/src/librustc_mir_build/hair/pattern/mod.rs
index f15d2fc..2b6d8e9 100644
--- a/src/librustc_mir_build/hair/pattern/mod.rs
+++ b/src/librustc_mir_build/hair/pattern/mod.rs
@@ -19,13 +19,13 @@
 use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
 use rustc_middle::mir::UserTypeProjection;
 use rustc_middle::mir::{BorrowKind, Field, Mutability};
-use rustc_middle::ty::layout::VariantIdx;
 use rustc_middle::ty::subst::{GenericArg, SubstsRef};
 use rustc_middle::ty::{self, AdtDef, DefIdTree, Region, Ty, TyCtxt, UserType};
 use rustc_middle::ty::{
     CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations,
 };
 use rustc_span::{Span, DUMMY_SP};
+use rustc_target::abi::VariantIdx;
 
 use std::cmp::Ordering;
 use std::fmt;
@@ -1047,8 +1047,8 @@
             }
             ty::Int(ity) => {
                 use rustc_attr::SignedInt;
-                use rustc_middle::ty::layout::{Integer, IntegerExt};
-                let size = Integer::from_attr(&tcx, SignedInt(ity)).size();
+                use rustc_middle::ty::layout::IntegerExt;
+                let size = rustc_target::abi::Integer::from_attr(&tcx, SignedInt(ity)).size();
                 let a = sign_extend(a, size);
                 let b = sign_extend(b, size);
                 Some((a as i128).cmp(&(b as i128)))
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index 6b7a9ec..798eb85 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -1496,7 +1496,7 @@
     }
 
     /// Is the current token the start of an `FnHeader` / not a valid parse?
-    fn check_fn_front_matter(&mut self) -> bool {
+    pub(super) fn check_fn_front_matter(&mut self) -> bool {
         // We use an over-approximation here.
         // `const const`, `fn const` won't parse, but we're not stepping over other syntax either.
         const QUALS: [Symbol; 4] = [kw::Const, kw::Async, kw::Unsafe, kw::Extern];
@@ -1523,7 +1523,7 @@
     /// FnQual = "const"? "async"? "unsafe"? Extern? ;
     /// FnFrontMatter = FnQual? "fn" ;
     /// ```
-    fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> {
+    pub(super) fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> {
         let constness = self.parse_constness();
         let asyncness = self.parse_asyncness();
         let unsafety = self.parse_unsafety();
diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs
index fddfe48..b3764d2 100644
--- a/src/librustc_parse/parser/stmt.rs
+++ b/src/librustc_parse/parser/stmt.rs
@@ -165,9 +165,9 @@
                     // Rewind to before attempting to parse the type and continue parsing.
                     let parser_snapshot_after_type = self.clone();
                     mem::replace(self, parser_snapshot_before_type);
-
-                    let snippet = self.span_to_snippet(pat.span).unwrap();
-                    err.span_label(pat.span, format!("while parsing the type for `{}`", snippet));
+                    if let Ok(snip) = self.span_to_snippet(pat.span) {
+                        err.span_label(pat.span, format!("while parsing the type for `{}`", snip));
+                    }
                     (Some((parser_snapshot_after_type, colon_sp, err)), None)
                 }
             }
diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs
index c21ac8d..a601550 100644
--- a/src/librustc_parse/parser/ty.rs
+++ b/src/librustc_parse/parser/ty.rs
@@ -127,16 +127,16 @@
         } else if self.eat_keyword(kw::Underscore) {
             // A type to be inferred `_`
             TyKind::Infer
-        } else if self.token_is_bare_fn_keyword() {
+        } else if self.check_fn_front_matter() {
             // Function pointer type
-            self.parse_ty_bare_fn(Vec::new())?
+            self.parse_ty_bare_fn(lo, Vec::new())?
         } else if self.check_keyword(kw::For) {
             // Function pointer type or bound list (trait object type) starting with a poly-trait.
             //   `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
             //   `for<'lt> Trait1<'lt> + Trait2 + 'a`
             let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
-            if self.token_is_bare_fn_keyword() {
-                self.parse_ty_bare_fn(lifetime_defs)?
+            if self.check_fn_front_matter() {
+                self.parse_ty_bare_fn(lo, lifetime_defs)?
             } else {
                 let path = self.parse_path(PathStyle::Type)?;
                 let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
@@ -291,13 +291,6 @@
         Ok(TyKind::Typeof(expr))
     }
 
-    /// Is the current token one of the keywords that signals a bare function type?
-    fn token_is_bare_fn_keyword(&mut self) -> bool {
-        self.check_keyword(kw::Fn)
-            || self.check_keyword(kw::Unsafe)
-            || self.check_keyword(kw::Extern)
-    }
-
     /// Parses a function pointer type (`TyKind::BareFn`).
     /// ```
     /// [unsafe] [extern "ABI"] fn (S) -> T
@@ -306,12 +299,31 @@
     ///    |               |        |   Return type
     /// Function Style    ABI  Parameter types
     /// ```
-    fn parse_ty_bare_fn(&mut self, generic_params: Vec<GenericParam>) -> PResult<'a, TyKind> {
-        let unsafety = self.parse_unsafety();
-        let ext = self.parse_extern()?;
-        self.expect_keyword(kw::Fn)?;
+    /// We actually parse `FnHeader FnDecl`, but we error on `const` and `async` qualifiers.
+    fn parse_ty_bare_fn(&mut self, lo: Span, params: Vec<GenericParam>) -> PResult<'a, TyKind> {
+        let ast::FnHeader { ext, unsafety, constness, asyncness } = self.parse_fn_front_matter()?;
         let decl = self.parse_fn_decl(|_| false, AllowPlus::No)?;
-        Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params, decl })))
+        let whole_span = lo.to(self.prev_token.span);
+        if let ast::Const::Yes(span) = constness {
+            self.error_fn_ptr_bad_qualifier(whole_span, span, "const");
+        }
+        if let ast::Async::Yes { span, .. } = asyncness {
+            self.error_fn_ptr_bad_qualifier(whole_span, span, "async");
+        }
+        Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params: params, decl })))
+    }
+
+    /// Emit an error for the given bad function pointer qualifier.
+    fn error_fn_ptr_bad_qualifier(&self, span: Span, qual_span: Span, qual: &str) {
+        self.struct_span_err(span, &format!("an `fn` pointer type cannot be `{}`", qual))
+            .span_label(qual_span, format!("`{}` because of this", qual))
+            .span_suggestion_short(
+                qual_span,
+                &format!("remove the `{}` qualifier", qual),
+                String::new(),
+                Applicability::MaybeIncorrect,
+            )
+            .emit();
     }
 
     /// Parses an `impl B0 + ... + Bn` type.
diff --git a/src/librustc_passes/intrinsicck.rs b/src/librustc_passes/intrinsicck.rs
index 11096c6..cc1af63 100644
--- a/src/librustc_passes/intrinsicck.rs
+++ b/src/librustc_passes/intrinsicck.rs
@@ -4,10 +4,11 @@
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_index::vec::Idx;
-use rustc_middle::ty::layout::{LayoutError, Pointer, SizeSkeleton, VariantIdx};
+use rustc_middle::ty::layout::{LayoutError, SizeSkeleton};
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::{sym, Span};
+use rustc_target::abi::{Pointer, VariantIdx};
 use rustc_target::spec::abi::Abi::RustIntrinsic;
 
 fn check_mod_intrinsics(tcx: TyCtxt<'_>, module_def_id: DefId) {
diff --git a/src/librustc_passes/layout_test.rs b/src/librustc_passes/layout_test.rs
index 9fa3225..22ce909 100644
--- a/src/librustc_passes/layout_test.rs
+++ b/src/librustc_passes/layout_test.rs
@@ -3,16 +3,10 @@
 use rustc_hir::def_id::DefId;
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_hir::ItemKind;
-use rustc_middle::ty::layout::HasDataLayout;
-use rustc_middle::ty::layout::HasParamEnv;
-use rustc_middle::ty::layout::HasTyCtxt;
-use rustc_middle::ty::layout::LayoutOf;
-use rustc_middle::ty::layout::TargetDataLayout;
-use rustc_middle::ty::layout::TyAndLayout;
-use rustc_middle::ty::ParamEnv;
-use rustc_middle::ty::Ty;
-use rustc_middle::ty::TyCtxt;
+use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt, TyAndLayout};
+use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
 use rustc_span::symbol::sym;
+use rustc_target::abi::{HasDataLayout, LayoutOf, TargetDataLayout};
 
 pub fn test_layout(tcx: TyCtxt<'_>) {
     if tcx.features().rustc_attrs {
@@ -33,7 +27,8 @@
             ItemKind::TyAlias(..)
             | ItemKind::Enum(..)
             | ItemKind::Struct(..)
-            | ItemKind::Union(..) => {
+            | ItemKind::Union(..)
+            | ItemKind::OpaqueTy(..) => {
                 for attr in self.tcx.get_attrs(item_def_id).iter() {
                     if attr.check_name(sym::rustc_layout) {
                         self.dump_layout_of(item_def_id, item, attr);
@@ -90,7 +85,7 @@
                         sym::debug => {
                             self.tcx.sess.span_err(
                                 item.span,
-                                &format!("layout debugging: {:#?}", *ty_layout),
+                                &format!("layout debugging for type {:?}: {:#?}", ty, *ty_layout),
                             );
                         }
 
diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs
index c906033..ee71d09 100644
--- a/src/librustc_passes/liveness.rs
+++ b/src/librustc_passes/liveness.rs
@@ -112,10 +112,10 @@
 use rustc_span::Span;
 
 use std::collections::VecDeque;
+use std::fmt;
 use std::io;
 use std::io::prelude::*;
 use std::rc::Rc;
-use std::{fmt, u32};
 
 #[derive(Copy, Clone, PartialEq)]
 struct Variable(u32);
diff --git a/src/librustc_passes/region.rs b/src/librustc_passes/region.rs
index 290454c..485480d 100644
--- a/src/librustc_passes/region.rs
+++ b/src/librustc_passes/region.rs
@@ -27,8 +27,8 @@
     /// of the innermost fn body. Each fn forms its own disjoint tree
     /// in the region hierarchy. These fn bodies are themselves
     /// arranged into a tree. See the "Modeling closures" section of
-    /// the README in `infer::region_constraints` for more
-    /// details.
+    /// the README in `rustc_trait_selection::infer::region_constraints`
+    /// for more details.
     root_id: Option<hir::ItemLocalId>,
 
     /// The scope that contains any new variables declared, plus its depth in
diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs
index 6fbfdbd..ad81aa3 100644
--- a/src/librustc_passes/stability.rs
+++ b/src/librustc_passes/stability.rs
@@ -438,7 +438,7 @@
         // If the `-Z force-unstable-if-unmarked` flag is passed then we provide
         // a parent stability annotation which indicates that this is private
         // with the `rustc_private` feature. This is intended for use when
-        // compiling librustc_middle crates themselves so we can leverage crates.io
+        // compiling `librustc_*` crates themselves so we can leverage crates.io
         // while maintaining the invariant that all sysroot crates are unstable
         // by default and are unable to be used.
         if tcx.sess.opts.debugging_opts.force_unstable_if_unmarked {
diff --git a/src/librustc_passes/weak_lang_items.rs b/src/librustc_passes/weak_lang_items.rs
index 8d11af1..8e56ef0 100644
--- a/src/librustc_passes/weak_lang_items.rs
+++ b/src/librustc_passes/weak_lang_items.rs
@@ -4,8 +4,8 @@
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
+use rustc_hir::lang_items;
 use rustc_hir::weak_lang_items::WEAK_ITEMS_REFS;
-use rustc_middle::middle::lang_items;
 use rustc_middle::middle::lang_items::whitelisted;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config;
diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs
index 54481bd..58a03db 100644
--- a/src/librustc_session/config.rs
+++ b/src/librustc_session/config.rs
@@ -18,9 +18,10 @@
 use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST};
 use rustc_span::source_map::{FileName, FilePathMapping};
 use rustc_span::symbol::{sym, Symbol};
+use rustc_span::SourceFileHashAlgorithm;
 
 use rustc_errors::emitter::HumanReadableErrorType;
-use rustc_errors::{ColorConfig, FatalError, Handler, HandlerFlags};
+use rustc_errors::{ColorConfig, HandlerFlags};
 
 use std::collections::btree_map::{
     Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter,
@@ -748,25 +749,30 @@
     user_cfg
 }
 
-pub fn build_target_config(opts: &Options, sp: &Handler) -> Config {
+pub fn build_target_config(opts: &Options, error_format: ErrorOutputType) -> Config {
     let target = Target::search(&opts.target_triple).unwrap_or_else(|e| {
-        sp.struct_fatal(&format!("Error loading target specification: {}", e))
-            .help("Use `--print target-list` for a list of built-in targets")
-            .emit();
-        FatalError.raise();
+        early_error(
+            error_format,
+            &format!(
+                "Error loading target specification: {}. \
+            Use `--print target-list` for a list of built-in targets",
+                e
+            ),
+        )
     });
 
     let ptr_width = match &target.target_pointer_width[..] {
         "16" => 16,
         "32" => 32,
         "64" => 64,
-        w => sp
-            .fatal(&format!(
+        w => early_error(
+            error_format,
+            &format!(
                 "target specification was invalid: \
              unrecognized target-pointer-width {}",
                 w
-            ))
-            .raise(),
+            ),
+        ),
     };
 
     Config { target, ptr_width }
@@ -1971,7 +1977,8 @@
 crate mod dep_tracking {
     use super::{
         CFGuard, CrateType, DebugInfo, ErrorOutputType, LinkerPluginLto, LtoCli, OptLevel,
-        OutputTypes, Passes, Sanitizer, SwitchWithOptPath, SymbolManglingVersion,
+        OutputTypes, Passes, Sanitizer, SourceFileHashAlgorithm, SwitchWithOptPath,
+        SymbolManglingVersion,
     };
     use crate::lint;
     use crate::utils::NativeLibraryKind;
@@ -2049,6 +2056,7 @@
     impl_dep_tracking_hash_via_hash!(LinkerPluginLto);
     impl_dep_tracking_hash_via_hash!(SwitchWithOptPath);
     impl_dep_tracking_hash_via_hash!(SymbolManglingVersion);
+    impl_dep_tracking_hash_via_hash!(Option<SourceFileHashAlgorithm>);
 
     impl_dep_tracking_hash_for_sortable_vec_of!(String);
     impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf);
diff --git a/src/librustc_session/filesearch.rs b/src/librustc_session/filesearch.rs
index 4310c50..4347512 100644
--- a/src/librustc_session/filesearch.rs
+++ b/src/librustc_session/filesearch.rs
@@ -143,8 +143,8 @@
     // FIXME: This is a quick hack to make the rustc binary able to locate
     // Rust libraries in Linux environments where libraries might be installed
     // to lib64/lib32. This would be more foolproof by basing the sysroot off
-    // of the directory where librustc_middle is located, rather than where the rustc
-    // binary is.
+    // of the directory where `librustc_driver` is located, rather than
+    // where the rustc binary is.
     // If --libdir is set during configuration to the value other than
     // "lib" (i.e., non-default), this value is used (see issue #16552).
 
diff --git a/src/librustc_session/lint.rs b/src/librustc_session/lint.rs
index 0707586..b16d513 100644
--- a/src/librustc_session/lint.rs
+++ b/src/librustc_session/lint.rs
@@ -195,7 +195,7 @@
 }
 
 /// Lints that are buffered up early on in the `Session` before the
-/// `LintLevels` is calculated. These are later passed to `librustc_middle`.
+/// `LintLevels` is calculated.
 #[derive(PartialEq)]
 pub struct BufferedEarlyLint {
     /// The span of code that we are linting on.
@@ -207,7 +207,8 @@
     /// The `NodeId` of the AST node that generated the lint.
     pub node_id: NodeId,
 
-    /// A lint Id that can be passed to `rustc_session::lint::Lint::from_parser_lint_id`.
+    /// A lint Id that can be passed to
+    /// `rustc_lint::early::EarlyContextAndPass::check_id`.
     pub lint_id: LintId,
 
     /// Customization of the `DiagnosticBuilder<'_>` for the lint.
diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs
index 432f1e1..8cd6ca8 100644
--- a/src/librustc_session/options.rs
+++ b/src/librustc_session/options.rs
@@ -10,6 +10,7 @@
 
 use rustc_feature::UnstableFeatures;
 use rustc_span::edition::Edition;
+use rustc_span::SourceFileHashAlgorithm;
 
 use std::collections::BTreeMap;
 
@@ -283,19 +284,29 @@
             Some("one of: `disabled`, `trampolines`, or `aliases`");
         pub const parse_symbol_mangling_version: Option<&str> =
             Some("either `legacy` or `v0` (RFC 2603)");
+        pub const parse_src_file_hash: Option<&str> =
+            Some("either `md5`, or `sha1`");
     }
 
     #[allow(dead_code)]
     mod $mod_set {
         use super::{$struct_name, Passes, Sanitizer, LtoCli, LinkerPluginLto, SwitchWithOptPath,
-            SymbolManglingVersion, CFGuard};
+            SymbolManglingVersion, CFGuard, SourceFileHashAlgorithm};
         use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel};
         use std::path::PathBuf;
         use std::str::FromStr;
 
+        // Sometimes different options need to build a common structure.
+        // That structure can kept in one of the options' fields, the others become dummy.
+        macro_rules! redirect_field {
+            ($cg:ident.link_arg) => { $cg.link_args };
+            ($cg:ident.pre_link_arg) => { $cg.pre_link_args };
+            ($cg:ident.$field:ident) => { $cg.$field };
+        }
+
         $(
             pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool {
-                $parse(&mut cg.$opt, v)
+                $parse(&mut redirect_field!(cg.$opt), v)
             }
         )*
 
@@ -622,6 +633,14 @@
             };
             true
         }
+
+        fn parse_src_file_hash(slot: &mut Option<SourceFileHashAlgorithm>, v: Option<&str>) -> bool {
+            match v.and_then(|s| SourceFileHashAlgorithm::from_str(s).ok()) {
+                Some(hash_kind) => *slot = Some(hash_kind),
+                _ => return false,
+            }
+            true
+        }
     }
 ) }
 
@@ -632,9 +651,9 @@
         "this option is deprecated and does nothing"),
     linker: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
         "system linker to link outputs with"),
-    link_arg: Vec<String> = (vec![], parse_string_push, [UNTRACKED],
+    link_arg: (/* redirected to link_args */) = ((), parse_string_push, [UNTRACKED],
         "a single extra argument to append to the linker invocation (can be used several times)"),
-    link_args: Option<Vec<String>> = (None, parse_opt_list, [UNTRACKED],
+    link_args: Vec<String> = (Vec::new(), parse_list, [UNTRACKED],
         "extra arguments to append to the linker invocation (space separated)"),
     link_dead_code: bool = (false, parse_bool, [UNTRACKED],
         "don't let linker strip dead code (turning it on can be used for code coverage)"),
@@ -865,9 +884,9 @@
         "make rustc print the total optimization fuel used by a crate"),
     force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED],
         "force all crates to be `rustc_private` unstable"),
-    pre_link_arg: Vec<String> = (vec![], parse_string_push, [UNTRACKED],
+    pre_link_arg: (/* redirected to pre_link_args */) = ((), parse_string_push, [UNTRACKED],
         "a single extra argument to prepend the linker invocation (can be used several times)"),
-    pre_link_args: Option<Vec<String>> = (None, parse_opt_list, [UNTRACKED],
+    pre_link_args: Vec<String> = (Vec::new(), parse_list, [UNTRACKED],
         "extra arguments to prepend to the linker invocation (space separated)"),
     profile: bool = (false, parse_bool, [TRACKED],
                      "insert profiling code"),
@@ -961,4 +980,6 @@
         "use new LLVM pass manager"),
     link_native_libraries: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
         "Link native libraries in the linker invocation."),
+    src_hash_algorithm: Option<SourceFileHashAlgorithm> = (None, parse_src_file_hash, [TRACKED],
+        "hash algorithm of source files in debug info (`md5`, or `sha1`)"),
 }
diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs
index b3d7514..1c5d19d 100644
--- a/src/librustc_session/session.rs
+++ b/src/librustc_session/session.rs
@@ -20,7 +20,8 @@
 use rustc_errors::json::JsonEmitter;
 use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId, ErrorReported};
 use rustc_span::edition::Edition;
-use rustc_span::source_map::{self, MultiSpan, Span};
+use rustc_span::source_map::{self, FileLoader, MultiSpan, RealFileLoader, SourceMap, Span};
+use rustc_span::SourceFileHashAlgorithm;
 use rustc_target::spec::{PanicStrategy, RelroLevel, Target, TargetTriple};
 
 use std::cell::{self, RefCell};
@@ -140,6 +141,15 @@
     /// Options range from returning the error without a backtrace to returning an error
     /// and immediately printing the backtrace to stderr.
     pub ctfe_backtrace: Lock<CtfeBacktrace>,
+
+    /// Base directory containing the `src/` for the Rust standard library, and
+    /// potentially `rustc` as well, if we can can find it. Right now it's always
+    /// `$sysroot/lib/rustlib/src/rust` (i.e. the `rustup` `rust-src` component).
+    ///
+    /// This directory is what the virtual `/rustc/$hash` is translated back to,
+    /// if Rust was built with path remapping to `/rustc/$hash` enabled
+    /// (the `rust.remap-debuginfo` option in `config.toml`).
+    pub real_rust_source_base_dir: Option<PathBuf>,
 }
 
 pub struct PerfStats {
@@ -758,6 +768,13 @@
             return n as usize;
         }
 
+        // If incremental compilation is turned on, we default to a high number
+        // codegen units in order to reduce the "collateral damage" small
+        // changes cause.
+        if self.opts.incremental.is_some() {
+            return 256;
+        }
+
         // Why is 16 codegen units the default all the time?
         //
         // The main reason for enabling multiple codegen units by default is to
@@ -854,16 +871,15 @@
     local_crate_source_file: Option<PathBuf>,
     registry: rustc_errors::registry::Registry,
 ) -> Session {
-    let file_path_mapping = sopts.file_path_mapping();
-
     build_session_with_source_map(
         sopts,
         local_crate_source_file,
         registry,
-        Lrc::new(source_map::SourceMap::new(file_path_mapping)),
         DiagnosticOutput::Default,
         Default::default(),
+        None,
     )
+    .0
 }
 
 fn default_emitter(
@@ -940,10 +956,10 @@
     sopts: config::Options,
     local_crate_source_file: Option<PathBuf>,
     registry: rustc_errors::registry::Registry,
-    source_map: Lrc<source_map::SourceMap>,
     diagnostics_output: DiagnosticOutput,
-    lint_caps: FxHashMap<lint::LintId, lint::Level>,
-) -> Session {
+    driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
+    file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
+) -> (Session, Lrc<SourceMap>) {
     // FIXME: This is not general enough to make the warning lint completely override
     // normal diagnostic warnings, since the warning lint can also be denied and changed
     // later via the source code.
@@ -961,23 +977,33 @@
         DiagnosticOutput::Default => None,
         DiagnosticOutput::Raw(write) => Some(write),
     };
+
+    let target_cfg = config::build_target_config(&sopts, sopts.error_format);
+    let host_triple = TargetTriple::from_triple(config::host_triple());
+    let host = Target::search(&host_triple).unwrap_or_else(|e| {
+        early_error(sopts.error_format, &format!("Error loading host specification: {}", e))
+    });
+
+    let loader = file_loader.unwrap_or(Box::new(RealFileLoader));
+    let hash_kind = sopts.debugging_opts.src_hash_algorithm.unwrap_or_else(|| {
+        if target_cfg.target.options.is_like_msvc {
+            SourceFileHashAlgorithm::Sha1
+        } else {
+            SourceFileHashAlgorithm::Md5
+        }
+    });
+    let source_map = Lrc::new(SourceMap::with_file_loader_and_hash_kind(
+        loader,
+        sopts.file_path_mapping(),
+        hash_kind,
+    ));
     let emitter = default_emitter(&sopts, registry, &source_map, write_dest);
 
-    let diagnostic_handler = rustc_errors::Handler::with_emitter_and_flags(
+    let span_diagnostic = rustc_errors::Handler::with_emitter_and_flags(
         emitter,
         sopts.debugging_opts.diagnostic_handler_flags(can_emit_warnings),
     );
 
-    build_session_(sopts, local_crate_source_file, diagnostic_handler, source_map, lint_caps)
-}
-
-fn build_session_(
-    sopts: config::Options,
-    local_crate_source_file: Option<PathBuf>,
-    span_diagnostic: rustc_errors::Handler,
-    source_map: Lrc<source_map::SourceMap>,
-    driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
-) -> Session {
     let self_profiler = if let SwitchWithOptPath::Enabled(ref d) = sopts.debugging_opts.self_profile
     {
         let directory =
@@ -999,13 +1025,7 @@
         None
     };
 
-    let host_triple = TargetTriple::from_triple(config::host_triple());
-    let host = Target::search(&host_triple).unwrap_or_else(|e| {
-        span_diagnostic.fatal(&format!("Error loading host specification: {}", e)).raise()
-    });
-    let target_cfg = config::build_target_config(&sopts, &span_diagnostic);
-
-    let parse_sess = ParseSess::with_span_handler(span_diagnostic, source_map);
+    let parse_sess = ParseSess::with_span_handler(span_diagnostic, source_map.clone());
     let sysroot = match &sopts.maybe_sysroot {
         Some(sysroot) => sysroot.clone(),
         None => filesearch::get_or_default_sysroot(),
@@ -1056,6 +1076,26 @@
         _ => CtfeBacktrace::Disabled,
     });
 
+    // Try to find a directory containing the Rust `src`, for more details see
+    // the doc comment on the `real_rust_source_base_dir` field.
+    let real_rust_source_base_dir = {
+        // This is the location used by the `rust-src` `rustup` component.
+        let mut candidate = sysroot.join("lib/rustlib/src/rust");
+        if let Ok(metadata) = candidate.symlink_metadata() {
+            // Replace the symlink rustbuild creates, with its destination.
+            // We could try to use `fs::canonicalize` instead, but that might
+            // produce unnecessarily verbose path.
+            if metadata.file_type().is_symlink() {
+                if let Ok(symlink_dest) = std::fs::read_link(&candidate) {
+                    candidate = symlink_dest;
+                }
+            }
+        }
+
+        // Only use this directory if it has a file we can expect to always find.
+        if candidate.join("src/libstd/lib.rs").is_file() { Some(candidate) } else { None }
+    };
+
     let sess = Session {
         target: target_cfg,
         host,
@@ -1094,11 +1134,12 @@
         confused_type_with_std_module: Lock::new(Default::default()),
         system_library_path: OneThread::new(RefCell::new(Default::default())),
         ctfe_backtrace,
+        real_rust_source_base_dir,
     };
 
     validate_commandline_args_with_session_available(&sess);
 
-    sess
+    (sess, source_map)
 }
 
 // If it is useful to have a Session available already for validating a
diff --git a/src/librustc_span/Cargo.toml b/src/librustc_span/Cargo.toml
index c3fa233..1c27212 100644
--- a/src/librustc_span/Cargo.toml
+++ b/src/librustc_span/Cargo.toml
@@ -19,3 +19,5 @@
 unicode-width = "0.1.4"
 cfg-if = "0.1.2"
 log = "0.4"
+sha-1 = "0.8"
+md-5 = "0.8"
diff --git a/src/librustc_span/def_id.rs b/src/librustc_span/def_id.rs
index 3551220..73b46d7 100644
--- a/src/librustc_span/def_id.rs
+++ b/src/librustc_span/def_id.rs
@@ -7,7 +7,6 @@
 use rustc_serialize::{Decoder, Encoder};
 use std::borrow::Borrow;
 use std::fmt;
-use std::{u32, u64};
 
 rustc_index::newtype_index! {
     pub struct CrateId {
diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs
index 3bcc20d..0d9f3f21 100644
--- a/src/librustc_span/lib.rs
+++ b/src/librustc_span/lib.rs
@@ -47,9 +47,14 @@
 use std::cell::RefCell;
 use std::cmp::{self, Ordering};
 use std::fmt;
-use std::hash::{Hash, Hasher};
+use std::hash::Hash;
 use std::ops::{Add, Sub};
 use std::path::PathBuf;
+use std::str::FromStr;
+
+use md5::Md5;
+use sha1::Digest;
+use sha1::Sha1;
 
 #[cfg(test)]
 mod tests;
@@ -874,6 +879,70 @@
 #[derive(Debug)]
 pub struct OffsetOverflowError;
 
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+pub enum SourceFileHashAlgorithm {
+    Md5,
+    Sha1,
+}
+
+impl FromStr for SourceFileHashAlgorithm {
+    type Err = ();
+
+    fn from_str(s: &str) -> Result<SourceFileHashAlgorithm, ()> {
+        match s {
+            "md5" => Ok(SourceFileHashAlgorithm::Md5),
+            "sha1" => Ok(SourceFileHashAlgorithm::Sha1),
+            _ => Err(()),
+        }
+    }
+}
+
+rustc_data_structures::impl_stable_hash_via_hash!(SourceFileHashAlgorithm);
+
+/// The hash of the on-disk source file used for debug info.
+#[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
+#[derive(HashStable_Generic)]
+pub struct SourceFileHash {
+    pub kind: SourceFileHashAlgorithm,
+    value: [u8; 20],
+}
+
+impl SourceFileHash {
+    pub fn new(kind: SourceFileHashAlgorithm, src: &str) -> SourceFileHash {
+        let mut hash = SourceFileHash { kind, value: Default::default() };
+        let len = hash.hash_len();
+        let value = &mut hash.value[..len];
+        let data = src.as_bytes();
+        match kind {
+            SourceFileHashAlgorithm::Md5 => {
+                value.copy_from_slice(&Md5::digest(data));
+            }
+            SourceFileHashAlgorithm::Sha1 => {
+                value.copy_from_slice(&Sha1::digest(data));
+            }
+        }
+        hash
+    }
+
+    /// Check if the stored hash matches the hash of the string.
+    pub fn matches(&self, src: &str) -> bool {
+        Self::new(self.kind, src) == *self
+    }
+
+    /// The bytes of the hash.
+    pub fn hash_bytes(&self) -> &[u8] {
+        let len = self.hash_len();
+        &self.value[..len]
+    }
+
+    fn hash_len(&self) -> usize {
+        match self.kind {
+            SourceFileHashAlgorithm::Md5 => 16,
+            SourceFileHashAlgorithm::Sha1 => 20,
+        }
+    }
+}
+
 /// A single source in the `SourceMap`.
 #[derive(Clone)]
 pub struct SourceFile {
@@ -889,7 +958,7 @@
     /// The complete source code.
     pub src: Option<Lrc<String>>,
     /// The source code's hash.
-    pub src_hash: u128,
+    pub src_hash: SourceFileHash,
     /// The external source code (used for external crates, which will have a `None`
     /// value as `self.src`.
     pub external_src: Lock<ExternalSource>,
@@ -987,7 +1056,8 @@
             let name: FileName = d.read_struct_field("name", 0, |d| Decodable::decode(d))?;
             let name_was_remapped: bool =
                 d.read_struct_field("name_was_remapped", 1, |d| Decodable::decode(d))?;
-            let src_hash: u128 = d.read_struct_field("src_hash", 2, |d| Decodable::decode(d))?;
+            let src_hash: SourceFileHash =
+                d.read_struct_field("src_hash", 2, |d| Decodable::decode(d))?;
             let start_pos: BytePos =
                 d.read_struct_field("start_pos", 3, |d| Decodable::decode(d))?;
             let end_pos: BytePos = d.read_struct_field("end_pos", 4, |d| Decodable::decode(d))?;
@@ -1062,14 +1132,12 @@
         unmapped_path: FileName,
         mut src: String,
         start_pos: BytePos,
+        hash_kind: SourceFileHashAlgorithm,
     ) -> Self {
+        // Compute the file hash before any normalization.
+        let src_hash = SourceFileHash::new(hash_kind, &src);
         let normalized_pos = normalize_src(&mut src, start_pos);
 
-        let src_hash = {
-            let mut hasher: StableHasher = StableHasher::new();
-            hasher.write(src.as_bytes());
-            hasher.finish::<u128>()
-        };
         let name_hash = {
             let mut hasher: StableHasher = StableHasher::new();
             name.hash(&mut hasher);
@@ -1125,10 +1193,7 @@
             } = &mut *external_src
             {
                 if let Some(src) = src {
-                    let mut hasher: StableHasher = StableHasher::new();
-                    hasher.write(src.as_bytes());
-
-                    if hasher.finish::<u128>() == self.src_hash {
+                    if self.src_hash.matches(&src) {
                         *src_kind = ExternalSourceKind::Present(Lrc::new(src));
                         return true;
                     }
diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs
index 57e6832..49e2144 100644
--- a/src/librustc_span/source_map.rs
+++ b/src/librustc_span/source_map.rs
@@ -141,27 +141,31 @@
     // This is used to apply the file path remapping as specified via
     // `--remap-path-prefix` to all `SourceFile`s allocated within this `SourceMap`.
     path_mapping: FilePathMapping,
+
+    /// The algorithm used for hashing the contents of each source file.
+    hash_kind: SourceFileHashAlgorithm,
 }
 
 impl SourceMap {
     pub fn new(path_mapping: FilePathMapping) -> SourceMap {
-        SourceMap {
-            used_address_space: AtomicU32::new(0),
-            files: Default::default(),
-            file_loader: Box::new(RealFileLoader),
+        Self::with_file_loader_and_hash_kind(
+            Box::new(RealFileLoader),
             path_mapping,
-        }
+            SourceFileHashAlgorithm::Md5,
+        )
     }
 
-    pub fn with_file_loader(
+    pub fn with_file_loader_and_hash_kind(
         file_loader: Box<dyn FileLoader + Sync + Send>,
         path_mapping: FilePathMapping,
+        hash_kind: SourceFileHashAlgorithm,
     ) -> SourceMap {
         SourceMap {
             used_address_space: AtomicU32::new(0),
             files: Default::default(),
             file_loader,
             path_mapping,
+            hash_kind,
         }
     }
 
@@ -275,6 +279,7 @@
                     unmapped_path,
                     src,
                     Pos::from_usize(start_pos),
+                    self.hash_kind,
                 ));
 
                 let mut files = self.files.borrow_mut();
@@ -296,7 +301,7 @@
         &self,
         filename: FileName,
         name_was_remapped: bool,
-        src_hash: u128,
+        src_hash: SourceFileHash,
         name_hash: u128,
         source_len: usize,
         cnum: CrateNum,
diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs
index f382ef9..4c25363 100644
--- a/src/librustc_target/abi/mod.rs
+++ b/src/librustc_target/abi/mod.rs
@@ -577,7 +577,7 @@
     pub value: Primitive,
 
     /// Inclusive wrap-around range of valid values, that is, if
-    /// start > end, it represents `start..=max_value()`,
+    /// start > end, it represents `start..=MAX`,
     /// followed by `0..=end`.
     ///
     /// That is, for an i8 primitive, a range of `254..=2` means following
diff --git a/src/librustc_target/spec/aarch64_pc_windows_msvc.rs b/src/librustc_target/spec/aarch64_pc_windows_msvc.rs
index 7a46c7d..8c03f1e 100644
--- a/src/librustc_target/spec/aarch64_pc_windows_msvc.rs
+++ b/src/librustc_target/spec/aarch64_pc_windows_msvc.rs
@@ -1,4 +1,4 @@
-use crate::spec::{LinkerFlavor, PanicStrategy, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
 
 pub fn target() -> TargetResult {
     let mut base = super::windows_msvc_base::opts();
@@ -6,9 +6,6 @@
     base.has_elf_tls = true;
     base.features = "+neon,+fp-armv8".to_string();
 
-    // FIXME: this shouldn't be panic=abort, it should be panic=unwind
-    base.panic_strategy = PanicStrategy::Abort;
-
     Ok(Target {
         llvm_target: "aarch64-pc-windows-msvc".to_string(),
         target_endian: "little".to_string(),
diff --git a/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs b/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs
index a793860..6a8d148 100644
--- a/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs
+++ b/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs
@@ -1,13 +1,10 @@
-use crate::spec::{LinkerFlavor, PanicStrategy, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
 
 pub fn target() -> TargetResult {
     let mut base = super::windows_uwp_msvc_base::opts();
     base.max_atomic_width = Some(64);
     base.has_elf_tls = true;
 
-    // FIXME: this shouldn't be panic=abort, it should be panic=unwind
-    base.panic_strategy = PanicStrategy::Abort;
-
     Ok(Target {
         llvm_target: "aarch64-pc-windows-msvc".to_string(),
         target_endian: "little".to_string(),
diff --git a/src/librustc_target/spec/hermit_base.rs b/src/librustc_target/spec/hermit_base.rs
index ee29d67..3f9dad6 100644
--- a/src/librustc_target/spec/hermit_base.rs
+++ b/src/librustc_target/spec/hermit_base.rs
@@ -14,7 +14,6 @@
         has_elf_tls: true,
         linker_is_gnu: true,
         pre_link_args,
-        no_default_libraries: true,
         panic_strategy: PanicStrategy::Abort,
         position_independent_executables: true,
         relocation_model: "static".to_string(),
diff --git a/src/librustc_target/spec/hermit_kernel_base.rs b/src/librustc_target/spec/hermit_kernel_base.rs
index 44d3ee6..650219c 100644
--- a/src/librustc_target/spec/hermit_kernel_base.rs
+++ b/src/librustc_target/spec/hermit_kernel_base.rs
@@ -15,7 +15,6 @@
         has_elf_tls: true,
         linker_is_gnu: true,
         pre_link_args,
-        no_default_libraries: true,
         panic_strategy: PanicStrategy::Abort,
         position_independent_executables: true,
         relocation_model: "static".to_string(),
diff --git a/src/librustc_target/spec/windows_base.rs b/src/librustc_target/spec/windows_base.rs
index 5f59ca8..34fcdf2 100644
--- a/src/librustc_target/spec/windows_base.rs
+++ b/src/librustc_target/spec/windows_base.rs
@@ -77,7 +77,6 @@
         exe_suffix: ".exe".to_string(),
         staticlib_prefix: String::new(),
         staticlib_suffix: ".lib".to_string(),
-        no_default_libraries: true,
         target_family: Some("windows".to_string()),
         is_like_windows: true,
         allows_weak_linkage: false,
diff --git a/src/librustc_target/spec/windows_uwp_base.rs b/src/librustc_target/spec/windows_uwp_base.rs
index 3f7eb44..f19bd10 100644
--- a/src/librustc_target/spec/windows_uwp_base.rs
+++ b/src/librustc_target/spec/windows_uwp_base.rs
@@ -43,7 +43,6 @@
         exe_suffix: ".exe".to_string(),
         staticlib_prefix: "lib".to_string(),
         staticlib_suffix: ".a".to_string(),
-        no_default_libraries: true,
         target_family: Some("windows".to_string()),
         is_like_windows: true,
         allows_weak_linkage: false,
diff --git a/src/librustc_trait_selection/infer.rs b/src/librustc_trait_selection/infer.rs
index d7a2e72..24eb22f 100644
--- a/src/librustc_trait_selection/infer.rs
+++ b/src/librustc_trait_selection/infer.rs
@@ -2,11 +2,11 @@
 use crate::traits::{self, TraitEngine, TraitEngineExt};
 
 use rustc_hir as hir;
+use rustc_hir::lang_items;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::traits::ObligationCause;
 use rustc_middle::arena::ArenaAllocatable;
 use rustc_middle::infer::canonical::{Canonical, CanonicalizedQueryResponse, QueryResponse};
-use rustc_middle::middle::lang_items;
 use rustc_middle::traits::query::Fallible;
 use rustc_middle::ty::{self, Ty, TypeFoldable};
 use rustc_span::{Span, DUMMY_SP};
diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs
index 7d6b3b5..f0a157b 100644
--- a/src/librustc_trait_selection/traits/error_reporting/mod.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs
@@ -65,7 +65,7 @@
     /// returns a span and `ArgKind` information that describes the
     /// arguments it expects. This can be supplied to
     /// `report_arg_count_mismatch`.
-    fn get_fn_like_arguments(&self, node: Node<'_>) -> (Span, Vec<ArgKind>);
+    fn get_fn_like_arguments(&self, node: Node<'_>) -> Option<(Span, Vec<ArgKind>)>;
 
     /// Reports an error when the number of arguments needed by a
     /// trait match doesn't match the number that the expression
@@ -611,10 +611,10 @@
                     )
                 } else {
                     let (closure_span, found) = found_did
-                        .and_then(|did| self.tcx.hir().get_if_local(did))
-                        .map(|node| {
-                            let (found_span, found) = self.get_fn_like_arguments(node);
-                            (Some(found_span), found)
+                        .and_then(|did| {
+                            let node = self.tcx.hir().get_if_local(did)?;
+                            let (found_span, found) = self.get_fn_like_arguments(node)?;
+                            Some((Some(found_span), found))
                         })
                         .unwrap_or((found_span, found));
 
@@ -672,43 +672,38 @@
     /// returns a span and `ArgKind` information that describes the
     /// arguments it expects. This can be supplied to
     /// `report_arg_count_mismatch`.
-    fn get_fn_like_arguments(&self, node: Node<'_>) -> (Span, Vec<ArgKind>) {
-        match node {
+    fn get_fn_like_arguments(&self, node: Node<'_>) -> Option<(Span, Vec<ArgKind>)> {
+        let sm = self.tcx.sess.source_map();
+        let hir = self.tcx.hir();
+        Some(match node {
             Node::Expr(&hir::Expr {
                 kind: hir::ExprKind::Closure(_, ref _decl, id, span, _),
                 ..
             }) => (
-                self.tcx.sess.source_map().guess_head_span(span),
-                self.tcx
-                    .hir()
-                    .body(id)
+                sm.guess_head_span(span),
+                hir.body(id)
                     .params
                     .iter()
                     .map(|arg| {
                         if let hir::Pat { kind: hir::PatKind::Tuple(ref args, _), span, .. } =
                             *arg.pat
                         {
-                            ArgKind::Tuple(
+                            Some(ArgKind::Tuple(
                                 Some(span),
                                 args.iter()
                                     .map(|pat| {
-                                        let snippet = self
-                                            .tcx
-                                            .sess
-                                            .source_map()
-                                            .span_to_snippet(pat.span)
-                                            .unwrap();
-                                        (snippet, "_".to_owned())
+                                        sm.span_to_snippet(pat.span)
+                                            .ok()
+                                            .map(|snippet| (snippet, "_".to_owned()))
                                     })
-                                    .collect::<Vec<_>>(),
-                            )
+                                    .collect::<Option<Vec<_>>>()?,
+                            ))
                         } else {
-                            let name =
-                                self.tcx.sess.source_map().span_to_snippet(arg.pat.span).unwrap();
-                            ArgKind::Arg(name, "_".to_owned())
+                            let name = sm.span_to_snippet(arg.pat.span).ok()?;
+                            Some(ArgKind::Arg(name, "_".to_owned()))
                         }
                     })
-                    .collect::<Vec<ArgKind>>(),
+                    .collect::<Option<Vec<ArgKind>>>()?,
             ),
             Node::Item(&hir::Item { span, kind: hir::ItemKind::Fn(ref sig, ..), .. })
             | Node::ImplItem(&hir::ImplItem {
@@ -721,7 +716,7 @@
                 kind: hir::TraitItemKind::Fn(ref sig, _),
                 ..
             }) => (
-                self.tcx.sess.source_map().guess_head_span(span),
+                sm.guess_head_span(span),
                 sig.decl
                     .inputs
                     .iter()
@@ -735,16 +730,12 @@
                     .collect::<Vec<ArgKind>>(),
             ),
             Node::Ctor(ref variant_data) => {
-                let span = variant_data
-                    .ctor_hir_id()
-                    .map(|hir_id| self.tcx.hir().span(hir_id))
-                    .unwrap_or(DUMMY_SP);
-                let span = self.tcx.sess.source_map().guess_head_span(span);
-
+                let span = variant_data.ctor_hir_id().map(|id| hir.span(id)).unwrap_or(DUMMY_SP);
+                let span = sm.guess_head_span(span);
                 (span, vec![ArgKind::empty(); variant_data.fields().len()])
             }
             _ => panic!("non-FnLike node found: {:?}", node),
-        }
+        })
     }
 
     /// Reports an error when the number of arguments needed by a
@@ -1386,7 +1377,7 @@
                     return;
                 }
                 let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0283);
-                err.note(&format!("cannot resolve `{}`", predicate));
+                err.note(&format!("cannot satisfy `{}`", predicate));
                 if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code {
                     self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());
                 } else if let (
@@ -1416,7 +1407,7 @@
                         // LL |     const fn const_val<T: Sized>() -> usize {
                         //    |              --------- - required by this bound in `Tt::const_val`
                         //    |
-                        //    = note: cannot resolve `_: Tt`
+                        //    = note: cannot satisfy `_: Tt`
 
                         err.span_suggestion_verbose(
                             span.shrink_to_hi(),
@@ -1466,7 +1457,7 @@
                     return;
                 }
                 let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0284);
-                err.note(&format!("cannot resolve `{}`", predicate));
+                err.note(&format!("cannot satisfy `{}`", predicate));
                 err
             }
 
@@ -1478,10 +1469,10 @@
                     self.tcx.sess,
                     span,
                     E0284,
-                    "type annotations needed: cannot resolve `{}`",
+                    "type annotations needed: cannot satisfy `{}`",
                     predicate,
                 );
-                err.span_label(span, &format!("cannot resolve `{}`", predicate));
+                err.span_label(span, &format!("cannot satisfy `{}`", predicate));
                 err
             }
         };
diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
index 6a35260..fcec29a 100644
--- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
@@ -732,12 +732,13 @@
                 true
             };
 
+        let sm = self.tcx.sess.source_map();
         let (snippet, last_ty) =
             if let (true, hir::TyKind::TraitObject(..), Ok(snippet), true, Some(last_ty)) = (
                 // Verify that we're dealing with a return `dyn Trait`
                 ret_ty.span.overlaps(span),
                 &ret_ty.kind,
-                self.tcx.sess.source_map().span_to_snippet(ret_ty.span),
+                sm.span_to_snippet(ret_ty.span),
                 // If any of the return types does not conform to the trait, then we can't
                 // suggest `impl Trait` nor trait objects, it is a type mismatch error.
                 all_returns_conform_to_trait,
@@ -775,26 +776,23 @@
             if is_object_safe {
                 // Suggest `-> Box<dyn Trait>` and `Box::new(returned_value)`.
                 // Get all the return values and collect their span and suggestion.
-                let mut suggestions = visitor
+                if let Some(mut suggestions) = visitor
                     .returns
                     .iter()
                     .map(|expr| {
-                        (
-                            expr.span,
-                            format!(
-                                "Box::new({})",
-                                self.tcx.sess.source_map().span_to_snippet(expr.span).unwrap()
-                            ),
-                        )
+                        let snip = sm.span_to_snippet(expr.span).ok()?;
+                        Some((expr.span, format!("Box::new({})", snip)))
                     })
-                    .collect::<Vec<_>>();
-                // Add the suggestion for the return type.
-                suggestions.push((ret_ty.span, format!("Box<dyn {}>", trait_obj)));
-                err.multipart_suggestion(
-                    "return a boxed trait object instead",
-                    suggestions,
-                    Applicability::MaybeIncorrect,
-                );
+                    .collect::<Option<Vec<_>>>()
+                {
+                    // Add the suggestion for the return type.
+                    suggestions.push((ret_ty.span, format!("Box<dyn {}>", trait_obj)));
+                    err.multipart_suggestion(
+                        "return a boxed trait object instead",
+                        suggestions,
+                        Applicability::MaybeIncorrect,
+                    );
+                }
             } else {
                 // This is currently not possible to trigger because E0038 takes precedence, but
                 // leave it in for completeness in case anything changes in an earlier stage.
diff --git a/src/librustc_trait_selection/traits/mod.rs b/src/librustc_trait_selection/traits/mod.rs
index 5f98850..9a853c3 100644
--- a/src/librustc_trait_selection/traits/mod.rs
+++ b/src/librustc_trait_selection/traits/mod.rs
@@ -24,13 +24,13 @@
 use crate::infer::{InferCtxt, RegionckMode, TyCtxtInferExt};
 use crate::traits::error_reporting::InferCtxtExt as _;
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
+use rustc_errors::ErrorReported;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_middle::middle::region;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
 use rustc_middle::ty::{self, GenericParamDefKind, ToPredicate, Ty, TyCtxt, WithConstness};
-use rustc_middle::util::common::ErrorReported;
 use rustc_span::{Span, DUMMY_SP};
 
 use std::fmt::Debug;
diff --git a/src/librustc_trait_selection/traits/object_safety.rs b/src/librustc_trait_selection/traits/object_safety.rs
index 3877c7f..20b3fa9 100644
--- a/src/librustc_trait_selection/traits/object_safety.rs
+++ b/src/librustc_trait_selection/traits/object_safety.rs
@@ -420,7 +420,7 @@
         } else {
             // Do sanity check to make sure the receiver actually has the layout of a pointer.
 
-            use rustc_middle::ty::layout::Abi;
+            use rustc_target::abi::Abi;
 
             let param_env = tcx.param_env(method.def_id);
 
diff --git a/src/librustc_trait_selection/traits/on_unimplemented.rs b/src/librustc_trait_selection/traits/on_unimplemented.rs
index 23c3bd4..cf29c42 100644
--- a/src/librustc_trait_selection/traits/on_unimplemented.rs
+++ b/src/librustc_trait_selection/traits/on_unimplemented.rs
@@ -1,13 +1,11 @@
 use fmt_macros::{Parser, Piece, Position};
 
-use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt};
-use rustc_middle::util::common::ErrorReported;
-
 use rustc_ast::ast::{MetaItem, NestedMetaItem};
 use rustc_attr as attr;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::struct_span_err;
+use rustc_errors::{struct_span_err, ErrorReported};
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt};
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::Span;
 
diff --git a/src/librustc_trait_selection/traits/project.rs b/src/librustc_trait_selection/traits/project.rs
index aae0d46..e4ca7d4 100644
--- a/src/librustc_trait_selection/traits/project.rs
+++ b/src/librustc_trait_selection/traits/project.rs
@@ -1010,7 +1010,7 @@
                 // type.
                 //
                 // NOTE: This should be kept in sync with the similar code in
-                // `rustc_middle::ty::instance::resolve_associated_item()`.
+                // `rustc_ty::instance::resolve_associated_item()`.
                 let node_item =
                     assoc_ty_def(selcx, impl_data.impl_def_id, obligation.predicate.item_def_id)
                         .map_err(|ErrorReported| ())?;
@@ -1028,7 +1028,7 @@
                         // assume `poly_trait_ref` isn't monomorphic, if it contains any.
                         let poly_trait_ref =
                             selcx.infcx().resolve_vars_if_possible(&poly_trait_ref);
-                        !poly_trait_ref.needs_infer() && !poly_trait_ref.needs_subst()
+                        !poly_trait_ref.still_further_specializable()
                     } else {
                         debug!(
                             "assemble_candidates_from_impls: not eligible due to default: \
diff --git a/src/librustc_trait_selection/traits/select.rs b/src/librustc_trait_selection/traits/select.rs
index 1e5a1ed..3d95824 100644
--- a/src/librustc_trait_selection/traits/select.rs
+++ b/src/librustc_trait_selection/traits/select.rs
@@ -39,9 +39,9 @@
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_hir::lang_items;
 use rustc_index::bit_set::GrowableBitSet;
 use rustc_middle::dep_graph::{DepKind, DepNodeIndex};
-use rustc_middle::middle::lang_items;
 use rustc_middle::ty::fast_reject;
 use rustc_middle::ty::relate::TypeRelation;
 use rustc_middle::ty::subst::{Subst, SubstsRef};
diff --git a/src/librustc_trait_selection/traits/util.rs b/src/librustc_trait_selection/traits/util.rs
index 6348673..725c41c 100644
--- a/src/librustc_trait_selection/traits/util.rs
+++ b/src/librustc_trait_selection/traits/util.rs
@@ -5,270 +5,11 @@
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def_id::DefId;
-use rustc_middle::ty::outlives::Component;
 use rustc_middle::ty::subst::{GenericArg, Subst, SubstsRef};
-use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness};
+use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness};
 
 use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext};
-
-fn anonymize_predicate<'tcx>(tcx: TyCtxt<'tcx>, pred: &ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
-    match *pred {
-        ty::Predicate::Trait(ref data, constness) => {
-            ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data), constness)
-        }
-
-        ty::Predicate::RegionOutlives(ref data) => {
-            ty::Predicate::RegionOutlives(tcx.anonymize_late_bound_regions(data))
-        }
-
-        ty::Predicate::TypeOutlives(ref data) => {
-            ty::Predicate::TypeOutlives(tcx.anonymize_late_bound_regions(data))
-        }
-
-        ty::Predicate::Projection(ref data) => {
-            ty::Predicate::Projection(tcx.anonymize_late_bound_regions(data))
-        }
-
-        ty::Predicate::WellFormed(data) => ty::Predicate::WellFormed(data),
-
-        ty::Predicate::ObjectSafe(data) => ty::Predicate::ObjectSafe(data),
-
-        ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
-            ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind)
-        }
-
-        ty::Predicate::Subtype(ref data) => {
-            ty::Predicate::Subtype(tcx.anonymize_late_bound_regions(data))
-        }
-
-        ty::Predicate::ConstEvaluatable(def_id, substs) => {
-            ty::Predicate::ConstEvaluatable(def_id, substs)
-        }
-    }
-}
-
-struct PredicateSet<'tcx> {
-    tcx: TyCtxt<'tcx>,
-    set: FxHashSet<ty::Predicate<'tcx>>,
-}
-
-impl PredicateSet<'tcx> {
-    fn new(tcx: TyCtxt<'tcx>) -> Self {
-        Self { tcx, set: Default::default() }
-    }
-
-    fn insert(&mut self, pred: &ty::Predicate<'tcx>) -> bool {
-        // We have to be careful here because we want
-        //
-        //    for<'a> Foo<&'a int>
-        //
-        // and
-        //
-        //    for<'b> Foo<&'b int>
-        //
-        // to be considered equivalent. So normalize all late-bound
-        // regions before we throw things into the underlying set.
-        self.set.insert(anonymize_predicate(self.tcx, pred))
-    }
-}
-
-impl<T: AsRef<ty::Predicate<'tcx>>> Extend<T> for PredicateSet<'tcx> {
-    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
-        for pred in iter {
-            self.insert(pred.as_ref());
-        }
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// `Elaboration` iterator
-///////////////////////////////////////////////////////////////////////////
-
-/// "Elaboration" is the process of identifying all the predicates that
-/// are implied by a source predicate. Currently, this basically means
-/// walking the "supertraits" and other similar assumptions. For example,
-/// if we know that `T: Ord`, the elaborator would deduce that `T: PartialOrd`
-/// holds as well. Similarly, if we have `trait Foo: 'static`, and we know that
-/// `T: Foo`, then we know that `T: 'static`.
-pub struct Elaborator<'tcx> {
-    stack: Vec<ty::Predicate<'tcx>>,
-    visited: PredicateSet<'tcx>,
-}
-
-pub fn elaborate_trait_ref<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    trait_ref: ty::PolyTraitRef<'tcx>,
-) -> Elaborator<'tcx> {
-    elaborate_predicates(tcx, vec![trait_ref.without_const().to_predicate()])
-}
-
-pub fn elaborate_trait_refs<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
-) -> Elaborator<'tcx> {
-    let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate()).collect();
-    elaborate_predicates(tcx, predicates)
-}
-
-pub fn elaborate_predicates<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    mut predicates: Vec<ty::Predicate<'tcx>>,
-) -> Elaborator<'tcx> {
-    let mut visited = PredicateSet::new(tcx);
-    predicates.retain(|pred| visited.insert(pred));
-    Elaborator { stack: predicates, visited }
-}
-
-impl Elaborator<'tcx> {
-    pub fn filter_to_traits(self) -> FilterToTraits<Self> {
-        FilterToTraits::new(self)
-    }
-
-    fn elaborate(&mut self, predicate: &ty::Predicate<'tcx>) {
-        let tcx = self.visited.tcx;
-        match *predicate {
-            ty::Predicate::Trait(ref data, _) => {
-                // Get predicates declared on the trait.
-                let predicates = tcx.super_predicates_of(data.def_id());
-
-                let predicates = predicates
-                    .predicates
-                    .iter()
-                    .map(|(pred, _)| pred.subst_supertrait(tcx, &data.to_poly_trait_ref()));
-                debug!("super_predicates: data={:?} predicates={:?}", data, predicates.clone());
-
-                // Only keep those bounds that we haven't already seen.
-                // This is necessary to prevent infinite recursion in some
-                // cases. One common case is when people define
-                // `trait Sized: Sized { }` rather than `trait Sized { }`.
-                let visited = &mut self.visited;
-                let predicates = predicates.filter(|pred| visited.insert(pred));
-
-                self.stack.extend(predicates);
-            }
-            ty::Predicate::WellFormed(..) => {
-                // Currently, we do not elaborate WF predicates,
-                // although we easily could.
-            }
-            ty::Predicate::ObjectSafe(..) => {
-                // Currently, we do not elaborate object-safe
-                // predicates.
-            }
-            ty::Predicate::Subtype(..) => {
-                // Currently, we do not "elaborate" predicates like `X <: Y`,
-                // though conceivably we might.
-            }
-            ty::Predicate::Projection(..) => {
-                // Nothing to elaborate in a projection predicate.
-            }
-            ty::Predicate::ClosureKind(..) => {
-                // Nothing to elaborate when waiting for a closure's kind to be inferred.
-            }
-            ty::Predicate::ConstEvaluatable(..) => {
-                // Currently, we do not elaborate const-evaluatable
-                // predicates.
-            }
-            ty::Predicate::RegionOutlives(..) => {
-                // Nothing to elaborate from `'a: 'b`.
-            }
-            ty::Predicate::TypeOutlives(ref data) => {
-                // We know that `T: 'a` for some type `T`. We can
-                // often elaborate this. For example, if we know that
-                // `[U]: 'a`, that implies that `U: 'a`. Similarly, if
-                // we know `&'a U: 'b`, then we know that `'a: 'b` and
-                // `U: 'b`.
-                //
-                // We can basically ignore bound regions here. So for
-                // example `for<'c> Foo<'a,'c>: 'b` can be elaborated to
-                // `'a: 'b`.
-
-                // Ignore `for<'a> T: 'a` -- we might in the future
-                // consider this as evidence that `T: 'static`, but
-                // I'm a bit wary of such constructions and so for now
-                // I want to be conservative. --nmatsakis
-                let ty_max = data.skip_binder().0;
-                let r_min = data.skip_binder().1;
-                if r_min.is_late_bound() {
-                    return;
-                }
-
-                let visited = &mut self.visited;
-                let mut components = smallvec![];
-                tcx.push_outlives_components(ty_max, &mut components);
-                self.stack.extend(
-                    components
-                        .into_iter()
-                        .filter_map(|component| match component {
-                            Component::Region(r) => {
-                                if r.is_late_bound() {
-                                    None
-                                } else {
-                                    Some(ty::Predicate::RegionOutlives(ty::Binder::dummy(
-                                        ty::OutlivesPredicate(r, r_min),
-                                    )))
-                                }
-                            }
-
-                            Component::Param(p) => {
-                                let ty = tcx.mk_ty_param(p.index, p.name);
-                                Some(ty::Predicate::TypeOutlives(ty::Binder::dummy(
-                                    ty::OutlivesPredicate(ty, r_min),
-                                )))
-                            }
-
-                            Component::UnresolvedInferenceVariable(_) => None,
-
-                            Component::Projection(_) | Component::EscapingProjection(_) => {
-                                // We can probably do more here. This
-                                // corresponds to a case like `<T as
-                                // Foo<'a>>::U: 'b`.
-                                None
-                            }
-                        })
-                        .filter(|p| visited.insert(p)),
-                );
-            }
-        }
-    }
-}
-
-impl Iterator for Elaborator<'tcx> {
-    type Item = ty::Predicate<'tcx>;
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        (self.stack.len(), None)
-    }
-
-    fn next(&mut self) -> Option<ty::Predicate<'tcx>> {
-        // Extract next item from top-most stack frame, if any.
-        if let Some(pred) = self.stack.pop() {
-            self.elaborate(&pred);
-            Some(pred)
-        } else {
-            None
-        }
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Supertrait iterator
-///////////////////////////////////////////////////////////////////////////
-
-pub type Supertraits<'tcx> = FilterToTraits<Elaborator<'tcx>>;
-
-pub fn supertraits<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    trait_ref: ty::PolyTraitRef<'tcx>,
-) -> Supertraits<'tcx> {
-    elaborate_trait_ref(tcx, trait_ref).filter_to_traits()
-}
-
-pub fn transitive_bounds<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
-) -> Supertraits<'tcx> {
-    elaborate_trait_refs(tcx, bounds).filter_to_traits()
-}
+pub use rustc_infer::traits::util::*;
 
 ///////////////////////////////////////////////////////////////////////////
 // `TraitAliasExpander` iterator
@@ -450,40 +191,6 @@
 // Other
 ///////////////////////////////////////////////////////////////////////////
 
-/// A filter around an iterator of predicates that makes it yield up
-/// just trait references.
-pub struct FilterToTraits<I> {
-    base_iterator: I,
-}
-
-impl<I> FilterToTraits<I> {
-    fn new(base: I) -> FilterToTraits<I> {
-        FilterToTraits { base_iterator: base }
-    }
-}
-
-impl<'tcx, I: Iterator<Item = ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> {
-    type Item = ty::PolyTraitRef<'tcx>;
-
-    fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
-        while let Some(pred) = self.base_iterator.next() {
-            if let ty::Predicate::Trait(data, _) = pred {
-                return Some(data.to_poly_trait_ref());
-            }
-        }
-        None
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        let (_, upper) = self.base_iterator.size_hint();
-        (0, upper)
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Other
-///////////////////////////////////////////////////////////////////////////
-
 /// Instantiate all bound parameters of the impl with the given substs,
 /// returning the resulting trait ref and all obligations that arise.
 /// The obligations are closed under normalization.
diff --git a/src/librustc_trait_selection/traits/wf.rs b/src/librustc_trait_selection/traits/wf.rs
index 59b56d6..1eb41e0 100644
--- a/src/librustc_trait_selection/traits/wf.rs
+++ b/src/librustc_trait_selection/traits/wf.rs
@@ -3,7 +3,7 @@
 use crate::traits::{self, AssocTypeBoundData};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
-use rustc_middle::middle::lang_items;
+use rustc_hir::lang_items;
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
 use rustc_span::symbol::{kw, Ident};
diff --git a/src/librustc_traits/implied_outlives_bounds.rs b/src/librustc_traits/implied_outlives_bounds.rs
index 0f43224..33ecbe7 100644
--- a/src/librustc_traits/implied_outlives_bounds.rs
+++ b/src/librustc_traits/implied_outlives_bounds.rs
@@ -1,5 +1,6 @@
 //! Provider for the `implied_outlives_bounds` query.
-//! Do not call this query directory. See [`rustc_middle::traits::query::implied_outlives_bounds`].
+//! Do not call this query directory. See
+//! [`rustc_trait_selection::traits::query::type_op::implied_outlives_bounds`].
 
 use rustc_hir as hir;
 use rustc_infer::infer::canonical::{self, Canonical};
diff --git a/src/librustc_ty/common_traits.rs b/src/librustc_ty/common_traits.rs
index 597bc85..265b811 100644
--- a/src/librustc_ty/common_traits.rs
+++ b/src/librustc_ty/common_traits.rs
@@ -1,7 +1,7 @@
 //! Queries for checking whether a type implements one of a few common traits.
 
+use rustc_hir::lang_items;
 use rustc_infer::infer::TyCtxtInferExt;
-use rustc_middle::middle::lang_items;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::DUMMY_SP;
 use rustc_trait_selection::traits;
diff --git a/src/librustc_ty/instance.rs b/src/librustc_ty/instance.rs
index 47c4b1c..955e2e3 100644
--- a/src/librustc_ty/instance.rs
+++ b/src/librustc_ty/instance.rs
@@ -11,9 +11,7 @@
 
 pub fn resolve_instance<'tcx>(
     tcx: TyCtxt<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-    def_id: DefId,
-    substs: SubstsRef<'tcx>,
+    (param_env, def_id, substs): (ty::ParamEnv<'tcx>, DefId, SubstsRef<'tcx>),
 ) -> Option<Instance<'tcx>> {
     debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
     let result = if let Some(trait_def_id) = tcx.trait_of_item(def_id) {
@@ -118,7 +116,7 @@
             // Since this is a trait item, we need to see if the item is either a trait default item
             // or a specialization because we can't resolve those unless we can `Reveal::All`.
             // NOTE: This should be kept in sync with the similar code in
-            // `rustc_middle::traits::project::assemble_candidates_from_impls()`.
+            // `rustc_trait_selection::traits::project::assemble_candidates_from_impls()`.
             let eligible = if leaf_def.is_final() {
                 // Non-specializable items are always projectable.
                 true
@@ -127,7 +125,11 @@
                 // and the obligation is monomorphic, otherwise passes such as
                 // transmute checking and polymorphic MIR optimizations could
                 // get a result which isn't correct for all monomorphizations.
-                if param_env.reveal == Reveal::All { !trait_ref.needs_subst() } else { false }
+                if param_env.reveal == Reveal::All {
+                    !trait_ref.still_further_specializable()
+                } else {
+                    false
+                }
             };
 
             if !eligible {
@@ -195,3 +197,7 @@
         traits::VtableAutoImpl(..) | traits::VtableParam(..) | traits::VtableTraitAlias(..) => None,
     }
 }
+
+pub fn provide(providers: &mut ty::query::Providers<'_>) {
+    *providers = ty::query::Providers { resolve_instance, ..*providers };
+}
diff --git a/src/librustc_ty/lib.rs b/src/librustc_ty/lib.rs
index 04909b8..75e62e7 100644
--- a/src/librustc_ty/lib.rs
+++ b/src/librustc_ty/lib.rs
@@ -25,4 +25,5 @@
     common_traits::provide(providers);
     needs_drop::provide(providers);
     ty::provide(providers);
+    instance::provide(providers);
 }
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 932032b..c3ebcbf 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -6,18 +6,18 @@
 // ignore-tidy-filelength
 
 use crate::collect::PlaceholderHirTyCollector;
-use crate::middle::lang_items::SizedTraitLangItem;
 use crate::middle::resolve_lifetime as rl;
 use crate::require_c_abi_if_c_variadic;
-use crate::util::common::ErrorReported;
 use rustc_ast::ast;
 use rustc_ast::util::lev_distance::find_best_match_for_name;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_errors::ErrorReported;
 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, FatalError};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{walk_generics, Visitor as _};
+use rustc_hir::lang_items::SizedTraitLangItem;
 use rustc_hir::{Constness, GenericArg, GenericArgs};
 use rustc_middle::ty::subst::{self, InternalSubsts, Subst, SubstsRef};
 use rustc_middle::ty::{
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 7f1631a..5de0184 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -32,11 +32,10 @@
 
 use crate::hir::def_id::DefId;
 use crate::type_error_struct;
-use crate::util::common::ErrorReported;
 use rustc_ast::ast;
-use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
+use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
 use rustc_hir as hir;
-use rustc_middle::middle::lang_items;
+use rustc_hir::lang_items;
 use rustc_middle::ty::adjustment::AllowTwoPhase;
 use rustc_middle::ty::cast::{CastKind, CastTy};
 use rustc_middle::ty::error::TypeError;
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 415b510..2ccf789 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -3,9 +3,10 @@
 use super::{check_fn, Expectation, FnCtxt, GeneratorTypes};
 
 use crate::astconv::AstConv;
-use crate::middle::{lang_items, region};
+use crate::middle::region;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_hir::lang_items;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::LateBoundRegionConversionTime;
 use rustc_infer::infer::{InferOk, InferResult};
@@ -431,18 +432,23 @@
         body: &hir::Body<'_>,
         expected_sig: ExpectedSig<'tcx>,
     ) -> ClosureSignatures<'tcx> {
-        let expr_map_node = self.tcx.hir().get_if_local(expr_def_id).unwrap();
+        let hir = self.tcx.hir();
+        let expr_map_node = hir.get_if_local(expr_def_id).unwrap();
         let expected_args: Vec<_> = expected_sig
             .sig
             .inputs()
             .iter()
             .map(|ty| ArgKind::from_expected_ty(ty, None))
             .collect();
-        let (closure_span, found_args) = self.get_fn_like_arguments(expr_map_node);
-        let expected_span = expected_sig.cause_span.unwrap_or(closure_span);
+        let (closure_span, found_args) = match self.get_fn_like_arguments(expr_map_node) {
+            Some((sp, args)) => (Some(sp), args),
+            None => (None, Vec::new()),
+        };
+        let expected_span =
+            expected_sig.cause_span.unwrap_or_else(|| hir.span_if_local(expr_def_id).unwrap());
         self.report_arg_count_mismatch(
             expected_span,
-            Some(closure_span),
+            closure_span,
             expected_args,
             found_args,
             true,
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 9e45793..24db25a 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -1,4 +1,4 @@
-use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId};
+use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorReported};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit;
@@ -8,7 +8,6 @@
 use rustc_middle::ty::subst::{InternalSubsts, Subst};
 use rustc_middle::ty::util::ExplicitSelf;
 use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt};
-use rustc_middle::util::common::ErrorReported;
 use rustc_span::Span;
 use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
 use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs
index a44a607..72220d9 100644
--- a/src/librustc_typeck/check/dropck.rs
+++ b/src/librustc_typeck/check/dropck.rs
@@ -1,8 +1,7 @@
 use crate::check::regionck::RegionCtxt;
 use crate::hir;
 use crate::hir::def_id::DefId;
-use crate::util::common::ErrorReported;
-use rustc_errors::struct_span_err;
+use rustc_errors::{struct_span_err, ErrorReported};
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{InferOk, RegionckMode, TyCtxtInferExt};
 use rustc_infer::traits::TraitEngineExt as _;
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index bfcb6fe..9c57ffa 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -15,19 +15,19 @@
 use crate::check::Needs;
 use crate::check::TupleArgumentsFlag::DontTupleArguments;
 use crate::type_error_struct;
-use crate::util::common::ErrorReported;
 
 use rustc_ast::ast;
 use rustc_ast::util::lev_distance::find_best_match_for_name;
 use rustc_data_structures::fx::FxHashMap;
+use rustc_errors::ErrorReported;
 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::DefId;
+use rustc_hir::lang_items;
 use rustc_hir::{ExprKind, QPath};
 use rustc_infer::infer;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
-use rustc_middle::middle::lang_items;
 use rustc_middle::ty;
 use rustc_middle::ty::adjustment::{
     Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index ce7166b..05028ff 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -275,7 +275,7 @@
             "fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" => {
                 (1, vec![param(0), param(0)], param(0))
             }
-            "float_to_int_approx_unchecked" => (2, vec![param(0)], param(1)),
+            "float_to_int_unchecked" => (2, vec![param(0)], param(1)),
 
             "assume" => (0, vec![tcx.types.bool], tcx.mk_unit()),
             "likely" => (0, vec![tcx.types.bool], tcx.types.bool),
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index c863208..add706b 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -2,7 +2,6 @@
 //! found or is otherwise invalid.
 
 use crate::check::FnCtxt;
-use crate::middle::lang_items::FnOnceTraitLangItem;
 use rustc_ast::ast;
 use rustc_ast::util::lev_distance;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -11,6 +10,7 @@
 use rustc_hir::def::{DefKind, Namespace, Res};
 use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::intravisit;
+use rustc_hir::lang_items::FnOnceTraitLangItem;
 use rustc_hir::{ExprKind, Node, QPath};
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_middle::hir::map as hir_map;
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 3823efe..293c4fe 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -88,18 +88,19 @@
 pub mod writeback;
 
 use crate::astconv::{AstConv, GenericArgCountMismatch, PathSeg};
-use crate::middle::lang_items;
 use rustc_ast::ast;
 use rustc_ast::util::parser::ExprPrecedence;
 use rustc_attr as attr;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_errors::ErrorReported;
 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE};
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
+use rustc_hir::lang_items;
 use rustc_hir::{ExprKind, GenericArg, HirIdMap, Item, ItemKind, Node, PatKind, QPath};
 use rustc_index::vec::Idx;
 use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
@@ -114,7 +115,6 @@
     Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
 };
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
-use rustc_middle::ty::layout::VariantIdx;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::subst::{
     GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSelfTy, UserSubsts,
@@ -132,6 +132,7 @@
 use rustc_span::source_map::{original_sp, DUMMY_SP};
 use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::{self, BytePos, MultiSpan, Span};
+use rustc_target::abi::VariantIdx;
 use rustc_target::spec::abi::Abi;
 use rustc_trait_selection::infer::InferCtxtExt as _;
 use rustc_trait_selection::opaque_types::{InferCtxtExt as _, OpaqueTypeDecl};
@@ -151,7 +152,7 @@
 use std::slice;
 
 use crate::require_c_abi_if_c_variadic;
-use crate::util::common::{indenter, ErrorReported};
+use crate::util::common::indenter;
 use crate::TypeAndSubsts;
 
 use self::autoderef::Autoderef;
diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
index 7367338..cac9113 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/src/librustc_typeck/check/op.rs
@@ -481,7 +481,7 @@
     }
 
     /// If one of the types is an uncalled function and calling it would yield the other type,
-    /// suggest calling the function. Returns whether a suggestion was given.
+    /// suggest calling the function. Returns `true` if suggestion would apply (even if not given).
     fn add_type_neq_err_label(
         &self,
         err: &mut rustc_errors::DiagnosticBuilder<'_>,
@@ -514,24 +514,20 @@
                 .lookup_op_method(fn_sig.output(), &[other_ty], Op::Binary(op, is_assign))
                 .is_ok()
             {
-                let (variable_snippet, applicability) = if !fn_sig.inputs().is_empty() {
-                    (
-                        format!("{}( /* arguments */ )", source_map.span_to_snippet(span).unwrap()),
-                        Applicability::HasPlaceholders,
-                    )
-                } else {
-                    (
-                        format!("{}()", source_map.span_to_snippet(span).unwrap()),
-                        Applicability::MaybeIncorrect,
-                    )
-                };
+                if let Ok(snippet) = source_map.span_to_snippet(span) {
+                    let (variable_snippet, applicability) = if !fn_sig.inputs().is_empty() {
+                        (format!("{}( /* arguments */ )", snippet), Applicability::HasPlaceholders)
+                    } else {
+                        (format!("{}()", snippet), Applicability::MaybeIncorrect)
+                    };
 
-                err.span_suggestion(
-                    span,
-                    "you might have forgotten to call this function",
-                    variable_snippet,
-                    applicability,
-                );
+                    err.span_suggestion(
+                        span,
+                        "you might have forgotten to call this function",
+                        variable_snippet,
+                        applicability,
+                    );
+                }
                 return true;
             }
         }
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 6419113..b0ff17a 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -7,9 +7,9 @@
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::itemlikevisit::ParItemLikeVisitor;
+use rustc_hir::lang_items;
 use rustc_hir::ItemKind;
-use rustc_middle::middle::lang_items;
-use rustc_middle::ty::subst::{InternalSubsts, Subst};
+use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
 use rustc_middle::ty::trait_def::TraitSpecializationKind;
 use rustc_middle::ty::{
     self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
@@ -864,87 +864,77 @@
                 trace!("check_opaque_types: opaque_ty, {:?}, {:?}", def_id, substs);
                 let generics = tcx.generics_of(def_id);
                 // Only check named `impl Trait` types defined in this crate.
+                // FIXME(eddyb) is  `generics.parent.is_none()` correct? It seems
+                // potentially risky wrt associated types in `impl`s.
                 if generics.parent.is_none() && def_id.is_local() {
                     let opaque_hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
                     if may_define_opaque_type(tcx, fn_def_id, opaque_hir_id) {
                         trace!("check_opaque_types: may define, generics={:#?}", generics);
-                        let mut seen: FxHashMap<_, Vec<_>> = FxHashMap::default();
-                        for (subst, param) in substs.iter().zip(&generics.params) {
-                            match subst.unpack() {
-                                ty::subst::GenericArgKind::Type(ty) => match ty.kind {
-                                    ty::Param(..) => {}
-                                    // Prevent `fn foo() -> Foo<u32>` from being defining.
-                                    _ => {
-                                        tcx.sess
-                                            .struct_span_err(
-                                                span,
-                                                "non-defining opaque type use \
-                                                 in defining scope",
-                                            )
-                                            .span_note(
-                                                tcx.def_span(param.def_id),
-                                                &format!(
-                                                    "used non-generic type {} for \
-                                                     generic parameter",
-                                                    ty,
-                                                ),
-                                            )
-                                            .emit();
-                                    }
-                                },
+                        let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default();
+                        for (i, &arg) in substs.iter().enumerate() {
+                            let arg_is_param = match arg.unpack() {
+                                GenericArgKind::Type(ty) => matches!(ty.kind, ty::Param(_)),
 
-                                ty::subst::GenericArgKind::Lifetime(region) => {
-                                    let param_span = tcx.def_span(param.def_id);
+                                GenericArgKind::Lifetime(region) => {
                                     if let ty::ReStatic = region {
                                         tcx.sess
                                             .struct_span_err(
                                                 span,
-                                                "non-defining opaque type use \
-                                                 in defining scope",
+                                                "non-defining opaque type use in defining scope",
                                             )
                                             .span_label(
-                                                param_span,
+                                                tcx.def_span(generics.param_at(i, tcx).def_id),
                                                 "cannot use static lifetime; use a bound lifetime \
                                                  instead or remove the lifetime parameter from the \
                                                  opaque type",
                                             )
                                             .emit();
-                                    } else {
-                                        seen.entry(region).or_default().push(param_span);
+                                        continue;
                                     }
+
+                                    true
                                 }
 
-                                ty::subst::GenericArgKind::Const(ct) => match ct.val {
-                                    ty::ConstKind::Param(_) => {}
-                                    _ => {
-                                        tcx.sess
-                                            .struct_span_err(
-                                                span,
-                                                "non-defining opaque type use \
-                                                 in defining scope",
-                                            )
-                                            .span_note(
-                                                tcx.def_span(param.def_id),
-                                                &format!(
-                                                    "used non-generic const {} for \
-                                                     generic parameter",
-                                                    ty,
-                                                ),
-                                            )
-                                            .emit();
-                                    }
-                                },
-                            } // match subst
-                        } // for (subst, param)
-                        for (_, spans) in seen {
-                            if spans.len() > 1 {
+                                GenericArgKind::Const(ct) => {
+                                    matches!(ct.val, ty::ConstKind::Param(_))
+                                }
+                            };
+
+                            if arg_is_param {
+                                seen_params.entry(arg).or_default().push(i);
+                            } else {
+                                // Prevent `fn foo() -> Foo<u32>` from being defining.
+                                let opaque_param = generics.param_at(i, tcx);
                                 tcx.sess
                                     .struct_span_err(
                                         span,
-                                        "non-defining opaque type use \
-                                         in defining scope",
+                                        "non-defining opaque type use in defining scope",
                                     )
-                                    .span_note(spans, "lifetime used multiple times")
+                                    .span_note(
+                                        tcx.def_span(opaque_param.def_id),
+                                        &format!(
+                                            "used non-generic {} `{}` for generic parameter",
+                                            opaque_param.kind.descr(),
+                                            arg,
+                                        ),
+                                    )
+                                    .emit();
+                            }
+                        } // for (arg, param)
+
+                        for (_, indices) in seen_params {
+                            if indices.len() > 1 {
+                                let descr = generics.param_at(indices[0], tcx).kind.descr();
+                                let spans: Vec<_> = indices
+                                    .into_iter()
+                                    .map(|i| tcx.def_span(generics.param_at(i, tcx).def_id))
+                                    .collect();
+                                tcx.sess
+                                    .struct_span_err(
+                                        span,
+                                        "non-defining opaque type use in defining scope",
+                                    )
+                                    .span_note(spans, &format!("{} used multiple times", descr))
                                     .emit();
                             }
                         }
diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs
index 32963b6..384a22d 100644
--- a/src/librustc_typeck/coherence/builtin.rs
+++ b/src/librustc_typeck/coherence/builtin.rs
@@ -4,11 +4,11 @@
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_hir::lang_items::UnsizeTraitLangItem;
 use rustc_hir::ItemKind;
 use rustc_infer::infer;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{RegionckMode, TyCtxtInferExt};
-use rustc_middle::middle::lang_items::UnsizeTraitLangItem;
 use rustc_middle::middle::region;
 use rustc_middle::ty::adjustment::CoerceUnsizedInfo;
 use rustc_middle::ty::TypeFoldable;
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 30887f8..13c6670 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -17,7 +17,6 @@
 use crate::astconv::{AstConv, Bounds, SizedByDefault};
 use crate::check::intrinsic::intrinsic_operation_unsafety;
 use crate::constrained_generic_params as cgp;
-use crate::middle::lang_items;
 use crate::middle::resolve_lifetime as rl;
 use rustc_ast::ast;
 use rustc_ast::ast::{Ident, MetaItemKind};
@@ -29,6 +28,7 @@
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
+use rustc_hir::weak_lang_items;
 use rustc_hir::{GenericParamKind, Node, Unsafety};
 use rustc_middle::hir::map::blocks::FnLikeNode;
 use rustc_middle::hir::map::Map;
@@ -2569,7 +2569,7 @@
     if tcx.is_weak_lang_item(id) {
         codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
     }
-    if let Some(name) = lang_items::link_name(&attrs) {
+    if let Some(name) = weak_lang_items::link_name(&attrs) {
         codegen_fn_attrs.export_name = Some(name);
         codegen_fn_attrs.link_name = Some(name);
     }
diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs
index 1d34a58..d45c827 100644
--- a/src/librustc_typeck/collect/type_of.rs
+++ b/src/librustc_typeck/collect/type_of.rs
@@ -1,4 +1,4 @@
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{struct_span_err, Applicability, StashKey};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -7,7 +7,7 @@
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::Node;
 use rustc_middle::hir::map::Map;
-use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
+use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
 use rustc_middle::ty::util::IntTypeExt;
 use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable};
 use rustc_session::parse::feature_err;
@@ -369,13 +369,8 @@
     struct ConstraintLocator<'tcx> {
         tcx: TyCtxt<'tcx>,
         def_id: DefId,
-        // (first found type span, actual type, mapping from the opaque type's generic
-        // parameters to the concrete type's generic parameters)
-        //
-        // The mapping is an index for each use site of a generic parameter in the concrete type
-        //
-        // The indices index into the generic parameters on the opaque type.
-        found: Option<(Span, Ty<'tcx>, Vec<usize>)>,
+        // (first found type span, actual type)
+        found: Option<(Span, Ty<'tcx>)>,
     }
 
     impl ConstraintLocator<'_> {
@@ -407,83 +402,51 @@
 
                 // FIXME(oli-obk): trace the actual span from inference to improve errors.
                 let span = self.tcx.def_span(def_id);
-                // used to quickly look up the position of a generic parameter
-                let mut index_map: FxHashMap<ty::ParamTy, usize> = FxHashMap::default();
-                // Skipping binder is ok, since we only use this to find generic parameters and
-                // their positions.
-                for (idx, subst) in substs.iter().enumerate() {
-                    if let GenericArgKind::Type(ty) = subst.unpack() {
-                        if let ty::Param(p) = ty.kind {
-                            if index_map.insert(p, idx).is_some() {
-                                // There was already an entry for `p`, meaning a generic parameter
-                                // was used twice.
-                                self.tcx.sess.span_err(
-                                    span,
-                                    &format!(
-                                        "defining opaque type use restricts opaque \
-                                         type by using the generic parameter `{}` twice",
-                                        p,
-                                    ),
-                                );
-                                return;
-                            }
-                        } else {
+
+                // HACK(eddyb) this check shouldn't be needed, as `wfcheck`
+                // performs the same checks, in theory, but I've kept it here
+                // using `delay_span_bug`, just in case `wfcheck` slips up.
+                let opaque_generics = self.tcx.generics_of(self.def_id);
+                let mut used_params: FxHashSet<_> = FxHashSet::default();
+                for (i, arg) in substs.iter().enumerate() {
+                    let arg_is_param = match arg.unpack() {
+                        GenericArgKind::Type(ty) => matches!(ty.kind, ty::Param(_)),
+                        GenericArgKind::Lifetime(lt) => {
+                            matches!(lt, ty::ReEarlyBound(_) | ty::ReFree(_))
+                        }
+                        GenericArgKind::Const(ct) => matches!(ct.val, ty::ConstKind::Param(_)),
+                    };
+
+                    if arg_is_param {
+                        if !used_params.insert(arg) {
+                            // There was already an entry for `arg`, meaning a generic parameter
+                            // was used twice.
                             self.tcx.sess.delay_span_bug(
                                 span,
                                 &format!(
-                                    "non-defining opaque ty use in defining scope: {:?}, {:?}",
-                                    concrete_type, substs,
+                                    "defining opaque type use restricts opaque \
+                                     type by using the generic parameter `{}` twice",
+                                    arg,
                                 ),
                             );
                         }
-                    }
-                }
-                // Compute the index within the opaque type for each generic parameter used in
-                // the concrete type.
-                let indices = concrete_type
-                    .subst(self.tcx, substs)
-                    .walk()
-                    .filter_map(|t| match &t.kind {
-                        ty::Param(p) => Some(*index_map.get(p).unwrap()),
-                        _ => None,
-                    })
-                    .collect();
-                let is_param = |ty: Ty<'_>| match ty.kind {
-                    ty::Param(_) => true,
-                    _ => false,
-                };
-                let bad_substs: Vec<_> = substs
-                    .iter()
-                    .enumerate()
-                    .filter_map(|(i, k)| {
-                        if let GenericArgKind::Type(ty) = k.unpack() { Some((i, ty)) } else { None }
-                    })
-                    .filter(|(_, ty)| !is_param(ty))
-                    .collect();
-                if !bad_substs.is_empty() {
-                    let identity_substs = InternalSubsts::identity_for_item(self.tcx, self.def_id);
-                    for (i, bad_subst) in bad_substs {
-                        self.tcx.sess.span_err(
+                    } else {
+                        let param = opaque_generics.param_at(i, self.tcx);
+                        self.tcx.sess.delay_span_bug(
                             span,
                             &format!(
                                 "defining opaque type use does not fully define opaque type: \
-                            generic parameter `{}` is specified as concrete type `{}`",
-                                identity_substs.type_at(i),
-                                bad_subst
+                                 generic parameter `{}` is specified as concrete {} `{}`",
+                                param.name,
+                                param.kind.descr(),
+                                arg,
                             ),
                         );
                     }
-                } else if let Some((prev_span, prev_ty, ref prev_indices)) = self.found {
-                    let mut ty = concrete_type.walk().fuse();
-                    let mut p_ty = prev_ty.walk().fuse();
-                    let iter_eq = (&mut ty).zip(&mut p_ty).all(|(t, p)| match (&t.kind, &p.kind) {
-                        // Type parameters are equal to any other type parameter for the purpose of
-                        // concrete type equality, as it is possible to obtain the same type just
-                        // by passing matching parameters to a function.
-                        (ty::Param(_), ty::Param(_)) => true,
-                        _ => t == p,
-                    });
-                    if !iter_eq || ty.next().is_some() || p_ty.next().is_some() {
+                }
+
+                if let Some((prev_span, prev_ty)) = self.found {
+                    if *concrete_type != prev_ty {
                         debug!("find_opaque_ty_constraints: span={:?}", span);
                         // Found different concrete types for the opaque type.
                         let mut err = self.tcx.sess.struct_span_err(
@@ -496,34 +459,9 @@
                         );
                         err.span_note(prev_span, "previous use here");
                         err.emit();
-                    } else if indices != *prev_indices {
-                        // Found "same" concrete types, but the generic parameter order differs.
-                        let mut err = self.tcx.sess.struct_span_err(
-                            span,
-                            "concrete type's generic parameters differ from previous defining use",
-                        );
-                        use std::fmt::Write;
-                        let mut s = String::new();
-                        write!(s, "expected [").unwrap();
-                        let list = |s: &mut String, indices: &Vec<usize>| {
-                            let mut indices = indices.iter().cloned();
-                            if let Some(first) = indices.next() {
-                                write!(s, "`{}`", substs[first]).unwrap();
-                                for i in indices {
-                                    write!(s, ", `{}`", substs[i]).unwrap();
-                                }
-                            }
-                        };
-                        list(&mut s, prev_indices);
-                        write!(s, "], got [").unwrap();
-                        list(&mut s, &indices);
-                        write!(s, "]").unwrap();
-                        err.span_label(span, s);
-                        err.span_note(prev_span, "previous use here");
-                        err.emit();
                     }
                 } else {
-                    self.found = Some((span, concrete_type, indices));
+                    self.found = Some((span, concrete_type));
                 }
             } else {
                 debug!(
@@ -606,7 +544,7 @@
     }
 
     match locator.found {
-        Some((_, ty, _)) => ty,
+        Some((_, ty)) => ty,
         None => {
             let span = tcx.def_span(def_id);
             tcx.sess.span_err(span, "could not find defining uses");
@@ -655,7 +593,11 @@
         }
     }
 
-    ty
+    // Typeck doesn't expect erased regions to be returned from `type_of`.
+    tcx.fold_regions(&ty, &mut false, |r, _| match r {
+        ty::ReErased => tcx.lifetimes.re_static,
+        _ => r,
+    })
 }
 
 fn report_assoc_ty_on_inherent_impl(tcx: TyCtxt<'_>, span: Span) {
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 1927b9c..7ea6c1c 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -89,7 +89,7 @@
 mod structured_errors;
 mod variance;
 
-use rustc_errors::struct_span_err;
+use rustc_errors::{struct_span_err, ErrorReported};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::Node;
@@ -100,7 +100,6 @@
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::util;
-use rustc_middle::util::common::ErrorReported;
 use rustc_session::config::EntryFnType;
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::spec::abi::Abi;
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 9f327b0..73df844 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -1,5 +1,6 @@
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
+use rustc_hir::lang_items;
 use rustc_middle::ty::{self, Region, RegionVid, TypeFoldable};
 use rustc_trait_selection::traits::auto_trait::{self, AutoTraitResult};
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index f8e44bc..f411148 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -17,7 +17,6 @@
 use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
-use rustc_middle::middle::lang_items;
 use rustc_middle::middle::resolve_lifetime as rl;
 use rustc_middle::middle::stability;
 use rustc_middle::ty::fold::TypeFolder;
@@ -33,7 +32,6 @@
 use std::default::Default;
 use std::hash::Hash;
 use std::rc::Rc;
-use std::u32;
 use std::{mem, vec};
 
 use crate::core::{self, DocContext, ImplTraitParam};
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 7b3fd82..2e5ecac 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -15,15 +15,15 @@
 use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::{CrateNum, DefId};
+use rustc_hir::lang_items;
 use rustc_hir::Mutability;
 use rustc_index::vec::IndexVec;
-use rustc_middle::middle::lang_items;
 use rustc_middle::middle::stability;
-use rustc_middle::ty::layout::VariantIdx;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::source_map::DUMMY_SP;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{self, FileName};
+use rustc_target::abi::VariantIdx;
 use rustc_target::spec::abi::Abi;
 
 use crate::clean::cfg::Cfg;
diff --git a/src/librustdoc/passes/unindent_comments.rs b/src/librustdoc/passes/unindent_comments.rs
index d4e09ce..5604a9c 100644
--- a/src/librustdoc/passes/unindent_comments.rs
+++ b/src/librustdoc/passes/unindent_comments.rs
@@ -1,6 +1,5 @@
 use std::cmp;
 use std::string::String;
-use std::usize;
 
 use crate::clean::{self, DocFragment, Item};
 use crate::core::DocContext;
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index f9e9a07..7841d5e 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -1,12 +1,12 @@
 use rustc_ast::ast;
 use rustc_ast::with_globals;
 use rustc_data_structures::sync::Lrc;
+use rustc_errors::ErrorReported;
 use rustc_feature::UnstableFeatures;
 use rustc_hir as hir;
 use rustc_hir::intravisit;
 use rustc_interface::interface;
 use rustc_middle::hir::map::Map;
-use rustc_middle::util::common::ErrorReported;
 use rustc_session::{self, config, DiagnosticOutput, Session};
 use rustc_span::edition::Edition;
 use rustc_span::source_map::SourceMap;
diff --git a/src/librustdoc/theme.rs b/src/librustdoc/theme.rs
index 9dd1d37..c8eb271 100644
--- a/src/librustdoc/theme.rs
+++ b/src/librustdoc/theme.rs
@@ -8,18 +8,6 @@
 #[cfg(test)]
 mod tests;
 
-macro_rules! try_something {
-    ($e:expr, $diag:expr, $out:expr) => {{
-        match $e {
-            Ok(c) => c,
-            Err(e) => {
-                $diag.struct_err(&e.to_string()).emit();
-                return $out;
-            }
-        }
-    }};
-}
-
 #[derive(Debug, Clone, Eq)]
 pub struct CssPath {
     pub name: String,
@@ -265,7 +253,13 @@
     against: &CssPath,
     diag: &Handler,
 ) -> (bool, Vec<String>) {
-    let data = try_something!(fs::read(f), diag, (false, vec![]));
+    let data = match fs::read(f) {
+        Ok(c) => c,
+        Err(e) => {
+            diag.struct_err(&e.to_string()).emit();
+            return (false, vec![]);
+        }
+    };
 
     let paths = load_css_paths(&data);
     let mut ret = vec![];
diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs
index 8c6548c..e80d16b 100644
--- a/src/libserialize/serialize.rs
+++ b/src/libserialize/serialize.rs
@@ -706,6 +706,30 @@
     }
 }
 
+impl Encodable for [u8; 20] {
+    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+        s.emit_seq(self.len(), |s| {
+            for (i, e) in self.iter().enumerate() {
+                s.emit_seq_elt(i, |s| e.encode(s))?
+            }
+            Ok(())
+        })
+    }
+}
+
+impl Decodable for [u8; 20] {
+    fn decode<D: Decoder>(d: &mut D) -> Result<[u8; 20], D::Error> {
+        d.read_seq(|d, len| {
+            assert!(len == 20);
+            let mut v = [0u8; 20];
+            for i in 0..len {
+                v[i] = d.read_seq_elt(i, |d| Decodable::decode(d))?;
+            }
+            Ok(v)
+        })
+    }
+}
+
 impl<'a, T: Encodable> Encodable for Cow<'a, [T]>
 where
     [T]: ToOwned<Owned = Vec<T>>,
diff --git a/src/libserialize/tests/json.rs b/src/libserialize/tests/json.rs
index c16426b..688bddc 100644
--- a/src/libserialize/tests/json.rs
+++ b/src/libserialize/tests/json.rs
@@ -17,7 +17,6 @@
 use std::collections::BTreeMap;
 use std::io::prelude::*;
 use std::string;
-use std::{f32, f64, i64, u64};
 use Animal::*;
 
 #[derive(RustcDecodable, Eq, PartialEq, Debug)]
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 0dd2f79..3a83f3f 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -41,7 +41,7 @@
 fortanix-sgx-abi = { version = "0.3.2", features = ['rustc-dep-of-std'] }
 
 [target.'cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_os = "hermit"))'.dependencies]
-hermit-abi = { version = "0.1", features = ['rustc-dep-of-std'] }
+hermit-abi = { version = "0.1.10", features = ['rustc-dep-of-std'] }
 
 [target.wasm32-wasi.dependencies]
 wasi = { version = "0.9.0", features = ['rustc-dep-of-std'], default-features = false }
diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs
index bbbf6f7..9840cfa 100644
--- a/src/libstd/alloc.rs
+++ b/src/libstd/alloc.rs
@@ -289,10 +289,10 @@
 pub mod __default_lib_allocator {
     use super::{GlobalAlloc, Layout, System};
     // These magic symbol names are used as a fallback for implementing the
-    // `__rust_alloc` etc symbols (see `src/liballoc/alloc.rs) when there is
+    // `__rust_alloc` etc symbols (see `src/liballoc/alloc.rs`) when there is
     // no `#[global_allocator]` attribute.
 
-    // for symbol names src/librustc_middle/middle/allocator.rs
+    // for symbol names src/librustc_ast/expand/allocator.rs
     // for signatures src/librustc_allocator/lib.rs
 
     // linkage directives are provided as part of the current compiler allocator
diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index 20425ae..6527327 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -112,8 +112,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let x = 3.6_f32;
     /// let y = -3.6_f32;
     /// let abs_difference_x = (x.fract() - 0.6).abs();
@@ -135,8 +133,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let x = 3.5_f32;
     /// let y = -3.5_f32;
     ///
@@ -164,8 +160,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let f = 3.5_f32;
     ///
     /// assert_eq!(f.signum(), 1.0);
@@ -190,8 +184,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let f = 3.5_f32;
     ///
     /// assert_eq!(f.copysign(0.42), 3.5_f32);
@@ -217,8 +209,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let m = 10.0_f32;
     /// let x = 4.0_f32;
     /// let b = 60.0_f32;
@@ -284,7 +274,7 @@
     /// assert_eq!(a.rem_euclid(-b), 3.0);
     /// assert_eq!((-a).rem_euclid(-b), 1.0);
     /// // limitation due to round-off error
-    /// assert!((-std::f32::EPSILON).rem_euclid(3.0) != 0.0);
+    /// assert!((-f32::EPSILON).rem_euclid(3.0) != 0.0);
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[inline]
@@ -301,8 +291,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let x = 2.0_f32;
     /// let abs_difference = (x.powi(2) - (x * x)).abs();
     ///
@@ -320,8 +308,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let x = 2.0_f32;
     /// let abs_difference = (x.powf(2.0) - (x * x)).abs();
     ///
@@ -341,8 +327,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let positive = 4.0_f32;
     /// let negative = -4.0_f32;
     ///
@@ -363,8 +347,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let one = 1.0f32;
     /// // e^1
     /// let e = one.exp();
@@ -386,8 +368,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let f = 2.0f32;
     ///
     /// // 2^2 - 4 == 0
@@ -407,8 +387,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let one = 1.0f32;
     /// // e^1
     /// let e = one.exp();
@@ -434,8 +412,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let five = 5.0f32;
     ///
     /// // log5(5) - 1 == 0
@@ -455,8 +431,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let two = 2.0f32;
     ///
     /// // log2(2) - 1 == 0
@@ -479,8 +453,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let ten = 10.0f32;
     ///
     /// // log10(10) - 1 == 0
@@ -503,8 +475,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let x = 3.0f32;
     /// let y = -3.0f32;
     ///
@@ -536,8 +506,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let x = 8.0f32;
     ///
     /// // x^(1/3) - 2 == 0
@@ -558,8 +526,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let x = 2.0f32;
     /// let y = 3.0f32;
     ///
@@ -580,9 +546,7 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
-    /// let x = f32::consts::FRAC_PI_2;
+    /// let x = std::f32::consts::FRAC_PI_2;
     ///
     /// let abs_difference = (x.sin() - 1.0).abs();
     ///
@@ -600,9 +564,7 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
-    /// let x = 2.0 * f32::consts::PI;
+    /// let x = 2.0 * std::f32::consts::PI;
     ///
     /// let abs_difference = (x.cos() - 1.0).abs();
     ///
@@ -620,9 +582,7 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
-    /// let x = f32::consts::FRAC_PI_4;
+    /// let x = std::f32::consts::FRAC_PI_4;
     /// let abs_difference = (x.tan() - 1.0).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
@@ -641,12 +601,10 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
-    /// let f = f32::consts::FRAC_PI_2;
+    /// let f = std::f32::consts::FRAC_PI_2;
     ///
     /// // asin(sin(pi/2))
-    /// let abs_difference = (f.sin().asin() - f32::consts::FRAC_PI_2).abs();
+    /// let abs_difference = (f.sin().asin() - std::f32::consts::FRAC_PI_2).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
@@ -664,12 +622,10 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
-    /// let f = f32::consts::FRAC_PI_4;
+    /// let f = std::f32::consts::FRAC_PI_4;
     ///
     /// // acos(cos(pi/4))
-    /// let abs_difference = (f.cos().acos() - f32::consts::FRAC_PI_4).abs();
+    /// let abs_difference = (f.cos().acos() - std::f32::consts::FRAC_PI_4).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
@@ -686,8 +642,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let f = 1.0f32;
     ///
     /// // atan(tan(1))
@@ -712,8 +666,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// // Positive angles measured counter-clockwise
     /// // from positive x axis
     /// // -pi/4 radians (45 deg clockwise)
@@ -724,8 +676,8 @@
     /// let x2 = -3.0f32;
     /// let y2 = 3.0f32;
     ///
-    /// let abs_difference_1 = (y1.atan2(x1) - (-f32::consts::FRAC_PI_4)).abs();
-    /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * f32::consts::FRAC_PI_4)).abs();
+    /// let abs_difference_1 = (y1.atan2(x1) - (-std::f32::consts::FRAC_PI_4)).abs();
+    /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * std::f32::consts::FRAC_PI_4)).abs();
     ///
     /// assert!(abs_difference_1 <= f32::EPSILON);
     /// assert!(abs_difference_2 <= f32::EPSILON);
@@ -743,9 +695,7 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
-    /// let x = f32::consts::FRAC_PI_4;
+    /// let x = std::f32::consts::FRAC_PI_4;
     /// let f = x.sin_cos();
     ///
     /// let abs_difference_0 = (f.0 - x.sin()).abs();
@@ -766,8 +716,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let x = 6.0f32;
     ///
     /// // e^(ln(6)) - 1
@@ -788,9 +736,7 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
-    /// let x = f32::consts::E - 1.0;
+    /// let x = std::f32::consts::E - 1.0;
     ///
     /// // ln(1 + (e - 1)) == ln(e) == 1
     /// let abs_difference = (x.ln_1p() - 1.0).abs();
@@ -809,9 +755,7 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
-    /// let e = f32::consts::E;
+    /// let e = std::f32::consts::E;
     /// let x = 1.0f32;
     ///
     /// let f = x.sinh();
@@ -833,9 +777,7 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
-    /// let e = f32::consts::E;
+    /// let e = std::f32::consts::E;
     /// let x = 1.0f32;
     /// let f = x.cosh();
     /// // Solving cosh() at 1 gives this result
@@ -857,9 +799,7 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
-    /// let e = f32::consts::E;
+    /// let e = std::f32::consts::E;
     /// let x = 1.0f32;
     ///
     /// let f = x.tanh();
@@ -881,8 +821,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let x = 1.0f32;
     /// let f = x.sinh().asinh();
     ///
@@ -906,8 +844,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
     /// let x = 1.0f32;
     /// let f = x.cosh().acosh();
     ///
@@ -927,9 +863,7 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
-    ///
-    /// let e = f32::consts::E;
+    /// let e = std::f32::consts::E;
     /// let f = e.tanh().atanh();
     ///
     /// let abs_difference = (f - e).abs();
@@ -962,7 +896,7 @@
     /// assert!((-3.0f32).clamp(-2.0, 1.0) == -2.0);
     /// assert!((0.0f32).clamp(-2.0, 1.0) == 0.0);
     /// assert!((2.0f32).clamp(-2.0, 1.0) == 1.0);
-    /// assert!((std::f32::NAN).clamp(-2.0, 1.0).is_nan());
+    /// assert!((f32::NAN).clamp(-2.0, 1.0).is_nan());
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[unstable(feature = "clamp", issue = "44095")]
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index a1128a5..ff222fc 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -133,8 +133,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f64;
-    ///
     /// let x = 3.5_f64;
     /// let y = -3.5_f64;
     ///
@@ -162,8 +160,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f64;
-    ///
     /// let f = 3.5_f64;
     ///
     /// assert_eq!(f.signum(), 1.0);
@@ -188,8 +184,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f64;
-    ///
     /// let f = 3.5_f64;
     ///
     /// assert_eq!(f.copysign(0.42), 3.5_f64);
@@ -280,7 +274,7 @@
     /// assert_eq!(a.rem_euclid(-b), 3.0);
     /// assert_eq!((-a).rem_euclid(-b), 1.0);
     /// // limitation due to round-off error
-    /// assert!((-std::f64::EPSILON).rem_euclid(3.0) != 0.0);
+    /// assert!((-f64::EPSILON).rem_euclid(3.0) != 0.0);
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[inline]
@@ -554,9 +548,7 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f64;
-    ///
-    /// let x = f64::consts::FRAC_PI_2;
+    /// let x = std::f64::consts::FRAC_PI_2;
     ///
     /// let abs_difference = (x.sin() - 1.0).abs();
     ///
@@ -574,9 +566,7 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f64;
-    ///
-    /// let x = 2.0 * f64::consts::PI;
+    /// let x = 2.0 * std::f64::consts::PI;
     ///
     /// let abs_difference = (x.cos() - 1.0).abs();
     ///
@@ -594,9 +584,7 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f64;
-    ///
-    /// let x = f64::consts::FRAC_PI_4;
+    /// let x = std::f64::consts::FRAC_PI_4;
     /// let abs_difference = (x.tan() - 1.0).abs();
     ///
     /// assert!(abs_difference < 1e-14);
@@ -615,12 +603,10 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f64;
-    ///
-    /// let f = f64::consts::FRAC_PI_2;
+    /// let f = std::f64::consts::FRAC_PI_2;
     ///
     /// // asin(sin(pi/2))
-    /// let abs_difference = (f.sin().asin() - f64::consts::FRAC_PI_2).abs();
+    /// let abs_difference = (f.sin().asin() - std::f64::consts::FRAC_PI_2).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
@@ -638,12 +624,10 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f64;
-    ///
-    /// let f = f64::consts::FRAC_PI_4;
+    /// let f = std::f64::consts::FRAC_PI_4;
     ///
     /// // acos(cos(pi/4))
-    /// let abs_difference = (f.cos().acos() - f64::consts::FRAC_PI_4).abs();
+    /// let abs_difference = (f.cos().acos() - std::f64::consts::FRAC_PI_4).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
@@ -684,8 +668,6 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f64;
-    ///
     /// // Positive angles measured counter-clockwise
     /// // from positive x axis
     /// // -pi/4 radians (45 deg clockwise)
@@ -696,8 +678,8 @@
     /// let x2 = -3.0_f64;
     /// let y2 = 3.0_f64;
     ///
-    /// let abs_difference_1 = (y1.atan2(x1) - (-f64::consts::FRAC_PI_4)).abs();
-    /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * f64::consts::FRAC_PI_4)).abs();
+    /// let abs_difference_1 = (y1.atan2(x1) - (-std::f64::consts::FRAC_PI_4)).abs();
+    /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * std::f64::consts::FRAC_PI_4)).abs();
     ///
     /// assert!(abs_difference_1 < 1e-10);
     /// assert!(abs_difference_2 < 1e-10);
@@ -715,9 +697,7 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f64;
-    ///
-    /// let x = f64::consts::FRAC_PI_4;
+    /// let x = std::f64::consts::FRAC_PI_4;
     /// let f = x.sin_cos();
     ///
     /// let abs_difference_0 = (f.0 - x.sin()).abs();
@@ -758,9 +738,7 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f64;
-    ///
-    /// let x = f64::consts::E - 1.0;
+    /// let x = std::f64::consts::E - 1.0;
     ///
     /// // ln(1 + (e - 1)) == ln(e) == 1
     /// let abs_difference = (x.ln_1p() - 1.0).abs();
@@ -779,9 +757,7 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f64;
-    ///
-    /// let e = f64::consts::E;
+    /// let e = std::f64::consts::E;
     /// let x = 1.0_f64;
     ///
     /// let f = x.sinh();
@@ -803,9 +779,7 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f64;
-    ///
-    /// let e = f64::consts::E;
+    /// let e = std::f64::consts::E;
     /// let x = 1.0_f64;
     /// let f = x.cosh();
     /// // Solving cosh() at 1 gives this result
@@ -827,9 +801,7 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f64;
-    ///
-    /// let e = f64::consts::E;
+    /// let e = std::f64::consts::E;
     /// let x = 1.0_f64;
     ///
     /// let f = x.tanh();
@@ -893,9 +865,7 @@
     /// # Examples
     ///
     /// ```
-    /// use std::f64;
-    ///
-    /// let e = f64::consts::E;
+    /// let e = std::f64::consts::E;
     /// let f = e.tanh().atanh();
     ///
     /// let abs_difference = (f - e).abs();
@@ -928,7 +898,7 @@
     /// assert!((-3.0f64).clamp(-2.0, 1.0) == -2.0);
     /// assert!((0.0f64).clamp(-2.0, 1.0) == 0.0);
     /// assert!((2.0f64).clamp(-2.0, 1.0) == 1.0);
-    /// assert!((std::f64::NAN).clamp(-2.0, 1.0).is_nan());
+    /// assert!((f64::NAN).clamp(-2.0, 1.0).is_nan());
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[unstable(feature = "clamp", issue = "44095")]
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index e20fcfa..119bdfc 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -734,7 +734,7 @@
     /// let file = options.read(true).open("foo.txt");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn new() -> OpenOptions {
+    pub fn new() -> Self {
         OpenOptions(fs_imp::OpenOptions::new())
     }
 
@@ -751,7 +751,7 @@
     /// let file = OpenOptions::new().read(true).open("foo.txt");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn read(&mut self, read: bool) -> &mut OpenOptions {
+    pub fn read(&mut self, read: bool) -> &mut Self {
         self.0.read(read);
         self
     }
@@ -772,7 +772,7 @@
     /// let file = OpenOptions::new().write(true).open("foo.txt");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn write(&mut self, write: bool) -> &mut OpenOptions {
+    pub fn write(&mut self, write: bool) -> &mut Self {
         self.0.write(write);
         self
     }
@@ -819,7 +819,7 @@
     /// let file = OpenOptions::new().append(true).open("foo.txt");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn append(&mut self, append: bool) -> &mut OpenOptions {
+    pub fn append(&mut self, append: bool) -> &mut Self {
         self.0.append(append);
         self
     }
@@ -839,7 +839,7 @@
     /// let file = OpenOptions::new().write(true).truncate(true).open("foo.txt");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn truncate(&mut self, truncate: bool) -> &mut OpenOptions {
+    pub fn truncate(&mut self, truncate: bool) -> &mut Self {
         self.0.truncate(truncate);
         self
     }
@@ -860,7 +860,7 @@
     /// let file = OpenOptions::new().write(true).create(true).open("foo.txt");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn create(&mut self, create: bool) -> &mut OpenOptions {
+    pub fn create(&mut self, create: bool) -> &mut Self {
         self.0.create(create);
         self
     }
@@ -893,7 +893,7 @@
     ///                              .open("foo.txt");
     /// ```
     #[stable(feature = "expand_open_options2", since = "1.9.0")]
-    pub fn create_new(&mut self, create_new: bool) -> &mut OpenOptions {
+    pub fn create_new(&mut self, create_new: bool) -> &mut Self {
         self.0.create_new(create_new);
         self
     }
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index ff8f673..a9a519f 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -517,20 +517,8 @@
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow(deprecated, deprecated_in_future)]
 pub use core::{
-    // Stable
-    assert_eq,
-    assert_ne,
-    debug_assert,
-    debug_assert_eq,
-    debug_assert_ne,
-    // Unstable
-    matches,
-    r#try,
-    todo,
-    unimplemented,
-    unreachable,
-    write,
-    writeln,
+    assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, matches, r#try, todo,
+    unimplemented, unreachable, write, writeln,
 };
 
 // Re-export built-in macros defined through libcore.
diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs
index adad90f..e0ceb9f 100644
--- a/src/libstd/primitive_docs.rs
+++ b/src/libstd/primitive_docs.rs
@@ -320,7 +320,7 @@
 
 #[doc(primitive = "unit")]
 //
-/// The `()` type, sometimes called "unit" or "nil".
+/// The `()` type, also called "unit".
 ///
 /// The `()` type has exactly one value `()`, and is used when there
 /// is no other meaningful value that could be returned. `()` is most
diff --git a/src/libstd/sync/mpsc/shared.rs b/src/libstd/sync/mpsc/shared.rs
index 2b03935..c4e9296 100644
--- a/src/libstd/sync/mpsc/shared.rs
+++ b/src/libstd/sync/mpsc/shared.rs
@@ -12,7 +12,6 @@
 
 use core::cmp;
 use core::intrinsics::abort;
-use core::isize;
 
 use crate::cell::UnsafeCell;
 use crate::ptr;
diff --git a/src/libstd/sync/mpsc/stream.rs b/src/libstd/sync/mpsc/stream.rs
index 2e3270e..f33493e 100644
--- a/src/libstd/sync/mpsc/stream.rs
+++ b/src/libstd/sync/mpsc/stream.rs
@@ -11,7 +11,6 @@
 pub use self::UpgradeResult::*;
 
 use core::cmp;
-use core::isize;
 
 use crate::cell::UnsafeCell;
 use crate::ptr;
diff --git a/src/libstd/sync/mpsc/sync.rs b/src/libstd/sync/mpsc/sync.rs
index 79e8681..3e20507 100644
--- a/src/libstd/sync/mpsc/sync.rs
+++ b/src/libstd/sync/mpsc/sync.rs
@@ -26,7 +26,6 @@
 pub use self::Failure::*;
 
 use core::intrinsics::abort;
-use core::isize;
 use core::mem;
 use core::ptr;
 
diff --git a/src/libstd/sys/cloudabi/stack_overflow.rs b/src/libstd/sys/cloudabi/stack_overflow.rs
index e97831b..9339b14 100644
--- a/src/libstd/sys/cloudabi/stack_overflow.rs
+++ b/src/libstd/sys/cloudabi/stack_overflow.rs
@@ -1,13 +1,5 @@
 #![cfg_attr(test, allow(dead_code))]
 
-pub struct Handler;
-
-impl Handler {
-    pub unsafe fn new() -> Handler {
-        Handler
-    }
-}
-
 pub unsafe fn init() {}
 
 pub unsafe fn cleanup() {}
diff --git a/src/libstd/sys/cloudabi/thread.rs b/src/libstd/sys/cloudabi/thread.rs
index 3afcae7..a15dc86 100644
--- a/src/libstd/sys/cloudabi/thread.rs
+++ b/src/libstd/sys/cloudabi/thread.rs
@@ -5,7 +5,6 @@
 use crate::ptr;
 use crate::sys::cloudabi::abi;
 use crate::sys::time::checked_dur2intervals;
-use crate::sys_common::thread::*;
 use crate::time::Duration;
 
 pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024;
@@ -22,7 +21,7 @@
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
     pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
-        let p = box p;
+        let p = Box::into_raw(box p);
         let mut native: libc::pthread_t = mem::zeroed();
         let mut attr: libc::pthread_attr_t = mem::zeroed();
         assert_eq!(libc::pthread_attr_init(&mut attr), 0);
@@ -30,19 +29,25 @@
         let stack_size = cmp::max(stack, min_stack_size(&attr));
         assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0);
 
-        let ret = libc::pthread_create(&mut native, &attr, thread_start, &*p as *const _ as *mut _);
+        let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _);
+        // Note: if the thread creation fails and this assert fails, then p will
+        // be leaked. However, an alternative design could cause double-free
+        // which is clearly worse.
         assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
 
         return if ret != 0 {
+            // The thread failed to start and as a result p was not consumed. Therefore, it is
+            // safe to reconstruct the box so that it gets deallocated.
+            drop(Box::from_raw(p));
             Err(io::Error::from_raw_os_error(ret))
         } else {
-            mem::forget(p); // ownership passed to pthread_create
             Ok(Thread { id: native })
         };
 
         extern "C" fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
             unsafe {
-                start_thread(main as *mut u8);
+                // Let's run some code.
+                Box::from_raw(main as *mut Box<dyn FnOnce()>)();
             }
             ptr::null_mut()
         }
diff --git a/src/libstd/sys/hermit/fast_thread_local.rs b/src/libstd/sys/hermit/fast_thread_local.rs
index 1108e25..9b683fc 100644
--- a/src/libstd/sys/hermit/fast_thread_local.rs
+++ b/src/libstd/sys/hermit/fast_thread_local.rs
@@ -1,4 +1,36 @@
 #![cfg(target_thread_local)]
 #![unstable(feature = "thread_local_internals", issue = "none")]
 
-pub use crate::sys_common::thread_local::register_dtor_fallback as register_dtor;
+// Simplify dtor registration by using a list of destructors.
+// The this solution works like the implementation of macOS and
+// doesn't additional OS support
+
+use crate::cell::Cell;
+use crate::ptr;
+
+#[thread_local]
+static DTORS: Cell<*mut List> = Cell::new(ptr::null_mut());
+
+type List = Vec<(*mut u8, unsafe extern "C" fn(*mut u8))>;
+
+pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
+    if DTORS.get().is_null() {
+        let v: Box<List> = box Vec::new();
+        DTORS.set(Box::into_raw(v));
+    }
+
+    let list: &mut List = &mut *DTORS.get();
+    list.push((t, dtor));
+}
+
+// every thread call this function to run through all possible destructors
+pub unsafe fn run_dtors() {
+    let mut ptr = DTORS.replace(ptr::null_mut());
+    while !ptr.is_null() {
+        let list = Box::from_raw(ptr);
+        for (ptr, dtor) in list.into_iter() {
+            dtor(ptr);
+        }
+        ptr = DTORS.replace(ptr::null_mut());
+    }
+}
diff --git a/src/libstd/sys/hermit/fs.rs b/src/libstd/sys/hermit/fs.rs
index 37ac598..287a039 100644
--- a/src/libstd/sys/hermit/fs.rs
+++ b/src/libstd/sys/hermit/fs.rs
@@ -6,6 +6,7 @@
 use crate::path::{Path, PathBuf};
 use crate::sys::cvt;
 use crate::sys::hermit::abi;
+use crate::sys::hermit::abi::{O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY};
 use crate::sys::hermit::fd::FileDesc;
 use crate::sys::time::SystemTime;
 use crate::sys::{unsupported, Void};
@@ -17,14 +18,6 @@
 fn cstr(path: &Path) -> io::Result<CString> {
     Ok(CString::new(path.as_os_str().as_bytes())?)
 }
-//const O_ACCMODE: i32 = 00000003;
-const O_RDONLY: i32 = 00000000;
-const O_WRONLY: i32 = 00000001;
-const O_RDWR: i32 = 00000002;
-const O_CREAT: i32 = 00000100;
-const O_EXCL: i32 = 00000200;
-const O_TRUNC: i32 = 00001000;
-const O_APPEND: i32 = 00002000;
 
 #[derive(Debug)]
 pub struct File(FileDesc);
diff --git a/src/libstd/sys/hermit/mod.rs b/src/libstd/sys/hermit/mod.rs
index 1e4a53a..6736d96 100644
--- a/src/libstd/sys/hermit/mod.rs
+++ b/src/libstd/sys/hermit/mod.rs
@@ -93,9 +93,7 @@
 
 #[cfg(not(test))]
 pub fn init() {
-    unsafe {
-        let _ = net::init();
-    }
+    let _ = net::init();
 }
 
 #[cfg(not(test))]
@@ -105,6 +103,7 @@
     argv: *const *const c_char,
     env: *const *const c_char,
 ) -> ! {
+    use crate::sys::hermit::fast_thread_local::run_dtors;
     extern "C" {
         fn main(argc: isize, argv: *const *const c_char) -> i32;
     }
@@ -114,6 +113,7 @@
 
     let result = main(argc as isize, argv);
 
+    run_dtors();
     abi::exit(result);
 }
 
diff --git a/src/libstd/sys/hermit/net.rs b/src/libstd/sys/hermit/net.rs
index 82917e7..377c313 100644
--- a/src/libstd/sys/hermit/net.rs
+++ b/src/libstd/sys/hermit/net.rs
@@ -1,291 +1,362 @@
 use crate::convert::TryFrom;
 use crate::fmt;
-use crate::io::{self, IoSlice, IoSliceMut};
+use crate::io::{self, ErrorKind, IoSlice, IoSliceMut};
 use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
 use crate::str;
+use crate::sys::hermit::abi;
 use crate::sys::{unsupported, Void};
 use crate::time::Duration;
 
-//// Iinitializes HermitCore's network stack
-pub unsafe fn init() -> io::Result<()> {
+/// Checks whether the HermitCore's socket interface has been started already, and
+/// if not, starts it.
+pub fn init() -> io::Result<()> {
+    if abi::network_init() < 0 {
+        return Err(io::Error::new(ErrorKind::Other, "Unable to initialize network interface"));
+    }
+
     Ok(())
 }
 
-pub struct TcpStream(Void);
+pub struct TcpStream(abi::Handle);
 
 impl TcpStream {
-    pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
-        unsupported()
+    pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
+        let addr = addr?;
+
+        match abi::tcpstream::connect(addr.ip().to_string().as_bytes(), addr.port(), None) {
+            Ok(handle) => Ok(TcpStream(handle)),
+            _ => {
+                Err(io::Error::new(ErrorKind::Other, "Unable to initiate a connection on a socket"))
+            }
+        }
     }
 
-    pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
-        unsupported()
+    pub fn connect_timeout(saddr: &SocketAddr, duration: Duration) -> io::Result<TcpStream> {
+        match abi::tcpstream::connect(
+            saddr.ip().to_string().as_bytes(),
+            saddr.port(),
+            Some(duration.as_millis() as u64),
+        ) {
+            Ok(handle) => Ok(TcpStream(handle)),
+            _ => {
+                Err(io::Error::new(ErrorKind::Other, "Unable to initiate a connection on a socket"))
+            }
+        }
     }
 
-    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-        match self.0 {}
+    pub fn set_read_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
+        abi::tcpstream::set_read_timeout(self.0, duration.map(|d| d.as_millis() as u64))
+            .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to set timeout value"))
     }
 
-    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-        match self.0 {}
+    pub fn set_write_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
+        abi::tcpstream::set_write_timeout(self.0, duration.map(|d| d.as_millis() as u64))
+            .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to set timeout value"))
     }
 
     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
-        match self.0 {}
+        let duration = abi::tcpstream::get_read_timeout(self.0)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to determine timeout value"))?;
+
+        Ok(duration.map(|d| Duration::from_millis(d)))
     }
 
     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
-        match self.0 {}
+        let duration = abi::tcpstream::get_write_timeout(self.0)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to determine timeout value"))?;
+
+        Ok(duration.map(|d| Duration::from_millis(d)))
     }
 
-    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
-        match self.0 {}
+    pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
+        abi::tcpstream::peek(self.0, buf)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "set_nodelay failed"))
     }
 
-    pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
-        match self.0 {}
+    pub fn read(&self, buffer: &mut [u8]) -> io::Result<usize> {
+        self.read_vectored(&mut [IoSliceMut::new(buffer)])
     }
 
-    pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        match self.0 {}
+    pub fn read_vectored(&self, ioslice: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        let mut size: usize = 0;
+
+        for i in ioslice.iter_mut() {
+            let mut pos: usize = 0;
+
+            while pos < i.len() {
+                let ret = abi::tcpstream::read(self.0, &mut i[pos..])
+                    .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to read on socket"))?;
+
+                if ret == 0 {
+                    return Ok(size);
+                } else {
+                    size += ret;
+                    pos += ret;
+                }
+            }
+        }
+
+        Ok(size)
     }
 
-    pub fn write(&self, _: &[u8]) -> io::Result<usize> {
-        match self.0 {}
+    pub fn write(&self, buffer: &[u8]) -> io::Result<usize> {
+        self.write_vectored(&[IoSlice::new(buffer)])
     }
 
-    pub fn write_vectored(&self, _: &[IoSlice<'_>]) -> io::Result<usize> {
-        match self.0 {}
+    pub fn write_vectored(&self, ioslice: &[IoSlice<'_>]) -> io::Result<usize> {
+        let mut size: usize = 0;
+
+        for i in ioslice.iter() {
+            size += abi::tcpstream::write(self.0, i)
+                .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to write on socket"))?;
+        }
+
+        Ok(size)
     }
 
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "peer_addr isn't supported"))
     }
 
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "socket_addr isn't supported"))
     }
 
-    pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
-        match self.0 {}
+    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
+        abi::tcpstream::shutdown(self.0, how as i32)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "unable to shutdown socket"))
     }
 
     pub fn duplicate(&self) -> io::Result<TcpStream> {
-        match self.0 {}
+        let handle = abi::tcpstream::duplicate(self.0)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "unable to duplicate stream"))?;
+
+        Ok(TcpStream(handle))
     }
 
-    pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+    pub fn set_nodelay(&self, mode: bool) -> io::Result<()> {
+        abi::tcpstream::set_nodelay(self.0, mode)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "set_nodelay failed"))
     }
 
     pub fn nodelay(&self) -> io::Result<bool> {
-        match self.0 {}
+        abi::tcpstream::nodelay(self.0)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "nodelay failed"))
     }
 
-    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
-        match self.0 {}
+    pub fn set_ttl(&self, tll: u32) -> io::Result<()> {
+        abi::tcpstream::set_tll(self.0, tll)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "unable to set TTL"))
     }
 
     pub fn ttl(&self) -> io::Result<u32> {
-        match self.0 {}
+        abi::tcpstream::get_tll(self.0)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "unable to get TTL"))
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "take_error isn't supported"))
     }
 
-    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+    pub fn set_nonblocking(&self, mode: bool) -> io::Result<()> {
+        abi::tcpstream::set_nonblocking(self.0, mode)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "unable to set blocking mode"))
+    }
+}
+
+impl Drop for TcpStream {
+    fn drop(&mut self) {
+        let _ = abi::tcpstream::close(self.0);
     }
 }
 
 impl fmt::Debug for TcpStream {
     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.0 {}
+        Ok(())
     }
 }
 
-pub struct TcpListener(Void);
+pub struct TcpListener(abi::Handle);
 
 impl TcpListener {
     pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
-        unsupported()
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn duplicate(&self) -> io::Result<TcpListener> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_ttl(&self, _: u32) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn ttl(&self) -> io::Result<u32> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn only_v6(&self) -> io::Result<bool> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 }
 
 impl fmt::Debug for TcpListener {
     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.0 {}
+        Ok(())
     }
 }
 
-pub struct UdpSocket(Void);
+pub struct UdpSocket(abi::Handle);
 
 impl UdpSocket {
     pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
-        unsupported()
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn duplicate(&self) -> io::Result<UdpSocket> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn broadcast(&self) -> io::Result<bool> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn multicast_loop_v4(&self) -> io::Result<bool> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn multicast_loop_v6(&self) -> io::Result<bool> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_ttl(&self, _: u32) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn ttl(&self) -> io::Result<u32> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn send(&self, _: &[u8]) -> io::Result<usize> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 }
 
 impl fmt::Debug for UdpSocket {
     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.0 {}
+        Ok(())
     }
 }
 
diff --git a/src/libstd/sys/hermit/stack_overflow.rs b/src/libstd/sys/hermit/stack_overflow.rs
index 65a1b17..121fe42 100644
--- a/src/libstd/sys/hermit/stack_overflow.rs
+++ b/src/libstd/sys/hermit/stack_overflow.rs
@@ -1,11 +1,3 @@
-pub struct Handler;
-
-impl Handler {
-    pub unsafe fn new() -> Handler {
-        Handler
-    }
-}
-
 #[inline]
 pub unsafe fn init() {}
 
diff --git a/src/libstd/sys/hermit/thread.rs b/src/libstd/sys/hermit/thread.rs
index c3c29c9..7e3fb4c 100644
--- a/src/libstd/sys/hermit/thread.rs
+++ b/src/libstd/sys/hermit/thread.rs
@@ -1,39 +1,14 @@
 #![allow(dead_code)]
 
 use crate::ffi::CStr;
-use crate::fmt;
 use crate::io;
 use crate::mem;
 use crate::sys::hermit::abi;
+use crate::sys::hermit::fast_thread_local::run_dtors;
 use crate::time::Duration;
-use core::u32;
-
-use crate::sys_common::thread::*;
 
 pub type Tid = abi::Tid;
 
-/// Priority of a task
-#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
-pub struct Priority(u8);
-
-impl Priority {
-    pub const fn into(self) -> u8 {
-        self.0
-    }
-
-    pub const fn from(x: u8) -> Self {
-        Priority(x)
-    }
-}
-
-impl fmt::Display for Priority {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", self.0)
-    }
-}
-
-pub const NORMAL_PRIO: Priority = Priority::from(2);
-
 pub struct Thread {
     tid: Tid,
 }
@@ -49,26 +24,32 @@
         p: Box<dyn FnOnce()>,
         core_id: isize,
     ) -> io::Result<Thread> {
-        let p = box p;
+        let p = Box::into_raw(box p);
         let mut tid: Tid = u32::MAX;
         let ret = abi::spawn(
             &mut tid as *mut Tid,
             thread_start,
             &*p as *const _ as *const u8 as usize,
-            Priority::into(NORMAL_PRIO),
+            abi::Priority::into(abi::NORMAL_PRIO),
             core_id,
         );
 
-        return if ret == 0 {
-            mem::forget(p); // ownership passed to pthread_create
-            Ok(Thread { tid: tid })
-        } else {
+        return if ret != 0 {
+            // The thread failed to start and as a result p was not consumed. Therefore, it is
+            // safe to reconstruct the box so that it gets deallocated.
+            drop(Box::from_raw(p));
             Err(io::Error::new(io::ErrorKind::Other, "Unable to create thread!"))
+        } else {
+            Ok(Thread { tid: tid })
         };
 
         extern "C" fn thread_start(main: usize) {
             unsafe {
-                start_thread(main as *mut u8);
+                // Finally, let's run some code.
+                Box::from_raw(main as *mut Box<dyn FnOnce()>)();
+
+                // run all destructors
+                run_dtors();
             }
         }
     }
diff --git a/src/libstd/sys/hermit/thread_local.rs b/src/libstd/sys/hermit/thread_local.rs
index c6f8adb..f8be986 100644
--- a/src/libstd/sys/hermit/thread_local.rs
+++ b/src/libstd/sys/hermit/thread_local.rs
@@ -1,60 +1,26 @@
-#![allow(dead_code)] // not used on all platforms
-
-use crate::collections::BTreeMap;
-use crate::ptr;
-use crate::sync::atomic::{AtomicUsize, Ordering};
-use crate::sys_common::mutex::Mutex;
-
 pub type Key = usize;
 
-type Dtor = unsafe extern "C" fn(*mut u8);
-
-static NEXT_KEY: AtomicUsize = AtomicUsize::new(0);
-
-static mut KEYS: *mut BTreeMap<Key, Option<Dtor>> = ptr::null_mut();
-static KEYS_LOCK: Mutex = Mutex::new();
-
-#[thread_local]
-static mut LOCALS: *mut BTreeMap<Key, *mut u8> = ptr::null_mut();
-
-unsafe fn keys() -> &'static mut BTreeMap<Key, Option<Dtor>> {
-    if KEYS.is_null() {
-        KEYS = Box::into_raw(Box::new(BTreeMap::new()));
-    }
-    &mut *KEYS
-}
-
-unsafe fn locals() -> &'static mut BTreeMap<Key, *mut u8> {
-    if LOCALS.is_null() {
-        LOCALS = Box::into_raw(Box::new(BTreeMap::new()));
-    }
-    &mut *LOCALS
+#[inline]
+pub unsafe fn create(_dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key {
+    panic!("should not be used on the wasm target");
 }
 
 #[inline]
-pub unsafe fn create(dtor: Option<Dtor>) -> Key {
-    let key = NEXT_KEY.fetch_add(1, Ordering::SeqCst);
-    let _guard = KEYS_LOCK.lock();
-    keys().insert(key, dtor);
-    key
+pub unsafe fn set(_key: Key, _value: *mut u8) {
+    panic!("should not be used on the wasm target");
 }
 
 #[inline]
-pub unsafe fn get(key: Key) -> *mut u8 {
-    if let Some(&entry) = locals().get(&key) { entry } else { ptr::null_mut() }
+pub unsafe fn get(_key: Key) -> *mut u8 {
+    panic!("should not be used on the wasm target");
 }
 
 #[inline]
-pub unsafe fn set(key: Key, value: *mut u8) {
-    locals().insert(key, value);
-}
-
-#[inline]
-pub unsafe fn destroy(key: Key) {
-    keys().remove(&key);
+pub unsafe fn destroy(_key: Key) {
+    panic!("should not be used on the wasm target");
 }
 
 #[inline]
 pub fn requires_synchronized_create() -> bool {
-    false
+    panic!("should not be used on the wasm target");
 }
diff --git a/src/libstd/sys/sgx/stack_overflow.rs b/src/libstd/sys/sgx/stack_overflow.rs
index a2d13d1..b96652a 100644
--- a/src/libstd/sys/sgx/stack_overflow.rs
+++ b/src/libstd/sys/sgx/stack_overflow.rs
@@ -1,11 +1,3 @@
-pub struct Handler;
-
-impl Handler {
-    pub unsafe fn new() -> Handler {
-        Handler
-    }
-}
-
 #[cfg_attr(test, allow(dead_code))]
 pub unsafe fn init() {}
 
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 674d4c7..aab5a92 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -3,11 +3,9 @@
 use crate::io;
 use crate::mem;
 use crate::ptr;
-use crate::sys::os;
+use crate::sys::{os, stack_overflow};
 use crate::time::Duration;
 
-use crate::sys_common::thread::*;
-
 #[cfg(not(target_os = "l4re"))]
 pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024;
 #[cfg(target_os = "l4re")]
@@ -43,7 +41,7 @@
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
     pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
-        let p = box p;
+        let p = Box::into_raw(box p);
         let mut native: libc::pthread_t = mem::zeroed();
         let mut attr: libc::pthread_attr_t = mem::zeroed();
         assert_eq!(libc::pthread_attr_init(&mut attr), 0);
@@ -65,19 +63,28 @@
             }
         };
 
-        let ret = libc::pthread_create(&mut native, &attr, thread_start, &*p as *const _ as *mut _);
+        let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _);
+        // Note: if the thread creation fails and this assert fails, then p will
+        // be leaked. However, an alternative design could cause double-free
+        // which is clearly worse.
         assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
 
         return if ret != 0 {
+            // The thread failed to start and as a result p was not consumed. Therefore, it is
+            // safe to reconstruct the box so that it gets deallocated.
+            drop(Box::from_raw(p));
             Err(io::Error::from_raw_os_error(ret))
         } else {
-            mem::forget(p); // ownership passed to pthread_create
             Ok(Thread { id: native })
         };
 
         extern "C" fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
             unsafe {
-                start_thread(main as *mut u8);
+                // Next, set up our stack overflow handler which may get triggered if we run
+                // out of stack.
+                let _handler = stack_overflow::Handler::new();
+                // Finally, let's run some code.
+                Box::from_raw(main as *mut Box<dyn FnOnce()>)();
             }
             ptr::null_mut()
         }
diff --git a/src/libstd/sys/vxworks/thread.rs b/src/libstd/sys/vxworks/thread.rs
index e0d104b..4d0196e 100644
--- a/src/libstd/sys/vxworks/thread.rs
+++ b/src/libstd/sys/vxworks/thread.rs
@@ -3,11 +3,9 @@
 use crate::io;
 use crate::mem;
 use crate::ptr;
-use crate::sys::os;
+use crate::sys::{os, stack_overflow};
 use crate::time::Duration;
 
-use crate::sys_common::thread::*;
-
 pub const DEFAULT_MIN_STACK_SIZE: usize = 0x40000; // 256K
 
 pub struct Thread {
@@ -31,7 +29,7 @@
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
     pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
-        let p = box p;
+        let p = Box::into_raw(box p);
         let mut native: libc::pthread_t = mem::zeroed();
         let mut attr: libc::pthread_attr_t = mem::zeroed();
         assert_eq!(libc::pthread_attr_init(&mut attr), 0);
@@ -53,19 +51,28 @@
             }
         };
 
-        let ret = libc::pthread_create(&mut native, &attr, thread_start, &*p as *const _ as *mut _);
+        let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _);
+        // Note: if the thread creation fails and this assert fails, then p will
+        // be leaked. However, an alternative design could cause double-free
+        // which is clearly worse.
         assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
 
         return if ret != 0 {
+            // The thread failed to start and as a result p was not consumed. Therefore, it is
+            // safe to reconstruct the box so that it gets deallocated.
+            drop(Box::from_raw(p));
             Err(io::Error::from_raw_os_error(ret))
         } else {
-            mem::forget(p); // ownership passed to pthread_create
             Ok(Thread { id: native })
         };
 
         extern "C" fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
             unsafe {
-                start_thread(main as *mut u8);
+                // Next, set up our stack overflow handler which may get triggered if we run
+                // out of stack.
+                let _handler = stack_overflow::Handler::new();
+                // Finally, let's run some code.
+                Box::from_raw(main as *mut Box<dyn FnOnce()>)();
             }
             ptr::null_mut()
         }
diff --git a/src/libstd/sys/wasm/stack_overflow.rs b/src/libstd/sys/wasm/stack_overflow.rs
index cbf62b6..3255539 100644
--- a/src/libstd/sys/wasm/stack_overflow.rs
+++ b/src/libstd/sys/wasm/stack_overflow.rs
@@ -1,11 +1,3 @@
-pub struct Handler;
-
-impl Handler {
-    pub unsafe fn new() -> Handler {
-        Handler
-    }
-}
-
 pub unsafe fn init() {}
 
 pub unsafe fn cleanup() {}
diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs
index c828243..38839ea 100644
--- a/src/libstd/sys/windows/thread.rs
+++ b/src/libstd/sys/windows/thread.rs
@@ -1,10 +1,9 @@
 use crate::ffi::CStr;
 use crate::io;
-use crate::mem;
 use crate::ptr;
 use crate::sys::c;
 use crate::sys::handle::Handle;
-use crate::sys_common::thread::*;
+use crate::sys::stack_overflow;
 use crate::time::Duration;
 
 use libc::c_void;
@@ -20,7 +19,7 @@
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
     pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
-        let p = box p;
+        let p = Box::into_raw(box p);
 
         // FIXME On UNIX, we guard against stack sizes that are too small but
         // that's because pthreads enforces that stacks are at least
@@ -34,21 +33,27 @@
             ptr::null_mut(),
             stack_size,
             thread_start,
-            &*p as *const _ as *mut _,
+            p as *mut _,
             c::STACK_SIZE_PARAM_IS_A_RESERVATION,
             ptr::null_mut(),
         );
 
         return if ret as usize == 0 {
+            // The thread failed to start and as a result p was not consumed. Therefore, it is
+            // safe to reconstruct the box so that it gets deallocated.
+            drop(Box::from_raw(p));
             Err(io::Error::last_os_error())
         } else {
-            mem::forget(p); // ownership passed to CreateThread
             Ok(Thread { handle: Handle::new(ret) })
         };
 
         extern "system" fn thread_start(main: *mut c_void) -> c::DWORD {
             unsafe {
-                start_thread(main as *mut u8);
+                // Next, set up our stack overflow handler which may get triggered if we run
+                // out of stack.
+                let _handler = stack_overflow::Handler::new();
+                // Finally, let's run some code.
+                Box::from_raw(main as *mut Box<dyn FnOnce()>)();
             }
             0
         }
diff --git a/src/libstd/sys_common/thread.rs b/src/libstd/sys_common/thread.rs
index 6ab0d5c..f3a8bef 100644
--- a/src/libstd/sys_common/thread.rs
+++ b/src/libstd/sys_common/thread.rs
@@ -1,18 +1,7 @@
 use crate::env;
 use crate::sync::atomic::{self, Ordering};
-use crate::sys::stack_overflow;
 use crate::sys::thread as imp;
 
-#[allow(dead_code)]
-pub unsafe fn start_thread(main: *mut u8) {
-    // Next, set up our stack overflow handler which may get triggered if we run
-    // out of stack.
-    let _handler = stack_overflow::Handler::new();
-
-    // Finally, let's run some code.
-    Box::from_raw(main as *mut Box<dyn FnOnce()>)()
-}
-
 pub fn min_stack() -> usize {
     static MIN: atomic::AtomicUsize = atomic::AtomicUsize::new(0);
     match MIN.load(Ordering::SeqCst) {
diff --git a/src/llvm-project b/src/llvm-project
index 992e608..027e428 160000
--- a/src/llvm-project
+++ b/src/llvm-project
@@ -1 +1 @@
-Subproject commit 992e608cfc5d1c126a23c640222fd396a3bdeb9f
+Subproject commit 027e428197f3702599cfbb632883768175f49173
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index 799adb4..21094b3 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -640,6 +640,25 @@
   }
 }
 
+enum class LLVMRustChecksumKind {
+  None,
+  MD5,
+  SHA1,
+};
+
+static Optional<DIFile::ChecksumKind> fromRust(LLVMRustChecksumKind Kind) {
+  switch (Kind) {
+  case LLVMRustChecksumKind::None:
+    return None;
+  case LLVMRustChecksumKind::MD5:
+    return DIFile::ChecksumKind::CSK_MD5;
+  case LLVMRustChecksumKind::SHA1:
+    return DIFile::ChecksumKind::CSK_SHA1;
+  default:
+    report_fatal_error("bad ChecksumKind.");
+  }
+}
+
 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
   return DEBUG_METADATA_VERSION;
 }
@@ -686,9 +705,15 @@
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(
     LLVMRustDIBuilderRef Builder,
     const char *Filename, size_t FilenameLen,
-    const char *Directory, size_t DirectoryLen) {
+    const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind,
+    const char *Checksum, size_t ChecksumLen) {
+  Optional<DIFile::ChecksumKind> llvmCSKind = fromRust(CSKind);
+  Optional<DIFile::ChecksumInfo<StringRef>> CSInfo{};
+  if (llvmCSKind)
+    CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen});
   return wrap(Builder->createFile(StringRef(Filename, FilenameLen),
-                                  StringRef(Directory, DirectoryLen)));
+                                  StringRef(Directory, DirectoryLen),
+                                  CSInfo));
 }
 
 extern "C" LLVMMetadataRef
diff --git a/src/test/codegen-units/partitioning/incremental-merging.rs b/src/test/codegen-units/partitioning/incremental-merging.rs
new file mode 100644
index 0000000..ca2df19
--- /dev/null
+++ b/src/test/codegen-units/partitioning/incremental-merging.rs
@@ -0,0 +1,42 @@
+// ignore-tidy-linelength
+// We specify -C incremental here because we want to test the partitioning for
+// incremental compilation
+// compile-flags:-Zprint-mono-items=lazy -Cincremental=tmp/partitioning-tests/incremental-merging
+// compile-flags:-Ccodegen-units=3
+
+#![crate_type = "rlib"]
+
+// This test makes sure that merging of CGUs works together with incremental
+// compilation but at the same time does not modify names of CGUs that were not
+// affected by merging.
+//
+// We expect CGUs `aaa` and `bbb` to be merged (because they are the smallest),
+// while `ccc` and `ddd` are supposed to stay untouched.
+
+pub mod aaa {
+    //~ MONO_ITEM fn incremental_merging::aaa[0]::foo[0] @@ incremental_merging-aaa--incremental_merging-bbb[External]
+    pub fn foo(a: u64) -> u64 {
+        a + 1
+    }
+}
+
+pub mod bbb {
+    //~ MONO_ITEM fn incremental_merging::bbb[0]::foo[0] @@ incremental_merging-aaa--incremental_merging-bbb[External]
+    pub fn foo(a: u64, b: u64) -> u64 {
+        a + b + 1
+    }
+}
+
+pub mod ccc {
+    //~ MONO_ITEM fn incremental_merging::ccc[0]::foo[0] @@ incremental_merging-ccc[External]
+    pub fn foo(a: u64, b: u64, c: u64) -> u64 {
+        a + b + c + 1
+    }
+}
+
+pub mod ddd {
+    //~ MONO_ITEM fn incremental_merging::ddd[0]::foo[0] @@ incremental_merging-ddd[External]
+    pub fn foo(a: u64, b: u64, c: u64, d: u64) -> u64 {
+        a + b + c + d + 1
+    }
+}
diff --git a/src/test/codegen/remap_path_prefix/main.rs b/src/test/codegen/remap_path_prefix/main.rs
index 4724dc3..20475ba 100644
--- a/src/test/codegen/remap_path_prefix/main.rs
+++ b/src/test/codegen/remap_path_prefix/main.rs
@@ -22,7 +22,7 @@
 }
 
 // Here we check that local debuginfo is mapped correctly.
-// CHECK: !DIFile(filename: "/the/src/remap_path_prefix/main.rs", directory: "/the/cwd/")
+// CHECK: !DIFile(filename: "/the/src/remap_path_prefix/main.rs", directory: "/the/cwd/"
 
 // And here that debuginfo from other crates are expanded to absolute paths.
-// CHECK: !DIFile(filename: "/the/aux-src/remap_path_prefix_aux.rs", directory: "")
+// CHECK: !DIFile(filename: "/the/aux-src/remap_path_prefix_aux.rs", directory: ""
diff --git a/src/test/codegen/remap_path_prefix/xcrate-generic.rs b/src/test/codegen/remap_path_prefix/xcrate-generic.rs
index 30d6112..7a9d2ca 100644
--- a/src/test/codegen/remap_path_prefix/xcrate-generic.rs
+++ b/src/test/codegen/remap_path_prefix/xcrate-generic.rs
@@ -11,4 +11,4 @@
 }
 
 // Here we check that local debuginfo is mapped correctly.
-// CHECK: !DIFile(filename: "/the/aux-src/xcrate-generic.rs", directory: "")
+// CHECK: !DIFile(filename: "/the/aux-src/xcrate-generic.rs", directory: ""
diff --git a/src/test/codegen/src-hash-algorithm/src-hash-algorithm-md5.rs b/src/test/codegen/src-hash-algorithm/src-hash-algorithm-md5.rs
new file mode 100644
index 0000000..64be112
--- /dev/null
+++ b/src/test/codegen/src-hash-algorithm/src-hash-algorithm-md5.rs
@@ -0,0 +1,6 @@
+// compile-flags: -g -Z src-hash-algorithm=md5
+
+#![crate_type = "lib"]
+
+pub fn test() {}
+// CHECK: checksumkind: CSK_MD5
diff --git a/src/test/codegen/src-hash-algorithm/src-hash-algorithm-sha1.rs b/src/test/codegen/src-hash-algorithm/src-hash-algorithm-sha1.rs
new file mode 100644
index 0000000..54e0715
--- /dev/null
+++ b/src/test/codegen/src-hash-algorithm/src-hash-algorithm-sha1.rs
@@ -0,0 +1,6 @@
+// compile-flags: -g -Z src-hash-algorithm=sha1
+
+#![crate_type = "lib"]
+
+pub fn test() {}
+// CHECK: checksumkind: CSK_SHA1
diff --git a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs
new file mode 100644
index 0000000..067fa87
--- /dev/null
+++ b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs
@@ -0,0 +1,12 @@
+fn map(x: Option<Box<()>>) -> Option<Box<()>> {
+    match x {
+        None => None,
+        Some(x) => Some(x),
+    }
+}
+
+fn main() {
+    map(None);
+}
+
+// EMIT_MIR rustc.map.SimplifyLocals.diff
diff --git a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/rustc.map.SimplifyLocals.diff b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/rustc.map.SimplifyLocals.diff
new file mode 100644
index 0000000..bba8bc8
--- /dev/null
+++ b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/rustc.map.SimplifyLocals.diff
@@ -0,0 +1,37 @@
+- // MIR for `map` before SimplifyLocals
++ // MIR for `map` after SimplifyLocals
+  
+  fn map(_1: std::option::Option<std::boxed::Box<()>>) -> std::option::Option<std::boxed::Box<()>> {
+      debug x => _1;                       // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:8: 1:9
+      let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:31: 1:46
+      let mut _2: isize;                   // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
+      let _3: std::boxed::Box<()>;         // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15
+-     let mut _4: std::boxed::Box<()>;     // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:25: 4:26
+-     let mut _5: isize;                   // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2
+-     let mut _6: isize;                   // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2
+      scope 1 {
+          debug x => _3;                   // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15
+      }
+  
+      bb0: {
+          _2 = discriminant(_1);           // bb0[0]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
+          switchInt(move _2) -> [0isize: bb2, otherwise: bb1]; // bb0[1]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
+      }
+  
+      bb1: {
+          _0 = move _1;                    // bb1[0]: scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:20: 4:27
+          goto -> bb3;                     // bb1[1]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:2:5: 5:6
+      }
+  
+      bb2: {
+          discriminant(_0) = 0;            // bb2[0]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:17: 3:21
+          goto -> bb3;                     // bb2[1]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:2:5: 5:6
+      }
+  
+      bb3: {
+-         _5 = discriminant(_1);           // bb3[0]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2
+-         return;                          // bb3[1]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:2: 6:2
++         return;                          // bb3[0]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:2: 6:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/simplify_try.rs b/src/test/mir-opt/simplify_try.rs
index abac66d..78a7f72 100644
--- a/src/test/mir-opt/simplify_try.rs
+++ b/src/test/mir-opt/simplify_try.rs
@@ -183,25 +183,24 @@
 // fn try_identity(_1: std::result::Result<u32, i32>) -> std::result::Result<u32, i32> {
 //     debug x => _1;
 //     let mut _0: std::result::Result<u32, i32>;
-//     let mut _2: isize;
-//     let _3: i32;
-//     let _4: u32;
+//     let _2: i32;
+//     let _3: u32;
 //     scope 1 {
-//         debug y => _4;
+//         debug y => _3;
 //     }
 //     scope 2 {
-//         debug err => _3;
+//         debug err => _2;
 //         scope 3 {
 //             scope 7 {
-//                 debug t => _3;
+//                 debug t => _2;
 //             }
 //             scope 8 {
-//                 debug v => _3;
+//                 debug v => _2;
 //             }
 //         }
 //     }
 //     scope 4 {
-//         debug val => _4;
+//         debug val => _3;
 //         scope 5 {
 //         }
 //     }
@@ -209,7 +208,6 @@
 //         debug self => _1;
 //     }
 //     bb0: {
-//         _2 = discriminant(_1);
 //         _0 = move _1;
 //         return;
 //     }
diff --git a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
index 7634124..2875ee5 100644
--- a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
+++ b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
@@ -1,6 +1,7 @@
 #![feature(rustc_private)]
 
 extern crate rustc_codegen_ssa;
+extern crate rustc_errors;
 extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_data_structures;
@@ -14,11 +15,11 @@
 use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_data_structures::owning_ref::OwningRef;
 use rustc_data_structures::sync::MetadataRef;
+use rustc_errors::ErrorReported;
 use rustc_middle::dep_graph::DepGraph;
 use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoader, MetadataLoaderDyn};
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::TyCtxt;
-use rustc_middle::util::common::ErrorReported;
 use rustc_session::config::OutputFilenames;
 use rustc_session::Session;
 use rustc_span::symbol::Symbol;
diff --git a/src/test/run-make-fulldeps/link-args-order/Makefile b/src/test/run-make-fulldeps/link-args-order/Makefile
new file mode 100644
index 0000000..98c1e0e
--- /dev/null
+++ b/src/test/run-make-fulldeps/link-args-order/Makefile
@@ -0,0 +1,10 @@
+# ignore-msvc
+
+-include ../tools.mk
+
+RUSTC_FLAGS = -C linker-flavor=ld -C link-arg=a -C link-args="b c" -C link-args="d e" -C link-arg=f
+RUSTC_FLAGS_PRE = -C linker-flavor=ld -Z pre-link-arg=a -Z pre-link-args="b c" -Z pre-link-args="d e" -Z pre-link-arg=f
+
+all:
+	$(RUSTC) $(RUSTC_FLAGS) empty.rs 2>&1 | $(CGREP) '"a" "b" "c" "d" "e" "f" "g"'
+	$(RUSTC) $(RUSTC_FLAGS_PRE) empty.rs 2>&1 | $(CGREP) '"a" "b" "c" "d" "e" "f"'
diff --git a/src/test/run-make-fulldeps/link-args-order/empty.rs b/src/test/run-make-fulldeps/link-args-order/empty.rs
new file mode 100644
index 0000000..2439171
--- /dev/null
+++ b/src/test/run-make-fulldeps/link-args-order/empty.rs
@@ -0,0 +1,6 @@
+#![feature(link_args)]
+
+#[link_args = "g"]
+extern "C" {}
+
+fn main() {}
diff --git a/src/test/ui-fulldeps/undef_mask.rs b/src/test/ui-fulldeps/undef_mask.rs
index cbf1b63..656d0b4 100644
--- a/src/test/ui-fulldeps/undef_mask.rs
+++ b/src/test/ui-fulldeps/undef_mask.rs
@@ -5,9 +5,10 @@
 #![feature(rustc_private)]
 
 extern crate rustc_middle;
+extern crate rustc_target;
 
 use rustc_middle::mir::interpret::UndefMask;
-use rustc_middle::ty::layout::Size;
+use rustc_target::abi::Size;
 
 fn main() {
     let mut mask = UndefMask::new(Size::from_bytes(500), false);
diff --git a/src/test/ui/associated-const/issue-63496.stderr b/src/test/ui/associated-const/issue-63496.stderr
index 3a70e7d..34e9470 100644
--- a/src/test/ui/associated-const/issue-63496.stderr
+++ b/src/test/ui/associated-const/issue-63496.stderr
@@ -10,7 +10,7 @@
    |                     cannot infer type
    |                     help: use the fully qualified path to an implementation: `<Type as A>::C`
    |
-   = note: cannot resolve `_: A`
+   = note: cannot satisfy `_: A`
    = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
 
 error[E0283]: type annotations needed
@@ -25,7 +25,7 @@
    |                                 cannot infer type
    |                                 help: use the fully qualified path to an implementation: `<Type as A>::C`
    |
-   = note: cannot resolve `_: A`
+   = note: cannot satisfy `_: A`
    = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/associated-const/issue-69020-assoc-const-arith-overflow.noopt.stderr b/src/test/ui/associated-const/issue-69020-assoc-const-arith-overflow.noopt.stderr
new file mode 100644
index 0000000..510a13e
--- /dev/null
+++ b/src/test/ui/associated-const/issue-69020-assoc-const-arith-overflow.noopt.stderr
@@ -0,0 +1,54 @@
+error: this arithmetic operation will overflow
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:29:22
+   |
+LL |     const NEG: i32 = -i32::MIN + T::NEG;
+   |                      ^^^^^^^^^ attempt to negate with overflow
+   |
+   = note: `#[deny(arithmetic_overflow)]` on by default
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:31:35
+   |
+LL |     const NEG_REV: i32 = T::NEG + (-i32::MIN);
+   |                                   ^^^^^^^^^^^ attempt to negate with overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:34:22
+   |
+LL |     const ADD: i32 = (i32::MAX+1) + T::ADD;
+   |                      ^^^^^^^^^^^^ attempt to add with overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:36:36
+   |
+LL |     const ADD_REV: i32 =  T::ADD + (i32::MAX+1);
+   |                                    ^^^^^^^^^^^^ attempt to add with overflow
+
+error: this operation will panic at runtime
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:39:22
+   |
+LL |     const DIV: i32 = (1/0) + T::DIV;
+   |                      ^^^^^ attempt to divide by zero
+   |
+   = note: `#[deny(unconditional_panic)]` on by default
+
+error: this operation will panic at runtime
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:41:35
+   |
+LL |     const DIV_REV: i32 = T::DIV + (1/0);
+   |                                   ^^^^^ attempt to divide by zero
+
+error: this operation will panic at runtime
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:44:22
+   |
+LL |     const OOB: i32 = [1][1] + T::OOB;
+   |                      ^^^^^^ index out of bounds: the len is 1 but the index is 1
+
+error: this operation will panic at runtime
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:46:35
+   |
+LL |     const OOB_REV: i32 = T::OOB + [1][1];
+   |                                   ^^^^^^ index out of bounds: the len is 1 but the index is 1
+
+error: aborting due to 8 previous errors
+
diff --git a/src/test/ui/associated-const/issue-69020-assoc-const-arith-overflow.opt.stderr b/src/test/ui/associated-const/issue-69020-assoc-const-arith-overflow.opt.stderr
new file mode 100644
index 0000000..510a13e
--- /dev/null
+++ b/src/test/ui/associated-const/issue-69020-assoc-const-arith-overflow.opt.stderr
@@ -0,0 +1,54 @@
+error: this arithmetic operation will overflow
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:29:22
+   |
+LL |     const NEG: i32 = -i32::MIN + T::NEG;
+   |                      ^^^^^^^^^ attempt to negate with overflow
+   |
+   = note: `#[deny(arithmetic_overflow)]` on by default
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:31:35
+   |
+LL |     const NEG_REV: i32 = T::NEG + (-i32::MIN);
+   |                                   ^^^^^^^^^^^ attempt to negate with overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:34:22
+   |
+LL |     const ADD: i32 = (i32::MAX+1) + T::ADD;
+   |                      ^^^^^^^^^^^^ attempt to add with overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:36:36
+   |
+LL |     const ADD_REV: i32 =  T::ADD + (i32::MAX+1);
+   |                                    ^^^^^^^^^^^^ attempt to add with overflow
+
+error: this operation will panic at runtime
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:39:22
+   |
+LL |     const DIV: i32 = (1/0) + T::DIV;
+   |                      ^^^^^ attempt to divide by zero
+   |
+   = note: `#[deny(unconditional_panic)]` on by default
+
+error: this operation will panic at runtime
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:41:35
+   |
+LL |     const DIV_REV: i32 = T::DIV + (1/0);
+   |                                   ^^^^^ attempt to divide by zero
+
+error: this operation will panic at runtime
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:44:22
+   |
+LL |     const OOB: i32 = [1][1] + T::OOB;
+   |                      ^^^^^^ index out of bounds: the len is 1 but the index is 1
+
+error: this operation will panic at runtime
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:46:35
+   |
+LL |     const OOB_REV: i32 = T::OOB + [1][1];
+   |                                   ^^^^^^ index out of bounds: the len is 1 but the index is 1
+
+error: aborting due to 8 previous errors
+
diff --git a/src/test/ui/associated-const/issue-69020-assoc-const-arith-overflow.opt_with_overflow_checks.stderr b/src/test/ui/associated-const/issue-69020-assoc-const-arith-overflow.opt_with_overflow_checks.stderr
new file mode 100644
index 0000000..510a13e
--- /dev/null
+++ b/src/test/ui/associated-const/issue-69020-assoc-const-arith-overflow.opt_with_overflow_checks.stderr
@@ -0,0 +1,54 @@
+error: this arithmetic operation will overflow
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:29:22
+   |
+LL |     const NEG: i32 = -i32::MIN + T::NEG;
+   |                      ^^^^^^^^^ attempt to negate with overflow
+   |
+   = note: `#[deny(arithmetic_overflow)]` on by default
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:31:35
+   |
+LL |     const NEG_REV: i32 = T::NEG + (-i32::MIN);
+   |                                   ^^^^^^^^^^^ attempt to negate with overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:34:22
+   |
+LL |     const ADD: i32 = (i32::MAX+1) + T::ADD;
+   |                      ^^^^^^^^^^^^ attempt to add with overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:36:36
+   |
+LL |     const ADD_REV: i32 =  T::ADD + (i32::MAX+1);
+   |                                    ^^^^^^^^^^^^ attempt to add with overflow
+
+error: this operation will panic at runtime
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:39:22
+   |
+LL |     const DIV: i32 = (1/0) + T::DIV;
+   |                      ^^^^^ attempt to divide by zero
+   |
+   = note: `#[deny(unconditional_panic)]` on by default
+
+error: this operation will panic at runtime
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:41:35
+   |
+LL |     const DIV_REV: i32 = T::DIV + (1/0);
+   |                                   ^^^^^ attempt to divide by zero
+
+error: this operation will panic at runtime
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:44:22
+   |
+LL |     const OOB: i32 = [1][1] + T::OOB;
+   |                      ^^^^^^ index out of bounds: the len is 1 but the index is 1
+
+error: this operation will panic at runtime
+  --> $DIR/issue-69020-assoc-const-arith-overflow.rs:46:35
+   |
+LL |     const OOB_REV: i32 = T::OOB + [1][1];
+   |                                   ^^^^^^ index out of bounds: the len is 1 but the index is 1
+
+error: aborting due to 8 previous errors
+
diff --git a/src/test/ui/associated-const/issue-69020-assoc-const-arith-overflow.rs b/src/test/ui/associated-const/issue-69020-assoc-const-arith-overflow.rs
new file mode 100644
index 0000000..850f65a
--- /dev/null
+++ b/src/test/ui/associated-const/issue-69020-assoc-const-arith-overflow.rs
@@ -0,0 +1,48 @@
+// revisions: noopt opt opt_with_overflow_checks
+//[noopt]compile-flags: -C opt-level=0
+//[opt]compile-flags: -O
+//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O
+
+#![crate_type="lib"]
+
+use std::i32;
+
+pub trait Foo {
+    const NEG: i32;
+    const NEG_REV: i32;
+
+    const ADD: i32;
+    const ADD_REV: i32;
+
+    const DIV: i32;
+    const DIV_REV: i32;
+
+    const OOB: i32;
+    const OOB_REV: i32;
+}
+
+// These constants cannot be evaluated already (they depend on `T::N`), so they can just be linted
+// like normal run-time code. But codegen works a bit different in const context, so this test
+// makes sure that we still catch overflow. Also make sure we emit the same lints if we reverse the
+// operands (so that the generic operand comes first).
+impl<T: Foo> Foo for Vec<T> {
+    const NEG: i32 = -i32::MIN + T::NEG;
+    //~^ ERROR arithmetic operation will overflow
+    const NEG_REV: i32 = T::NEG + (-i32::MIN);
+    //~^ ERROR arithmetic operation will overflow
+
+    const ADD: i32 = (i32::MAX+1) + T::ADD;
+    //~^ ERROR arithmetic operation will overflow
+    const ADD_REV: i32 =  T::ADD + (i32::MAX+1);
+    //~^ ERROR arithmetic operation will overflow
+
+    const DIV: i32 = (1/0) + T::DIV;
+    //~^ ERROR operation will panic
+    const DIV_REV: i32 = T::DIV + (1/0);
+    //~^ ERROR operation will panic
+
+    const OOB: i32 = [1][1] + T::OOB;
+    //~^ ERROR operation will panic
+    const OOB_REV: i32 = T::OOB + [1][1];
+    //~^ ERROR operation will panic
+}
diff --git a/src/test/ui/associated-item/issue-48027.stderr b/src/test/ui/associated-item/issue-48027.stderr
index 62a3807..98b545c 100644
--- a/src/test/ui/associated-item/issue-48027.stderr
+++ b/src/test/ui/associated-item/issue-48027.stderr
@@ -22,7 +22,7 @@
    |                                cannot infer type
    |                                help: use the fully qualified path to an implementation: `<Type as Bar>::X`
    |
-   = note: cannot resolve `_: Bar`
+   = note: cannot satisfy `_: Bar`
    = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding.stderr b/src/test/ui/associated-types/associated-types-overridden-binding.stderr
index 9e10ed7..683a2ab 100644
--- a/src/test/ui/associated-types/associated-types-overridden-binding.stderr
+++ b/src/test/ui/associated-types/associated-types-overridden-binding.stderr
@@ -6,7 +6,7 @@
 LL | trait Bar: Foo<Item = u32> {}
    |            ^^^^^^^^^^^^^^^ cannot infer type for type parameter `Self`
    |
-   = note: cannot resolve `<Self as std::iter::Iterator>::Item == i32`
+   = note: cannot satisfy `<Self as std::iter::Iterator>::Item == i32`
 
 error[E0284]: type annotations needed
   --> $DIR/associated-types-overridden-binding.rs:7:21
@@ -16,7 +16,7 @@
 LL | trait U32Iterator = I32Iterator<Item = u32>;
    |                     ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `Self`
    |
-   = note: cannot resolve `<Self as std::iter::Iterator>::Item == i32`
+   = note: cannot satisfy `<Self as std::iter::Iterator>::Item == i32`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/associated-types/associated-types-unconstrained.stderr b/src/test/ui/associated-types/associated-types-unconstrained.stderr
index 14ce483..2914a7f 100644
--- a/src/test/ui/associated-types/associated-types-unconstrained.stderr
+++ b/src/test/ui/associated-types/associated-types-unconstrained.stderr
@@ -4,7 +4,7 @@
 LL |     let x: isize = Foo::bar();
    |                    ^^^^^^^^ cannot infer type
    |
-   = note: cannot resolve `<_ as Foo>::A == _`
+   = note: cannot satisfy `<_ as Foo>::A == _`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/async-await/issue-70594.rs b/src/test/ui/async-await/issue-70594.rs
new file mode 100644
index 0000000..e78231a
--- /dev/null
+++ b/src/test/ui/async-await/issue-70594.rs
@@ -0,0 +1,12 @@
+// edition:2018
+
+async fn fun() {
+    [1; ().await];
+    //~^ error: `await` is only allowed inside `async` functions and blocks
+    //~| error: `.await` is not allowed in a `const`
+    //~| error: `loop` is not allowed in a `const`
+    //~| error: `.await` is not allowed in a `const`
+    //~| error: the trait bound `(): std::future::Future` is not satisfied
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issue-70594.stderr b/src/test/ui/async-await/issue-70594.stderr
new file mode 100644
index 0000000..d2fa7e5
--- /dev/null
+++ b/src/test/ui/async-await/issue-70594.stderr
@@ -0,0 +1,44 @@
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/issue-70594.rs:4:9
+   |
+LL | async fn fun() {
+   |          --- this is not `async`
+LL |     [1; ().await];
+   |         ^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0744]: `.await` is not allowed in a `const`
+  --> $DIR/issue-70594.rs:4:9
+   |
+LL |     [1; ().await];
+   |         ^^^^^^^^
+
+error[E0658]: `loop` is not allowed in a `const`
+  --> $DIR/issue-70594.rs:4:9
+   |
+LL |     [1; ().await];
+   |         ^^^^^^^^
+   |
+   = note: see issue #52000 <https://github.com/rust-lang/rust/issues/52000> for more information
+   = help: add `#![feature(const_loop)]` to the crate attributes to enable
+
+error[E0744]: `.await` is not allowed in a `const`
+  --> $DIR/issue-70594.rs:4:9
+   |
+LL |     [1; ().await];
+   |         ^^^^^^^^
+
+error[E0277]: the trait bound `(): std::future::Future` is not satisfied
+  --> $DIR/issue-70594.rs:4:9
+   |
+LL |     [1; ().await];
+   |         ^^^^^^^^ the trait `std::future::Future` is not implemented for `()`
+   | 
+  ::: $SRC_DIR/libcore/future/mod.rs:LL:COL
+   |
+LL |     F: Future,
+   |        ------ required by this bound in `std::future::poll_with_context`
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0277, E0658, E0728, E0744.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/issues/issue-62009-1.rs b/src/test/ui/async-await/issues/issue-62009-1.rs
index aa142eb..3ee7ab2 100644
--- a/src/test/ui/async-await/issues/issue-62009-1.rs
+++ b/src/test/ui/async-await/issues/issue-62009-1.rs
@@ -1,8 +1,4 @@
 // edition:2018
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 
 async fn print_dur() {}
 
diff --git a/src/test/ui/async-await/issues/issue-62009-1.stderr b/src/test/ui/async-await/issues/issue-62009-1.stderr
index 0624c04..2417b59 100644
--- a/src/test/ui/async-await/issues/issue-62009-1.stderr
+++ b/src/test/ui/async-await/issues/issue-62009-1.stderr
@@ -1,5 +1,5 @@
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009-1.rs:10:5
+  --> $DIR/issue-62009-1.rs:6:5
    |
 LL | fn main() {
    |    ---- this is not `async`
@@ -7,7 +7,7 @@
    |     ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009-1.rs:12:5
+  --> $DIR/issue-62009-1.rs:8:5
    |
 LL |   fn main() {
    |      ---- this is not `async`
@@ -19,7 +19,7 @@
    | |___________^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009-1.rs:16:5
+  --> $DIR/issue-62009-1.rs:12:5
    |
 LL | fn main() {
    |    ---- this is not `async`
@@ -27,11 +27,11 @@
 LL |     (|_| 2333).await;
    |     ^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
-error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:16:5: 16:15]: std::future::Future` is not satisfied
-  --> $DIR/issue-62009-1.rs:16:5
+error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]: std::future::Future` is not satisfied
+  --> $DIR/issue-62009-1.rs:12:5
    |
 LL |     (|_| 2333).await;
-   |     ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:16:5: 16:15]`
+   |     ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]`
    | 
   ::: $SRC_DIR/libcore/future/mod.rs:LL:COL
    |
diff --git a/src/test/ui/closures/closure-move-sync.rs b/src/test/ui/closures/closure-move-sync.rs
index 8738824..580cd1a 100644
--- a/src/test/ui/closures/closure-move-sync.rs
+++ b/src/test/ui/closures/closure-move-sync.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 use std::thread;
 use std::sync::mpsc::channel;
 
diff --git a/src/test/ui/closures/closure-move-sync.stderr b/src/test/ui/closures/closure-move-sync.stderr
index 2187823..a1fc427 100644
--- a/src/test/ui/closures/closure-move-sync.stderr
+++ b/src/test/ui/closures/closure-move-sync.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
-  --> $DIR/closure-move-sync.rs:10:13
+  --> $DIR/closure-move-sync.rs:6:13
    |
 LL |     let t = thread::spawn(|| {
    |             ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
@@ -11,10 +11,10 @@
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Receiver<()>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Receiver<()>`
-   = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:10:27: 13:6 recv:&std::sync::mpsc::Receiver<()>]`
+   = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:6:27: 9:6 recv:&std::sync::mpsc::Receiver<()>]`
 
 error[E0277]: `std::sync::mpsc::Sender<()>` cannot be shared between threads safely
-  --> $DIR/closure-move-sync.rs:22:5
+  --> $DIR/closure-move-sync.rs:18:5
    |
 LL |     thread::spawn(|| tx.send(()).unwrap());
    |     ^^^^^^^^^^^^^ `std::sync::mpsc::Sender<()>` cannot be shared between threads safely
@@ -26,7 +26,7 @@
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Sender<()>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Sender<()>`
-   = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:22:19: 22:42 tx:&std::sync::mpsc::Sender<()>]`
+   = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:18:19: 18:42 tx:&std::sync::mpsc::Sender<()>]`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/consts/const-eval/issue-70804-fn-subtyping.rs b/src/test/ui/consts/const-eval/issue-70804-fn-subtyping.rs
new file mode 100644
index 0000000..59d46ea
--- /dev/null
+++ b/src/test/ui/consts/const-eval/issue-70804-fn-subtyping.rs
@@ -0,0 +1,10 @@
+// check-pass
+#![feature(const_fn)]
+
+const fn nested(x: (for<'a> fn(&'a ()), String)) -> (fn(&'static ()), String) {
+    x
+}
+
+pub const TEST: (fn(&'static ()), String) = nested((|_x| (), String::new()));
+
+fn main() {}
diff --git a/src/test/ui/consts/const-size_of-cycle.rs b/src/test/ui/consts/const-size_of-cycle.rs
index c94bb4f..1f56c8b 100644
--- a/src/test/ui/consts/const-size_of-cycle.rs
+++ b/src/test/ui/consts/const-size_of-cycle.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // error-pattern: cycle detected
 
 struct Foo {
diff --git a/src/test/ui/consts/const-size_of-cycle.stderr b/src/test/ui/consts/const-size_of-cycle.stderr
index aac3622..730ad57 100644
--- a/src/test/ui/consts/const-size_of-cycle.stderr
+++ b/src/test/ui/consts/const-size_of-cycle.stderr
@@ -1,16 +1,16 @@
 error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{constant}}#0`
-  --> $DIR/const-size_of-cycle.rs:8:17
+  --> $DIR/const-size_of-cycle.rs:4:17
    |
 LL |     bytes: [u8; std::mem::size_of::<Foo>()]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}#0`...
-  --> $DIR/const-size_of-cycle.rs:8:17
+  --> $DIR/const-size_of-cycle.rs:4:17
    |
 LL |     bytes: [u8; std::mem::size_of::<Foo>()]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires const-evaluating `Foo::bytes::{{constant}}#0`...
-  --> $DIR/const-size_of-cycle.rs:8:17
+  --> $DIR/const-size_of-cycle.rs:4:17
    |
 LL |     bytes: [u8; std::mem::size_of::<Foo>()]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -28,7 +28,7 @@
    = note: ...which requires normalizing `[u8; _]`...
    = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle
 note: cycle used when processing `Foo`
-  --> $DIR/const-size_of-cycle.rs:7:1
+  --> $DIR/const-size_of-cycle.rs:3:1
    |
 LL | struct Foo {
    | ^^^^^^^^^^
diff --git a/src/test/ui/consts/issue-69020.noopt.stderr b/src/test/ui/consts/issue-69020.noopt.stderr
deleted file mode 100644
index c48a106..0000000
--- a/src/test/ui/consts/issue-69020.noopt.stderr
+++ /dev/null
@@ -1,30 +0,0 @@
-error: this arithmetic operation will overflow
-  --> $DIR/issue-69020.rs:21:22
-   |
-LL |     const NEG: i32 = -i32::MIN + T::NEG;
-   |                      ^^^^^^^^^ attempt to negate with overflow
-   |
-   = note: `#[deny(arithmetic_overflow)]` on by default
-
-error: this arithmetic operation will overflow
-  --> $DIR/issue-69020.rs:23:22
-   |
-LL |     const ADD: i32 = (i32::MAX+1) + T::ADD;
-   |                      ^^^^^^^^^^^^ attempt to add with overflow
-
-error: this operation will panic at runtime
-  --> $DIR/issue-69020.rs:25:22
-   |
-LL |     const DIV: i32 = (1/0) + T::DIV;
-   |                      ^^^^^ attempt to divide by zero
-   |
-   = note: `#[deny(unconditional_panic)]` on by default
-
-error: this operation will panic at runtime
-  --> $DIR/issue-69020.rs:27:22
-   |
-LL |     const OOB: i32 = [1][1] + T::OOB;
-   |                      ^^^^^^ index out of bounds: the len is 1 but the index is 1
-
-error: aborting due to 4 previous errors
-
diff --git a/src/test/ui/consts/issue-69020.opt.stderr b/src/test/ui/consts/issue-69020.opt.stderr
deleted file mode 100644
index c48a106..0000000
--- a/src/test/ui/consts/issue-69020.opt.stderr
+++ /dev/null
@@ -1,30 +0,0 @@
-error: this arithmetic operation will overflow
-  --> $DIR/issue-69020.rs:21:22
-   |
-LL |     const NEG: i32 = -i32::MIN + T::NEG;
-   |                      ^^^^^^^^^ attempt to negate with overflow
-   |
-   = note: `#[deny(arithmetic_overflow)]` on by default
-
-error: this arithmetic operation will overflow
-  --> $DIR/issue-69020.rs:23:22
-   |
-LL |     const ADD: i32 = (i32::MAX+1) + T::ADD;
-   |                      ^^^^^^^^^^^^ attempt to add with overflow
-
-error: this operation will panic at runtime
-  --> $DIR/issue-69020.rs:25:22
-   |
-LL |     const DIV: i32 = (1/0) + T::DIV;
-   |                      ^^^^^ attempt to divide by zero
-   |
-   = note: `#[deny(unconditional_panic)]` on by default
-
-error: this operation will panic at runtime
-  --> $DIR/issue-69020.rs:27:22
-   |
-LL |     const OOB: i32 = [1][1] + T::OOB;
-   |                      ^^^^^^ index out of bounds: the len is 1 but the index is 1
-
-error: aborting due to 4 previous errors
-
diff --git a/src/test/ui/consts/issue-69020.opt_with_overflow_checks.stderr b/src/test/ui/consts/issue-69020.opt_with_overflow_checks.stderr
deleted file mode 100644
index c48a106..0000000
--- a/src/test/ui/consts/issue-69020.opt_with_overflow_checks.stderr
+++ /dev/null
@@ -1,30 +0,0 @@
-error: this arithmetic operation will overflow
-  --> $DIR/issue-69020.rs:21:22
-   |
-LL |     const NEG: i32 = -i32::MIN + T::NEG;
-   |                      ^^^^^^^^^ attempt to negate with overflow
-   |
-   = note: `#[deny(arithmetic_overflow)]` on by default
-
-error: this arithmetic operation will overflow
-  --> $DIR/issue-69020.rs:23:22
-   |
-LL |     const ADD: i32 = (i32::MAX+1) + T::ADD;
-   |                      ^^^^^^^^^^^^ attempt to add with overflow
-
-error: this operation will panic at runtime
-  --> $DIR/issue-69020.rs:25:22
-   |
-LL |     const DIV: i32 = (1/0) + T::DIV;
-   |                      ^^^^^ attempt to divide by zero
-   |
-   = note: `#[deny(unconditional_panic)]` on by default
-
-error: this operation will panic at runtime
-  --> $DIR/issue-69020.rs:27:22
-   |
-LL |     const OOB: i32 = [1][1] + T::OOB;
-   |                      ^^^^^^ index out of bounds: the len is 1 but the index is 1
-
-error: aborting due to 4 previous errors
-
diff --git a/src/test/ui/consts/issue-69020.rs b/src/test/ui/consts/issue-69020.rs
deleted file mode 100644
index e079feb..0000000
--- a/src/test/ui/consts/issue-69020.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-// revisions: noopt opt opt_with_overflow_checks
-//[noopt]compile-flags: -C opt-level=0
-//[opt]compile-flags: -O
-//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O
-
-#![crate_type="lib"]
-
-use std::i32;
-
-pub trait Foo {
-    const NEG: i32;
-    const ADD: i32;
-    const DIV: i32;
-    const OOB: i32;
-}
-
-// These constants cannot be evaluated already (they depend on `T::N`), so
-// they can just be linted like normal run-time code.  But codegen works
-// a bit different in const context, so this test makes sure that we still catch overflow.
-impl<T: Foo> Foo for Vec<T> {
-    const NEG: i32 = -i32::MIN + T::NEG;
-    //~^ ERROR arithmetic operation will overflow
-    const ADD: i32 = (i32::MAX+1) + T::ADD;
-    //~^ ERROR arithmetic operation will overflow
-    const DIV: i32 = (1/0) + T::DIV;
-    //~^ ERROR operation will panic
-    const OOB: i32 = [1][1] + T::OOB;
-    //~^ ERROR operation will panic
-}
diff --git a/src/test/ui/consts/miri_unleashed/drop.rs b/src/test/ui/consts/miri_unleashed/drop.rs
index d2c34bc..2f39148 100644
--- a/src/test/ui/consts/miri_unleashed/drop.rs
+++ b/src/test/ui/consts/miri_unleashed/drop.rs
@@ -1,8 +1,4 @@
 // compile-flags: -Zunleash-the-miri-inside-of-you
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // error-pattern: calling non-const function `<std::vec::Vec<i32> as std::ops::Drop>::drop`
 #![deny(const_err)]
 
diff --git a/src/test/ui/consts/miri_unleashed/drop.stderr b/src/test/ui/consts/miri_unleashed/drop.stderr
index 5d560fa..902ccf8 100644
--- a/src/test/ui/consts/miri_unleashed/drop.stderr
+++ b/src/test/ui/consts/miri_unleashed/drop.stderr
@@ -1,5 +1,5 @@
 warning: skipping const checks
-  --> $DIR/drop.rs:21:9
+  --> $DIR/drop.rs:17:9
    |
 LL |     let _v: Vec<i32> = Vec::new();
    |         ^^
@@ -17,10 +17,10 @@
    | |_calling non-const function `<std::vec::Vec<i32> as std::ops::Drop>::drop`
    |   inside `std::intrinsics::drop_in_place::<std::vec::Vec<i32>> - shim(Some(std::vec::Vec<i32>))` at $SRC_DIR/libcore/ptr/mod.rs:LL:COL
    | 
-  ::: $DIR/drop.rs:23:1
+  ::: $DIR/drop.rs:19:1
    |
 LL |   };
-   |   - inside `TEST_BAD` at $DIR/drop.rs:23:1
+   |   - inside `TEST_BAD` at $DIR/drop.rs:19:1
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/offset_from_ub.rs b/src/test/ui/consts/offset_from_ub.rs
index 6c4beaf..a7902f2 100644
--- a/src/test/ui/consts/offset_from_ub.rs
+++ b/src/test/ui/consts/offset_from_ub.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 #![feature(const_raw_ptr_deref)]
 #![feature(const_ptr_offset_from)]
 #![feature(ptr_offset_from)]
diff --git a/src/test/ui/consts/offset_from_ub.stderr b/src/test/ui/consts/offset_from_ub.stderr
index f1a183b..4c591d5 100644
--- a/src/test/ui/consts/offset_from_ub.stderr
+++ b/src/test/ui/consts/offset_from_ub.stderr
@@ -6,9 +6,9 @@
    |           |
    |           ptr_offset_from cannot compute offset of pointers into different allocations.
    |           inside `std::ptr::const_ptr::<impl *const Struct>::offset_from` at $SRC_DIR/libcore/ptr/const_ptr.rs:LL:COL
-   |           inside `DIFFERENT_ALLOC` at $DIR/offset_from_ub.rs:22:27
+   |           inside `DIFFERENT_ALLOC` at $DIR/offset_from_ub.rs:17:27
    | 
-  ::: $DIR/offset_from_ub.rs:16:1
+  ::: $DIR/offset_from_ub.rs:11:1
    |
 LL | / pub const DIFFERENT_ALLOC: usize = {
 LL | |
@@ -29,9 +29,9 @@
    |           |
    |           unable to turn bytes into a pointer
    |           inside `std::ptr::const_ptr::<impl *const u8>::offset_from` at $SRC_DIR/libcore/ptr/const_ptr.rs:LL:COL
-   |           inside `NOT_PTR` at $DIR/offset_from_ub.rs:28:14
+   |           inside `NOT_PTR` at $DIR/offset_from_ub.rs:23:14
    | 
-  ::: $DIR/offset_from_ub.rs:26:1
+  ::: $DIR/offset_from_ub.rs:21:1
    |
 LL | / pub const NOT_PTR: usize = {
 LL | |
@@ -47,9 +47,9 @@
    |           |
    |           exact_div: 1isize cannot be divided by 2isize without remainder
    |           inside `std::ptr::const_ptr::<impl *const u16>::offset_from` at $SRC_DIR/libcore/ptr/const_ptr.rs:LL:COL
-   |           inside `NOT_MULTIPLE_OF_SIZE` at $DIR/offset_from_ub.rs:36:14
+   |           inside `NOT_MULTIPLE_OF_SIZE` at $DIR/offset_from_ub.rs:31:14
    | 
-  ::: $DIR/offset_from_ub.rs:31:1
+  ::: $DIR/offset_from_ub.rs:26:1
    |
 LL | / pub const NOT_MULTIPLE_OF_SIZE: isize = {
 LL | |
@@ -68,9 +68,9 @@
    |           |
    |           invalid use of NULL pointer
    |           inside `std::ptr::const_ptr::<impl *const u8>::offset_from` at $SRC_DIR/libcore/ptr/const_ptr.rs:LL:COL
-   |           inside `OFFSET_FROM_NULL` at $DIR/offset_from_ub.rs:42:14
+   |           inside `OFFSET_FROM_NULL` at $DIR/offset_from_ub.rs:37:14
    | 
-  ::: $DIR/offset_from_ub.rs:39:1
+  ::: $DIR/offset_from_ub.rs:34:1
    |
 LL | / pub const OFFSET_FROM_NULL: isize = {
 LL | |
@@ -87,9 +87,9 @@
    |           |
    |           unable to turn bytes into a pointer
    |           inside `std::ptr::const_ptr::<impl *const u8>::offset_from` at $SRC_DIR/libcore/ptr/const_ptr.rs:LL:COL
-   |           inside `DIFFERENT_INT` at $DIR/offset_from_ub.rs:49:14
+   |           inside `DIFFERENT_INT` at $DIR/offset_from_ub.rs:44:14
    | 
-  ::: $DIR/offset_from_ub.rs:45:1
+  ::: $DIR/offset_from_ub.rs:40:1
    |
 LL | / pub const DIFFERENT_INT: isize = { // offset_from with two different integers: like DIFFERENT_ALLOC
 LL | |
diff --git a/src/test/ui/copy-a-resource.rs b/src/test/ui/copy-a-resource.rs
index 1a64769..55f2dd4 100644
--- a/src/test/ui/copy-a-resource.rs
+++ b/src/test/ui/copy-a-resource.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 #[derive(Debug)]
 struct Foo {
   i: isize,
diff --git a/src/test/ui/copy-a-resource.stderr b/src/test/ui/copy-a-resource.stderr
index 71d2eea..a5c961a 100644
--- a/src/test/ui/copy-a-resource.stderr
+++ b/src/test/ui/copy-a-resource.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `clone` found for struct `Foo` in the current scope
-  --> $DIR/copy-a-resource.rs:23:16
+  --> $DIR/copy-a-resource.rs:18:16
    |
 LL | struct Foo {
    | ---------- method `clone` not found for this
diff --git a/src/test/ui/derives/derive-assoc-type-not-impl.rs b/src/test/ui/derives/derive-assoc-type-not-impl.rs
index fa5afd2..0f642d6 100644
--- a/src/test/ui/derives/derive-assoc-type-not-impl.rs
+++ b/src/test/ui/derives/derive-assoc-type-not-impl.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 trait Foo {
     type X;
     fn method(&self) {}
diff --git a/src/test/ui/derives/derive-assoc-type-not-impl.stderr b/src/test/ui/derives/derive-assoc-type-not-impl.stderr
index f15aba9..be446fe 100644
--- a/src/test/ui/derives/derive-assoc-type-not-impl.stderr
+++ b/src/test/ui/derives/derive-assoc-type-not-impl.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `clone` found for struct `Bar<NotClone>` in the current scope
-  --> $DIR/derive-assoc-type-not-impl.rs:23:30
+  --> $DIR/derive-assoc-type-not-impl.rs:18:30
    |
 LL | struct Bar<T: Foo> {
    | ------------------
diff --git a/src/test/ui/derives/derives-span-Clone-enum-struct-variant.rs b/src/test/ui/derives/derives-span-Clone-enum-struct-variant.rs
index 7c416fd..b556d44 100644
--- a/src/test/ui/derives/derives-span-Clone-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-Clone-enum-struct-variant.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr
index 8ef2d3d..bbb8776 100644
--- a/src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::clone::Clone` is not satisfied
-  --> $DIR/derives-span-Clone-enum-struct-variant.rs:13:6
+  --> $DIR/derives-span-Clone-enum-struct-variant.rs:9:6
    |
 LL |      x: Error
    |      ^^^^^^^^ the trait `std::clone::Clone` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Clone-enum.rs b/src/test/ui/derives/derives-span-Clone-enum.rs
index c013ccd..9bb4f48 100644
--- a/src/test/ui/derives/derives-span-Clone-enum.rs
+++ b/src/test/ui/derives/derives-span-Clone-enum.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Clone-enum.stderr b/src/test/ui/derives/derives-span-Clone-enum.stderr
index 8c74073..0e410e7 100644
--- a/src/test/ui/derives/derives-span-Clone-enum.stderr
+++ b/src/test/ui/derives/derives-span-Clone-enum.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::clone::Clone` is not satisfied
-  --> $DIR/derives-span-Clone-enum.rs:13:6
+  --> $DIR/derives-span-Clone-enum.rs:9:6
    |
 LL |      Error
    |      ^^^^^ the trait `std::clone::Clone` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Clone-struct.rs b/src/test/ui/derives/derives-span-Clone-struct.rs
index 5a78a92..f151636 100644
--- a/src/test/ui/derives/derives-span-Clone-struct.rs
+++ b/src/test/ui/derives/derives-span-Clone-struct.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Clone-struct.stderr b/src/test/ui/derives/derives-span-Clone-struct.stderr
index 75a59fb..889128a 100644
--- a/src/test/ui/derives/derives-span-Clone-struct.stderr
+++ b/src/test/ui/derives/derives-span-Clone-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::clone::Clone` is not satisfied
-  --> $DIR/derives-span-Clone-struct.rs:12:5
+  --> $DIR/derives-span-Clone-struct.rs:8:5
    |
 LL |     x: Error
    |     ^^^^^^^^ the trait `std::clone::Clone` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Clone-tuple-struct.rs b/src/test/ui/derives/derives-span-Clone-tuple-struct.rs
index 39461d6..7a62885 100644
--- a/src/test/ui/derives/derives-span-Clone-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Clone-tuple-struct.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Clone-tuple-struct.stderr b/src/test/ui/derives/derives-span-Clone-tuple-struct.stderr
index 1860c5f..0024199 100644
--- a/src/test/ui/derives/derives-span-Clone-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Clone-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::clone::Clone` is not satisfied
-  --> $DIR/derives-span-Clone-tuple-struct.rs:12:5
+  --> $DIR/derives-span-Clone-tuple-struct.rs:8:5
    |
 LL |     Error
    |     ^^^^^ the trait `std::clone::Clone` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Debug-enum-struct-variant.rs b/src/test/ui/derives/derives-span-Debug-enum-struct-variant.rs
index 060983d..949597b 100644
--- a/src/test/ui/derives/derives-span-Debug-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-Debug-enum-struct-variant.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr
index ab3c5ef..77779a5 100644
--- a/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `Error` doesn't implement `std::fmt::Debug`
-  --> $DIR/derives-span-Debug-enum-struct-variant.rs:13:6
+  --> $DIR/derives-span-Debug-enum-struct-variant.rs:9:6
    |
 LL |      x: Error
    |      ^^^^^^^^ `Error` cannot be formatted using `{:?}`
diff --git a/src/test/ui/derives/derives-span-Debug-enum.rs b/src/test/ui/derives/derives-span-Debug-enum.rs
index 109c8f2..b2a3970 100644
--- a/src/test/ui/derives/derives-span-Debug-enum.rs
+++ b/src/test/ui/derives/derives-span-Debug-enum.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Debug-enum.stderr b/src/test/ui/derives/derives-span-Debug-enum.stderr
index e0a76d5..f64c33c 100644
--- a/src/test/ui/derives/derives-span-Debug-enum.stderr
+++ b/src/test/ui/derives/derives-span-Debug-enum.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `Error` doesn't implement `std::fmt::Debug`
-  --> $DIR/derives-span-Debug-enum.rs:13:6
+  --> $DIR/derives-span-Debug-enum.rs:9:6
    |
 LL |      Error
    |      ^^^^^ `Error` cannot be formatted using `{:?}`
diff --git a/src/test/ui/derives/derives-span-Debug-struct.rs b/src/test/ui/derives/derives-span-Debug-struct.rs
index b52e287..cf91c94 100644
--- a/src/test/ui/derives/derives-span-Debug-struct.rs
+++ b/src/test/ui/derives/derives-span-Debug-struct.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Debug-struct.stderr b/src/test/ui/derives/derives-span-Debug-struct.stderr
index 2f5cba0..0013bcf 100644
--- a/src/test/ui/derives/derives-span-Debug-struct.stderr
+++ b/src/test/ui/derives/derives-span-Debug-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `Error` doesn't implement `std::fmt::Debug`
-  --> $DIR/derives-span-Debug-struct.rs:12:5
+  --> $DIR/derives-span-Debug-struct.rs:8:5
    |
 LL |     x: Error
    |     ^^^^^^^^ `Error` cannot be formatted using `{:?}`
diff --git a/src/test/ui/derives/derives-span-Debug-tuple-struct.rs b/src/test/ui/derives/derives-span-Debug-tuple-struct.rs
index 1855c7f..cea973c 100644
--- a/src/test/ui/derives/derives-span-Debug-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Debug-tuple-struct.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr b/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr
index 58ec131..7e0039e 100644
--- a/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `Error` doesn't implement `std::fmt::Debug`
-  --> $DIR/derives-span-Debug-tuple-struct.rs:12:5
+  --> $DIR/derives-span-Debug-tuple-struct.rs:8:5
    |
 LL |     Error
    |     ^^^^^ `Error` cannot be formatted using `{:?}`
diff --git a/src/test/ui/derives/derives-span-Default-struct.rs b/src/test/ui/derives/derives-span-Default-struct.rs
index bf60b12..71fd582 100644
--- a/src/test/ui/derives/derives-span-Default-struct.rs
+++ b/src/test/ui/derives/derives-span-Default-struct.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Default-struct.stderr b/src/test/ui/derives/derives-span-Default-struct.stderr
index b97dda7..492847f 100644
--- a/src/test/ui/derives/derives-span-Default-struct.stderr
+++ b/src/test/ui/derives/derives-span-Default-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::default::Default` is not satisfied
-  --> $DIR/derives-span-Default-struct.rs:12:5
+  --> $DIR/derives-span-Default-struct.rs:8:5
    |
 LL |     x: Error
    |     ^^^^^^^^ the trait `std::default::Default` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Default-tuple-struct.rs b/src/test/ui/derives/derives-span-Default-tuple-struct.rs
index 8b89b75..463f7d2 100644
--- a/src/test/ui/derives/derives-span-Default-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Default-tuple-struct.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Default-tuple-struct.stderr b/src/test/ui/derives/derives-span-Default-tuple-struct.stderr
index d976891..fa7b27e 100644
--- a/src/test/ui/derives/derives-span-Default-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Default-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::default::Default` is not satisfied
-  --> $DIR/derives-span-Default-tuple-struct.rs:12:5
+  --> $DIR/derives-span-Default-tuple-struct.rs:8:5
    |
 LL |     Error
    |     ^^^^^ the trait `std::default::Default` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Eq-enum-struct-variant.rs b/src/test/ui/derives/derives-span-Eq-enum-struct-variant.rs
index 36e6ae8..d2dab86 100644
--- a/src/test/ui/derives/derives-span-Eq-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-Eq-enum-struct-variant.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr
index f886c29..704825c 100644
--- a/src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Eq` is not satisfied
-  --> $DIR/derives-span-Eq-enum-struct-variant.rs:13:6
+  --> $DIR/derives-span-Eq-enum-struct-variant.rs:9:6
    |
 LL |      x: Error
    |      ^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Eq-enum.rs b/src/test/ui/derives/derives-span-Eq-enum.rs
index 4282515..c6c0d43 100644
--- a/src/test/ui/derives/derives-span-Eq-enum.rs
+++ b/src/test/ui/derives/derives-span-Eq-enum.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Eq-enum.stderr b/src/test/ui/derives/derives-span-Eq-enum.stderr
index 0b54701..8d24996 100644
--- a/src/test/ui/derives/derives-span-Eq-enum.stderr
+++ b/src/test/ui/derives/derives-span-Eq-enum.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Eq` is not satisfied
-  --> $DIR/derives-span-Eq-enum.rs:13:6
+  --> $DIR/derives-span-Eq-enum.rs:9:6
    |
 LL |      Error
    |      ^^^^^ the trait `std::cmp::Eq` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Eq-struct.rs b/src/test/ui/derives/derives-span-Eq-struct.rs
index d290ee5..df31003 100644
--- a/src/test/ui/derives/derives-span-Eq-struct.rs
+++ b/src/test/ui/derives/derives-span-Eq-struct.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Eq-struct.stderr b/src/test/ui/derives/derives-span-Eq-struct.stderr
index 76904d6..22db0bf 100644
--- a/src/test/ui/derives/derives-span-Eq-struct.stderr
+++ b/src/test/ui/derives/derives-span-Eq-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Eq` is not satisfied
-  --> $DIR/derives-span-Eq-struct.rs:12:5
+  --> $DIR/derives-span-Eq-struct.rs:8:5
    |
 LL |     x: Error
    |     ^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Eq-tuple-struct.rs b/src/test/ui/derives/derives-span-Eq-tuple-struct.rs
index 6458b63..abf6526 100644
--- a/src/test/ui/derives/derives-span-Eq-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Eq-tuple-struct.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Eq-tuple-struct.stderr b/src/test/ui/derives/derives-span-Eq-tuple-struct.stderr
index ff94b98..eaf1469 100644
--- a/src/test/ui/derives/derives-span-Eq-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Eq-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Eq` is not satisfied
-  --> $DIR/derives-span-Eq-tuple-struct.rs:12:5
+  --> $DIR/derives-span-Eq-tuple-struct.rs:8:5
    |
 LL |     Error
    |     ^^^^^ the trait `std::cmp::Eq` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs
index fc04b1a..3018a7b 100644
--- a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr
index 889c725..32f4265 100644
--- a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
-  --> $DIR/derives-span-Hash-enum-struct-variant.rs:13:6
+  --> $DIR/derives-span-Hash-enum-struct-variant.rs:9:6
    |
 LL |      x: Error
    |      ^^^^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Hash-enum.rs b/src/test/ui/derives/derives-span-Hash-enum.rs
index daff0b2..8ce7df1 100644
--- a/src/test/ui/derives/derives-span-Hash-enum.rs
+++ b/src/test/ui/derives/derives-span-Hash-enum.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 struct Error;
diff --git a/src/test/ui/derives/derives-span-Hash-enum.stderr b/src/test/ui/derives/derives-span-Hash-enum.stderr
index 70b8a85..b8d6277 100644
--- a/src/test/ui/derives/derives-span-Hash-enum.stderr
+++ b/src/test/ui/derives/derives-span-Hash-enum.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
-  --> $DIR/derives-span-Hash-enum.rs:12:6
+  --> $DIR/derives-span-Hash-enum.rs:8:6
    |
 LL |      Error
    |      ^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Hash-struct.rs b/src/test/ui/derives/derives-span-Hash-struct.rs
index 12a9eda..fa5e2af 100644
--- a/src/test/ui/derives/derives-span-Hash-struct.rs
+++ b/src/test/ui/derives/derives-span-Hash-struct.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Hash-struct.stderr b/src/test/ui/derives/derives-span-Hash-struct.stderr
index 6189739..ae431d2 100644
--- a/src/test/ui/derives/derives-span-Hash-struct.stderr
+++ b/src/test/ui/derives/derives-span-Hash-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
-  --> $DIR/derives-span-Hash-struct.rs:12:5
+  --> $DIR/derives-span-Hash-struct.rs:8:5
    |
 LL |     x: Error
    |     ^^^^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Hash-tuple-struct.rs b/src/test/ui/derives/derives-span-Hash-tuple-struct.rs
index 344b85d..3822bce 100644
--- a/src/test/ui/derives/derives-span-Hash-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Hash-tuple-struct.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr b/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
index fb929ad..db32193 100644
--- a/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
-  --> $DIR/derives-span-Hash-tuple-struct.rs:12:5
+  --> $DIR/derives-span-Hash-tuple-struct.rs:8:5
    |
 LL |     Error
    |     ^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Ord-enum-struct-variant.rs b/src/test/ui/derives/derives-span-Ord-enum-struct-variant.rs
index 196996c..62355cc 100644
--- a/src/test/ui/derives/derives-span-Ord-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-Ord-enum-struct-variant.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(Eq,PartialOrd,PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr
index 7e73392..d0286ad 100644
--- a/src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Ord` is not satisfied
-  --> $DIR/derives-span-Ord-enum-struct-variant.rs:13:6
+  --> $DIR/derives-span-Ord-enum-struct-variant.rs:9:6
    |
 LL |      x: Error
    |      ^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Ord-enum.rs b/src/test/ui/derives/derives-span-Ord-enum.rs
index 6282a690..7273893 100644
--- a/src/test/ui/derives/derives-span-Ord-enum.rs
+++ b/src/test/ui/derives/derives-span-Ord-enum.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(Eq,PartialOrd,PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Ord-enum.stderr b/src/test/ui/derives/derives-span-Ord-enum.stderr
index 68df309..aabbd0a 100644
--- a/src/test/ui/derives/derives-span-Ord-enum.stderr
+++ b/src/test/ui/derives/derives-span-Ord-enum.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Ord` is not satisfied
-  --> $DIR/derives-span-Ord-enum.rs:13:6
+  --> $DIR/derives-span-Ord-enum.rs:9:6
    |
 LL |      Error
    |      ^^^^^ the trait `std::cmp::Ord` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Ord-struct.rs b/src/test/ui/derives/derives-span-Ord-struct.rs
index e7bc7cf..53d4c2c 100644
--- a/src/test/ui/derives/derives-span-Ord-struct.rs
+++ b/src/test/ui/derives/derives-span-Ord-struct.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(Eq,PartialOrd,PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Ord-struct.stderr b/src/test/ui/derives/derives-span-Ord-struct.stderr
index 5e1ed33..eaac3da 100644
--- a/src/test/ui/derives/derives-span-Ord-struct.stderr
+++ b/src/test/ui/derives/derives-span-Ord-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Ord` is not satisfied
-  --> $DIR/derives-span-Ord-struct.rs:12:5
+  --> $DIR/derives-span-Ord-struct.rs:8:5
    |
 LL |     x: Error
    |     ^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Ord-tuple-struct.rs b/src/test/ui/derives/derives-span-Ord-tuple-struct.rs
index 3b62355..4e09c27 100644
--- a/src/test/ui/derives/derives-span-Ord-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Ord-tuple-struct.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(Eq,PartialOrd,PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Ord-tuple-struct.stderr b/src/test/ui/derives/derives-span-Ord-tuple-struct.stderr
index d9692e5..0ae36bc 100644
--- a/src/test/ui/derives/derives-span-Ord-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Ord-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Ord` is not satisfied
-  --> $DIR/derives-span-Ord-tuple-struct.rs:12:5
+  --> $DIR/derives-span-Ord-tuple-struct.rs:8:5
    |
 LL |     Error
    |     ^^^^^ the trait `std::cmp::Ord` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs
index f935d580..d66faa0 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr
index c669636..8ff4b46 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0369]: binary operation `==` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:13:6
+  --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:9:6
    |
 LL |      x: Error
    |      ^^^^^^^^
@@ -8,7 +8,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0369]: binary operation `!=` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:13:6
+  --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:9:6
    |
 LL |      x: Error
    |      ^^^^^^^^
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum.rs b/src/test/ui/derives/derives-span-PartialEq-enum.rs
index a0c5681..66edf460 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-enum.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum.stderr b/src/test/ui/derives/derives-span-PartialEq-enum.stderr
index ff98ede..b4a12b1 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-enum.stderr
@@ -1,5 +1,5 @@
 error[E0369]: binary operation `==` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-enum.rs:13:6
+  --> $DIR/derives-span-PartialEq-enum.rs:9:6
    |
 LL |      Error
    |      ^^^^^
@@ -8,7 +8,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0369]: binary operation `!=` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-enum.rs:13:6
+  --> $DIR/derives-span-PartialEq-enum.rs:9:6
    |
 LL |      Error
    |      ^^^^^
diff --git a/src/test/ui/derives/derives-span-PartialEq-struct.rs b/src/test/ui/derives/derives-span-PartialEq-struct.rs
index c190dd0..ce5c67a 100644
--- a/src/test/ui/derives/derives-span-PartialEq-struct.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-struct.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-PartialEq-struct.stderr b/src/test/ui/derives/derives-span-PartialEq-struct.stderr
index 200b8e2..b4f6c51 100644
--- a/src/test/ui/derives/derives-span-PartialEq-struct.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-struct.stderr
@@ -1,5 +1,5 @@
 error[E0369]: binary operation `==` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-struct.rs:12:5
+  --> $DIR/derives-span-PartialEq-struct.rs:8:5
    |
 LL |     x: Error
    |     ^^^^^^^^
@@ -8,7 +8,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0369]: binary operation `!=` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-struct.rs:12:5
+  --> $DIR/derives-span-PartialEq-struct.rs:8:5
    |
 LL |     x: Error
    |     ^^^^^^^^
diff --git a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs
index dfc9c03..eaa6283 100644
--- a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr
index 9e3d130..2e6b1d7 100644
--- a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0369]: binary operation `==` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-tuple-struct.rs:12:5
+  --> $DIR/derives-span-PartialEq-tuple-struct.rs:8:5
    |
 LL |     Error
    |     ^^^^^
@@ -8,7 +8,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0369]: binary operation `!=` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-tuple-struct.rs:12:5
+  --> $DIR/derives-span-PartialEq-tuple-struct.rs:8:5
    |
 LL |     Error
    |     ^^^^^
diff --git a/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs b/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs
index beef639..4e7a8d7 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr
index 6433d1f..0be7597 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:13:6
+  --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:9:6
    |
 LL |      x: Error
    |      ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
@@ -9,7 +9,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:13:6
+  --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:9:6
    |
 LL |      x: Error
    |      ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
@@ -19,7 +19,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:13:6
+  --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:9:6
    |
 LL |      x: Error
    |      ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
@@ -29,7 +29,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:13:6
+  --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:9:6
    |
 LL |      x: Error
    |      ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
@@ -39,7 +39,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:13:6
+  --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:9:6
    |
 LL |      x: Error
    |      ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
diff --git a/src/test/ui/derives/derives-span-PartialOrd-enum.rs b/src/test/ui/derives/derives-span-PartialOrd-enum.rs
index b02828d..d0a6c5a 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-enum.rs
+++ b/src/test/ui/derives/derives-span-PartialOrd-enum.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-PartialOrd-enum.stderr b/src/test/ui/derives/derives-span-PartialOrd-enum.stderr
index b1be7dd..6429002 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-enum.stderr
+++ b/src/test/ui/derives/derives-span-PartialOrd-enum.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-enum.rs:13:6
+  --> $DIR/derives-span-PartialOrd-enum.rs:9:6
    |
 LL |      Error
    |      ^^^^^ no implementation for `Error < Error` and `Error > Error`
@@ -9,7 +9,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-enum.rs:13:6
+  --> $DIR/derives-span-PartialOrd-enum.rs:9:6
    |
 LL |      Error
    |      ^^^^^ no implementation for `Error < Error` and `Error > Error`
@@ -19,7 +19,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-enum.rs:13:6
+  --> $DIR/derives-span-PartialOrd-enum.rs:9:6
    |
 LL |      Error
    |      ^^^^^ no implementation for `Error < Error` and `Error > Error`
@@ -29,7 +29,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-enum.rs:13:6
+  --> $DIR/derives-span-PartialOrd-enum.rs:9:6
    |
 LL |      Error
    |      ^^^^^ no implementation for `Error < Error` and `Error > Error`
@@ -39,7 +39,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-enum.rs:13:6
+  --> $DIR/derives-span-PartialOrd-enum.rs:9:6
    |
 LL |      Error
    |      ^^^^^ no implementation for `Error < Error` and `Error > Error`
diff --git a/src/test/ui/derives/derives-span-PartialOrd-struct.rs b/src/test/ui/derives/derives-span-PartialOrd-struct.rs
index bfcfc3d..a596a2e 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-struct.rs
+++ b/src/test/ui/derives/derives-span-PartialOrd-struct.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-PartialOrd-struct.stderr b/src/test/ui/derives/derives-span-PartialOrd-struct.stderr
index 064c91f..dcd8158 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-struct.stderr
+++ b/src/test/ui/derives/derives-span-PartialOrd-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-struct.rs:12:5
+  --> $DIR/derives-span-PartialOrd-struct.rs:8:5
    |
 LL |     x: Error
    |     ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
@@ -9,7 +9,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-struct.rs:12:5
+  --> $DIR/derives-span-PartialOrd-struct.rs:8:5
    |
 LL |     x: Error
    |     ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
@@ -19,7 +19,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-struct.rs:12:5
+  --> $DIR/derives-span-PartialOrd-struct.rs:8:5
    |
 LL |     x: Error
    |     ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
@@ -29,7 +29,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-struct.rs:12:5
+  --> $DIR/derives-span-PartialOrd-struct.rs:8:5
    |
 LL |     x: Error
    |     ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
@@ -39,7 +39,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-struct.rs:12:5
+  --> $DIR/derives-span-PartialOrd-struct.rs:8:5
    |
 LL |     x: Error
    |     ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
diff --git a/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.rs b/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.rs
index c8bdd64..6dd1623 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr b/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr
index 5b62702..8dbf103 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-tuple-struct.rs:12:5
+  --> $DIR/derives-span-PartialOrd-tuple-struct.rs:8:5
    |
 LL |     Error
    |     ^^^^^ no implementation for `Error < Error` and `Error > Error`
@@ -9,7 +9,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-tuple-struct.rs:12:5
+  --> $DIR/derives-span-PartialOrd-tuple-struct.rs:8:5
    |
 LL |     Error
    |     ^^^^^ no implementation for `Error < Error` and `Error > Error`
@@ -19,7 +19,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-tuple-struct.rs:12:5
+  --> $DIR/derives-span-PartialOrd-tuple-struct.rs:8:5
    |
 LL |     Error
    |     ^^^^^ no implementation for `Error < Error` and `Error > Error`
@@ -29,7 +29,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-tuple-struct.rs:12:5
+  --> $DIR/derives-span-PartialOrd-tuple-struct.rs:8:5
    |
 LL |     Error
    |     ^^^^^ no implementation for `Error < Error` and `Error > Error`
@@ -39,7 +39,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-tuple-struct.rs:12:5
+  --> $DIR/derives-span-PartialOrd-tuple-struct.rs:8:5
    |
 LL |     Error
    |     ^^^^^ no implementation for `Error < Error` and `Error > Error`
diff --git a/src/test/ui/derives/deriving-meta-unknown-trait.rs b/src/test/ui/derives/deriving-meta-unknown-trait.rs
index d1af5b4..6463a76 100644
--- a/src/test/ui/derives/deriving-meta-unknown-trait.rs
+++ b/src/test/ui/derives/deriving-meta-unknown-trait.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 #[derive(Eqr)]
 //~^ ERROR cannot find derive macro `Eqr` in this scope
 //~| ERROR cannot find derive macro `Eqr` in this scope
diff --git a/src/test/ui/derives/deriving-meta-unknown-trait.stderr b/src/test/ui/derives/deriving-meta-unknown-trait.stderr
index ead1313..a587c34 100644
--- a/src/test/ui/derives/deriving-meta-unknown-trait.stderr
+++ b/src/test/ui/derives/deriving-meta-unknown-trait.stderr
@@ -1,5 +1,5 @@
 error: cannot find derive macro `Eqr` in this scope
-  --> $DIR/deriving-meta-unknown-trait.rs:5:10
+  --> $DIR/deriving-meta-unknown-trait.rs:1:10
    |
 LL | #[derive(Eqr)]
    |          ^^^ help: a derive macro with a similar name exists: `Eq`
@@ -10,7 +10,7 @@
    | ------------------------ similarly named derive macro `Eq` defined here
 
 error: cannot find derive macro `Eqr` in this scope
-  --> $DIR/deriving-meta-unknown-trait.rs:5:10
+  --> $DIR/deriving-meta-unknown-trait.rs:1:10
    |
 LL | #[derive(Eqr)]
    |          ^^^ help: a derive macro with a similar name exists: `Eq`
diff --git a/src/test/ui/error-codes/E0004-2.rs b/src/test/ui/error-codes/E0004-2.rs
index 7f1d064..c7612fd 100644
--- a/src/test/ui/error-codes/E0004-2.rs
+++ b/src/test/ui/error-codes/E0004-2.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 fn main() {
     let x = Some(1);
 
diff --git a/src/test/ui/error-codes/E0004-2.stderr b/src/test/ui/error-codes/E0004-2.stderr
index fcc44b7..e48bc74 100644
--- a/src/test/ui/error-codes/E0004-2.stderr
+++ b/src/test/ui/error-codes/E0004-2.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: `None` and `Some(_)` not covered
-  --> $DIR/E0004-2.rs:9:11
+  --> $DIR/E0004-2.rs:4:11
    |
 LL |     match x { }
    |           ^ patterns `None` and `Some(_)` not covered
diff --git a/src/test/ui/error-codes/E0005.rs b/src/test/ui/error-codes/E0005.rs
index 75faad8..f473069 100644
--- a/src/test/ui/error-codes/E0005.rs
+++ b/src/test/ui/error-codes/E0005.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 fn main() {
     let x = Some(1);
     let Some(y) = x; //~ ERROR E0005
diff --git a/src/test/ui/error-codes/E0005.stderr b/src/test/ui/error-codes/E0005.stderr
index d43dc6f..68aff46 100644
--- a/src/test/ui/error-codes/E0005.stderr
+++ b/src/test/ui/error-codes/E0005.stderr
@@ -1,5 +1,5 @@
 error[E0005]: refutable pattern in local binding: `None` not covered
-  --> $DIR/E0005.rs:8:9
+  --> $DIR/E0005.rs:3:9
    |
 LL |     let Some(y) = x;
    |         ^^^^^^^ pattern `None` not covered
diff --git a/src/test/ui/error-codes/E0283.stderr b/src/test/ui/error-codes/E0283.stderr
index ae5b7c3..e95583c 100644
--- a/src/test/ui/error-codes/E0283.stderr
+++ b/src/test/ui/error-codes/E0283.stderr
@@ -7,7 +7,7 @@
 LL |     let cont: u32 = Generator::create();
    |                     ^^^^^^^^^^^^^^^^^ cannot infer type
    |
-   = note: cannot resolve `_: Generator`
+   = note: cannot satisfy `_: Generator`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0297.rs b/src/test/ui/error-codes/E0297.rs
index b26ede9..27c7960 100644
--- a/src/test/ui/error-codes/E0297.rs
+++ b/src/test/ui/error-codes/E0297.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 fn main() {
     let xs : Vec<Option<i32>> = vec![Some(1), None];
 
diff --git a/src/test/ui/error-codes/E0297.stderr b/src/test/ui/error-codes/E0297.stderr
index 3ad8418..b2d181b 100644
--- a/src/test/ui/error-codes/E0297.stderr
+++ b/src/test/ui/error-codes/E0297.stderr
@@ -1,5 +1,5 @@
 error[E0005]: refutable pattern in `for` loop binding: `None` not covered
-  --> $DIR/E0297.rs:9:9
+  --> $DIR/E0297.rs:4:9
    |
 LL |     for Some(x) in xs {}
    |         ^^^^^^^ pattern `None` not covered
diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs
index d2e5229..f0cc9ea 100644
--- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs
+++ b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 #![feature(never_type)]
 
 fn foo() -> Result<u32, !> {
diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
index 06c2e6e..823dad2 100644
--- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
+++ b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
@@ -1,5 +1,5 @@
 error[E0005]: refutable pattern in local binding: `Err(_)` not covered
-  --> $DIR/feature-gate-exhaustive-patterns.rs:13:9
+  --> $DIR/feature-gate-exhaustive-patterns.rs:8:9
    |
 LL |     let Ok(_x) = foo();
    |         ^^^^^^ pattern `Err(_)` not covered
diff --git a/src/test/ui/feature-gates/feature-gate-link_cfg.stderr b/src/test/ui/feature-gates/feature-gate-link_cfg.stderr
index 10b151f..41a7dfc 100644
--- a/src/test/ui/feature-gates/feature-gate-link_cfg.stderr
+++ b/src/test/ui/feature-gates/feature-gate-link_cfg.stderr
@@ -1,4 +1,4 @@
-error[E0658]: is unstable
+error[E0658]: kind="link_cfg" is unstable
   --> $DIR/feature-gate-link_cfg.rs:1:1
    |
 LL | #[link(name = "foo", cfg(foo))]
diff --git a/src/test/ui/generic-associated-types/iterable.rs b/src/test/ui/generic-associated-types/iterable.rs
index 6164211..105ab4a 100644
--- a/src/test/ui/generic-associated-types/iterable.rs
+++ b/src/test/ui/generic-associated-types/iterable.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 #![allow(incomplete_features)]
 #![feature(generic_associated_types)]
 
diff --git a/src/test/ui/generic-associated-types/iterable.stderr b/src/test/ui/generic-associated-types/iterable.stderr
index e18c6ce..b5bc0c7 100644
--- a/src/test/ui/generic-associated-types/iterable.stderr
+++ b/src/test/ui/generic-associated-types/iterable.stderr
@@ -1,5 +1,5 @@
 error[E0271]: type mismatch resolving `for<'a> <<std::vec::Vec<T> as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <std::vec::Vec<T> as Iterable>::Item<'a>`
-  --> $DIR/iterable.rs:20:5
+  --> $DIR/iterable.rs:15:5
    |
 LL | impl<T> Iterable for Vec<T> {
    | --------------------------- in this `impl` item
@@ -17,7 +17,7 @@
    = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error[E0271]: type mismatch resolving `for<'a> <<[T] as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <[T] as Iterable>::Item<'a>`
-  --> $DIR/iterable.rs:32:5
+  --> $DIR/iterable.rs:27:5
    |
 LL | impl<T> Iterable for [T] {
    | ------------------------ in this `impl` item
@@ -35,7 +35,7 @@
    = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error[E0271]: type mismatch resolving `for<'a> <<std::vec::Vec<T> as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <std::vec::Vec<T> as Iterable>::Item<'a>`
-  --> $DIR/iterable.rs:24:30
+  --> $DIR/iterable.rs:19:30
    |
 LL | trait Iterable {
    | -------------- required by `Iterable`
@@ -49,7 +49,7 @@
    = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error[E0271]: type mismatch resolving `for<'a> <<[T] as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <[T] as Iterable>::Item<'a>`
-  --> $DIR/iterable.rs:36:30
+  --> $DIR/iterable.rs:31:30
    |
 LL | trait Iterable {
    | -------------- required by `Iterable`
diff --git a/src/test/ui/impl-trait/impl-generic-mismatch.rs b/src/test/ui/impl-trait/impl-generic-mismatch.rs
index 615dd6d..ba678bb 100644
--- a/src/test/ui/impl-trait/impl-generic-mismatch.rs
+++ b/src/test/ui/impl-trait/impl-generic-mismatch.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 use std::fmt::Debug;
 
 trait Foo {
diff --git a/src/test/ui/impl-trait/impl-generic-mismatch.stderr b/src/test/ui/impl-trait/impl-generic-mismatch.stderr
index 0c294d1..8d8daa0 100644
--- a/src/test/ui/impl-trait/impl-generic-mismatch.stderr
+++ b/src/test/ui/impl-trait/impl-generic-mismatch.stderr
@@ -1,5 +1,5 @@
 error[E0643]: method `foo` has incompatible signature for trait
-  --> $DIR/impl-generic-mismatch.rs:13:12
+  --> $DIR/impl-generic-mismatch.rs:8:12
    |
 LL |     fn foo(&self, _: &impl Debug);
    |                       ---------- declaration in trait here
@@ -13,7 +13,7 @@
    |          --           ^^^^^^^^^^
 
 error[E0643]: method `bar` has incompatible signature for trait
-  --> $DIR/impl-generic-mismatch.rs:22:23
+  --> $DIR/impl-generic-mismatch.rs:17:23
    |
 LL |     fn bar<U: Debug>(&self, _: &U);
    |            - declaration in trait here
@@ -27,7 +27,7 @@
    |           ^^^^^^^^^^            ^
 
 error[E0643]: method `hash` has incompatible signature for trait
-  --> $DIR/impl-generic-mismatch.rs:33:33
+  --> $DIR/impl-generic-mismatch.rs:28:33
    |
 LL |     fn hash(&self, hasher: &mut impl Hasher) {}
    |                                 ^^^^^^^^^^^ expected generic parameter, found `impl Trait`
diff --git a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs
index 8c23def..6ff3ab7 100644
--- a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs
+++ b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // aux-build:two_macros.rs
 
 macro_rules! define_vec {
diff --git a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr
index e344d05..3269945 100644
--- a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr
+++ b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr
@@ -1,5 +1,5 @@
 error: macro-expanded `extern crate` items cannot shadow names passed with `--extern`
-  --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:23:9
+  --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:19:9
    |
 LL |         extern crate std as core;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -10,13 +10,13 @@
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0659]: `Vec` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
-  --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:17:9
+  --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:13:9
    |
 LL |         Vec::panic!();
    |         ^^^ ambiguous name
    |
 note: `Vec` could refer to the crate imported here
-  --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:9:9
+  --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:5:9
    |
 LL |         extern crate std as Vec;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs
index b07a7f1..1b524ec 100644
--- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs
+++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 use std::ops::Deref;
 trait Trait {}
 
diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr
index 374e308..c1c4ec9 100644
--- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr
+++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr
@@ -1,5 +1,5 @@
 error: `impl` item signature doesn't match `trait` item signature
-  --> $DIR/mismatched_trait_impl-2.rs:12:5
+  --> $DIR/mismatched_trait_impl-2.rs:8:5
    |
 LL |     fn deref(&self) -> &dyn Trait {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&Struct) -> &dyn Trait
diff --git a/src/test/ui/interior-mutability/interior-mutability.rs b/src/test/ui/interior-mutability/interior-mutability.rs
index e6586de..ddc882c 100644
--- a/src/test/ui/interior-mutability/interior-mutability.rs
+++ b/src/test/ui/interior-mutability/interior-mutability.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 use std::cell::Cell;
 use std::panic::catch_unwind;
 fn main() {
diff --git a/src/test/ui/interior-mutability/interior-mutability.stderr b/src/test/ui/interior-mutability/interior-mutability.stderr
index 2378e41..1a726be 100644
--- a/src/test/ui/interior-mutability/interior-mutability.stderr
+++ b/src/test/ui/interior-mutability/interior-mutability.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the type `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
-  --> $DIR/interior-mutability.rs:9:5
+  --> $DIR/interior-mutability.rs:5:5
    |
 LL |     catch_unwind(|| { x.set(23); });
    |     ^^^^^^^^^^^^ `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
@@ -12,7 +12,7 @@
    = help: within `std::cell::Cell<i32>`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<i32>`
    = note: required because it appears within the type `std::cell::Cell<i32>`
    = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&std::cell::Cell<i32>`
-   = note: required because it appears within the type `[closure@$DIR/interior-mutability.rs:9:18: 9:35 x:&std::cell::Cell<i32>]`
+   = note: required because it appears within the type `[closure@$DIR/interior-mutability.rs:5:18: 5:35 x:&std::cell::Cell<i32>]`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-12028.stderr b/src/test/ui/issues/issue-12028.stderr
index fe7e8f8..434c5de 100644
--- a/src/test/ui/issues/issue-12028.stderr
+++ b/src/test/ui/issues/issue-12028.stderr
@@ -4,7 +4,7 @@
 LL |         self.input_stream(&mut stream);
    |              ^^^^^^^^^^^^ cannot infer type for type parameter `H` declared on the trait `StreamHash`
    |
-   = note: cannot resolve `<_ as StreamHasher>::S == <H as StreamHasher>::S`
+   = note: cannot satisfy `<_ as StreamHasher>::S == <H as StreamHasher>::S`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-17546.rs b/src/test/ui/issues/issue-17546.rs
index c93a03c..dbfdad2 100644
--- a/src/test/ui/issues/issue-17546.rs
+++ b/src/test/ui/issues/issue-17546.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 use foo::MyEnum::Result;
 use foo::NoResult; // Through a re-export
 
diff --git a/src/test/ui/issues/issue-17546.stderr b/src/test/ui/issues/issue-17546.stderr
index 2d532cd..5bbe6d3 100644
--- a/src/test/ui/issues/issue-17546.stderr
+++ b/src/test/ui/issues/issue-17546.stderr
@@ -1,5 +1,5 @@
 error[E0573]: expected type, found variant `NoResult`
-  --> $DIR/issue-17546.rs:16:17
+  --> $DIR/issue-17546.rs:12:17
    |
 LL |     fn new() -> NoResult<MyEnum, String> {
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -19,7 +19,7 @@
    |                 ^^^^^^
 
 error[E0573]: expected type, found variant `Result`
-  --> $DIR/issue-17546.rs:26:17
+  --> $DIR/issue-17546.rs:22:17
    |
 LL |     fn new() -> Result<foo::MyEnum, String> {
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a type
@@ -37,7 +37,7 @@
      and 1 other candidate
 
 error[E0573]: expected type, found variant `Result`
-  --> $DIR/issue-17546.rs:32:13
+  --> $DIR/issue-17546.rs:28:13
    |
 LL | fn new() -> Result<foo::MyEnum, String> {
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a type
@@ -55,7 +55,7 @@
      and 1 other candidate
 
 error[E0573]: expected type, found variant `NoResult`
-  --> $DIR/issue-17546.rs:37:15
+  --> $DIR/issue-17546.rs:33:15
    |
 LL | fn newer() -> NoResult<foo::MyEnum, String> {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/issues/issue-21160.rs b/src/test/ui/issues/issue-21160.rs
index a13b778..4673356 100644
--- a/src/test/ui/issues/issue-21160.rs
+++ b/src/test/ui/issues/issue-21160.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 struct Bar;
 
 impl Bar {
diff --git a/src/test/ui/issues/issue-21160.stderr b/src/test/ui/issues/issue-21160.stderr
index a24dc8a..0c3d75c 100644
--- a/src/test/ui/issues/issue-21160.stderr
+++ b/src/test/ui/issues/issue-21160.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Bar: std::hash::Hash` is not satisfied
-  --> $DIR/issue-21160.rs:12:12
+  --> $DIR/issue-21160.rs:8:12
    |
 LL | struct Foo(Bar);
    |            ^^^ the trait `std::hash::Hash` is not implemented for `Bar`
diff --git a/src/test/ui/issues/issue-21974.stderr b/src/test/ui/issues/issue-21974.stderr
index 1982349..d36d0da 100644
--- a/src/test/ui/issues/issue-21974.stderr
+++ b/src/test/ui/issues/issue-21974.stderr
@@ -7,7 +7,7 @@
 LL |     where &'a T : Foo,
    |                   ^^^ cannot infer type for reference `&'a T`
    |
-   = note: cannot resolve `&'a T: Foo`
+   = note: cannot satisfy `&'a T: Foo`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-24424.stderr b/src/test/ui/issues/issue-24424.stderr
index 538d44c..f933898 100644
--- a/src/test/ui/issues/issue-24424.stderr
+++ b/src/test/ui/issues/issue-24424.stderr
@@ -7,7 +7,7 @@
 LL | impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {}
    |                                                         ^^^^^^^^^^^ cannot infer type for type parameter `T0`
    |
-   = note: cannot resolve `T0: Trait0<'l0>`
+   = note: cannot satisfy `T0: Trait0<'l0>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-27033.rs b/src/test/ui/issues/issue-27033.rs
index 2798e51..a23819a 100644
--- a/src/test/ui/issues/issue-27033.rs
+++ b/src/test/ui/issues/issue-27033.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 fn main() {
     match Some(1) {
         None @ _ => {} //~ ERROR match bindings cannot shadow unit variants
diff --git a/src/test/ui/issues/issue-27033.stderr b/src/test/ui/issues/issue-27033.stderr
index c0de0f1..3bd7469 100644
--- a/src/test/ui/issues/issue-27033.stderr
+++ b/src/test/ui/issues/issue-27033.stderr
@@ -1,5 +1,5 @@
 error[E0530]: match bindings cannot shadow unit variants
-  --> $DIR/issue-27033.rs:7:9
+  --> $DIR/issue-27033.rs:3:9
    |
 LL |         None @ _ => {}
    |         ^^^^ cannot be named the same as a unit variant
@@ -10,7 +10,7 @@
    |                                       ---- the unit variant `None` is defined here
 
 error[E0530]: match bindings cannot shadow constants
-  --> $DIR/issue-27033.rs:11:9
+  --> $DIR/issue-27033.rs:7:9
    |
 LL |     const C: u8 = 1;
    |     ---------------- the constant `C` is defined here
diff --git a/src/test/ui/issues/issue-2823.rs b/src/test/ui/issues/issue-2823.rs
index f00c230..7b443b4 100644
--- a/src/test/ui/issues/issue-2823.rs
+++ b/src/test/ui/issues/issue-2823.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 struct C {
     x: isize,
 }
diff --git a/src/test/ui/issues/issue-2823.stderr b/src/test/ui/issues/issue-2823.stderr
index 6e11dd4..0cdc501 100644
--- a/src/test/ui/issues/issue-2823.stderr
+++ b/src/test/ui/issues/issue-2823.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `clone` found for struct `C` in the current scope
-  --> $DIR/issue-2823.rs:18:16
+  --> $DIR/issue-2823.rs:13:16
    |
 LL | struct C {
    | -------- method `clone` not found for this
diff --git a/src/test/ui/issues/issue-29147.stderr b/src/test/ui/issues/issue-29147.stderr
index 1efedb4..94aff59 100644
--- a/src/test/ui/issues/issue-29147.stderr
+++ b/src/test/ui/issues/issue-29147.stderr
@@ -7,7 +7,7 @@
 LL |     let _ = <S5<_>>::xxx;
    |             ^^^^^^^^^^^^ cannot infer type for struct `S5<_>`
    |
-   = note: cannot resolve `S5<_>: Foo`
+   = note: cannot satisfy `S5<_>: Foo`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-31173.rs b/src/test/ui/issues/issue-31173.rs
index 25be266..2619531 100644
--- a/src/test/ui/issues/issue-31173.rs
+++ b/src/test/ui/issues/issue-31173.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 use std::vec::IntoIter;
 
 pub fn get_tok(it: &mut IntoIter<u8>) {
diff --git a/src/test/ui/issues/issue-31173.stderr b/src/test/ui/issues/issue-31173.stderr
index 20bfdee..62c9e56 100644
--- a/src/test/ui/issues/issue-31173.stderr
+++ b/src/test/ui/issues/issue-31173.stderr
@@ -1,5 +1,5 @@
-error[E0271]: type mismatch resolving `<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:10:39: 13:6 found_e:_]> as std::iter::Iterator>::Item == &_`
-  --> $DIR/issue-31173.rs:14:10
+error[E0271]: type mismatch resolving `<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 9:6 found_e:_]> as std::iter::Iterator>::Item == &_`
+  --> $DIR/issue-31173.rs:10:10
    |
 LL |         .cloned()
    |          ^^^^^^ expected `u8`, found reference
@@ -7,11 +7,11 @@
    = note:   expected type `u8`
            found reference `&_`
 
-error[E0599]: no method named `collect` found for struct `std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:10:39: 13:6 found_e:_]>>` in the current scope
-  --> $DIR/issue-31173.rs:18:10
+error[E0599]: no method named `collect` found for struct `std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 9:6 found_e:_]>>` in the current scope
+  --> $DIR/issue-31173.rs:14:10
    |
 LL |         .collect();
-   |          ^^^^^^^ method not found in `std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:10:39: 13:6 found_e:_]>>`
+   |          ^^^^^^^ method not found in `std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 9:6 found_e:_]>>`
    | 
   ::: $SRC_DIR/libcore/iter/adapters/mod.rs:LL:COL
    |
@@ -22,10 +22,10 @@
    | -------------------------- doesn't satisfy `<_ as std::iter::Iterator>::Item = &_`
    |
    = note: the method `collect` exists but the following trait bounds were not satisfied:
-           `<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:10:39: 13:6 found_e:_]> as std::iter::Iterator>::Item = &_`
-           which is required by `std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:10:39: 13:6 found_e:_]>>: std::iter::Iterator`
-           `std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:10:39: 13:6 found_e:_]>>: std::iter::Iterator`
-           which is required by `&mut std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:10:39: 13:6 found_e:_]>>: std::iter::Iterator`
+           `<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 9:6 found_e:_]> as std::iter::Iterator>::Item = &_`
+           which is required by `std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 9:6 found_e:_]>>: std::iter::Iterator`
+           `std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 9:6 found_e:_]>>: std::iter::Iterator`
+           which is required by `&mut std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 9:6 found_e:_]>>: std::iter::Iterator`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-38857.rs b/src/test/ui/issues/issue-38857.rs
index c0695f8..81d881c 100644
--- a/src/test/ui/issues/issue-38857.rs
+++ b/src/test/ui/issues/issue-38857.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 fn main() {
     let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() };
     //~^ ERROR failed to resolve: could not find `imp` in `sys` [E0433]
diff --git a/src/test/ui/issues/issue-38857.stderr b/src/test/ui/issues/issue-38857.stderr
index 1a287e9..ed700ff 100644
--- a/src/test/ui/issues/issue-38857.stderr
+++ b/src/test/ui/issues/issue-38857.stderr
@@ -1,11 +1,11 @@
 error[E0433]: failed to resolve: could not find `imp` in `sys`
-  --> $DIR/issue-38857.rs:7:23
+  --> $DIR/issue-38857.rs:2:23
    |
 LL |     let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() };
    |                       ^^^ could not find `imp` in `sys`
 
 error[E0603]: module `sys` is private
-  --> $DIR/issue-38857.rs:7:18
+  --> $DIR/issue-38857.rs:2:18
    |
 LL |     let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() };
    |                  ^^^ private module
diff --git a/src/test/ui/issues/issue-54954.stderr b/src/test/ui/issues/issue-54954.stderr
index 4967b82..ca5439e 100644
--- a/src/test/ui/issues/issue-54954.stderr
+++ b/src/test/ui/issues/issue-54954.stderr
@@ -13,7 +13,7 @@
 LL |     const fn const_val<T: Sized>() -> usize {
    |              --------- - required by this bound in `Tt::const_val`
    |
-   = note: cannot resolve `_: Tt`
+   = note: cannot satisfy `_: Tt`
 
 error[E0080]: evaluation of constant value failed
   --> $DIR/issue-54954.rs:13:15
diff --git a/src/test/ui/issues/issue-58022.stderr b/src/test/ui/issues/issue-58022.stderr
index 70a7c38..fb31467 100644
--- a/src/test/ui/issues/issue-58022.stderr
+++ b/src/test/ui/issues/issue-58022.stderr
@@ -16,7 +16,7 @@
    |                         cannot infer type
    |                         help: use the fully qualified path to an implementation: `<Type as Foo>::SIZE`
    |
-   = note: cannot resolve `_: Foo`
+   = note: cannot satisfy `_: Foo`
    = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-69725.rs b/src/test/ui/issues/issue-69725.rs
index a8e72e9..b8130b4 100644
--- a/src/test/ui/issues/issue-69725.rs
+++ b/src/test/ui/issues/issue-69725.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 // aux-build:issue-69725.rs
 
 extern crate issue_69725;
diff --git a/src/test/ui/issues/issue-69725.stderr b/src/test/ui/issues/issue-69725.stderr
index 439fae9..d9d61fe 100644
--- a/src/test/ui/issues/issue-69725.stderr
+++ b/src/test/ui/issues/issue-69725.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `clone` found for struct `issue_69725::Struct<A>` in the current scope
-  --> $DIR/issue-69725.rs:12:32
+  --> $DIR/issue-69725.rs:7:32
    |
 LL |     let _ = Struct::<A>::new().clone();
    |                                ^^^^^ method not found in `issue_69725::Struct<A>`
diff --git a/src/test/ui/issues/issue-69841.rs b/src/test/ui/issues/issue-69841.rs
new file mode 100644
index 0000000..942b99b
--- /dev/null
+++ b/src/test/ui/issues/issue-69841.rs
@@ -0,0 +1,30 @@
+// This is a regression test for issue rust-lang/rust#69841, which exposed an
+// LLVM bug which needed a fix to be backported.
+
+// run-pass
+
+fn main() {
+    let buffer = [49u8, 10];
+    let mut a : u64 = 0;
+    'read: loop {
+        for c in &buffer {
+            match c {
+                48..=57 => {
+                    a*= 10;
+                    a+= *c as u64 - 48;
+                }
+                10 => {
+                    break 'read;
+                }
+                _ => {
+                    unsafe { std::hint::unreachable_unchecked() };
+                }
+            }
+        }
+    }
+    if a == 1 {
+        println!("What did you expect?");
+    } else {
+        panic!("this should be unreachable.");
+    }
+}
diff --git a/src/test/ui/issues/issue-70673.rs b/src/test/ui/issues/issue-70673.rs
new file mode 100644
index 0000000..3561f40
--- /dev/null
+++ b/src/test/ui/issues/issue-70673.rs
@@ -0,0 +1,12 @@
+// Regression test for https://github.com/rust-lang/rust/issues/70673.
+
+// run-pass
+
+#![feature(thread_local)]
+
+#[thread_local]
+static A: &u8 = &42;
+
+fn main() {
+    dbg!(*A);
+}
diff --git a/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.rs b/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.rs
new file mode 100644
index 0000000..c268315
--- /dev/null
+++ b/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.rs
@@ -0,0 +1,10 @@
+fn a() -> i32 {
+    3
+}
+
+pub fn main() {
+    assert_eq!(a, 0);
+    //~^ ERROR binary operation `==` cannot
+    //~| ERROR mismatched types
+    //~| ERROR doesn't implement
+}
diff --git a/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr b/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr
new file mode 100644
index 0000000..467c15c
--- /dev/null
+++ b/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr
@@ -0,0 +1,41 @@
+error[E0369]: binary operation `==` cannot be applied to type `fn() -> i32 {a}`
+  --> $DIR/issue-70724-add_type_neq_err_label-unwrap.rs:6:5
+   |
+LL |     assert_eq!(a, 0);
+   |     ^^^^^^^^^^^^^^^^^
+   |     |
+   |     fn() -> i32 {a}
+   |     {integer}
+   |     help: you might have forgotten to call this function: `*left_val()`
+   |
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0308]: mismatched types
+  --> $DIR/issue-70724-add_type_neq_err_label-unwrap.rs:6:5
+   |
+LL |     assert_eq!(a, 0);
+   |     ^^^^^^^^^^^^^^^^^ expected fn item, found integer
+   |
+   = note: expected fn item `fn() -> i32 {a}`
+                 found type `i32`
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0277]: `fn() -> i32 {a}` doesn't implement `std::fmt::Debug`
+  --> $DIR/issue-70724-add_type_neq_err_label-unwrap.rs:6:5
+   |
+LL | fn a() -> i32 {
+   |    - consider calling this function
+...
+LL |     assert_eq!(a, 0);
+   |     ^^^^^^^^^^^^^^^^^ `fn() -> i32 {a}` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
+   |
+   = help: the trait `std::fmt::Debug` is not implemented for `fn() -> i32 {a}`
+   = help: use parentheses to call the function: `a()`
+   = note: required because of the requirements on the impl of `std::fmt::Debug` for `&fn() -> i32 {a}`
+   = note: required by `std::fmt::Debug::fmt`
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0277, E0308, E0369.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/issues/issue-7607-1.rs b/src/test/ui/issues/issue-7607-1.rs
index 1571cd2..5221f2c 100644
--- a/src/test/ui/issues/issue-7607-1.rs
+++ b/src/test/ui/issues/issue-7607-1.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 struct Foo {
     x: isize
 }
diff --git a/src/test/ui/issues/issue-7607-1.stderr b/src/test/ui/issues/issue-7607-1.stderr
index 94f489e..e86896a 100644
--- a/src/test/ui/issues/issue-7607-1.stderr
+++ b/src/test/ui/issues/issue-7607-1.stderr
@@ -1,5 +1,5 @@
 error[E0412]: cannot find type `Fo` in this scope
-  --> $DIR/issue-7607-1.rs:9:6
+  --> $DIR/issue-7607-1.rs:5:6
    |
 LL | impl Fo {
    |      ^^ help: a trait with a similar name exists: `Fn`
diff --git a/src/test/ui/keyword/extern/keyword-extern-as-identifier-type.rs b/src/test/ui/keyword/extern/keyword-extern-as-identifier-type.rs
index 3845a9a..12aa059 100644
--- a/src/test/ui/keyword/extern/keyword-extern-as-identifier-type.rs
+++ b/src/test/ui/keyword/extern/keyword-extern-as-identifier-type.rs
@@ -1,3 +1,3 @@
-type A = extern::foo::bar; //~ ERROR expected `fn`, found `::`
+type A = extern::foo::bar; //~ ERROR expected type, found keyword `extern`
 
 fn main() {}
diff --git a/src/test/ui/keyword/extern/keyword-extern-as-identifier-type.stderr b/src/test/ui/keyword/extern/keyword-extern-as-identifier-type.stderr
index 48c2f55..20ecf6b 100644
--- a/src/test/ui/keyword/extern/keyword-extern-as-identifier-type.stderr
+++ b/src/test/ui/keyword/extern/keyword-extern-as-identifier-type.stderr
@@ -1,8 +1,8 @@
-error: expected `fn`, found `::`
-  --> $DIR/keyword-extern-as-identifier-type.rs:1:16
+error: expected type, found keyword `extern`
+  --> $DIR/keyword-extern-as-identifier-type.rs:1:10
    |
 LL | type A = extern::foo::bar;
-   |                ^^ expected `fn`
+   |          ^^^^^^ expected type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/layout/debug.rs b/src/test/ui/layout/debug.rs
index 70ae200..034ed31 100644
--- a/src/test/ui/layout/debug.rs
+++ b/src/test/ui/layout/debug.rs
@@ -1,5 +1,5 @@
 // normalize-stderr-test "pref: Align \{\n *pow2: [1-3],\n *\}" -> "pref: $$PREF_ALIGN"
-#![feature(never_type, rustc_attrs)]
+#![feature(never_type, rustc_attrs, type_alias_impl_trait)]
 #![crate_type = "lib"]
 
 #[rustc_layout(debug)]
@@ -13,3 +13,10 @@
 
 #[rustc_layout(debug)]
 type Test = Result<i32, i32>; //~ ERROR: layout debugging
+
+#[rustc_layout(debug)]
+type T = impl std::fmt::Debug; //~ ERROR: layout debugging
+
+fn f() -> T {
+    0i32
+}
diff --git a/src/test/ui/layout/debug.stderr b/src/test/ui/layout/debug.stderr
index ef88cf1..3539cea 100644
--- a/src/test/ui/layout/debug.stderr
+++ b/src/test/ui/layout/debug.stderr
@@ -1,4 +1,4 @@
-error: layout debugging: Layout {
+error: layout debugging for type E: Layout {
     fields: Arbitrary {
         offsets: [
             Size {
@@ -110,7 +110,7 @@
 LL | enum E { Foo, Bar(!, i32, i32) }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: layout debugging: Layout {
+error: layout debugging for type S: Layout {
     fields: Arbitrary {
         offsets: [
             Size {
@@ -164,7 +164,7 @@
 LL | struct S { f1: i32, f2: (), f3: i32 }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: layout debugging: Layout {
+error: layout debugging for type U: Layout {
     fields: Union(
         2,
     ),
@@ -190,7 +190,7 @@
 LL | union U { f1: (i32, i32), f3: i32 }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: layout debugging: Layout {
+error: layout debugging for type std::result::Result<i32, i32>: Layout {
     fields: Arbitrary {
         offsets: [
             Size {
@@ -315,5 +315,37 @@
 LL | type Test = Result<i32, i32>;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: layout debugging for type i32: Layout {
+    fields: Union(
+        0,
+    ),
+    variants: Single {
+        index: 0,
+    },
+    abi: Scalar(
+        Scalar {
+            value: Int(
+                I32,
+                true,
+            ),
+            valid_range: 0..=4294967295,
+        },
+    ),
+    largest_niche: None,
+    align: AbiAndPrefAlign {
+        abi: Align {
+            pow2: 2,
+        },
+        pref: $PREF_ALIGN,
+    },
+    size: Size {
+        raw: 4,
+    },
+}
+  --> $DIR/debug.rs:18:1
+   |
+LL | type T = impl std::fmt::Debug;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/macros/issue-70446.rs b/src/test/ui/macros/issue-70446.rs
new file mode 100644
index 0000000..407094d
--- /dev/null
+++ b/src/test/ui/macros/issue-70446.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+macro_rules! foo {
+    ($(: $p:path)? $(: $l:lifetime)? ) => { bar! {$(: $p)? $(: $l)? } };
+}
+
+macro_rules! bar {
+    ($(: $p:path)? $(: $l:lifetime)? ) => {};
+}
+
+foo! {: 'a }
+
+fn main() {}
diff --git a/src/test/ui/macros/macro-name-typo.rs b/src/test/ui/macros/macro-name-typo.rs
index b2892f3..1ddc419 100644
--- a/src/test/ui/macros/macro-name-typo.rs
+++ b/src/test/ui/macros/macro-name-typo.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 fn main() {
     printlx!("oh noes!"); //~ ERROR cannot find
 }
diff --git a/src/test/ui/macros/macro-name-typo.stderr b/src/test/ui/macros/macro-name-typo.stderr
index 00afbde..5604341 100644
--- a/src/test/ui/macros/macro-name-typo.stderr
+++ b/src/test/ui/macros/macro-name-typo.stderr
@@ -1,5 +1,5 @@
 error: cannot find macro `printlx` in this scope
-  --> $DIR/macro-name-typo.rs:6:5
+  --> $DIR/macro-name-typo.rs:2:5
    |
 LL |     printlx!("oh noes!");
    |     ^^^^^^^ help: a macro with a similar name exists: `println`
diff --git a/src/test/ui/macros/macro-path-prelude-fail-3.rs b/src/test/ui/macros/macro-path-prelude-fail-3.rs
index 3c3948c..68eb350 100644
--- a/src/test/ui/macros/macro-path-prelude-fail-3.rs
+++ b/src/test/ui/macros/macro-path-prelude-fail-3.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 fn main() {
     inline!(); //~ ERROR cannot find macro `inline` in this scope
 }
diff --git a/src/test/ui/macros/macro-path-prelude-fail-3.stderr b/src/test/ui/macros/macro-path-prelude-fail-3.stderr
index 5364590..3e3a0b3 100644
--- a/src/test/ui/macros/macro-path-prelude-fail-3.stderr
+++ b/src/test/ui/macros/macro-path-prelude-fail-3.stderr
@@ -1,5 +1,5 @@
 error: cannot find macro `inline` in this scope
-  --> $DIR/macro-path-prelude-fail-3.rs:6:5
+  --> $DIR/macro-path-prelude-fail-3.rs:2:5
    |
 LL |     inline!();
    |     ^^^^^^ help: a macro with a similar name exists: `line`
diff --git a/src/test/ui/macros/unknown-builtin.rs b/src/test/ui/macros/unknown-builtin.rs
index 716a000..a96b99a 100644
--- a/src/test/ui/macros/unknown-builtin.rs
+++ b/src/test/ui/macros/unknown-builtin.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 // error-pattern: cannot find a built-in macro with name `line`
 
 #![feature(rustc_attrs)]
diff --git a/src/test/ui/macros/unknown-builtin.stderr b/src/test/ui/macros/unknown-builtin.stderr
index ed16375..665e92f 100644
--- a/src/test/ui/macros/unknown-builtin.stderr
+++ b/src/test/ui/macros/unknown-builtin.stderr
@@ -1,5 +1,5 @@
 error: cannot find a built-in macro with name `unknown`
-  --> $DIR/unknown-builtin.rs:11:1
+  --> $DIR/unknown-builtin.rs:6:1
    |
 LL | macro_rules! unknown { () => () }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/mismatched_types/issue-36053-2.rs b/src/test/ui/mismatched_types/issue-36053-2.rs
index 36211b4..9035e33 100644
--- a/src/test/ui/mismatched_types/issue-36053-2.rs
+++ b/src/test/ui/mismatched_types/issue-36053-2.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // Regression test for #36053. ICE was caused due to obligations
 // being added to a special, dedicated fulfillment cx during
 // a probe.
diff --git a/src/test/ui/mismatched_types/issue-36053-2.stderr b/src/test/ui/mismatched_types/issue-36053-2.stderr
index f8c0470..2793acf 100644
--- a/src/test/ui/mismatched_types/issue-36053-2.stderr
+++ b/src/test/ui/mismatched_types/issue-36053-2.stderr
@@ -1,8 +1,8 @@
-error[E0599]: no method named `count` found for struct `std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:11:39: 11:53]>` in the current scope
-  --> $DIR/issue-36053-2.rs:11:55
+error[E0599]: no method named `count` found for struct `std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>` in the current scope
+  --> $DIR/issue-36053-2.rs:7:55
    |
 LL |     once::<&str>("str").fuse().filter(|a: &str| true).count();
-   |                                       --------------  ^^^^^ method not found in `std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:11:39: 11:53]>`
+   |                                       --------------  ^^^^^ method not found in `std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>`
    |                                       |
    |                                       doesn't satisfy `<_ as std::ops::FnOnce<(&&str,)>>::Output = bool`
    |                                       doesn't satisfy `_: std::ops::FnMut<(&&str,)>`
@@ -13,15 +13,15 @@
    | ----------------------- doesn't satisfy `_: std::iter::Iterator`
    |
    = note: the method `count` exists but the following trait bounds were not satisfied:
-           `<[closure@$DIR/issue-36053-2.rs:11:39: 11:53] as std::ops::FnOnce<(&&str,)>>::Output = bool`
-           which is required by `std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:11:39: 11:53]>: std::iter::Iterator`
-           `[closure@$DIR/issue-36053-2.rs:11:39: 11:53]: std::ops::FnMut<(&&str,)>`
-           which is required by `std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:11:39: 11:53]>: std::iter::Iterator`
-           `std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:11:39: 11:53]>: std::iter::Iterator`
-           which is required by `&mut std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:11:39: 11:53]>: std::iter::Iterator`
+           `<[closure@$DIR/issue-36053-2.rs:7:39: 7:53] as std::ops::FnOnce<(&&str,)>>::Output = bool`
+           which is required by `std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>: std::iter::Iterator`
+           `[closure@$DIR/issue-36053-2.rs:7:39: 7:53]: std::ops::FnMut<(&&str,)>`
+           which is required by `std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>: std::iter::Iterator`
+           `std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>: std::iter::Iterator`
+           which is required by `&mut std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>: std::iter::Iterator`
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/issue-36053-2.rs:11:32
+  --> $DIR/issue-36053-2.rs:7:32
    |
 LL |     once::<&str>("str").fuse().filter(|a: &str| true).count();
    |                                ^^^^^^ -------------- found signature of `for<'r> fn(&'r str) -> _`
diff --git a/src/test/ui/no-send-res-ports.rs b/src/test/ui/no-send-res-ports.rs
index 6a1965f..e10f447 100644
--- a/src/test/ui/no-send-res-ports.rs
+++ b/src/test/ui/no-send-res-ports.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 use std::thread;
 use std::rc::Rc;
 
diff --git a/src/test/ui/no-send-res-ports.stderr b/src/test/ui/no-send-res-ports.stderr
index 65946ee..13683cf 100644
--- a/src/test/ui/no-send-res-ports.stderr
+++ b/src/test/ui/no-send-res-ports.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
-  --> $DIR/no-send-res-ports.rs:29:5
+  --> $DIR/no-send-res-ports.rs:25:5
    |
 LL |       thread::spawn(move|| {
    |  _____^^^^^^^^^^^^^_-
@@ -9,17 +9,17 @@
 LL | |         let y = x;
 LL | |         println!("{:?}", y);
 LL | |     });
-   | |_____- within this `[closure@$DIR/no-send-res-ports.rs:29:19: 33:6 x:main::Foo]`
+   | |_____- within this `[closure@$DIR/no-send-res-ports.rs:25:19: 29:6 x:main::Foo]`
    | 
   ::: $SRC_DIR/libstd/thread/mod.rs:LL:COL
    |
 LL |       F: Send + 'static,
    |          ---- required by this bound in `std::thread::spawn`
    |
-   = help: within `[closure@$DIR/no-send-res-ports.rs:29:19: 33:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
+   = help: within `[closure@$DIR/no-send-res-ports.rs:25:19: 29:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
    = note: required because it appears within the type `Port<()>`
    = note: required because it appears within the type `main::Foo`
-   = note: required because it appears within the type `[closure@$DIR/no-send-res-ports.rs:29:19: 33:6 x:main::Foo]`
+   = note: required because it appears within the type `[closure@$DIR/no-send-res-ports.rs:25:19: 29:6 x:main::Foo]`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/non-copyable-void.rs b/src/test/ui/non-copyable-void.rs
index 186731f..ddaaee4 100644
--- a/src/test/ui/non-copyable-void.rs
+++ b/src/test/ui/non-copyable-void.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 // ignore-wasm32-bare no libc to test ffi with
 
 #![feature(rustc_private)]
diff --git a/src/test/ui/non-copyable-void.stderr b/src/test/ui/non-copyable-void.stderr
index dd67a11..78d212f 100644
--- a/src/test/ui/non-copyable-void.stderr
+++ b/src/test/ui/non-copyable-void.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `clone` found for enum `libc::c_void` in the current scope
-  --> $DIR/non-copyable-void.rs:16:23
+  --> $DIR/non-copyable-void.rs:11:23
    |
 LL |         let _z = (*y).clone();
    |                       ^^^^^ method not found in `libc::c_void`
diff --git a/src/test/ui/noncopyable-class.rs b/src/test/ui/noncopyable-class.rs
index 731f4ab..11b6eb7 100644
--- a/src/test/ui/noncopyable-class.rs
+++ b/src/test/ui/noncopyable-class.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 // Test that a class with a non-copyable field can't be
 // copied
 
diff --git a/src/test/ui/noncopyable-class.stderr b/src/test/ui/noncopyable-class.stderr
index 472ce34..994eb65 100644
--- a/src/test/ui/noncopyable-class.stderr
+++ b/src/test/ui/noncopyable-class.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `clone` found for struct `Foo` in the current scope
-  --> $DIR/noncopyable-class.rs:39:16
+  --> $DIR/noncopyable-class.rs:34:16
    |
 LL | struct Foo {
    | ---------- method `clone` not found for this
diff --git a/src/test/ui/parser/issue-32214.stderr b/src/test/ui/parser/issue-32214.stderr
index 742f4fd..bc61b3b 100644
--- a/src/test/ui/parser/issue-32214.stderr
+++ b/src/test/ui/parser/issue-32214.stderr
@@ -4,7 +4,12 @@
 LL | pub fn test<W, I: Trait<Item=(), W> >() {}
    |                         -------  ^ generic argument
    |                         |
-   |                         the first constraint is provided here
+   |                         constraint
+   |
+help: move the constraint after the generic argument
+   |
+LL | pub fn test<W, I: Trait<W, Item = ()> >() {}
+   |                        ^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-62894.rs b/src/test/ui/parser/issue-62894.rs
index e38b7b6..b9c0bf8 100644
--- a/src/test/ui/parser/issue-62894.rs
+++ b/src/test/ui/parser/issue-62894.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 // Regression test for #62894, shouldn't crash.
 // error-pattern: this file contains an unclosed delimiter
 // error-pattern: expected one of `(`, `[`, or `{`, found keyword `fn`
diff --git a/src/test/ui/parser/issue-62894.stderr b/src/test/ui/parser/issue-62894.stderr
index 4a1d7e2..73e3552 100644
--- a/src/test/ui/parser/issue-62894.stderr
+++ b/src/test/ui/parser/issue-62894.stderr
@@ -1,5 +1,5 @@
 error: this file contains an unclosed delimiter
-  --> $DIR/issue-62894.rs:12:14
+  --> $DIR/issue-62894.rs:7:14
    |
 LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
    |        -           -                   - unclosed delimiter
@@ -11,7 +11,7 @@
    |              ^
 
 error: this file contains an unclosed delimiter
-  --> $DIR/issue-62894.rs:12:14
+  --> $DIR/issue-62894.rs:7:14
    |
 LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
    |        -           -                   - unclosed delimiter
@@ -23,7 +23,7 @@
    |              ^
 
 error: this file contains an unclosed delimiter
-  --> $DIR/issue-62894.rs:12:14
+  --> $DIR/issue-62894.rs:7:14
    |
 LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
    |        -           -                   - unclosed delimiter
@@ -35,7 +35,7 @@
    |              ^
 
 error: expected one of `(`, `[`, or `{`, found keyword `fn`
-  --> $DIR/issue-62894.rs:12:1
+  --> $DIR/issue-62894.rs:7:1
    |
 LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
    |                                                   - expected one of `(`, `[`, or `{`
diff --git a/src/test/ui/parser/issue-63116.stderr b/src/test/ui/parser/issue-63116.stderr
index 15cd3df..80a450d 100644
--- a/src/test/ui/parser/issue-63116.stderr
+++ b/src/test/ui/parser/issue-63116.stderr
@@ -12,7 +12,7 @@
 LL | impl W <s(f;Y(;]
    |            ^ expected one of 7 possible tokens
 
-error: expected one of `!`, `&&`, `&`, `(`, `)`, `*`, `+`, `,`, `->`, `...`, `::`, `<`, `>`, `?`, `[`, `_`, `dyn`, `extern`, `fn`, `for`, `impl`, `unsafe`, lifetime, or path, found `;`
+error: expected one of `!`, `&&`, `&`, `(`, `)`, `*`, `+`, `,`, `->`, `...`, `::`, `<`, `>`, `?`, `[`, `_`, `async`, `const`, `dyn`, `extern`, `fn`, `for`, `impl`, `unsafe`, lifetime, or path, found `;`
   --> $DIR/issue-63116.rs:3:15
    |
 LL | impl W <s(f;Y(;]
diff --git a/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.rs b/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.rs
new file mode 100644
index 0000000..bdfc29a
--- /dev/null
+++ b/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.rs
@@ -0,0 +1,5 @@
+// This won't actually panic because of the error comment -- the `"` needs to be
+// the last byte in the file (including not having a trailing newline)
+// Prior to the fix you get the error: 'expected item, found `r" ...`'
+// because the string being unterminated wasn't properly detected.
+r" //~ unterminated raw string
diff --git a/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.stderr b/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.stderr
new file mode 100644
index 0000000..3a7e2a4
--- /dev/null
+++ b/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.stderr
@@ -0,0 +1,9 @@
+error[E0748]: unterminated raw string
+  --> $DIR/issue-70677-panic-on-unterminated-raw-str-at-eof.rs:5:1
+   |
+LL | r"
+   | ^ unterminated raw string
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0748`.
diff --git a/src/test/ui/parser/recover-const-async-fn-ptr.rs b/src/test/ui/parser/recover-const-async-fn-ptr.rs
new file mode 100644
index 0000000..25af877
--- /dev/null
+++ b/src/test/ui/parser/recover-const-async-fn-ptr.rs
@@ -0,0 +1,25 @@
+// edition:2018
+
+type T0 = const fn(); //~ ERROR an `fn` pointer type cannot be `const`
+type T1 = const extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
+type T2 = const unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const`
+type T3 = async fn(); //~ ERROR an `fn` pointer type cannot be `async`
+type T4 = async extern fn(); //~ ERROR an `fn` pointer type cannot be `async`
+type T5 = async unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
+type T6 = const async unsafe extern "C" fn();
+//~^ ERROR an `fn` pointer type cannot be `const`
+//~| ERROR an `fn` pointer type cannot be `async`
+
+type FT0 = for<'a> const fn(); //~ ERROR an `fn` pointer type cannot be `const`
+type FT1 = for<'a> const extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
+type FT2 = for<'a> const unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const`
+type FT3 = for<'a> async fn(); //~ ERROR an `fn` pointer type cannot be `async`
+type FT4 = for<'a> async extern fn(); //~ ERROR an `fn` pointer type cannot be `async`
+type FT5 = for<'a> async unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
+type FT6 = for<'a> const async unsafe extern "C" fn();
+//~^ ERROR an `fn` pointer type cannot be `const`
+//~| ERROR an `fn` pointer type cannot be `async`
+
+fn main() {
+    let _recovery_witness: () = 0; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/parser/recover-const-async-fn-ptr.stderr b/src/test/ui/parser/recover-const-async-fn-ptr.stderr
new file mode 100644
index 0000000..7012096
--- /dev/null
+++ b/src/test/ui/parser/recover-const-async-fn-ptr.stderr
@@ -0,0 +1,155 @@
+error: an `fn` pointer type cannot be `const`
+  --> $DIR/recover-const-async-fn-ptr.rs:3:11
+   |
+LL | type T0 = const fn();
+   |           -----^^^^^
+   |           |
+   |           `const` because of this
+   |           help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `const`
+  --> $DIR/recover-const-async-fn-ptr.rs:4:11
+   |
+LL | type T1 = const extern "C" fn();
+   |           -----^^^^^^^^^^^^^^^^
+   |           |
+   |           `const` because of this
+   |           help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `const`
+  --> $DIR/recover-const-async-fn-ptr.rs:5:11
+   |
+LL | type T2 = const unsafe extern fn();
+   |           -----^^^^^^^^^^^^^^^^^^^
+   |           |
+   |           `const` because of this
+   |           help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `async`
+  --> $DIR/recover-const-async-fn-ptr.rs:6:11
+   |
+LL | type T3 = async fn();
+   |           -----^^^^^
+   |           |
+   |           `async` because of this
+   |           help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `async`
+  --> $DIR/recover-const-async-fn-ptr.rs:7:11
+   |
+LL | type T4 = async extern fn();
+   |           -----^^^^^^^^^^^^
+   |           |
+   |           `async` because of this
+   |           help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `async`
+  --> $DIR/recover-const-async-fn-ptr.rs:8:11
+   |
+LL | type T5 = async unsafe extern "C" fn();
+   |           -----^^^^^^^^^^^^^^^^^^^^^^^
+   |           |
+   |           `async` because of this
+   |           help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `const`
+  --> $DIR/recover-const-async-fn-ptr.rs:9:11
+   |
+LL | type T6 = const async unsafe extern "C" fn();
+   |           -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |           |
+   |           `const` because of this
+   |           help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `async`
+  --> $DIR/recover-const-async-fn-ptr.rs:9:11
+   |
+LL | type T6 = const async unsafe extern "C" fn();
+   |           ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^
+   |                 |
+   |                 `async` because of this
+   |                 help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `const`
+  --> $DIR/recover-const-async-fn-ptr.rs:13:12
+   |
+LL | type FT0 = for<'a> const fn();
+   |            ^^^^^^^^-----^^^^^
+   |                    |
+   |                    `const` because of this
+   |                    help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `const`
+  --> $DIR/recover-const-async-fn-ptr.rs:14:12
+   |
+LL | type FT1 = for<'a> const extern "C" fn();
+   |            ^^^^^^^^-----^^^^^^^^^^^^^^^^
+   |                    |
+   |                    `const` because of this
+   |                    help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `const`
+  --> $DIR/recover-const-async-fn-ptr.rs:15:12
+   |
+LL | type FT2 = for<'a> const unsafe extern fn();
+   |            ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^
+   |                    |
+   |                    `const` because of this
+   |                    help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `async`
+  --> $DIR/recover-const-async-fn-ptr.rs:16:12
+   |
+LL | type FT3 = for<'a> async fn();
+   |            ^^^^^^^^-----^^^^^
+   |                    |
+   |                    `async` because of this
+   |                    help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `async`
+  --> $DIR/recover-const-async-fn-ptr.rs:17:12
+   |
+LL | type FT4 = for<'a> async extern fn();
+   |            ^^^^^^^^-----^^^^^^^^^^^^
+   |                    |
+   |                    `async` because of this
+   |                    help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `async`
+  --> $DIR/recover-const-async-fn-ptr.rs:18:12
+   |
+LL | type FT5 = for<'a> async unsafe extern "C" fn();
+   |            ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^
+   |                    |
+   |                    `async` because of this
+   |                    help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `const`
+  --> $DIR/recover-const-async-fn-ptr.rs:19:12
+   |
+LL | type FT6 = for<'a> const async unsafe extern "C" fn();
+   |            ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                    |
+   |                    `const` because of this
+   |                    help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `async`
+  --> $DIR/recover-const-async-fn-ptr.rs:19:12
+   |
+LL | type FT6 = for<'a> const async unsafe extern "C" fn();
+   |            ^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^
+   |                          |
+   |                          `async` because of this
+   |                          help: remove the `async` qualifier
+
+error[E0308]: mismatched types
+  --> $DIR/recover-const-async-fn-ptr.rs:24:33
+   |
+LL |     let _recovery_witness: () = 0;
+   |                            --   ^ expected `()`, found integer
+   |                            |
+   |                            expected due to this
+
+error: aborting due to 17 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/pattern/usefulness/match-arm-statics-2.rs b/src/test/ui/pattern/usefulness/match-arm-statics-2.rs
index 728d4a6..4c5f2d3 100644
--- a/src/test/ui/pattern/usefulness/match-arm-statics-2.rs
+++ b/src/test/ui/pattern/usefulness/match-arm-statics-2.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 use self::Direction::{North, East, South, West};
 
 #[derive(PartialEq, Eq)]
diff --git a/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr b/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr
index 09b92fc..3d329e2 100644
--- a/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr
+++ b/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: `(true, false)` not covered
-  --> $DIR/match-arm-statics-2.rs:22:11
+  --> $DIR/match-arm-statics-2.rs:17:11
    |
 LL |     match (true, false) {
    |           ^^^^^^^^^^^^^ pattern `(true, false)` not covered
@@ -8,7 +8,7 @@
    = note: the matched value is of type `(bool, bool)`
 
 error[E0004]: non-exhaustive patterns: `Some(Some(West))` not covered
-  --> $DIR/match-arm-statics-2.rs:34:11
+  --> $DIR/match-arm-statics-2.rs:29:11
    |
 LL |     match Some(Some(North)) {
    |           ^^^^^^^^^^^^^^^^^ pattern `Some(Some(West))` not covered
@@ -25,7 +25,7 @@
    = note: the matched value is of type `std::option::Option<std::option::Option<Direction>>`
 
 error[E0004]: non-exhaustive patterns: `Foo { bar: Some(North), baz: NewBool(true) }` not covered
-  --> $DIR/match-arm-statics-2.rs:53:11
+  --> $DIR/match-arm-statics-2.rs:48:11
    |
 LL | / struct Foo {
 LL | |     bar: Option<Direction>,
diff --git a/src/test/ui/pattern/usefulness/match-privately-empty.rs b/src/test/ui/pattern/usefulness/match-privately-empty.rs
index c7cde46..315eb03 100644
--- a/src/test/ui/pattern/usefulness/match-privately-empty.rs
+++ b/src/test/ui/pattern/usefulness/match-privately-empty.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 #![feature(never_type)]
 #![feature(exhaustive_patterns)]
 
diff --git a/src/test/ui/pattern/usefulness/match-privately-empty.stderr b/src/test/ui/pattern/usefulness/match-privately-empty.stderr
index 62e6e66..50a4674 100644
--- a/src/test/ui/pattern/usefulness/match-privately-empty.stderr
+++ b/src/test/ui/pattern/usefulness/match-privately-empty.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered
-  --> $DIR/match-privately-empty.rs:18:11
+  --> $DIR/match-privately-empty.rs:13:11
    |
 LL |     match private::DATA {
    |           ^^^^^^^^^^^^^ pattern `Some(Private { misc: true, .. })` not covered
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs
index 59f7bb8..9947989 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 #![allow(illegal_floating_point_literal_pattern)]
 
 enum T { A, B }
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
index 358ecf2..436a293 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: `A` not covered
-  --> $DIR/non-exhaustive-match.rs:12:11
+  --> $DIR/non-exhaustive-match.rs:7:11
    |
 LL | enum T { A, B }
    | ---------------
@@ -14,7 +14,7 @@
    = note: the matched value is of type `T`
 
 error[E0004]: non-exhaustive patterns: `false` not covered
-  --> $DIR/non-exhaustive-match.rs:13:11
+  --> $DIR/non-exhaustive-match.rs:8:11
    |
 LL |     match true {
    |           ^^^^ pattern `false` not covered
@@ -23,7 +23,7 @@
    = note: the matched value is of type `bool`
 
 error[E0004]: non-exhaustive patterns: `Some(_)` not covered
-  --> $DIR/non-exhaustive-match.rs:16:11
+  --> $DIR/non-exhaustive-match.rs:11:11
    |
 LL |     match Some(10) {
    |           ^^^^^^^^ pattern `Some(_)` not covered
@@ -37,7 +37,7 @@
    = note: the matched value is of type `std::option::Option<i32>`
 
 error[E0004]: non-exhaustive patterns: `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered
-  --> $DIR/non-exhaustive-match.rs:19:11
+  --> $DIR/non-exhaustive-match.rs:14:11
    |
 LL |     match (2, 3, 4) {
    |           ^^^^^^^^^ patterns `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered
@@ -46,7 +46,7 @@
    = note: the matched value is of type `(i32, i32, i32)`
 
 error[E0004]: non-exhaustive patterns: `(A, A)` not covered
-  --> $DIR/non-exhaustive-match.rs:23:11
+  --> $DIR/non-exhaustive-match.rs:18:11
    |
 LL |     match (T::A, T::A) {
    |           ^^^^^^^^^^^^ pattern `(A, A)` not covered
@@ -55,7 +55,7 @@
    = note: the matched value is of type `(T, T)`
 
 error[E0004]: non-exhaustive patterns: `B` not covered
-  --> $DIR/non-exhaustive-match.rs:27:11
+  --> $DIR/non-exhaustive-match.rs:22:11
    |
 LL | enum T { A, B }
    | ---------------
@@ -70,7 +70,7 @@
    = note: the matched value is of type `T`
 
 error[E0004]: non-exhaustive patterns: `[]` not covered
-  --> $DIR/non-exhaustive-match.rs:38:11
+  --> $DIR/non-exhaustive-match.rs:33:11
    |
 LL |     match *vec {
    |           ^^^^ pattern `[]` not covered
@@ -79,7 +79,7 @@
    = note: the matched value is of type `[std::option::Option<isize>]`
 
 error[E0004]: non-exhaustive patterns: `[_, _, _, _, ..]` not covered
-  --> $DIR/non-exhaustive-match.rs:51:11
+  --> $DIR/non-exhaustive-match.rs:46:11
    |
 LL |     match *vec {
    |           ^^^^ pattern `[_, _, _, _, ..]` not covered
diff --git a/src/test/ui/proc-macro/parent-source-spans.rs b/src/test/ui/proc-macro/parent-source-spans.rs
index 95a3f96..7b2ffef 100644
--- a/src/test/ui/proc-macro/parent-source-spans.rs
+++ b/src/test/ui/proc-macro/parent-source-spans.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // aux-build:parent-source-spans.rs
 #![feature(decl_macro, proc_macro_hygiene)]
 
diff --git a/src/test/ui/proc-macro/parent-source-spans.stderr b/src/test/ui/proc-macro/parent-source-spans.stderr
index 254f877..c7d15b4 100644
--- a/src/test/ui/proc-macro/parent-source-spans.stderr
+++ b/src/test/ui/proc-macro/parent-source-spans.stderr
@@ -1,5 +1,5 @@
 error: first final: "hello"
-  --> $DIR/parent-source-spans.rs:19:12
+  --> $DIR/parent-source-spans.rs:15:12
    |
 LL |     three!($a, $b);
    |            ^^
@@ -10,7 +10,7 @@
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: second final: "world"
-  --> $DIR/parent-source-spans.rs:19:16
+  --> $DIR/parent-source-spans.rs:15:16
    |
 LL |     three!($a, $b);
    |                ^^
@@ -21,7 +21,7 @@
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: first parent: "hello"
-  --> $DIR/parent-source-spans.rs:13:5
+  --> $DIR/parent-source-spans.rs:9:5
    |
 LL |     two!($a, $b);
    |     ^^^^^^^^^^^^^
@@ -32,7 +32,7 @@
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: second parent: "world"
-  --> $DIR/parent-source-spans.rs:13:5
+  --> $DIR/parent-source-spans.rs:9:5
    |
 LL |     two!($a, $b);
    |     ^^^^^^^^^^^^^
@@ -43,31 +43,31 @@
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: first grandparent: "hello"
-  --> $DIR/parent-source-spans.rs:39:5
+  --> $DIR/parent-source-spans.rs:35:5
    |
 LL |     one!("hello", "world");
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: second grandparent: "world"
-  --> $DIR/parent-source-spans.rs:39:5
+  --> $DIR/parent-source-spans.rs:35:5
    |
 LL |     one!("hello", "world");
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: first source: "hello"
-  --> $DIR/parent-source-spans.rs:39:5
+  --> $DIR/parent-source-spans.rs:35:5
    |
 LL |     one!("hello", "world");
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: second source: "world"
-  --> $DIR/parent-source-spans.rs:39:5
+  --> $DIR/parent-source-spans.rs:35:5
    |
 LL |     one!("hello", "world");
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: first final: "yay"
-  --> $DIR/parent-source-spans.rs:19:12
+  --> $DIR/parent-source-spans.rs:15:12
    |
 LL |     three!($a, $b);
    |            ^^
@@ -78,7 +78,7 @@
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: second final: "rust"
-  --> $DIR/parent-source-spans.rs:19:16
+  --> $DIR/parent-source-spans.rs:15:16
    |
 LL |     three!($a, $b);
    |                ^^
@@ -89,55 +89,55 @@
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: first parent: "yay"
-  --> $DIR/parent-source-spans.rs:45:5
+  --> $DIR/parent-source-spans.rs:41:5
    |
 LL |     two!("yay", "rust");
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: second parent: "rust"
-  --> $DIR/parent-source-spans.rs:45:5
+  --> $DIR/parent-source-spans.rs:41:5
    |
 LL |     two!("yay", "rust");
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: first source: "yay"
-  --> $DIR/parent-source-spans.rs:45:5
+  --> $DIR/parent-source-spans.rs:41:5
    |
 LL |     two!("yay", "rust");
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: second source: "rust"
-  --> $DIR/parent-source-spans.rs:45:5
+  --> $DIR/parent-source-spans.rs:41:5
    |
 LL |     two!("yay", "rust");
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: first final: "hip"
-  --> $DIR/parent-source-spans.rs:51:12
+  --> $DIR/parent-source-spans.rs:47:12
    |
 LL |     three!("hip", "hop");
    |            ^^^^^
 
 error: second final: "hop"
-  --> $DIR/parent-source-spans.rs:51:19
+  --> $DIR/parent-source-spans.rs:47:19
    |
 LL |     three!("hip", "hop");
    |                   ^^^^^
 
 error: first source: "hip"
-  --> $DIR/parent-source-spans.rs:51:12
+  --> $DIR/parent-source-spans.rs:47:12
    |
 LL |     three!("hip", "hop");
    |            ^^^^^
 
 error: second source: "hop"
-  --> $DIR/parent-source-spans.rs:51:19
+  --> $DIR/parent-source-spans.rs:47:19
    |
 LL |     three!("hip", "hop");
    |                   ^^^^^
 
 error[E0425]: cannot find value `ok` in this scope
-  --> $DIR/parent-source-spans.rs:32:5
+  --> $DIR/parent-source-spans.rs:28:5
    |
 LL |     parent_source_spans!($($tokens)*);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a tuple variant with a similar name exists: `Ok`
@@ -153,7 +153,7 @@
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0425]: cannot find value `ok` in this scope
-  --> $DIR/parent-source-spans.rs:32:5
+  --> $DIR/parent-source-spans.rs:28:5
    |
 LL |     parent_source_spans!($($tokens)*);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a tuple variant with a similar name exists: `Ok`
@@ -169,7 +169,7 @@
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0425]: cannot find value `ok` in this scope
-  --> $DIR/parent-source-spans.rs:32:5
+  --> $DIR/parent-source-spans.rs:28:5
    |
 LL |     parent_source_spans!($($tokens)*);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a tuple variant with a similar name exists: `Ok`
diff --git a/src/test/ui/proc-macro/resolve-error.rs b/src/test/ui/proc-macro/resolve-error.rs
index 8ff36ff..ad8a5bb 100644
--- a/src/test/ui/proc-macro/resolve-error.rs
+++ b/src/test/ui/proc-macro/resolve-error.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // aux-build:derive-foo.rs
 // aux-build:derive-clona.rs
 // aux-build:test-macros.rs
diff --git a/src/test/ui/proc-macro/resolve-error.stderr b/src/test/ui/proc-macro/resolve-error.stderr
index 15a1d6d..fc18982 100644
--- a/src/test/ui/proc-macro/resolve-error.stderr
+++ b/src/test/ui/proc-macro/resolve-error.stderr
@@ -1,5 +1,5 @@
 error: cannot find macro `bang_proc_macrp` in this scope
-  --> $DIR/resolve-error.rs:64:5
+  --> $DIR/resolve-error.rs:60:5
    |
 LL |     bang_proc_macrp!();
    |     ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `bang_proc_macro`
@@ -10,13 +10,13 @@
    | ------------------------------------------- similarly named macro `bang_proc_macro` defined here
 
 error: cannot find macro `Dlona` in this scope
-  --> $DIR/resolve-error.rs:61:5
+  --> $DIR/resolve-error.rs:57:5
    |
 LL |     Dlona!();
    |     ^^^^^
 
 error: cannot find macro `attr_proc_macra` in this scope
-  --> $DIR/resolve-error.rs:58:5
+  --> $DIR/resolve-error.rs:54:5
    |
 LL | macro_rules! attr_proc_mac {
    | -------------------------- similarly named macro `attr_proc_mac` defined here
@@ -25,7 +25,7 @@
    |     ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `attr_proc_mac`
 
 error: cannot find macro `FooWithLongNama` in this scope
-  --> $DIR/resolve-error.rs:55:5
+  --> $DIR/resolve-error.rs:51:5
    |
 LL | macro_rules! FooWithLongNam {
    | --------------------------- similarly named macro `FooWithLongNam` defined here
@@ -34,19 +34,19 @@
    |     ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `FooWithLongNam`
 
 error: cannot find derive macro `attr_proc_macra` in this scope
-  --> $DIR/resolve-error.rs:49:10
+  --> $DIR/resolve-error.rs:45:10
    |
 LL | #[derive(attr_proc_macra)]
    |          ^^^^^^^^^^^^^^^
 
 error: cannot find derive macro `attr_proc_macra` in this scope
-  --> $DIR/resolve-error.rs:49:10
+  --> $DIR/resolve-error.rs:45:10
    |
 LL | #[derive(attr_proc_macra)]
    |          ^^^^^^^^^^^^^^^
 
 error: cannot find derive macro `Dlona` in this scope
-  --> $DIR/resolve-error.rs:44:10
+  --> $DIR/resolve-error.rs:40:10
    |
 LL | #[derive(Dlona)]
    |          ^^^^^ help: a derive macro with a similar name exists: `Clona`
@@ -57,7 +57,7 @@
    | ------------------------------------------------------- similarly named derive macro `Clona` defined here
 
 error: cannot find derive macro `Dlona` in this scope
-  --> $DIR/resolve-error.rs:44:10
+  --> $DIR/resolve-error.rs:40:10
    |
 LL | #[derive(Dlona)]
    |          ^^^^^ help: a derive macro with a similar name exists: `Clona`
@@ -68,7 +68,7 @@
    | ------------------------------------------------------- similarly named derive macro `Clona` defined here
 
 error: cannot find derive macro `Dlone` in this scope
-  --> $DIR/resolve-error.rs:39:10
+  --> $DIR/resolve-error.rs:35:10
    |
 LL | #[derive(Dlone)]
    |          ^^^^^ help: a derive macro with a similar name exists: `Clone`
@@ -79,7 +79,7 @@
    | --------------------------- similarly named derive macro `Clone` defined here
 
 error: cannot find derive macro `Dlone` in this scope
-  --> $DIR/resolve-error.rs:39:10
+  --> $DIR/resolve-error.rs:35:10
    |
 LL | #[derive(Dlone)]
    |          ^^^^^ help: a derive macro with a similar name exists: `Clone`
@@ -90,13 +90,13 @@
    | --------------------------- similarly named derive macro `Clone` defined here
 
 error: cannot find attribute `FooWithLongNan` in this scope
-  --> $DIR/resolve-error.rs:36:3
+  --> $DIR/resolve-error.rs:32:3
    |
 LL | #[FooWithLongNan]
    |   ^^^^^^^^^^^^^^
 
 error: cannot find attribute `attr_proc_macra` in this scope
-  --> $DIR/resolve-error.rs:32:3
+  --> $DIR/resolve-error.rs:28:3
    |
 LL | #[attr_proc_macra]
    |   ^^^^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `attr_proc_macro`
@@ -107,7 +107,7 @@
    | ---------------------------------------------------------------- similarly named attribute macro `attr_proc_macro` defined here
 
 error: cannot find derive macro `FooWithLongNan` in this scope
-  --> $DIR/resolve-error.rs:26:10
+  --> $DIR/resolve-error.rs:22:10
    |
 LL | #[derive(FooWithLongNan)]
    |          ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName`
@@ -118,7 +118,7 @@
    | ---------------------------------------------------- similarly named derive macro `FooWithLongName` defined here
 
 error: cannot find derive macro `FooWithLongNan` in this scope
-  --> $DIR/resolve-error.rs:26:10
+  --> $DIR/resolve-error.rs:22:10
    |
 LL | #[derive(FooWithLongNan)]
    |          ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName`
diff --git a/src/test/ui/question-mark-type-infer.stderr b/src/test/ui/question-mark-type-infer.stderr
index 262344f..64d8f68 100644
--- a/src/test/ui/question-mark-type-infer.stderr
+++ b/src/test/ui/question-mark-type-infer.stderr
@@ -4,7 +4,7 @@
 LL |     l.iter().map(f).collect()?
    |                     ^^^^^^^ cannot infer type
    |
-   = note: cannot resolve `<_ as std::ops::Try>::Ok == _`
+   = note: cannot satisfy `<_ as std::ops::Try>::Ok == _`
 help: consider specifying the type argument in the method call
    |
 LL |     l.iter().map(f).collect::<B>()?
diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs b/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs
index 5be426e..4489303 100644
--- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs
+++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 struct R<'a> {
     r: &'a R<'a>,
 }
diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
index d3e0549..75e8ae2 100644
--- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
+++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
@@ -1,5 +1,5 @@
 error[E0005]: refutable pattern in local binding: `Err(_)` not covered
-  --> $DIR/recursive-types-are-not-uninhabited.rs:11:9
+  --> $DIR/recursive-types-are-not-uninhabited.rs:6:9
    |
 LL |     let Ok(x) = res;
    |         ^^^^^ pattern `Err(_)` not covered
diff --git a/src/test/ui/resolve/levenshtein.rs b/src/test/ui/resolve/levenshtein.rs
index 6a98782..a6f4716 100644
--- a/src/test/ui/resolve/levenshtein.rs
+++ b/src/test/ui/resolve/levenshtein.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 const MAX_ITEM: usize = 10;
 
 fn foo_bar() {}
diff --git a/src/test/ui/resolve/levenshtein.stderr b/src/test/ui/resolve/levenshtein.stderr
index ecdec3c..68e0cf0 100644
--- a/src/test/ui/resolve/levenshtein.stderr
+++ b/src/test/ui/resolve/levenshtein.stderr
@@ -1,11 +1,11 @@
 error[E0412]: cannot find type `esize` in this scope
-  --> $DIR/levenshtein.rs:9:11
+  --> $DIR/levenshtein.rs:5:11
    |
 LL | fn foo(c: esize) {} // Misspelled primitive type name.
    |           ^^^^^ help: a builtin type with a similar name exists: `isize`
 
 error[E0412]: cannot find type `Baz` in this scope
-  --> $DIR/levenshtein.rs:14:10
+  --> $DIR/levenshtein.rs:10:10
    |
 LL | enum Bar { }
    | -------- similarly named enum `Bar` defined here
@@ -14,7 +14,7 @@
    |          ^^^ help: an enum with a similar name exists: `Bar`
 
 error[E0412]: cannot find type `Opiton` in this scope
-  --> $DIR/levenshtein.rs:16:10
+  --> $DIR/levenshtein.rs:12:10
    |
 LL | type B = Opiton<u8>; // Misspelled type name from the prelude.
    |          ^^^^^^ help: an enum with a similar name exists: `Option`
@@ -25,13 +25,13 @@
    | ------------------ similarly named enum `Option` defined here
 
 error[E0412]: cannot find type `Baz` in this scope
-  --> $DIR/levenshtein.rs:20:14
+  --> $DIR/levenshtein.rs:16:14
    |
 LL |     type A = Baz; // No suggestion here, Bar is not visible
    |              ^^^ not found in this scope
 
 error[E0425]: cannot find value `MAXITEM` in this scope
-  --> $DIR/levenshtein.rs:28:20
+  --> $DIR/levenshtein.rs:24:20
    |
 LL | const MAX_ITEM: usize = 10;
    | --------------------------- similarly named constant `MAX_ITEM` defined here
@@ -40,7 +40,7 @@
    |                    ^^^^^^^ help: a constant with a similar name exists: `MAX_ITEM`
 
 error[E0425]: cannot find function `foobar` in this scope
-  --> $DIR/levenshtein.rs:30:5
+  --> $DIR/levenshtein.rs:26:5
    |
 LL | fn foo_bar() {}
    | ------------ similarly named function `foo_bar` defined here
@@ -49,7 +49,7 @@
    |     ^^^^^^ help: a function with a similar name exists: `foo_bar`
 
 error[E0412]: cannot find type `first` in module `m`
-  --> $DIR/levenshtein.rs:32:15
+  --> $DIR/levenshtein.rs:28:15
    |
 LL |     pub struct First;
    |     ----------------- similarly named struct `First` defined here
@@ -58,7 +58,7 @@
    |               ^^^^^ help: a struct with a similar name exists (notice the capitalization): `First`
 
 error[E0425]: cannot find value `second` in module `m`
-  --> $DIR/levenshtein.rs:32:26
+  --> $DIR/levenshtein.rs:28:26
    |
 LL |     pub struct Second;
    |     ------------------ similarly named unit struct `Second` defined here
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs
index 519fb75..193a523 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs
@@ -1,8 +1,4 @@
 // compile-flags: --test
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 
 use std::num::ParseFloatError;
 
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
index d4bd760..1c47aaf 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `main` has invalid return type `std::result::Result<f32, std::num::ParseFloatError>`
-  --> $DIR/termination-trait-test-wrong-type.rs:10:1
+  --> $DIR/termination-trait-test-wrong-type.rs:6:1
    |
 LL | / fn can_parse_zero_as_f32() -> Result<f32, ParseFloatError> {
 LL | |     "0".parse()
diff --git a/src/test/ui/stability-in-private-module.rs b/src/test/ui/stability-in-private-module.rs
index 1815897..f12e919 100644
--- a/src/test/ui/stability-in-private-module.rs
+++ b/src/test/ui/stability-in-private-module.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 fn main() {
     let _ = std::thread::thread_info::current_thread();
     //~^ERROR module `thread_info` is private
diff --git a/src/test/ui/stability-in-private-module.stderr b/src/test/ui/stability-in-private-module.stderr
index 35a09b2..8a7588c 100644
--- a/src/test/ui/stability-in-private-module.stderr
+++ b/src/test/ui/stability-in-private-module.stderr
@@ -1,5 +1,5 @@
 error[E0603]: module `thread_info` is private
-  --> $DIR/stability-in-private-module.rs:7:26
+  --> $DIR/stability-in-private-module.rs:2:26
    |
 LL |     let _ = std::thread::thread_info::current_thread();
    |                          ^^^^^^^^^^^ private module
diff --git a/src/test/ui/suggestions/attribute-typos.rs b/src/test/ui/suggestions/attribute-typos.rs
index e1e3317..7c8231b 100644
--- a/src/test/ui/suggestions/attribute-typos.rs
+++ b/src/test/ui/suggestions/attribute-typos.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 #[deprcated] //~ ERROR cannot find attribute `deprcated` in this scope
 fn foo() {}
 
diff --git a/src/test/ui/suggestions/attribute-typos.stderr b/src/test/ui/suggestions/attribute-typos.stderr
index 1c307f0..152700a 100644
--- a/src/test/ui/suggestions/attribute-typos.stderr
+++ b/src/test/ui/suggestions/attribute-typos.stderr
@@ -1,17 +1,17 @@
 error: attributes starting with `rustc` are reserved for use by the `rustc` compiler
-  --> $DIR/attribute-typos.rs:11:3
+  --> $DIR/attribute-typos.rs:7:3
    |
 LL | #[rustc_err]
    |   ^^^^^^^^^
 
 error: cannot find attribute `rustc_err` in this scope
-  --> $DIR/attribute-typos.rs:11:3
+  --> $DIR/attribute-typos.rs:7:3
    |
 LL | #[rustc_err]
    |   ^^^^^^^^^ help: a built-in attribute with a similar name exists: `rustc_error`
 
 error: cannot find attribute `tests` in this scope
-  --> $DIR/attribute-typos.rs:8:3
+  --> $DIR/attribute-typos.rs:4:3
    |
 LL | #[tests]
    |   ^^^^^ help: an attribute macro with a similar name exists: `test`
@@ -22,7 +22,7 @@
    |     -------------------------- similarly named attribute macro `test` defined here
 
 error: cannot find attribute `deprcated` in this scope
-  --> $DIR/attribute-typos.rs:5:3
+  --> $DIR/attribute-typos.rs:1:3
    |
 LL | #[deprcated]
    |   ^^^^^^^^^ help: a built-in attribute with a similar name exists: `deprecated`
diff --git a/src/test/ui/suggestions/const-no-type.rs b/src/test/ui/suggestions/const-no-type.rs
index 6b79697..b931a04 100644
--- a/src/test/ui/suggestions/const-no-type.rs
+++ b/src/test/ui/suggestions/const-no-type.rs
@@ -35,6 +35,11 @@
 //~| HELP provide a type for the item
 //~| SUGGESTION C: i32
 
+const D = &&42;
+//~^ ERROR missing type for `const` item
+//~| HELP provide a type for the item
+//~| SUGGESTION D: &&i32
+
 static S = Vec::<String>::new();
 //~^ ERROR missing type for `static` item
 //~| HELP provide a type for the item
diff --git a/src/test/ui/suggestions/const-no-type.stderr b/src/test/ui/suggestions/const-no-type.stderr
index a7b5aa5..874c1ba 100644
--- a/src/test/ui/suggestions/const-no-type.stderr
+++ b/src/test/ui/suggestions/const-no-type.stderr
@@ -4,14 +4,20 @@
 LL | const C = 42;
    |       ^ help: provide a type for the item: `C: i32`
 
+error: missing type for `const` item
+  --> $DIR/const-no-type.rs:38:7
+   |
+LL | const D = &&42;
+   |       ^ help: provide a type for the item: `D: &&i32`
+
 error: missing type for `static` item
-  --> $DIR/const-no-type.rs:38:8
+  --> $DIR/const-no-type.rs:43:8
    |
 LL | static S = Vec::<String>::new();
    |        ^ help: provide a type for the item: `S: std::vec::Vec<std::string::String>`
 
 error: missing type for `static mut` item
-  --> $DIR/const-no-type.rs:43:12
+  --> $DIR/const-no-type.rs:48:12
    |
 LL | static mut SM = "abc";
    |            ^^ help: provide a type for the item: `SM: &str`
@@ -34,5 +40,5 @@
 LL | static mut SM2 = "abc";
    |            ^^^ help: provide a type for the item: `SM2: <type>`
 
-error: aborting due to 6 previous errors
+error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/suggestions/imm-ref-trait-object.rs b/src/test/ui/suggestions/imm-ref-trait-object.rs
index 241dde9..288d6c6 100644
--- a/src/test/ui/suggestions/imm-ref-trait-object.rs
+++ b/src/test/ui/suggestions/imm-ref-trait-object.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 fn test(t: &dyn Iterator<Item=&u64>) -> u64 {
      t.min().unwrap() //~ ERROR the `min` method cannot be invoked on a trait object
 }
diff --git a/src/test/ui/suggestions/imm-ref-trait-object.stderr b/src/test/ui/suggestions/imm-ref-trait-object.stderr
index c5fe6dd..37c2053 100644
--- a/src/test/ui/suggestions/imm-ref-trait-object.stderr
+++ b/src/test/ui/suggestions/imm-ref-trait-object.stderr
@@ -1,5 +1,5 @@
 error: the `min` method cannot be invoked on a trait object
-  --> $DIR/imm-ref-trait-object.rs:7:8
+  --> $DIR/imm-ref-trait-object.rs:2:8
    |
 LL |      t.min().unwrap()
    |        ^^^
diff --git a/src/test/ui/suggestions/mut-borrow-needed-by-trait.rs b/src/test/ui/suggestions/mut-borrow-needed-by-trait.rs
index 49a3749..f8b8637 100644
--- a/src/test/ui/suggestions/mut-borrow-needed-by-trait.rs
+++ b/src/test/ui/suggestions/mut-borrow-needed-by-trait.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 use std::env::args;
 use std::fs::File;
 use std::io::{stdout, Write, BufWriter};
diff --git a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr
index e4234cf..57a389c 100644
--- a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr
+++ b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
-  --> $DIR/mut-borrow-needed-by-trait.rs:21:29
+  --> $DIR/mut-borrow-needed-by-trait.rs:17:29
    |
 LL |     let fp = BufWriter::new(fp);
    |                             ^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write`
@@ -8,7 +8,7 @@
    = note: required by `std::io::BufWriter::<W>::new`
 
 error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
-  --> $DIR/mut-borrow-needed-by-trait.rs:21:14
+  --> $DIR/mut-borrow-needed-by-trait.rs:17:14
    |
 LL |     let fp = BufWriter::new(fp);
    |              ^^^^^^^^^^^^^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write`
@@ -17,7 +17,7 @@
    = note: required by `std::io::BufWriter`
 
 error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
-  --> $DIR/mut-borrow-needed-by-trait.rs:21:14
+  --> $DIR/mut-borrow-needed-by-trait.rs:17:14
    |
 LL |     let fp = BufWriter::new(fp);
    |              ^^^^^^^^^^^^^^^^^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write`
@@ -26,7 +26,7 @@
    = note: required by `std::io::BufWriter`
 
 error[E0599]: no method named `write_fmt` found for struct `std::io::BufWriter<&dyn std::io::Write>` in the current scope
-  --> $DIR/mut-borrow-needed-by-trait.rs:26:5
+  --> $DIR/mut-borrow-needed-by-trait.rs:22:5
    |
 LL |     writeln!(fp, "hello world").unwrap();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ method not found in `std::io::BufWriter<&dyn std::io::Write>`
diff --git a/src/test/ui/suggestions/suggest-move-types.stderr b/src/test/ui/suggestions/suggest-move-types.stderr
index 4dd0613..3bb6fd6 100644
--- a/src/test/ui/suggestions/suggest-move-types.stderr
+++ b/src/test/ui/suggestions/suggest-move-types.stderr
@@ -4,79 +4,103 @@
 LL | struct A<T, M: One<A=(), T>> {
    |                    ----  ^ generic argument
    |                    |
-   |                    the first constraint is provided here
+   |                    constraint
+   |
+help: move the constraint after the generic argument
+   |
+LL | struct A<T, M: One<T, A = ()>> {
+   |                   ^^^^^^^^^^^
 
 error: generic arguments must come before the first constraint
   --> $DIR/suggest-move-types.rs:33:43
    |
 LL | struct Al<'a, T, M: OneWithLifetime<A=(), T, 'a>> {
-   |                                     ----  ^  ^^ generic argument
-   |                                     |     |
-   |                                     |     generic argument
-   |                                     the first constraint is provided here
+   |                                     ----  ^  ^^ generic arguments
+   |                                     |
+   |                                     constraint
+   |
+help: move the constraint after the generic arguments
+   |
+LL | struct Al<'a, T, M: OneWithLifetime<'a, T, A = ()>> {
+   |                                    ^^^^^^^^^^^^^^^
 
 error: generic arguments must come before the first constraint
   --> $DIR/suggest-move-types.rs:40:46
    |
 LL | struct B<T, U, V, M: Three<A=(), B=(), C=(), T, U, V>> {
-   |                            ----              ^  ^  ^ generic argument
-   |                            |                 |  |
-   |                            |                 |  generic argument
-   |                            |                 generic argument
-   |                            the first constraint is provided here
+   |                            ----  ----  ----  ^  ^  ^ generic arguments
+   |                            |
+   |                            constraints
+   |
+help: move the constraints after the generic arguments
+   |
+LL | struct B<T, U, V, M: Three<T, U, V, A = (), B = (), C = ()>> {
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: generic arguments must come before the first constraint
   --> $DIR/suggest-move-types.rs:48:71
    |
 LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<A=(), B=(), C=(), T, U, V, 'a, 'b, 'c>> {
-   |                                                     ----              ^  ^  ^  ^^  ^^  ^^ generic argument
-   |                                                     |                 |  |  |  |   |
-   |                                                     |                 |  |  |  |   generic argument
-   |                                                     |                 |  |  |  generic argument
-   |                                                     |                 |  |  generic argument
-   |                                                     |                 |  generic argument
-   |                                                     |                 generic argument
-   |                                                     the first constraint is provided here
+   |                                                     ----  ----  ----  ^  ^  ^  ^^  ^^  ^^ generic arguments
+   |                                                     |
+   |                                                     constraints
+   |
+help: move the constraints after the generic arguments
+   |
+LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A = (), B = (), C = ()>> {
+   |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: generic arguments must come before the first constraint
-  --> $DIR/suggest-move-types.rs:57:49
+  --> $DIR/suggest-move-types.rs:57:28
    |
 LL | struct C<T, U, V, M: Three<T, A=(), B=(), C=(), U, V>> {
-   |                               ----              ^  ^ generic argument
-   |                               |                 |
-   |                               |                 generic argument
-   |                               the first constraint is provided here
+   |                            ^  ----  ----  ----  ^  ^ generic arguments
+   |                               |
+   |                               constraints
+   |
+help: move the constraints after the generic arguments
+   |
+LL | struct C<T, U, V, M: Three<T, U, V, A = (), B = (), C = ()>> {
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: generic arguments must come before the first constraint
-  --> $DIR/suggest-move-types.rs:65:78
+  --> $DIR/suggest-move-types.rs:65:53
    |
 LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), C=(), U, 'b, V, 'c>> {
-   |                                                            ----              ^  ^^  ^  ^^ generic argument
-   |                                                            |                 |  |   |
-   |                                                            |                 |  |   generic argument
-   |                                                            |                 |  generic argument
-   |                                                            |                 generic argument
-   |                                                            the first constraint is provided here
+   |                                                     ^  ^^  ----  ----  ----  ^  ^^  ^  ^^ generic arguments
+   |                                                            |
+   |                                                            constraints
+   |
+help: move the constraints after the generic arguments
+   |
+LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A = (), B = (), C = ()>> {
+   |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: generic arguments must come before the first constraint
-  --> $DIR/suggest-move-types.rs:74:43
+  --> $DIR/suggest-move-types.rs:74:28
    |
 LL | struct D<T, U, V, M: Three<T, A=(), B=(), U, C=(), V>> {
-   |                               ----        ^        ^ generic argument
-   |                               |           |
-   |                               |           generic argument
-   |                               the first constraint is provided here
+   |                            ^  ----  ----  ^  ----  ^ generic arguments
+   |                               |
+   |                               constraints
+   |
+help: move the constraints after the generic arguments
+   |
+LL | struct D<T, U, V, M: Three<T, U, V, A = (), B = (), C = ()>> {
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: generic arguments must come before the first constraint
-  --> $DIR/suggest-move-types.rs:82:72
+  --> $DIR/suggest-move-types.rs:82:53
    |
 LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), U, 'b, C=(), V, 'c>> {
-   |                                                            ----        ^  ^^        ^  ^^ generic argument
-   |                                                            |           |  |         |
-   |                                                            |           |  |         generic argument
-   |                                                            |           |  generic argument
-   |                                                            |           generic argument
-   |                                                            the first constraint is provided here
+   |                                                     ^  ^^  ----  ----  ^  ^^  ----  ^  ^^ generic arguments
+   |                                                            |
+   |                                                            constraints
+   |
+help: move the constraints after the generic arguments
+   |
+LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A = (), B = (), C = ()>> {
+   |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0747]: type provided when a lifetime was expected
   --> $DIR/suggest-move-types.rs:33:43
diff --git a/src/test/ui/traits/impl_trait_as_trait_return_position.rs b/src/test/ui/traits/impl_trait_as_trait_return_position.rs
new file mode 100644
index 0000000..c3325fd
--- /dev/null
+++ b/src/test/ui/traits/impl_trait_as_trait_return_position.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+trait A {
+    type Foo;
+}
+
+impl<T> A for T {
+    type Foo = ();
+}
+
+fn foo() -> impl std::borrow::Borrow<<u8 as A>::Foo> {
+    ()
+}
+
+fn main() {
+    foo();
+}
diff --git a/src/test/ui/traits/trait-alias/trait-alias-object-fail.rs b/src/test/ui/traits/trait-alias/trait-alias-object-fail.rs
index 3be8db8..d62fd7e 100644
--- a/src/test/ui/traits/trait-alias/trait-alias-object-fail.rs
+++ b/src/test/ui/traits/trait-alias/trait-alias-object-fail.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 #![feature(trait_alias)]
 
 trait EqAlias = Eq;
diff --git a/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr b/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr
index 2181809..56ecb72 100644
--- a/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr
+++ b/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr
@@ -1,5 +1,5 @@
 error[E0038]: the trait `std::cmp::Eq` cannot be made into an object
-  --> $DIR/trait-alias-object-fail.rs:12:13
+  --> $DIR/trait-alias-object-fail.rs:7:13
    |
 LL |     let _: &dyn EqAlias = &123;
    |             ^^^^^^^^^^^ the trait `std::cmp::Eq` cannot be made into an object
@@ -10,7 +10,7 @@
    |               --------------- the trait cannot be made into an object because it uses `Self` as a type parameter in this
 
 error[E0191]: the value of the associated type `Item` (from trait `std::iter::Iterator`) must be specified
-  --> $DIR/trait-alias-object-fail.rs:14:17
+  --> $DIR/trait-alias-object-fail.rs:9:17
    |
 LL |     let _: &dyn IteratorAlias = &vec![123].into_iter();
    |                 ^^^^^^^^^^^^^ help: specify the associated type: `IteratorAlias<Item = Type>`
diff --git a/src/test/ui/traits/trait-static-method-generic-inference.stderr b/src/test/ui/traits/trait-static-method-generic-inference.stderr
index f9718da..8f20cc5 100644
--- a/src/test/ui/traits/trait-static-method-generic-inference.stderr
+++ b/src/test/ui/traits/trait-static-method-generic-inference.stderr
@@ -7,7 +7,7 @@
 LL |     let _f: base::Foo = base::HasNew::new();
    |                         ^^^^^^^^^^^^^^^^^ cannot infer type
    |
-   = note: cannot resolve `_: base::HasNew<base::Foo>`
+   = note: cannot satisfy `_: base::HasNew<base::Foo>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/trait-suggest-where-clause.rs b/src/test/ui/traits/trait-suggest-where-clause.rs
index 5b34ed0..8405e5f 100644
--- a/src/test/ui/traits/trait-suggest-where-clause.rs
+++ b/src/test/ui/traits/trait-suggest-where-clause.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 use std::mem;
 
 struct Misc<T:?Sized>(T);
diff --git a/src/test/ui/traits/trait-suggest-where-clause.stderr b/src/test/ui/traits/trait-suggest-where-clause.stderr
index 9680d58..4dddcd6 100644
--- a/src/test/ui/traits/trait-suggest-where-clause.stderr
+++ b/src/test/ui/traits/trait-suggest-where-clause.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the size for values of type `U` cannot be known at compilation time
-  --> $DIR/trait-suggest-where-clause.rs:11:20
+  --> $DIR/trait-suggest-where-clause.rs:7:20
    |
 LL | fn check<T: Iterator, U: ?Sized>() {
    |                       - this type parameter needs to be `std::marker::Sized`
@@ -16,7 +16,7 @@
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
 
 error[E0277]: the size for values of type `U` cannot be known at compilation time
-  --> $DIR/trait-suggest-where-clause.rs:14:5
+  --> $DIR/trait-suggest-where-clause.rs:10:5
    |
 LL | fn check<T: Iterator, U: ?Sized>() {
    |                       - this type parameter needs to be `std::marker::Sized`
@@ -34,7 +34,7 @@
    = note: required because it appears within the type `Misc<U>`
 
 error[E0277]: the trait bound `u64: std::convert::From<T>` is not satisfied
-  --> $DIR/trait-suggest-where-clause.rs:19:5
+  --> $DIR/trait-suggest-where-clause.rs:15:5
    |
 LL |     <u64 as From<T>>::from;
    |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<T>` is not implemented for `u64`
@@ -42,7 +42,7 @@
    = note: required by `std::convert::From::from`
 
 error[E0277]: the trait bound `u64: std::convert::From<<T as std::iter::Iterator>::Item>` is not satisfied
-  --> $DIR/trait-suggest-where-clause.rs:22:5
+  --> $DIR/trait-suggest-where-clause.rs:18:5
    |
 LL |     <u64 as From<<T as Iterator>::Item>>::from;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<<T as std::iter::Iterator>::Item>` is not implemented for `u64`
@@ -50,7 +50,7 @@
    = note: required by `std::convert::From::from`
 
 error[E0277]: the trait bound `Misc<_>: std::convert::From<T>` is not satisfied
-  --> $DIR/trait-suggest-where-clause.rs:27:5
+  --> $DIR/trait-suggest-where-clause.rs:23:5
    |
 LL |     <Misc<_> as From<T>>::from;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<T>` is not implemented for `Misc<_>`
@@ -58,7 +58,7 @@
    = note: required by `std::convert::From::from`
 
 error[E0277]: the size for values of type `[T]` cannot be known at compilation time
-  --> $DIR/trait-suggest-where-clause.rs:32:20
+  --> $DIR/trait-suggest-where-clause.rs:28:20
    |
 LL |     mem::size_of::<[T]>();
    |                    ^^^ doesn't have a size known at compile-time
@@ -72,7 +72,7 @@
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
 
 error[E0277]: the size for values of type `[&U]` cannot be known at compilation time
-  --> $DIR/trait-suggest-where-clause.rs:35:5
+  --> $DIR/trait-suggest-where-clause.rs:31:5
    |
 LL |     mem::size_of::<[&U]>();
    |     ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction2.rs b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs
index 1becb1e..0a4cc9b 100644
--- a/src/test/ui/type-alias-impl-trait/bound_reduction2.rs
+++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs
@@ -8,13 +8,12 @@
 }
 
 type Foo<V> = impl Trait<V>;
-//~^ ERROR could not find defining uses
-//~| ERROR the trait bound `T: TraitWithAssoc` is not satisfied
+//~^ ERROR the trait bound `T: TraitWithAssoc` is not satisfied
 
 trait Trait<U> {}
 
 impl<W> Trait<W> for () {}
 
-fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> { //~ ERROR does not fully define
+fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
     ()
 }
diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr
index aff5585..b871f79 100644
--- a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr
+++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr
@@ -9,20 +9,6 @@
 LL | fn foo_desugared<T: TraitWithAssoc + TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
    |                                    ^^^^^^^^^^^^^^^^
 
-error: defining opaque type use does not fully define opaque type: generic parameter `V` is specified as concrete type `<T as TraitWithAssoc>::Assoc`
-  --> $DIR/bound_reduction2.rs:18:1
-   |
-LL | / fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
-LL | |     ()
-LL | | }
-   | |_^
-
-error: could not find defining uses
-  --> $DIR/bound_reduction2.rs:10:1
-   |
-LL | type Foo<V> = impl Trait<V>;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs
index 165e320..4503607 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs
@@ -1,14 +1,26 @@
-#![feature(type_alias_impl_trait)]
+#![feature(type_alias_impl_trait, const_generics)]
+#![allow(incomplete_features)]
 
 use std::fmt::Debug;
 
 fn main() {}
 
 // test that unused generic parameters are ok
-type Two<T, U> = impl Debug;
-//~^ could not find defining uses
+type TwoTys<T, U> = impl Debug;
+type TwoLifetimes<'a, 'b> = impl Debug;
+type TwoConsts<const X: usize, const Y: usize> = impl Debug;
 
-fn one<T: Debug>(t: T) -> Two<T, T> {
-//~^ ERROR defining opaque type use restricts opaque type
+fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> {
+//~^ ERROR non-defining opaque type use in defining scope
+    t
+}
+
+fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> {
+//~^ ERROR non-defining opaque type use in defining scope
+    t
+}
+
+fn one_const<const N: usize>(t: *mut [u8; N]) -> TwoConsts<N, N> {
+//~^ ERROR non-defining opaque type use in defining scope
     t
 }
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr
index e179403..b4757e2 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr
@@ -1,17 +1,38 @@
-error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
-  --> $DIR/generic_duplicate_param_use.rs:11:1
+error: non-defining opaque type use in defining scope
+  --> $DIR/generic_duplicate_param_use.rs:13:30
    |
-LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
-LL | |
-LL | |     t
-LL | | }
-   | |_^
-
-error: could not find defining uses
-  --> $DIR/generic_duplicate_param_use.rs:8:1
+LL | fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> {
+   |                              ^^^^^^^^^^^^
    |
-LL | type Two<T, U> = impl Debug;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: type used multiple times
+  --> $DIR/generic_duplicate_param_use.rs:9:13
+   |
+LL | type TwoTys<T, U> = impl Debug;
+   |             ^  ^
 
-error: aborting due to 2 previous errors
+error: non-defining opaque type use in defining scope
+  --> $DIR/generic_duplicate_param_use.rs:18:36
+   |
+LL | fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> {
+   |                                    ^^^^^^^^^^^^^^^^^^^^
+   |
+note: lifetime used multiple times
+  --> $DIR/generic_duplicate_param_use.rs:10:19
+   |
+LL | type TwoLifetimes<'a, 'b> = impl Debug;
+   |                   ^^  ^^
+
+error: non-defining opaque type use in defining scope
+  --> $DIR/generic_duplicate_param_use.rs:23:50
+   |
+LL | fn one_const<const N: usize>(t: *mut [u8; N]) -> TwoConsts<N, N> {
+   |                                                  ^^^^^^^^^^^^^^^
+   |
+note: constant used multiple times
+  --> $DIR/generic_duplicate_param_use.rs:11:22
+   |
+LL | type TwoConsts<const X: usize, const Y: usize> = impl Debug;
+   |                      ^               ^
+
+error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs
index 0adce81..2b98d8f 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs
@@ -8,10 +8,10 @@
 type Two<T, U> = impl Debug;
 
 fn one<T: Debug>(t: T) -> Two<T, T> {
-//~^ defining opaque type use restricts opaque type
     t
 }
 
 fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
+//~^ ERROR concrete type differs from previous defining opaque type use
     t
 }
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr
index a9a51fa..8170c67 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr
@@ -1,8 +1,16 @@
-error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/generic_duplicate_param_use2.rs:14:1
+   |
+LL | / fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
+LL | |
+LL | |     t
+LL | | }
+   | |_^ expected `U`, got `T`
+   |
+note: previous use here
   --> $DIR/generic_duplicate_param_use2.rs:10:1
    |
 LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
-LL | |
 LL | |     t
 LL | | }
    | |_^
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs
index 8d3e7f9..d9133fd 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs
@@ -8,15 +8,14 @@
 type Two<T, U> = impl Debug;
 
 fn one<T: Debug>(t: T) -> Two<T, T> {
-//~^ defining opaque type use restricts opaque type
     t
 }
 
 fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
+//~^ ERROR concrete type differs from previous defining opaque type use
     t
 }
 
 fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
-//~^ concrete type's generic parameters differ from previous defining use
     u
 }
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr
index 04dcdc2..86dd336 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr
@@ -1,28 +1,19 @@
-error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/generic_duplicate_param_use3.rs:14:1
+   |
+LL | / fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
+LL | |
+LL | |     t
+LL | | }
+   | |_^ expected `U`, got `T`
+   |
+note: previous use here
   --> $DIR/generic_duplicate_param_use3.rs:10:1
    |
 LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
-LL | |
 LL | |     t
 LL | | }
    | |_^
 
-error: concrete type's generic parameters differ from previous defining use
-  --> $DIR/generic_duplicate_param_use3.rs:19:1
-   |
-LL | / fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
-LL | |
-LL | |     u
-LL | | }
-   | |_^ expected [`T`], got [`U`]
-   |
-note: previous use here
-  --> $DIR/generic_duplicate_param_use3.rs:15:1
-   |
-LL | / fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
-LL | |     t
-LL | | }
-   | |_^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs
index 65f7d7f..40388c3 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs
@@ -8,7 +8,7 @@
 type Two<T, U> = impl Debug;
 
 fn one<T: Debug>(t: T) -> Two<T, T> {
-//~^ ERROR defining opaque type use restricts opaque type
+//~^ ERROR non-defining opaque type use in defining scope
     t
 }
 
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr
index 082177b..fcf01f5 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr
@@ -1,11 +1,14 @@
-error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
-  --> $DIR/generic_duplicate_param_use4.rs:10:1
+error: non-defining opaque type use in defining scope
+  --> $DIR/generic_duplicate_param_use4.rs:10:27
    |
-LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
-LL | |
-LL | |     t
-LL | | }
-   | |_^
+LL | fn one<T: Debug>(t: T) -> Two<T, T> {
+   |                           ^^^^^^^^^
+   |
+note: type used multiple times
+  --> $DIR/generic_duplicate_param_use4.rs:8:10
+   |
+LL | type Two<T, U> = impl Debug;
+   |          ^  ^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs
index 60106eb..b178212 100644
--- a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs
+++ b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs
@@ -1,13 +1,27 @@
-#![feature(type_alias_impl_trait)]
+#![feature(type_alias_impl_trait, const_generics)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
 
 fn main() {}
 
-type Cmp<T> = impl 'static;
-//~^ ERROR could not find defining uses
-//~^^ ERROR: at least one trait must be specified
+type OneTy<T> = impl Debug;
+type OneLifetime<'a> = impl Debug;
+type OneConst<const X: usize> = impl Debug;
 
+// Not defining uses, because they doesn't define *all* possible generics.
 
-// not a defining use, because it doesn't define *all* possible generics
-fn cmp() -> Cmp<u32> { //~ ERROR defining opaque type use does not fully define
+fn concrete_ty() -> OneTy<u32> {
+//~^ ERROR non-defining opaque type use in defining scope
     5u32
 }
+
+fn concrete_lifetime() -> OneLifetime<'static> {
+//~^ ERROR non-defining opaque type use in defining scope
+    6u32
+}
+
+fn concrete_const() -> OneConst<{123}> {
+//~^ ERROR non-defining opaque type use in defining scope
+    7u32
+}
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 b952aaa..b0ffc4a 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,22 +1,35 @@
-error: at least one trait must be specified
-  --> $DIR/generic_nondefining_use.rs:5:15
+error: non-defining opaque type use in defining scope
+  --> $DIR/generic_nondefining_use.rs:14:21
    |
-LL | type Cmp<T> = impl 'static;
-   |               ^^^^^^^^^^^^
+LL | fn concrete_ty() -> OneTy<u32> {
+   |                     ^^^^^^^^^^
+   |
+note: used non-generic type `u32` for generic parameter
+  --> $DIR/generic_nondefining_use.rs:8:12
+   |
+LL | type OneTy<T> = impl Debug;
+   |            ^
 
-error: defining opaque type use does not fully define opaque type: generic parameter `T` is specified as concrete type `u32`
-  --> $DIR/generic_nondefining_use.rs:11:1
+error: non-defining opaque type use in defining scope
+  --> $DIR/generic_nondefining_use.rs:19:27
    |
-LL | / fn cmp() -> Cmp<u32> {
-LL | |     5u32
-LL | | }
-   | |_^
+LL | type OneLifetime<'a> = impl Debug;
+   |                  -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
+...
+LL | fn concrete_lifetime() -> OneLifetime<'static> {
+   |                           ^^^^^^^^^^^^^^^^^^^^
 
-error: could not find defining uses
-  --> $DIR/generic_nondefining_use.rs:5:1
+error: non-defining opaque type use in defining scope
+  --> $DIR/generic_nondefining_use.rs:24:24
    |
-LL | type Cmp<T> = impl 'static;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | fn concrete_const() -> OneConst<{123}> {
+   |                        ^^^^^^^^^^^^^^^
+   |
+note: used non-generic constant `123usize` for generic parameter
+  --> $DIR/generic_nondefining_use.rs:10:21
+   |
+LL | type OneConst<const X: usize> = impl Debug;
+   |                     ^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.rs b/src/test/ui/type-alias-impl-trait/issue-60564.rs
index 73acc92..4eb7f78 100644
--- a/src/test/ui/type-alias-impl-trait/issue-60564.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-60564.rs
@@ -6,7 +6,6 @@
 }
 
 type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
-//~^ ERROR could not find defining uses
 
 impl<T: Copy, E> IterBits for T
 where
@@ -18,7 +17,8 @@
 {
     type BitsIter = IterBitsIter<T, E, u8>;
     fn iter_bits(self, n: u8) -> Self::BitsIter {
-    //~^ ERROR defining opaque type use does not fully define opaque type
+    //~^ ERROR non-defining opaque type use in defining scope
+    //~| ERROR non-defining opaque type use in defining scope
         (0u8..n)
             .rev()
             .map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.stderr b/src/test/ui/type-alias-impl-trait/issue-60564.stderr
index 9de3e75..5598460 100644
--- a/src/test/ui/type-alias-impl-trait/issue-60564.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-60564.stderr
@@ -1,19 +1,26 @@
-error: defining opaque type use does not fully define opaque type: generic parameter `I` is specified as concrete type `u8`
-  --> $DIR/issue-60564.rs:20:5
+error: non-defining opaque type use in defining scope
+  --> $DIR/issue-60564.rs:19:34
    |
-LL | /     fn iter_bits(self, n: u8) -> Self::BitsIter {
-LL | |
-LL | |         (0u8..n)
-LL | |             .rev()
-LL | |             .map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
-LL | |     }
-   | |_____^
-
-error: could not find defining uses
-  --> $DIR/issue-60564.rs:8:1
+LL |     fn iter_bits(self, n: u8) -> Self::BitsIter {
+   |                                  ^^^^^^^^^^^^^^
+   |
+note: used non-generic type `_` for generic parameter
+  --> $DIR/issue-60564.rs:8:22
    |
 LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                      ^
+
+error: non-defining opaque type use in defining scope
+  --> $DIR/issue-60564.rs:19:34
+   |
+LL |     fn iter_bits(self, n: u8) -> Self::BitsIter {
+   |                                  ^^^^^^^^^^^^^^
+   |
+note: used non-generic type `u8` for generic parameter
+  --> $DIR/issue-60564.rs:8:25
+   |
+LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
+   |                         ^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs
index d00f8d7..3b6decb 100644
--- a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs
@@ -4,9 +4,9 @@
 
 #![feature(type_alias_impl_trait)]
 trait Trait<T> {}
-type Alias<'a, U> = impl Trait<U>; //~ ERROR could not find defining uses
+type Alias<'a, U> = impl Trait<U>;
 fn f<'a>() -> Alias<'a, ()> {}
-//~^ ERROR defining opaque type use does not fully define opaque type: generic parameter `U`
+//~^ ERROR non-defining opaque type use in defining scope
 
 fn main() {}
 
diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr
index b585942..c2fa54f 100644
--- a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr
@@ -1,14 +1,14 @@
-error: defining opaque type use does not fully define opaque type: generic parameter `U` is specified as concrete type `()`
-  --> $DIR/issue-68368-non-defining-use.rs:8:1
+error: non-defining opaque type use in defining scope
+  --> $DIR/issue-68368-non-defining-use.rs:8:15
    |
 LL | fn f<'a>() -> Alias<'a, ()> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: could not find defining uses
-  --> $DIR/issue-68368-non-defining-use.rs:7:1
+   |               ^^^^^^^^^^^^^
+   |
+note: used non-generic type `()` for generic parameter
+  --> $DIR/issue-68368-non-defining-use.rs:7:16
    |
 LL | type Alias<'a, U> = impl Trait<U>;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
diff --git a/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs b/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs
index ca00e58..02485b2 100644
--- a/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs
+++ b/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs
@@ -7,7 +7,6 @@
 type Two<T, U> = impl Debug;
 
 fn two<T: Debug>(t: T) -> Two<T, u32> {
-    //~^ ERROR defining opaque type use does not fully define opaque type
     (t, 4i8)
 }
 
diff --git a/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr
index d68f1bd..cce861b 100644
--- a/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr
+++ b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr
@@ -1,14 +1,5 @@
-error: defining opaque type use does not fully define opaque type: generic parameter `U` is specified as concrete type `u32`
-  --> $DIR/not_a_defining_use.rs:9:1
-   |
-LL | / fn two<T: Debug>(t: T) -> Two<T, u32> {
-LL | |
-LL | |     (t, 4i8)
-LL | | }
-   | |_^
-
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/not_a_defining_use.rs:30:1
+  --> $DIR/not_a_defining_use.rs:29:1
    |
 LL | / fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> {
 LL | |     (t, <U as Bar>::FOO)
@@ -16,12 +7,12 @@
    | |_^ expected `(T, i8)`, got `(T, <U as Bar>::Blub)`
    |
 note: previous use here
-  --> $DIR/not_a_defining_use.rs:14:1
+  --> $DIR/not_a_defining_use.rs:9:1
    |
-LL | / fn three<T: Debug, U>(t: T) -> Two<T, U> {
-LL | |     (t, 5i8)
+LL | / fn two<T: Debug>(t: T) -> Two<T, u32> {
+LL | |     (t, 4i8)
 LL | | }
    | |_^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
diff --git a/src/test/ui/type-sizes.rs b/src/test/ui/type-sizes.rs
index 1d332cc..6a3f3c9 100644
--- a/src/test/ui/type-sizes.rs
+++ b/src/test/ui/type-sizes.rs
@@ -37,6 +37,29 @@
     B(u8, u16, u8),
 }
 
+enum ReorderedEnum2 {
+    A(u8, u32, u8),
+    B(u16, u8, u16, u8),
+
+    // 0x100 niche variants.
+    _00, _01, _02, _03, _04, _05, _06, _07, _08, _09, _0A, _0B, _0C, _0D, _0E, _0F,
+    _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _1A, _1B, _1C, _1D, _1E, _1F,
+    _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _2A, _2B, _2C, _2D, _2E, _2F,
+    _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _3A, _3B, _3C, _3D, _3E, _3F,
+    _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _4A, _4B, _4C, _4D, _4E, _4F,
+    _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _5A, _5B, _5C, _5D, _5E, _5F,
+    _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _6A, _6B, _6C, _6D, _6E, _6F,
+    _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _7A, _7B, _7C, _7D, _7E, _7F,
+    _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _8A, _8B, _8C, _8D, _8E, _8F,
+    _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _9A, _9B, _9C, _9D, _9E, _9F,
+    _A0, _A1, _A2, _A3, _A4, _A5, _A6, _A7, _A8, _A9, _AA, _AB, _AC, _AD, _AE, _AF,
+    _B0, _B1, _B2, _B3, _B4, _B5, _B6, _B7, _B8, _B9, _BA, _BB, _BC, _BD, _BE, _BF,
+    _C0, _C1, _C2, _C3, _C4, _C5, _C6, _C7, _C8, _C9, _CA, _CB, _CC, _CD, _CE, _CF,
+    _D0, _D1, _D2, _D3, _D4, _D5, _D6, _D7, _D8, _D9, _DA, _DB, _DC, _DD, _DE, _DF,
+    _E0, _E1, _E2, _E3, _E4, _E5, _E6, _E7, _E8, _E9, _EA, _EB, _EC, _ED, _EE, _EF,
+    _F0, _F1, _F2, _F3, _F4, _F5, _F6, _F7, _F8, _F9, _FA, _FB, _FC, _FD, _FE, _FF,
+}
+
 enum EnumEmpty {}
 
 enum EnumSingle1 {
@@ -104,6 +127,8 @@
     assert_eq!(size_of::<e3>(), 4 as usize);
     assert_eq!(size_of::<ReorderedStruct>(), 4);
     assert_eq!(size_of::<ReorderedEnum>(), 6);
+    assert_eq!(size_of::<ReorderedEnum2>(), 8);
+
 
     assert_eq!(size_of::<EnumEmpty>(), 0);
     assert_eq!(size_of::<EnumSingle1>(), 0);
diff --git a/src/test/ui/type/type-annotation-needed.rs b/src/test/ui/type/type-annotation-needed.rs
index a420515..b9bf6d7 100644
--- a/src/test/ui/type/type-annotation-needed.rs
+++ b/src/test/ui/type/type-annotation-needed.rs
@@ -6,5 +6,5 @@
     foo(42);
     //~^ ERROR type annotations needed
     //~| NOTE cannot infer type
-    //~| NOTE cannot resolve
+    //~| NOTE cannot satisfy
 }
diff --git a/src/test/ui/type/type-annotation-needed.stderr b/src/test/ui/type/type-annotation-needed.stderr
index df7d73d..e6cd7ac 100644
--- a/src/test/ui/type/type-annotation-needed.stderr
+++ b/src/test/ui/type/type-annotation-needed.stderr
@@ -7,7 +7,7 @@
 LL |     foo(42);
    |     ^^^ cannot infer type for type parameter `T` declared on the function `foo`
    |
-   = note: cannot resolve `_: std::convert::Into<std::string::String>`
+   = note: cannot satisfy `_: std::convert::Into<std::string::String>`
 help: consider specifying the type argument in the function call
    |
 LL |     foo::<T>(42);
diff --git a/src/test/ui/type/type-check/issue-40294.stderr b/src/test/ui/type/type-check/issue-40294.stderr
index 2c889b6..7d81e0c 100644
--- a/src/test/ui/type/type-check/issue-40294.stderr
+++ b/src/test/ui/type/type-check/issue-40294.stderr
@@ -7,7 +7,7 @@
 LL |     where &'a T : Foo,
    |                   ^^^ cannot infer type for reference `&'a T`
    |
-   = note: cannot resolve `&'a T: Foo`
+   = note: cannot satisfy `&'a T: Foo`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type_length_limit.rs b/src/test/ui/type_length_limit.rs
index 0ecd5cf..1f1c8ad9 100644
--- a/src/test/ui/type_length_limit.rs
+++ b/src/test/ui/type_length_limit.rs
@@ -1,8 +1,4 @@
 // build-fail
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 // error-pattern: reached the type-length limit while instantiating
 
 // Test that the type length limit can be changed.
diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs
index a959aaa..e804afc 100644
--- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs
+++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 use std::mem::zeroed;
 enum Void {}
 
diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
index bfe37b5..c7bf671 100644
--- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
+++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: `Err(_)` not covered
-  --> $DIR/uninhabited-matches-feature-gated.rs:11:19
+  --> $DIR/uninhabited-matches-feature-gated.rs:6:19
    |
 LL |     let _ = match x {
    |                   ^ pattern `Err(_)` not covered
@@ -13,7 +13,7 @@
    = note: the matched value is of type `std::result::Result<u32, &Void>`
 
 error[E0004]: non-exhaustive patterns: type `&Void` is non-empty
-  --> $DIR/uninhabited-matches-feature-gated.rs:20:19
+  --> $DIR/uninhabited-matches-feature-gated.rs:15:19
    |
 LL | enum Void {}
    | ------------ `Void` defined here
@@ -25,7 +25,7 @@
    = note: the matched value is of type `&Void`
 
 error[E0004]: non-exhaustive patterns: type `(Void,)` is non-empty
-  --> $DIR/uninhabited-matches-feature-gated.rs:23:19
+  --> $DIR/uninhabited-matches-feature-gated.rs:18:19
    |
 LL |     let _ = match x {};
    |                   ^
@@ -34,7 +34,7 @@
    = note: the matched value is of type `(Void,)`
 
 error[E0004]: non-exhaustive patterns: type `[Void; 1]` is non-empty
-  --> $DIR/uninhabited-matches-feature-gated.rs:26:19
+  --> $DIR/uninhabited-matches-feature-gated.rs:21:19
    |
 LL |     let _ = match x {};
    |                   ^
@@ -43,7 +43,7 @@
    = note: the matched value is of type `[Void; 1]`
 
 error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
-  --> $DIR/uninhabited-matches-feature-gated.rs:29:19
+  --> $DIR/uninhabited-matches-feature-gated.rs:24:19
    |
 LL |     let _ = match x {
    |                   ^ pattern `&[_, ..]` not covered
@@ -52,7 +52,7 @@
    = note: the matched value is of type `&[Void]`
 
 error[E0004]: non-exhaustive patterns: `Err(_)` not covered
-  --> $DIR/uninhabited-matches-feature-gated.rs:37:19
+  --> $DIR/uninhabited-matches-feature-gated.rs:32:19
    |
 LL |     let _ = match x {
    |                   ^ pattern `Err(_)` not covered
@@ -66,7 +66,7 @@
    = note: the matched value is of type `std::result::Result<u32, Void>`
 
 error[E0005]: refutable pattern in local binding: `Err(_)` not covered
-  --> $DIR/uninhabited-matches-feature-gated.rs:42:9
+  --> $DIR/uninhabited-matches-feature-gated.rs:37:9
    |
 LL |     let Ok(x) = x;
    |         ^^^^^ pattern `Err(_)` not covered
diff --git a/src/test/ui/union/union-derive-clone.rs b/src/test/ui/union/union-derive-clone.rs
index 4b92475..4a106cc 100644
--- a/src/test/ui/union/union-derive-clone.rs
+++ b/src/test/ui/union/union-derive-clone.rs
@@ -1,8 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
-
 #![feature(untagged_unions)]
 
 use std::mem::ManuallyDrop;
diff --git a/src/test/ui/union/union-derive-clone.stderr b/src/test/ui/union/union-derive-clone.stderr
index d0a82a9..6643761 100644
--- a/src/test/ui/union/union-derive-clone.stderr
+++ b/src/test/ui/union/union-derive-clone.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `U1: std::marker::Copy` is not satisfied
-  --> $DIR/union-derive-clone.rs:10:10
+  --> $DIR/union-derive-clone.rs:5:10
    |
 LL | #[derive(Clone)]
    |          ^^^^^ the trait `std::marker::Copy` is not implemented for `U1`
@@ -8,7 +8,7 @@
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0599]: no method named `clone` found for union `U5<CloneNoCopy>` in the current scope
-  --> $DIR/union-derive-clone.rs:42:15
+  --> $DIR/union-derive-clone.rs:37:15
    |
 LL | union U5<T> {
    | -----------
diff --git a/src/test/ui/unique-object-noncopyable.rs b/src/test/ui/unique-object-noncopyable.rs
index bedaf27..dd38a71 100644
--- a/src/test/ui/unique-object-noncopyable.rs
+++ b/src/test/ui/unique-object-noncopyable.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 #![feature(box_syntax)]
 
 trait Foo {
diff --git a/src/test/ui/unique-object-noncopyable.stderr b/src/test/ui/unique-object-noncopyable.stderr
index 2e81e7c..161e25b 100644
--- a/src/test/ui/unique-object-noncopyable.stderr
+++ b/src/test/ui/unique-object-noncopyable.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `clone` found for struct `std::boxed::Box<dyn Foo>` in the current scope
-  --> $DIR/unique-object-noncopyable.rs:28:16
+  --> $DIR/unique-object-noncopyable.rs:24:16
    |
 LL | trait Foo {
    | ---------
diff --git a/src/test/ui/unique-pinned-nocopy.rs b/src/test/ui/unique-pinned-nocopy.rs
index 091b8a4..4c30450 100644
--- a/src/test/ui/unique-pinned-nocopy.rs
+++ b/src/test/ui/unique-pinned-nocopy.rs
@@ -1,7 +1,3 @@
-// FIXME: missing sysroot spans (#53081)
-// ignore-i586-unknown-linux-gnu
-// ignore-i586-unknown-linux-musl
-// ignore-i686-unknown-linux-musl
 #[derive(Debug)]
 struct R {
   b: bool,
diff --git a/src/test/ui/unique-pinned-nocopy.stderr b/src/test/ui/unique-pinned-nocopy.stderr
index 06c4b95..38c110c 100644
--- a/src/test/ui/unique-pinned-nocopy.stderr
+++ b/src/test/ui/unique-pinned-nocopy.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `clone` found for struct `std::boxed::Box<R>` in the current scope
-  --> $DIR/unique-pinned-nocopy.rs:16:16
+  --> $DIR/unique-pinned-nocopy.rs:12:16
    |
 LL | struct R {
    | -------- doesn't satisfy `R: std::clone::Clone`
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 98e9fe7..f075d3e 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -56,6 +56,8 @@
     "aarch64-unknown-hermit",
     "aarch64-unknown-linux-gnu",
     "aarch64-unknown-linux-musl",
+    "aarch64-unknown-none",
+    "aarch64-unknown-none-softfloat",
     "aarch64-unknown-redox",
     "arm-linux-androideabi",
     "arm-unknown-linux-gnueabi",
diff --git a/src/tools/cargo b/src/tools/cargo
index 8a0d4d9..6e07d2d 160000
--- a/src/tools/cargo
+++ b/src/tools/cargo
@@ -1 +1 @@
-Subproject commit 8a0d4d9c9abc74fd670353094387d62028b40ae9
+Subproject commit 6e07d2dfb7fc87b1c9489de41da4dafa239daf03
diff --git a/src/tools/clippy b/src/tools/clippy
index 326b220..7907abe 160000
--- a/src/tools/clippy
+++ b/src/tools/clippy
@@ -1 +1 @@
-Subproject commit 326b22048a6305d7c918b748be1c081468917ac6
+Subproject commit 7907abea272bbf97812683ce03a1ab9c22f0557b
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 8a291a3..04d34fd 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2513,7 +2513,7 @@
                     .filter(|s| !s.is_empty())
                     .map(|s| {
                         if cgu_has_crate_disambiguator {
-                            remove_crate_disambiguator_from_cgu(s)
+                            remove_crate_disambiguators_from_set_of_cgu_names(s)
                         } else {
                             s.to_string()
                         }
@@ -2563,6 +2563,16 @@
 
             new_name
         }
+
+        // The name of merged CGUs is constructed as the names of the original
+        // CGUs joined with "--". This function splits such composite CGU names
+        // and handles each component individually.
+        fn remove_crate_disambiguators_from_set_of_cgu_names(cgus: &str) -> String {
+            cgus.split("--")
+                .map(|cgu| remove_crate_disambiguator_from_cgu(cgu))
+                .collect::<Vec<_>>()
+                .join("--")
+        }
     }
 
     fn init_incremental_test(&self) {
diff --git a/src/tools/miri b/src/tools/miri
index d1e06b4..147ea8f 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit d1e06b429812916e5fc3129bff992d37639d9da4
+Subproject commit 147ea8f400de3ca529abcb5eb7b65f84a4896ae9
diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index 6cc20a2..b55ead0 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -40,7 +40,7 @@
         'ryankurte', 'thejpster', 'therealprof',
     },
     'edition-guide': {'ehuss', 'Centril', 'steveklabnik'},
-    'rustc-guide': {'mark-i-m', 'spastorino', 'amanjeev', 'JohnTitor'},
+    'rustc-dev-guide': {'mark-i-m', 'spastorino', 'amanjeev', 'JohnTitor'},
 }
 
 REPOS = {
@@ -54,7 +54,7 @@
     'rust-by-example': 'https://github.com/rust-lang/rust-by-example',
     'embedded-book': 'https://github.com/rust-embedded/book',
     'edition-guide': 'https://github.com/rust-lang/edition-guide',
-    'rustc-guide': 'https://github.com/rust-lang/rustc-guide',
+    'rustc-dev-guide': 'https://github.com/rust-lang/rustc-dev-guide',
 }
 
 
@@ -202,7 +202,7 @@
                 old = status[os]
                 new = s.get(tool, old)
                 status[os] = new
-                maintainers = ' '.join('@'+name for name in MAINTAINERS[tool])
+                maintainers = ' '.join('@'+name for name in MAINTAINERS.get(tool, ()))
                 # comparing the strings, but they are ordered appropriately:
                 # "test-pass" > "test-fail" > "build-fail"
                 if new > old:
diff --git a/src/tools/rls b/src/tools/rls
index 5fde462..1cfb878 160000
--- a/src/tools/rls
+++ b/src/tools/rls
@@ -1 +1 @@
-Subproject commit 5fde462d8c53b86840100a927a17c8353bba3e3f
+Subproject commit 1cfb87845f45758442830506b7242947dfc989d9
diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml
index 936e8ae..7e70b52 100644
--- a/src/tools/rustc-workspace-hack/Cargo.toml
+++ b/src/tools/rustc-workspace-hack/Cargo.toml
@@ -59,7 +59,7 @@
 
 [dependencies]
 curl-sys = { version = "0.4.13", features = ["http2", "libnghttp2-sys"], optional = true }
-crossbeam-utils = { version = "0.6.5", features = ["nightly"] }
+crossbeam-utils = { version = "0.7.2", features = ["nightly"] }
 serde = { version = "1.0.82", features = ['derive'] }
 serde_json = { version = "1.0.31", features = ["raw_value"] }
 smallvec-0_6 = { package = "smallvec", version = "0.6", features = ['union', 'may_dangle'] }
diff --git a/src/tools/rustdoc-js-common/lib.js b/src/tools/rustdoc-js-common/lib.js
new file mode 100644
index 0000000..81e64ae
--- /dev/null
+++ b/src/tools/rustdoc-js-common/lib.js
@@ -0,0 +1,319 @@
+const fs = require('fs');
+
+function getNextStep(content, pos, stop) {
+    while (pos < content.length && content[pos] !== stop &&
+           (content[pos] === ' ' || content[pos] === '\t' || content[pos] === '\n')) {
+        pos += 1;
+    }
+    if (pos >= content.length) {
+        return null;
+    }
+    if (content[pos] !== stop) {
+        return pos * -1;
+    }
+    return pos;
+}
+
+// Stupid function extractor based on indent. Doesn't support block
+// comments. If someone puts a ' or an " in a block comment this
+// will blow up. Template strings are not tested and might also be
+// broken.
+function extractFunction(content, functionName) {
+    var indent = 0;
+    var splitter = "function " + functionName + "(";
+
+    while (true) {
+        var start = content.indexOf(splitter);
+        if (start === -1) {
+            break;
+        }
+        var pos = start;
+        while (pos < content.length && content[pos] !== ')') {
+            pos += 1;
+        }
+        if (pos >= content.length) {
+            break;
+        }
+        pos = getNextStep(content, pos + 1, '{');
+        if (pos === null) {
+            break;
+        } else if (pos < 0) {
+            content = content.slice(-pos);
+            continue;
+        }
+        while (pos < content.length) {
+            // Eat single-line comments
+            if (content[pos] === '/' && pos > 0 && content[pos-1] === '/') {
+                do {
+                    pos += 1;
+                } while (pos < content.length && content[pos] !== '\n');
+
+            // Eat quoted strings
+            } else if (content[pos] === '"' || content[pos] === "'" || content[pos] === "`") {
+                var stop = content[pos];
+                var is_escaped = false;
+                do {
+                    if (content[pos] === '\\') {
+                        pos += 2;
+                    } else {
+                        pos += 1;
+                    }
+                } while (pos < content.length &&
+                         (content[pos] !== stop || content[pos - 1] === '\\'));
+
+            // Otherwise, check for indent
+            } else if (content[pos] === '{') {
+                indent += 1;
+            } else if (content[pos] === '}') {
+                indent -= 1;
+                if (indent === 0) {
+                    return content.slice(start, pos + 1);
+                }
+            }
+            pos += 1;
+        }
+        content = content.slice(start + 1);
+    }
+    return null;
+}
+
+// Stupid function extractor for array.
+function extractArrayVariable(content, arrayName) {
+    var splitter = "var " + arrayName;
+    while (true) {
+        var start = content.indexOf(splitter);
+        if (start === -1) {
+            break;
+        }
+        var pos = getNextStep(content, start, '=');
+        if (pos === null) {
+            break;
+        } else if (pos < 0) {
+            content = content.slice(-pos);
+            continue;
+        }
+        pos = getNextStep(content, pos, '[');
+        if (pos === null) {
+            break;
+        } else if (pos < 0) {
+            content = content.slice(-pos);
+            continue;
+        }
+        while (pos < content.length) {
+            if (content[pos] === '"' || content[pos] === "'") {
+                var stop = content[pos];
+                do {
+                    if (content[pos] === '\\') {
+                        pos += 2;
+                    } else {
+                        pos += 1;
+                    }
+                } while (pos < content.length &&
+                         (content[pos] !== stop || content[pos - 1] === '\\'));
+            } else if (content[pos] === ']' &&
+                       pos + 1 < content.length &&
+                       content[pos + 1] === ';') {
+                return content.slice(start, pos + 2);
+            }
+            pos += 1;
+        }
+        content = content.slice(start + 1);
+    }
+    return null;
+}
+
+// Stupid function extractor for variable.
+function extractVariable(content, varName) {
+    var splitter = "var " + varName;
+    while (true) {
+        var start = content.indexOf(splitter);
+        if (start === -1) {
+            break;
+        }
+        var pos = getNextStep(content, start, '=');
+        if (pos === null) {
+            break;
+        } else if (pos < 0) {
+            content = content.slice(-pos);
+            continue;
+        }
+        while (pos < content.length) {
+            if (content[pos] === '"' || content[pos] === "'") {
+                var stop = content[pos];
+                do {
+                    if (content[pos] === '\\') {
+                        pos += 2;
+                    } else {
+                        pos += 1;
+                    }
+                } while (pos < content.length &&
+                         (content[pos] !== stop || content[pos - 1] === '\\'));
+            } else if (content[pos] === ';' || content[pos] === ',') {
+                return content.slice(start, pos + 1);
+            }
+            pos += 1;
+        }
+        content = content.slice(start + 1);
+    }
+    return null;
+}
+
+function loadContent(content) {
+    var Module = module.constructor;
+    var m = new Module();
+    m._compile(content, "tmp.js");
+    m.exports.ignore_order = content.indexOf("\n// ignore-order\n") !== -1 ||
+        content.startsWith("// ignore-order\n");
+    m.exports.exact_check = content.indexOf("\n// exact-check\n") !== -1 ||
+        content.startsWith("// exact-check\n");
+    m.exports.should_fail = content.indexOf("\n// should-fail\n") !== -1 ||
+        content.startsWith("// should-fail\n");
+    return m.exports;
+}
+
+function readFile(filePath) {
+    return fs.readFileSync(filePath, 'utf8');
+}
+
+function loadThings(thingsToLoad, kindOfLoad, funcToCall, fileContent) {
+    var content = '';
+    for (var i = 0; i < thingsToLoad.length; ++i) {
+        var tmp = funcToCall(fileContent, thingsToLoad[i]);
+        if (tmp === null) {
+            console.error('unable to find ' + kindOfLoad + ' "' + thingsToLoad[i] + '"');
+            process.exit(1);
+        }
+        content += tmp;
+        content += 'exports.' + thingsToLoad[i] + ' = ' + thingsToLoad[i] + ';';
+    }
+    return content;
+}
+
+function lookForEntry(entry, data) {
+    for (var i = 0; i < data.length; ++i) {
+        var allGood = true;
+        for (var key in entry) {
+            if (!entry.hasOwnProperty(key)) {
+                continue;
+            }
+            var value = data[i][key];
+            // To make our life easier, if there is a "parent" type, we add it to the path.
+            if (key === 'path' && data[i]['parent'] !== undefined) {
+                if (value.length > 0) {
+                    value += '::' + data[i]['parent']['name'];
+                } else {
+                    value = data[i]['parent']['name'];
+                }
+            }
+            if (value !== entry[key]) {
+                allGood = false;
+                break;
+            }
+        }
+        if (allGood === true) {
+            return i;
+        }
+    }
+    return null;
+}
+
+function loadMainJsAndIndex(mainJs, aliases, searchIndex, crate) {
+    if (searchIndex[searchIndex.length - 1].length === 0) {
+        searchIndex.pop();
+    }
+    searchIndex.pop();
+    searchIndex = loadContent(searchIndex.join("\n") + '\nexports.searchIndex = searchIndex;');
+    finalJS = "";
+
+    var arraysToLoad = ["itemTypes"];
+    var variablesToLoad = ["MAX_LEV_DISTANCE", "MAX_RESULTS", "NO_TYPE_FILTER",
+                           "GENERICS_DATA", "NAME", "INPUTS_DATA", "OUTPUT_DATA",
+                           "TY_PRIMITIVE", "TY_KEYWORD",
+                           "levenshtein_row2"];
+    // execQuery first parameter is built in getQuery (which takes in the search input).
+    // execQuery last parameter is built in buildIndex.
+    // buildIndex requires the hashmap from search-index.
+    var functionsToLoad = ["buildHrefAndPath", "pathSplitter", "levenshtein", "validateResult",
+                           "getQuery", "buildIndex", "execQuery", "execSearch"];
+
+    finalJS += 'window = { "currentCrate": "' + crate + '" };\n';
+    finalJS += 'var rootPath = "../";\n';
+    finalJS += aliases;
+    finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs);
+    finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs);
+    finalJS += loadThings(functionsToLoad, 'function', extractFunction, mainJs);
+
+    var loaded = loadContent(finalJS);
+    var index = loaded.buildIndex(searchIndex.searchIndex);
+
+    return [loaded, index];
+}
+
+function runChecks(testFile, loaded, index) {
+    var errors = 0;
+    var loadedFile = loadContent(
+        readFile(testFile) + 'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;');
+
+    const expected = loadedFile.EXPECTED;
+    const query = loadedFile.QUERY;
+    const filter_crate = loadedFile.FILTER_CRATE;
+    const ignore_order = loadedFile.ignore_order;
+    const exact_check = loadedFile.exact_check;
+    const should_fail = loadedFile.should_fail;
+
+    var results = loaded.execSearch(loaded.getQuery(query), index);
+    var error_text = [];
+
+    for (var key in expected) {
+        if (!expected.hasOwnProperty(key)) {
+            continue;
+        }
+        if (!results.hasOwnProperty(key)) {
+            error_text.push('==> Unknown key "' + key + '"');
+            break;
+        }
+        var entry = expected[key];
+        var prev_pos = -1;
+        for (var i = 0; i < entry.length; ++i) {
+            var entry_pos = lookForEntry(entry[i], results[key]);
+            if (entry_pos === null) {
+                error_text.push("==> Result not found in '" + key + "': '" +
+                                JSON.stringify(entry[i]) + "'");
+            } else if (exact_check === true && prev_pos + 1 !== entry_pos) {
+                error_text.push("==> Exact check failed at position " + (prev_pos + 1) + ": " +
+                                "expected '" + JSON.stringify(entry[i]) + "' but found '" +
+                                JSON.stringify(results[key][i]) + "'");
+            } else if (ignore_order === false && entry_pos < prev_pos) {
+                error_text.push("==> '" + JSON.stringify(entry[i]) + "' was supposed to be " +
+                                " before '" + JSON.stringify(results[key][entry_pos]) + "'");
+            } else {
+                prev_pos = entry_pos;
+            }
+        }
+    }
+    if (error_text.length === 0 && should_fail === true) {
+        errors += 1;
+        console.error("FAILED");
+        console.error("==> Test was supposed to fail but all items were found...");
+    } else if (error_text.length !== 0 && should_fail === false) {
+        errors += 1;
+        console.error("FAILED");
+        console.error(error_text.join("\n"));
+    } else {
+        console.log("OK");
+    }
+    return errors;
+}
+
+module.exports = {
+    'getNextStep': getNextStep,
+    'extractFunction': extractFunction,
+    'extractArrayVariable': extractArrayVariable,
+    'extractVariable': extractVariable,
+    'loadContent': loadContent,
+    'readFile': readFile,
+    'loadThings': loadThings,
+    'lookForEntry': lookForEntry,
+    'loadMainJsAndIndex': loadMainJsAndIndex,
+    'runChecks': runChecks,
+};
diff --git a/src/tools/rustdoc-js-std/tester.js b/src/tools/rustdoc-js-std/tester.js
index 08930ff..6f730b0 100644
--- a/src/tools/rustdoc-js-std/tester.js
+++ b/src/tools/rustdoc-js-std/tester.js
@@ -1,225 +1,11 @@
 const fs = require('fs');
 const path = require('path');
+const tools = require('../rustdoc-js-common/lib.js');
 
-function getNextStep(content, pos, stop) {
-    while (pos < content.length && content[pos] !== stop &&
-           (content[pos] === ' ' || content[pos] === '\t' || content[pos] === '\n')) {
-        pos += 1;
-    }
-    if (pos >= content.length) {
-        return null;
-    }
-    if (content[pos] !== stop) {
-        return pos * -1;
-    }
-    return pos;
-}
-
-// Stupid function extractor based on indent. Doesn't support block
-// comments. If someone puts a ' or an " in a block comment this
-// will blow up. Template strings are not tested and might also be
-// broken.
-function extractFunction(content, functionName) {
-    var indent = 0;
-    var splitter = "function " + functionName + "(";
-
-    while (true) {
-        var start = content.indexOf(splitter);
-        if (start === -1) {
-            break;
-        }
-        var pos = start;
-        while (pos < content.length && content[pos] !== ')') {
-            pos += 1;
-        }
-        if (pos >= content.length) {
-            break;
-        }
-        pos = getNextStep(content, pos + 1, '{');
-        if (pos === null) {
-            break;
-        } else if (pos < 0) {
-            content = content.slice(-pos);
-            continue;
-        }
-        while (pos < content.length) {
-            // Eat single-line comments
-            if (content[pos] === '/' && pos > 0 && content[pos-1] === '/') {
-                do {
-                    pos += 1;
-                } while (pos < content.length && content[pos] !== '\n');
-
-            // Eat quoted strings
-            } else if (content[pos] === '"' || content[pos] === "'" || content[pos] === "`") {
-                var stop = content[pos];
-                var is_escaped = false;
-                do {
-                    if (content[pos] === '\\') {
-                        pos += 2;
-                    } else {
-                        pos += 1;
-                    }
-                } while (pos < content.length &&
-                         (content[pos] !== stop || content[pos - 1] === '\\'));
-
-            // Otherwise, check for indent
-            } else if (content[pos] === '{') {
-                indent += 1;
-            } else if (content[pos] === '}') {
-                indent -= 1;
-                if (indent === 0) {
-                    return content.slice(start, pos + 1);
-                }
-            }
-            pos += 1;
-        }
-        content = content.slice(start + 1);
-    }
-    return null;
-}
-
-// Stupid function extractor for array.
-function extractArrayVariable(content, arrayName) {
-    var splitter = "var " + arrayName;
-    while (true) {
-        var start = content.indexOf(splitter);
-        if (start === -1) {
-            break;
-        }
-        var pos = getNextStep(content, start, '=');
-        if (pos === null) {
-            break;
-        } else if (pos < 0) {
-            content = content.slice(-pos);
-            continue;
-        }
-        pos = getNextStep(content, pos, '[');
-        if (pos === null) {
-            break;
-        } else if (pos < 0) {
-            content = content.slice(-pos);
-            continue;
-        }
-        while (pos < content.length) {
-            if (content[pos] === '"' || content[pos] === "'") {
-                var stop = content[pos];
-                do {
-                    if (content[pos] === '\\') {
-                        pos += 2;
-                    } else {
-                        pos += 1;
-                    }
-                } while (pos < content.length &&
-                         (content[pos] !== stop || content[pos - 1] === '\\'));
-            } else if (content[pos] === ']' &&
-                       pos + 1 < content.length &&
-                       content[pos + 1] === ';') {
-                return content.slice(start, pos + 2);
-            }
-            pos += 1;
-        }
-        content = content.slice(start + 1);
-    }
-    return null;
-}
-
-// Stupid function extractor for variable.
-function extractVariable(content, varName) {
-    var splitter = "var " + varName;
-    while (true) {
-        var start = content.indexOf(splitter);
-        if (start === -1) {
-            break;
-        }
-        var pos = getNextStep(content, start, '=');
-        if (pos === null) {
-            break;
-        } else if (pos < 0) {
-            content = content.slice(-pos);
-            continue;
-        }
-        while (pos < content.length) {
-            if (content[pos] === '"' || content[pos] === "'") {
-                var stop = content[pos];
-                do {
-                    if (content[pos] === '\\') {
-                        pos += 2;
-                    } else {
-                        pos += 1;
-                    }
-                } while (pos < content.length &&
-                         (content[pos] !== stop || content[pos - 1] === '\\'));
-            } else if (content[pos] === ';') {
-                return content.slice(start, pos + 1);
-            }
-            pos += 1;
-        }
-        content = content.slice(start + 1);
-    }
-    return null;
-}
-
-function loadContent(content) {
-    var Module = module.constructor;
-    var m = new Module();
-    m._compile(content, "tmp.js");
-    m.exports.ignore_order = content.indexOf("\n// ignore-order\n") !== -1 ||
-        content.startsWith("// ignore-order\n");
-    m.exports.exact_check = content.indexOf("\n// exact-check\n") !== -1 ||
-        content.startsWith("// exact-check\n");
-    m.exports.should_fail = content.indexOf("\n// should-fail\n") !== -1 ||
-        content.startsWith("// should-fail\n");
-    return m.exports;
-}
-
-function readFile(filePath) {
-    return fs.readFileSync(filePath, 'utf8');
-}
-
-function loadThings(thingsToLoad, kindOfLoad, funcToCall, fileContent) {
-    var content = '';
-    for (var i = 0; i < thingsToLoad.length; ++i) {
-        var tmp = funcToCall(fileContent, thingsToLoad[i]);
-        if (tmp === null) {
-            console.error('unable to find ' + kindOfLoad + ' "' + thingsToLoad[i] + '"');
-            process.exit(1);
-        }
-        content += tmp;
-        content += 'exports.' + thingsToLoad[i] + ' = ' + thingsToLoad[i] + ';';
-    }
-    return content;
-}
-
-function lookForEntry(entry, data) {
-    for (var i = 0; i < data.length; ++i) {
-        var allGood = true;
-        for (var key in entry) {
-            if (!entry.hasOwnProperty(key)) {
-                continue;
-            }
-            var value = data[i][key];
-            // To make our life easier, if there is a "parent" type, we add it to the path.
-            if (key === 'path' && data[i]['parent'] !== undefined) {
-                if (value.length > 0) {
-                    value += '::' + data[i]['parent']['name'];
-                } else {
-                    value = data[i]['parent']['name'];
-                }
-            }
-            if (value !== entry[key]) {
-                allGood = false;
-                break;
-            }
-        }
-        if (allGood === true) {
-            return i;
-        }
-    }
-    return null;
-}
 
 function findFile(dir, name, extension) {
     var entries = fs.readdirSync(dir);
+    var matches = [];
     for (var i = 0; i < entries.length; ++i) {
         var entry = entries[i];
         var file_type = fs.statSync(dir + entry);
@@ -227,10 +13,28 @@
             continue;
         }
         if (entry.startsWith(name) && entry.endsWith(extension)) {
-            return entry;
+            var version = entry.slice(name.length, entry.length - extension.length);
+            version = version.split(".").map(function(x) {
+                return parseInt(x);
+            });
+            var total = 0;
+            var mult = 1;
+            for (var j = version.length - 1; j >= 0; --j) {
+                total += version[j] * mult;
+                mult *= 1000;
+            }
+            matches.push([entry, total]);
         }
     }
-    return null;
+    if (matches.length === 0) {
+        return null;
+    }
+    // We make a reverse sort to have the "highest" file. Very useful in case you didn't clean up
+    // you std doc folder...
+    matches.sort(function(a, b) {
+        return b[1] - a[1];
+    });
+    return matches[0][0];
 }
 
 function readFileMatching(dir, name, extension) {
@@ -241,7 +45,7 @@
     if (f === null) {
         return "";
     }
-    return readFile(dir + f);
+    return tools.readFile(dir + f);
 }
 
 function main(argv) {
@@ -253,88 +57,16 @@
     var test_folder = argv[3];
 
     var mainJs = readFileMatching(std_docs, "main", ".js");
-    var ALIASES = readFileMatching(std_docs, "aliases", ".js");
+    var aliases = readFileMatching(std_docs, "aliases", ".js");
     var searchIndex = readFileMatching(std_docs, "search-index", ".js").split("\n");
-    if (searchIndex[searchIndex.length - 1].length === 0) {
-        searchIndex.pop();
-    }
-    searchIndex.pop();
-    searchIndex = loadContent(searchIndex.join("\n") + '\nexports.searchIndex = searchIndex;');
-    finalJS = "";
 
-    var arraysToLoad = ["itemTypes"];
-    var variablesToLoad = ["MAX_LEV_DISTANCE", "MAX_RESULTS", "NO_TYPE_FILTER",
-                           "GENERICS_DATA", "NAME", "INPUTS_DATA", "OUTPUT_DATA",
-                           "TY_PRIMITIVE", "TY_KEYWORD",
-                           "levenshtein_row2"];
-    // execQuery first parameter is built in getQuery (which takes in the search input).
-    // execQuery last parameter is built in buildIndex.
-    // buildIndex requires the hashmap from search-index.
-    var functionsToLoad = ["buildHrefAndPath", "pathSplitter", "levenshtein", "validateResult",
-                           "getQuery", "buildIndex", "execQuery", "execSearch"];
-
-    finalJS += 'window = { "currentCrate": "std" };\n';
-    finalJS += 'var rootPath = "../";\n';
-    finalJS += ALIASES;
-    finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs);
-    finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs);
-    finalJS += loadThings(functionsToLoad, 'function', extractFunction, mainJs);
-
-    var loaded = loadContent(finalJS);
-    var index = loaded.buildIndex(searchIndex.searchIndex);
+    var [loaded, index] = tools.loadMainJsAndIndex(mainJs, aliases, searchIndex, "std");
 
     var errors = 0;
 
     fs.readdirSync(test_folder).forEach(function(file) {
-        var loadedFile = loadContent(readFile(path.join(test_folder, file)) +
-                               'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;');
-        const expected = loadedFile.EXPECTED;
-        const query = loadedFile.QUERY;
-        const filter_crate = loadedFile.FILTER_CRATE;
-        const ignore_order = loadedFile.ignore_order;
-        const exact_check = loadedFile.exact_check;
-        const should_fail = loadedFile.should_fail;
-        var results = loaded.execSearch(loaded.getQuery(query), index);
         process.stdout.write('Checking "' + file + '" ... ');
-        var error_text = [];
-        for (var key in expected) {
-            if (!expected.hasOwnProperty(key)) {
-                continue;
-            }
-            if (!results.hasOwnProperty(key)) {
-                error_text.push('==> Unknown key "' + key + '"');
-                break;
-            }
-            var entry = expected[key];
-            var prev_pos = -1;
-            for (var i = 0; i < entry.length; ++i) {
-                var entry_pos = lookForEntry(entry[i], results[key]);
-                if (entry_pos === null) {
-                    error_text.push("==> Result not found in '" + key + "': '" +
-                                    JSON.stringify(entry[i]) + "'");
-                } else if (exact_check === true && prev_pos + 1 !== entry_pos) {
-                    error_text.push("==> Exact check failed at position " + (prev_pos + 1) + ": " +
-                                    "expected '" + JSON.stringify(entry[i]) + "' but found '" +
-                                    JSON.stringify(results[key][i]) + "'");
-                } else if (ignore_order === false && entry_pos < prev_pos) {
-                    error_text.push("==> '" + JSON.stringify(entry[i]) + "' was supposed to be " +
-                                    " before '" + JSON.stringify(results[key][entry_pos]) + "'");
-                } else {
-                    prev_pos = entry_pos;
-                }
-            }
-        }
-        if (error_text.length === 0 && should_fail === true) {
-            errors += 1;
-            console.error("FAILED");
-            console.error("==> Test was supposed to fail but all items were found...");
-        } else if (error_text.length !== 0 && should_fail === false) {
-            errors += 1;
-            console.error("FAILED");
-            console.error(error_text.join("\n"));
-        } else {
-            console.log("OK");
-        }
+        errors += tools.runChecks(path.join(test_folder, file), loaded, index);
     });
     return errors > 0 ? 1 : 0;
 }
diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js
index 143e1a7..2e8901d 100644
--- a/src/tools/rustdoc-js/tester.js
+++ b/src/tools/rustdoc-js/tester.js
@@ -1,255 +1,13 @@
 const fs = require('fs');
 const path = require('path');
-const { spawnSync } = require('child_process');
-
-function getNextStep(content, pos, stop) {
-    while (pos < content.length && content[pos] !== stop &&
-           (content[pos] === ' ' || content[pos] === '\t' || content[pos] === '\n')) {
-        pos += 1;
-    }
-    if (pos >= content.length) {
-        return null;
-    }
-    if (content[pos] !== stop) {
-        return pos * -1;
-    }
-    return pos;
-}
-
-// Stupid function extractor based on indent. Doesn't support block
-// comments. If someone puts a ' or an " in a block comment this
-// will blow up. Template strings are not tested and might also be
-// broken.
-function extractFunction(content, functionName) {
-    var indent = 0;
-    var splitter = "function " + functionName + "(";
-
-    while (true) {
-        var start = content.indexOf(splitter);
-        if (start === -1) {
-            break;
-        }
-        var pos = start;
-        while (pos < content.length && content[pos] !== ')') {
-            pos += 1;
-        }
-        if (pos >= content.length) {
-            break;
-        }
-        pos = getNextStep(content, pos + 1, '{');
-        if (pos === null) {
-            break;
-        } else if (pos < 0) {
-            content = content.slice(-pos);
-            continue;
-        }
-        while (pos < content.length) {
-            // Eat single-line comments
-            if (content[pos] === '/' && pos > 0 && content[pos-1] === '/') {
-                do {
-                    pos += 1;
-                } while (pos < content.length && content[pos] !== '\n');
-
-            // Eat quoted strings
-            } else if (content[pos] === '"' || content[pos] === "'" || content[pos] === "`") {
-                var stop = content[pos];
-                var is_escaped = false;
-                do {
-                    if (content[pos] === '\\') {
-                        pos += 2;
-                    } else {
-                        pos += 1;
-                    }
-                } while (pos < content.length &&
-                         (content[pos] !== stop || content[pos - 1] === '\\'));
-
-            // Otherwise, check for indent
-            } else if (content[pos] === '{') {
-                indent += 1;
-            } else if (content[pos] === '}') {
-                indent -= 1;
-                if (indent === 0) {
-                    return content.slice(start, pos + 1);
-                }
-            }
-            pos += 1;
-        }
-        content = content.slice(start + 1);
-    }
-    return null;
-}
-
-// Stupid function extractor for array.
-function extractArrayVariable(content, arrayName) {
-    var splitter = "var " + arrayName;
-    while (true) {
-        var start = content.indexOf(splitter);
-        if (start === -1) {
-            break;
-        }
-        var pos = getNextStep(content, start, '=');
-        if (pos === null) {
-            break;
-        } else if (pos < 0) {
-            content = content.slice(-pos);
-            continue;
-        }
-        pos = getNextStep(content, pos, '[');
-        if (pos === null) {
-            break;
-        } else if (pos < 0) {
-            content = content.slice(-pos);
-            continue;
-        }
-        while (pos < content.length) {
-            if (content[pos] === '"' || content[pos] === "'") {
-                var stop = content[pos];
-                do {
-                    if (content[pos] === '\\') {
-                        pos += 2;
-                    } else {
-                        pos += 1;
-                    }
-                } while (pos < content.length &&
-                         (content[pos] !== stop || content[pos - 1] === '\\'));
-            } else if (content[pos] === ']' &&
-                       pos + 1 < content.length &&
-                       content[pos + 1] === ';') {
-                return content.slice(start, pos + 2);
-            }
-            pos += 1;
-        }
-        content = content.slice(start + 1);
-    }
-    return null;
-}
-
-// Stupid function extractor for variable.
-function extractVariable(content, varName) {
-    var splitter = "var " + varName;
-    while (true) {
-        var start = content.indexOf(splitter);
-        if (start === -1) {
-            break;
-        }
-        var pos = getNextStep(content, start, '=');
-        if (pos === null) {
-            break;
-        } else if (pos < 0) {
-            content = content.slice(-pos);
-            continue;
-        }
-        while (pos < content.length) {
-            if (content[pos] === '"' || content[pos] === "'") {
-                var stop = content[pos];
-                do {
-                    if (content[pos] === '\\') {
-                        pos += 2;
-                    } else {
-                        pos += 1;
-                    }
-                } while (pos < content.length &&
-                         (content[pos] !== stop || content[pos - 1] === '\\'));
-            } else if (content[pos] === ';') {
-                return content.slice(start, pos + 1);
-            }
-            pos += 1;
-        }
-        content = content.slice(start + 1);
-    }
-    return null;
-}
-
-function loadContent(content) {
-    var Module = module.constructor;
-    var m = new Module();
-    m._compile(content, "tmp.js");
-    m.exports.ignore_order = content.indexOf("\n// ignore-order\n") !== -1 ||
-        content.startsWith("// ignore-order\n");
-    m.exports.exact_check = content.indexOf("\n// exact-check\n") !== -1 ||
-        content.startsWith("// exact-check\n");
-    m.exports.should_fail = content.indexOf("\n// should-fail\n") !== -1 ||
-        content.startsWith("// should-fail\n");
-    return m.exports;
-}
-
-function readFile(filePath) {
-    return fs.readFileSync(filePath, 'utf8');
-}
-
-function loadThings(thingsToLoad, kindOfLoad, funcToCall, fileContent) {
-    var content = '';
-    for (var i = 0; i < thingsToLoad.length; ++i) {
-        var tmp = funcToCall(fileContent, thingsToLoad[i]);
-        if (tmp === null) {
-            console.error('unable to find ' + kindOfLoad + ' "' + thingsToLoad[i] + '"');
-            process.exit(1);
-        }
-        content += tmp;
-        content += 'exports.' + thingsToLoad[i] + ' = ' + thingsToLoad[i] + ';';
-    }
-    return content;
-}
-
-function lookForEntry(entry, data) {
-    for (var i = 0; i < data.length; ++i) {
-        var allGood = true;
-        for (var key in entry) {
-            if (!entry.hasOwnProperty(key)) {
-                continue;
-            }
-            var value = data[i][key];
-            // To make our life easier, if there is a "parent" type, we add it to the path.
-            if (key === 'path' && data[i]['parent'] !== undefined) {
-                if (value.length > 0) {
-                    value += '::' + data[i]['parent']['name'];
-                } else {
-                    value = data[i]['parent']['name'];
-                }
-            }
-            if (value !== entry[key]) {
-                allGood = false;
-                break;
-            }
-        }
-        if (allGood === true) {
-            return i;
-        }
-    }
-    return null;
-}
+const tools = require('../rustdoc-js-common/lib.js');
 
 function load_files(out_folder, crate) {
-    var mainJs = readFile(out_folder + "/main.js");
-    var ALIASES = readFile(out_folder + "/aliases.js");
-    var searchIndex = readFile(out_folder + "/search-index.js").split("\n");
-    if (searchIndex[searchIndex.length - 1].length === 0) {
-        searchIndex.pop();
-    }
-    searchIndex.pop();
-    searchIndex = loadContent(searchIndex.join("\n") + '\nexports.searchIndex = searchIndex;');
-    finalJS = "";
+    var mainJs = tools.readFile(out_folder + "/main.js");
+    var aliases = tools.readFile(out_folder + "/aliases.js");
+    var searchIndex = tools.readFile(out_folder + "/search-index.js").split("\n");
 
-    var arraysToLoad = ["itemTypes"];
-    var variablesToLoad = ["MAX_LEV_DISTANCE", "MAX_RESULTS", "NO_TYPE_FILTER",
-                           "GENERICS_DATA", "NAME", "INPUTS_DATA", "OUTPUT_DATA",
-                           "TY_PRIMITIVE", "TY_KEYWORD",
-                           "levenshtein_row2"];
-    // execQuery first parameter is built in getQuery (which takes in the search input).
-    // execQuery last parameter is built in buildIndex.
-    // buildIndex requires the hashmap from search-index.
-    var functionsToLoad = ["buildHrefAndPath", "pathSplitter", "levenshtein", "validateResult",
-                           "getQuery", "buildIndex", "execQuery", "execSearch"];
-
-    finalJS += 'window = { "currentCrate": "' + crate + '" };\n';
-    finalJS += 'var rootPath = "../";\n';
-    finalJS += ALIASES;
-    finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs);
-    finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs);
-    finalJS += loadThings(functionsToLoad, 'function', extractFunction, mainJs);
-
-    var loaded = loadContent(finalJS);
-    return [loaded, loaded.buildIndex(searchIndex.searchIndex)];
+    return tools.loadMainJsAndIndex(mainJs, aliases, searchIndex, crate);
 }
 
 function main(argv) {
@@ -279,54 +37,7 @@
         const test_out_folder = out_folder + test_name;
 
         var [loaded, index] = load_files(test_out_folder, test_name);
-        var loadedFile = loadContent(readFile(test_file) +
-                               'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;');
-        const expected = loadedFile.EXPECTED;
-        const query = loadedFile.QUERY;
-        const filter_crate = loadedFile.FILTER_CRATE;
-        const ignore_order = loadedFile.ignore_order;
-        const exact_check = loadedFile.exact_check;
-        const should_fail = loadedFile.should_fail;
-        var results = loaded.execSearch(loaded.getQuery(query), index);
-        var error_text = [];
-        for (var key in expected) {
-            if (!expected.hasOwnProperty(key)) {
-                continue;
-            }
-            if (!results.hasOwnProperty(key)) {
-                error_text.push('==> Unknown key "' + key + '"');
-                break;
-            }
-            var entry = expected[key];
-            var prev_pos = -1;
-            for (var i = 0; i < entry.length; ++i) {
-                var entry_pos = lookForEntry(entry[i], results[key]);
-                if (entry_pos === null) {
-                    error_text.push("==> Result not found in '" + key + "': '" +
-                                    JSON.stringify(entry[i]) + "'");
-                } else if (exact_check === true && prev_pos + 1 !== entry_pos) {
-                    error_text.push("==> Exact check failed at position " + (prev_pos + 1) + ": " +
-                                    "expected '" + JSON.stringify(entry[i]) + "' but found '" +
-                                    JSON.stringify(results[key][i]) + "'");
-                } else if (ignore_order === false && entry_pos < prev_pos) {
-                    error_text.push("==> '" + JSON.stringify(entry[i]) + "' was supposed to be " +
-                                    " before '" + JSON.stringify(results[key][entry_pos]) + "'");
-                } else {
-                    prev_pos = entry_pos;
-                }
-            }
-        }
-        if (error_text.length === 0 && should_fail === true) {
-            errors += 1;
-            console.error("FAILED");
-            console.error("==> Test was supposed to fail but all items were found...");
-        } else if (error_text.length !== 0 && should_fail === false) {
-            errors += 1;
-            console.error("FAILED");
-            console.error(error_text.join("\n"));
-        } else {
-            console.log("OK");
-        }
+        errors += tools.runChecks(test_file, loaded, index);
     }
     return errors > 0 ? 1 : 0;
 }
diff --git a/src/tools/rustfmt b/src/tools/rustfmt
index 9f53665..c126730 160000
--- a/src/tools/rustfmt
+++ b/src/tools/rustfmt
@@ -1 +1 @@
-Subproject commit 9f53665f91be16c9aa7afd83f7c79357fec9152b
+Subproject commit c1267303bc06408b4ce406175e8f9cddbbe11b92
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index a221184..8d38404 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -26,7 +26,6 @@
 const EXCEPTIONS: &[(&str, &str)] = &[
     ("mdbook", "MPL-2.0"),                  // mdbook
     ("openssl", "Apache-2.0"),              // cargo, mdbook
-    ("arrayref", "BSD-2-Clause"),           // mdbook via handlebars via pest
     ("toml-query", "MPL-2.0"),              // mdbook
     ("toml-query_derive", "MPL-2.0"),       // mdbook
     ("is-match", "MPL-2.0"),                // mdbook
@@ -74,6 +73,9 @@
     "backtrace",
     "backtrace-sys",
     "bitflags",
+    "block-buffer",
+    "block-padding",
+    "byte-tools",
     "byteorder",
     "c2-chacha",
     "cc",
@@ -87,15 +89,18 @@
     "crossbeam-queue",
     "crossbeam-utils",
     "datafrog",
+    "digest",
     "dlmalloc",
     "either",
     "ena",
     "env_logger",
+    "fake-simd",
     "filetime",
     "flate2",
     "fortanix-sgx-abi",
     "fuchsia-zircon",
     "fuchsia-zircon-sys",
+    "generic-array",
     "getopts",
     "getrandom",
     "hashbrown",
@@ -111,6 +116,7 @@
     "lock_api",
     "log",
     "log_settings",
+    "md-5",
     "measureme",
     "memchr",
     "memmap",
@@ -118,6 +124,7 @@
     "miniz_oxide",
     "nodrop",
     "num_cpus",
+    "opaque-debug",
     "parking_lot",
     "parking_lot_core",
     "pkg-config",
@@ -150,6 +157,7 @@
     "semver-parser",
     "serde",
     "serde_derive",
+    "sha-1",
     "smallvec",
     "stable_deref_trait",
     "syn",
@@ -159,6 +167,7 @@
     "termion",
     "termize",
     "thread_local",
+    "typenum",
     "ucd-util",
     "unicode-normalization",
     "unicode-script",
@@ -350,7 +359,7 @@
         // to accidentally sneak into our dependency graph, in order to ensure we keep our CI times
         // under control.
         "cargo",
-        "rustc-ap-syntax",
+        "rustc-ap-rustc_ast",
     ];
 
     for &name in FORBIDDEN_TO_HAVE_DUPLICATES {