about summary refs log tree commit diff
diff options
context:
space:
mode:
authorStefan Lankes <stlankes@users.noreply.github.com>2020-04-04 07:41:05 +0200
committerGitHub <noreply@github.com>2020-04-04 07:41:05 +0200
commitaa223304dc130c5ace18d48c53b192b14088862e (patch)
tree1971ea5717f0e2ef2dc9468b3a0e96c209d481fe
parent9f6b96e461003853bf36052cfaf79b12e1c35413 (diff)
parent9e55101bb681010c82c3c827305e2665fc8f2aa0 (diff)
downloadrust-aa223304dc130c5ace18d48c53b192b14088862e.tar.gz
rust-aa223304dc130c5ace18d48c53b192b14088862e.zip
Merge branch 'master' into abi
-rw-r--r--.github/ISSUE_TEMPLATE/ice.md2
-rw-r--r--.github/workflows/ci.yml6
-rw-r--r--Cargo.lock110
-rw-r--r--README.md2
-rw-r--r--src/bootstrap/builder.rs7
-rw-r--r--src/bootstrap/compile.rs32
-rw-r--r--src/bootstrap/config.rs2
-rw-r--r--src/bootstrap/flags.rs3
-rw-r--r--src/bootstrap/lib.rs14
-rw-r--r--src/bootstrap/test.rs11
-rw-r--r--src/ci/docker/README.md18
-rw-r--r--src/ci/docker/dist-arm-linux/Dockerfile10
-rw-r--r--src/ci/docker/dist-arm-linux/arm-linux-gnueabi.config819
-rw-r--r--src/ci/docker/dist-arm-linux/patches/glibc/ports-2.16.0/001-arm-libgcc_s_resume-used.patch48
-rw-r--r--src/ci/docker/dist-armhf-linux/Dockerfile10
-rw-r--r--src/ci/docker/dist-armhf-linux/arm-linux-gnueabihf.config821
-rw-r--r--src/ci/docker/dist-armhf-linux/patches/glibc/ports-2.16.0/001-arm-libgcc_s_resume-used.patch48
-rw-r--r--src/ci/docker/dist-armv7-linux/Dockerfile4
-rw-r--r--src/ci/docker/dist-various-1/Dockerfile9
-rwxr-xr-xsrc/ci/docker/dist-various-1/install-aarch64-none-elf.sh6
-rw-r--r--src/ci/docker/scripts/crosstool-ng-1.24.sh (renamed from src/ci/docker/dist-armv7-linux/crosstool-ng.sh)0
-rw-r--r--src/ci/github-actions/ci.yml1
m---------src/doc/book0
m---------src/doc/nomicon0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
-rw-r--r--src/doc/rustc/src/codegen-options/index.md5
-rw-r--r--src/doc/unstable-book/book.toml3
-rw-r--r--src/doc/unstable-book/src/compiler-flags/sanitizer.md236
-rw-r--r--src/doc/unstable-book/src/language-features/generators.md4
-rw-r--r--src/doc/unstable-book/src/library-features/llvm-asm.md2
-rwxr-xr-xsrc/etc/generate-deriving-span-tests.py3
-rw-r--r--src/liballoc/alloc.rs112
-rw-r--r--src/liballoc/alloc/tests.rs9
-rw-r--r--src/liballoc/benches/btree/set.rs32
-rw-r--r--src/liballoc/benches/lib.rs1
-rw-r--r--src/liballoc/boxed.rs41
-rw-r--r--src/liballoc/collections/btree/map.rs210
-rw-r--r--src/liballoc/collections/btree/node.rs9
-rw-r--r--src/liballoc/collections/btree/set.rs101
-rw-r--r--src/liballoc/collections/vec_deque.rs205
-rw-r--r--src/liballoc/collections/vec_deque/tests.rs83
-rw-r--r--src/liballoc/lib.rs1
-rw-r--r--src/liballoc/macros.rs6
-rw-r--r--src/liballoc/raw_vec.rs655
-rw-r--r--src/liballoc/raw_vec/tests.rs9
-rw-r--r--src/liballoc/rc.rs8
-rw-r--r--src/liballoc/slice.rs2
-rw-r--r--src/liballoc/str.rs2
-rw-r--r--src/liballoc/string.rs15
-rw-r--r--src/liballoc/sync.rs8
-rw-r--r--src/liballoc/task.rs6
-rw-r--r--src/liballoc/tests/btree/map.rs261
-rw-r--r--src/liballoc/tests/btree/set.rs81
-rw-r--r--src/liballoc/tests/heap.rs10
-rw-r--r--src/liballoc/tests/lib.rs1
-rw-r--r--src/liballoc/vec.rs3
-rw-r--r--src/libcore/alloc.rs1043
-rw-r--r--src/libcore/alloc/global.rs198
-rw-r--r--src/libcore/alloc/layout.rs346
-rw-r--r--src/libcore/alloc/mod.rs367
-rw-r--r--src/libcore/array/iter.rs18
-rw-r--r--src/libcore/clone.rs3
-rw-r--r--src/libcore/cmp.rs2
-rw-r--r--src/libcore/convert/mod.rs8
-rw-r--r--src/libcore/convert/num.rs15
-rw-r--r--src/libcore/fmt/mod.rs2
-rw-r--r--src/libcore/hint.rs2
-rw-r--r--src/libcore/intrinsics.rs20
-rw-r--r--src/libcore/iter/traits/iterator.rs8
-rw-r--r--src/libcore/macros/mod.rs16
-rw-r--r--src/libcore/marker.rs3
-rw-r--r--src/libcore/num/f32.rs14
-rw-r--r--src/libcore/num/f64.rs14
-rw-r--r--src/libcore/num/mod.rs6
-rw-r--r--src/libcore/ops/range.rs10
-rw-r--r--src/libcore/ptr/const_ptr.rs4
-rw-r--r--src/libcore/ptr/mut_ptr.rs4
-rw-r--r--src/libcore/raw.rs3
-rw-r--r--src/libcore/slice/mod.rs2
-rw-r--r--src/libcore/str/mod.rs41
-rw-r--r--src/libcore/str/pattern.rs85
-rw-r--r--src/libcore/time.rs4
-rw-r--r--src/librustc/arena.rs132
-rw-r--r--src/librustc_ast/entry.rs2
-rw-r--r--src/librustc_ast/expand/mod.rs2
-rw-r--r--src/librustc_ast/lib.rs2
-rw-r--r--src/librustc_ast_lowering/item.rs19
-rw-r--r--src/librustc_ast_lowering/lib.rs2
-rw-r--r--src/librustc_ast_passes/feature_gate.rs14
-rw-r--r--src/librustc_ast_pretty/pprust.rs31
-rw-r--r--src/librustc_attr/builtin.rs2
-rw-r--r--src/librustc_builtin_macros/format_foreign.rs12
-rw-r--r--src/librustc_codegen_llvm/Cargo.toml2
-rw-r--r--src/librustc_codegen_llvm/README.md2
-rw-r--r--src/librustc_codegen_llvm/abi.rs25
-rw-r--r--src/librustc_codegen_llvm/allocator.rs4
-rw-r--r--src/librustc_codegen_llvm/attributes.rs64
-rw-r--r--src/librustc_codegen_llvm/back/lto.rs6
-rw-r--r--src/librustc_codegen_llvm/back/write.rs4
-rw-r--r--src/librustc_codegen_llvm/base.rs12
-rw-r--r--src/librustc_codegen_llvm/builder.rs29
-rw-r--r--src/librustc_codegen_llvm/callee.rs6
-rw-r--r--src/librustc_codegen_llvm/common.rs35
-rw-r--r--src/librustc_codegen_llvm/consts.rs46
-rw-r--r--src/librustc_codegen_llvm/context.rs21
-rw-r--r--src/librustc_codegen_llvm/debuginfo/create_scope_map.rs2
-rw-r--r--src/librustc_codegen_llvm/debuginfo/gdb.rs2
-rw-r--r--src/librustc_codegen_llvm/debuginfo/metadata.rs102
-rw-r--r--src/librustc_codegen_llvm/debuginfo/mod.rs32
-rw-r--r--src/librustc_codegen_llvm/debuginfo/namespace.rs2
-rw-r--r--src/librustc_codegen_llvm/debuginfo/utils.rs2
-rw-r--r--src/librustc_codegen_llvm/declare.rs2
-rw-r--r--src/librustc_codegen_llvm/intrinsic.rs27
-rw-r--r--src/librustc_codegen_llvm/lib.rs9
-rw-r--r--src/librustc_codegen_llvm/llvm_util.rs2
-rw-r--r--src/librustc_codegen_llvm/metadata.rs2
-rw-r--r--src/librustc_codegen_llvm/mono_item.rs12
-rw-r--r--src/librustc_codegen_llvm/type_.rs32
-rw-r--r--src/librustc_codegen_llvm/type_of.rs91
-rw-r--r--src/librustc_codegen_llvm/va_arg.rs5
-rw-r--r--src/librustc_codegen_ssa/Cargo.toml2
-rw-r--r--src/librustc_codegen_ssa/back/link.rs4
-rw-r--r--src/librustc_codegen_ssa/back/linker.rs4
-rw-r--r--src/librustc_codegen_ssa/back/rpath.rs2
-rw-r--r--src/librustc_codegen_ssa/back/symbol_export.rs18
-rw-r--r--src/librustc_codegen_ssa/back/write.rs8
-rw-r--r--src/librustc_codegen_ssa/base.rs31
-rw-r--r--src/librustc_codegen_ssa/common.rs11
-rw-r--r--src/librustc_codegen_ssa/debuginfo/type_names.rs2
-rw-r--r--src/librustc_codegen_ssa/glue.rs2
-rw-r--r--src/librustc_codegen_ssa/lib.rs14
-rw-r--r--src/librustc_codegen_ssa/meth.rs2
-rw-r--r--src/librustc_codegen_ssa/mir/analyze.rs17
-rw-r--r--src/librustc_codegen_ssa/mir/block.rs27
-rw-r--r--src/librustc_codegen_ssa/mir/constant.rs11
-rw-r--r--src/librustc_codegen_ssa/mir/debuginfo.rs7
-rw-r--r--src/librustc_codegen_ssa/mir/mod.rs10
-rw-r--r--src/librustc_codegen_ssa/mir/operand.rs27
-rw-r--r--src/librustc_codegen_ssa/mir/place.rs54
-rw-r--r--src/librustc_codegen_ssa/mir/rvalue.rs29
-rw-r--r--src/librustc_codegen_ssa/mir/statement.rs2
-rw-r--r--src/librustc_codegen_ssa/mono_item.rs6
-rw-r--r--src/librustc_codegen_ssa/traits/abi.rs2
-rw-r--r--src/librustc_codegen_ssa/traits/backend.rs17
-rw-r--r--src/librustc_codegen_ssa/traits/builder.rs5
-rw-r--r--src/librustc_codegen_ssa/traits/consts.rs17
-rw-r--r--src/librustc_codegen_ssa/traits/debuginfo.rs6
-rw-r--r--src/librustc_codegen_ssa/traits/declare.rs4
-rw-r--r--src/librustc_codegen_ssa/traits/intrinsic.rs2
-rw-r--r--src/librustc_codegen_ssa/traits/misc.rs4
-rw-r--r--src/librustc_codegen_ssa/traits/mod.rs2
-rw-r--r--src/librustc_codegen_ssa/traits/statics.rs2
-rw-r--r--src/librustc_codegen_ssa/traits/type_.rs21
-rw-r--r--src/librustc_codegen_ssa/traits/write.rs2
-rw-r--r--src/librustc_data_structures/lib.rs2
-rw-r--r--src/librustc_driver/Cargo.toml2
-rw-r--r--src/librustc_driver/lib.rs11
-rw-r--r--src/librustc_driver/pretty.rs36
-rw-r--r--src/librustc_error_codes/error_codes.rs2
-rw-r--r--src/librustc_error_codes/error_codes/E0226.md21
-rw-r--r--src/librustc_error_codes/error_codes/E0264.md2
-rw-r--r--src/librustc_error_codes/error_codes/E0466.md2
-rw-r--r--src/librustc_error_codes/error_codes/E0468.md4
-rw-r--r--src/librustc_error_codes/error_codes/E0502.md3
-rw-r--r--src/librustc_error_codes/error_codes/E0730.md4
-rw-r--r--src/librustc_errors/emitter.rs38
-rw-r--r--src/librustc_errors/lib.rs2
-rw-r--r--src/librustc_expand/mbe/macro_rules.rs25
-rw-r--r--src/librustc_feature/builtin_attrs.rs2
-rw-r--r--src/librustc_hir/intravisit.rs2
-rw-r--r--src/librustc_hir/stable_hash_impls.rs2
-rw-r--r--src/librustc_hir_pretty/lib.rs25
-rw-r--r--src/librustc_incremental/Cargo.toml2
-rw-r--r--src/librustc_incremental/assert_dep_graph.rs8
-rw-r--r--src/librustc_incremental/assert_module_sources.rs4
-rw-r--r--src/librustc_incremental/lib.rs2
-rw-r--r--src/librustc_incremental/persist/data.rs2
-rw-r--r--src/librustc_incremental/persist/dirty_clean.rs8
-rw-r--r--src/librustc_incremental/persist/load.rs6
-rw-r--r--src/librustc_incremental/persist/save.rs4
-rw-r--r--src/librustc_incremental/persist/work_product.rs2
-rw-r--r--src/librustc_infer/Cargo.toml2
-rw-r--r--src/librustc_infer/infer/at.rs4
-rw-r--r--src/librustc_infer/infer/canonical/canonicalizer.rs8
-rw-r--r--src/librustc_infer/infer/canonical/mod.rs8
-rw-r--r--src/librustc_infer/infer/canonical/query_response.rs10
-rw-r--r--src/librustc_infer/infer/canonical/substitute.rs6
-rw-r--r--src/librustc_infer/infer/combine.rs10
-rw-r--r--src/librustc_infer/infer/equate.rs8
-rw-r--r--src/librustc_infer/infer/error_reporting/mod.rs176
-rw-r--r--src/librustc_infer/infer/error_reporting/need_type_info.rs6
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs3
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/find_anon_type.rs6
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs5
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs2
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/outlives_closure.rs4
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/placeholder_error.rs8
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs5
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs39
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/util.rs2
-rw-r--r--src/librustc_infer/infer/error_reporting/note.rs6
-rw-r--r--src/librustc_infer/infer/freshen.rs4
-rw-r--r--src/librustc_infer/infer/fudge.rs4
-rw-r--r--src/librustc_infer/infer/glb.rs4
-rw-r--r--src/librustc_infer/infer/higher_ranked/mod.rs4
-rw-r--r--src/librustc_infer/infer/lattice.rs6
-rw-r--r--src/librustc_infer/infer/lexical_region_resolve/graphviz.rs8
-rw-r--r--src/librustc_infer/infer/lexical_region_resolve/mod.rs12
-rw-r--r--src/librustc_infer/infer/lub.rs4
-rw-r--r--src/librustc_infer/infer/mod.rs36
-rw-r--r--src/librustc_infer/infer/nll_relate/mod.rs10
-rw-r--r--src/librustc_infer/infer/outlives/env.rs4
-rw-r--r--src/librustc_infer/infer/outlives/mod.rs4
-rw-r--r--src/librustc_infer/infer/outlives/obligations.rs6
-rw-r--r--src/librustc_infer/infer/outlives/verify.rs4
-rw-r--r--src/librustc_infer/infer/region_constraints/leak_check.rs4
-rw-r--r--src/librustc_infer/infer/region_constraints/mod.rs10
-rw-r--r--src/librustc_infer/infer/resolve.rs4
-rw-r--r--src/librustc_infer/infer/sub.rs8
-rw-r--r--src/librustc_infer/infer/type_variable.rs2
-rw-r--r--src/librustc_infer/lib.rs2
-rw-r--r--src/librustc_infer/traits/engine.rs2
-rw-r--r--src/librustc_infer/traits/error_reporting/mod.rs2
-rw-r--r--src/librustc_infer/traits/mod.rs8
-rw-r--r--src/librustc_infer/traits/project.rs6
-rw-r--r--src/librustc_infer/traits/structural_impls.rs4
-rw-r--r--src/librustc_infer/traits/util.rs82
-rw-r--r--src/librustc_interface/Cargo.toml2
-rw-r--r--src/librustc_interface/callbacks.rs12
-rw-r--r--src/librustc_interface/interface.rs4
-rw-r--r--src/librustc_interface/passes.rs19
-rw-r--r--src/librustc_interface/proc_macro_decls.rs4
-rw-r--r--src/librustc_interface/queries.rs10
-rw-r--r--src/librustc_interface/tests.rs4
-rw-r--r--src/librustc_interface/util.rs2
-rw-r--r--src/librustc_lexer/src/lib.rs153
-rw-r--r--src/librustc_lexer/src/tests.rs148
-rw-r--r--src/librustc_lint/Cargo.toml2
-rw-r--r--src/librustc_lint/array_into_iter.rs4
-rw-r--r--src/librustc_lint/builtin.rs92
-rw-r--r--src/librustc_lint/context.rs20
-rw-r--r--src/librustc_lint/early.rs5
-rw-r--r--src/librustc_lint/internal.rs17
-rw-r--r--src/librustc_lint/late.rs4
-rw-r--r--src/librustc_lint/levels.rs10
-rw-r--r--src/librustc_lint/lib.rs10
-rw-r--r--src/librustc_lint/nonstandard_style.rs2
-rw-r--r--src/librustc_lint/passes.rs1
-rw-r--r--src/librustc_lint/types.rs17
-rw-r--r--src/librustc_lint/unused.rs505
-rw-r--r--src/librustc_macros/src/hash_stable.rs4
-rw-r--r--src/librustc_macros/src/lift.rs4
-rw-r--r--src/librustc_macros/src/query.rs10
-rw-r--r--src/librustc_macros/src/type_foldable.rs10
-rw-r--r--src/librustc_metadata/Cargo.toml2
-rw-r--r--src/librustc_metadata/build.rs1
-rw-r--r--src/librustc_metadata/creader.rs8
-rw-r--r--src/librustc_metadata/dependency_format.rs8
-rw-r--r--src/librustc_metadata/foreign_modules.rs4
-rw-r--r--src/librustc_metadata/lib.rs2
-rw-r--r--src/librustc_metadata/link_args.rs2
-rw-r--r--src/librustc_metadata/locator.rs2
-rw-r--r--src/librustc_metadata/native_libs.rs13
-rw-r--r--src/librustc_metadata/rmeta/decoder.rs135
-rw-r--r--src/librustc_metadata/rmeta/decoder/cstore_impl.rs14
-rw-r--r--src/librustc_metadata/rmeta/encoder.rs197
-rw-r--r--src/librustc_metadata/rmeta/mod.rs30
-rw-r--r--src/librustc_middle/Cargo.toml (renamed from src/librustc/Cargo.toml)4
-rw-r--r--src/librustc_middle/README.md (renamed from src/librustc/README.md)0
-rw-r--r--src/librustc_middle/arena.rs132
-rw-r--r--src/librustc_middle/benches/lib.rs (renamed from src/librustc/benches/lib.rs)0
-rw-r--r--src/librustc_middle/build.rs (renamed from src/librustc/build.rs)0
-rw-r--r--src/librustc_middle/dep_graph/dep_node.rs (renamed from src/librustc/dep_graph/dep_node.rs)0
-rw-r--r--src/librustc_middle/dep_graph/mod.rs (renamed from src/librustc/dep_graph/mod.rs)0
-rw-r--r--src/librustc_middle/hir/exports.rs (renamed from src/librustc/hir/exports.rs)0
-rw-r--r--src/librustc_middle/hir/map/blocks.rs (renamed from src/librustc/hir/map/blocks.rs)0
-rw-r--r--src/librustc_middle/hir/map/collector.rs (renamed from src/librustc/hir/map/collector.rs)0
-rw-r--r--src/librustc_middle/hir/map/mod.rs (renamed from src/librustc/hir/map/mod.rs)0
-rw-r--r--src/librustc_middle/hir/mod.rs (renamed from src/librustc/hir/mod.rs)0
-rw-r--r--src/librustc_middle/ich/hcx.rs (renamed from src/librustc/ich/hcx.rs)0
-rw-r--r--src/librustc_middle/ich/impls_hir.rs (renamed from src/librustc/ich/impls_hir.rs)0
-rw-r--r--src/librustc_middle/ich/impls_syntax.rs (renamed from src/librustc/ich/impls_syntax.rs)0
-rw-r--r--src/librustc_middle/ich/impls_ty.rs (renamed from src/librustc/ich/impls_ty.rs)2
-rw-r--r--src/librustc_middle/ich/mod.rs (renamed from src/librustc/ich/mod.rs)1
-rw-r--r--src/librustc_middle/infer/canonical.rs (renamed from src/librustc/infer/canonical.rs)0
-rw-r--r--src/librustc_middle/infer/mod.rs (renamed from src/librustc/infer/mod.rs)0
-rw-r--r--src/librustc_middle/infer/unify_key.rs (renamed from src/librustc/infer/unify_key.rs)0
-rw-r--r--src/librustc_middle/lib.rs (renamed from src/librustc/lib.rs)4
-rw-r--r--src/librustc_middle/lint.rs (renamed from src/librustc/lint.rs)0
-rw-r--r--src/librustc_middle/macros.rs (renamed from src/librustc/macros.rs)0
-rw-r--r--src/librustc_middle/middle/codegen_fn_attrs.rs (renamed from src/librustc/middle/codegen_fn_attrs.rs)0
-rw-r--r--src/librustc_middle/middle/cstore.rs (renamed from src/librustc/middle/cstore.rs)0
-rw-r--r--src/librustc_middle/middle/dependency_format.rs (renamed from src/librustc/middle/dependency_format.rs)0
-rw-r--r--src/librustc_middle/middle/exported_symbols.rs (renamed from src/librustc/middle/exported_symbols.rs)0
-rw-r--r--src/librustc_middle/middle/free_region.rs (renamed from src/librustc/middle/free_region.rs)0
-rw-r--r--src/librustc_middle/middle/lang_items.rs (renamed from src/librustc/middle/lang_items.rs)6
-rw-r--r--src/librustc_middle/middle/limits.rs (renamed from src/librustc/middle/limits.rs)2
-rw-r--r--src/librustc_middle/middle/mod.rs (renamed from src/librustc/middle/mod.rs)0
-rw-r--r--src/librustc_middle/middle/privacy.rs (renamed from src/librustc/middle/privacy.rs)0
-rw-r--r--src/librustc_middle/middle/region.rs (renamed from src/librustc/middle/region.rs)2
-rw-r--r--src/librustc_middle/middle/resolve_lifetime.rs (renamed from src/librustc/middle/resolve_lifetime.rs)0
-rw-r--r--src/librustc_middle/middle/stability.rs (renamed from src/librustc/middle/stability.rs)0
-rw-r--r--src/librustc_middle/mir/cache.rs (renamed from src/librustc/mir/cache.rs)0
-rw-r--r--src/librustc_middle/mir/interpret/allocation.rs (renamed from src/librustc/mir/interpret/allocation.rs)20
-rw-r--r--src/librustc_middle/mir/interpret/error.rs (renamed from src/librustc/mir/interpret/error.rs)25
-rw-r--r--src/librustc_middle/mir/interpret/mod.rs (renamed from src/librustc/mir/interpret/mod.rs)14
-rw-r--r--src/librustc_middle/mir/interpret/pointer.rs (renamed from src/librustc/mir/interpret/pointer.rs)7
-rw-r--r--src/librustc_middle/mir/interpret/queries.rs (renamed from src/librustc/mir/interpret/queries.rs)0
-rw-r--r--src/librustc_middle/mir/interpret/value.rs (renamed from src/librustc/mir/interpret/value.rs)7
-rw-r--r--src/librustc_middle/mir/mod.rs (renamed from src/librustc/mir/mod.rs)6
-rw-r--r--src/librustc_middle/mir/mono.rs (renamed from src/librustc/mir/mono.rs)0
-rw-r--r--src/librustc_middle/mir/query.rs (renamed from src/librustc/mir/query.rs)0
-rw-r--r--src/librustc_middle/mir/tcx.rs (renamed from src/librustc/mir/tcx.rs)2
-rw-r--r--src/librustc_middle/mir/traversal.rs (renamed from src/librustc/mir/traversal.rs)0
-rw-r--r--src/librustc_middle/mir/type_foldable.rs (renamed from src/librustc/mir/type_foldable.rs)0
-rw-r--r--src/librustc_middle/mir/visit.rs (renamed from src/librustc/mir/visit.rs)14
-rw-r--r--src/librustc_middle/query/mod.rs (renamed from src/librustc/query/mod.rs)2
-rw-r--r--src/librustc_middle/tests.rs (renamed from src/librustc/tests.rs)2
-rw-r--r--src/librustc_middle/traits/mod.rs (renamed from src/librustc/traits/mod.rs)0
-rw-r--r--src/librustc_middle/traits/query.rs (renamed from src/librustc/traits/query.rs)0
-rw-r--r--src/librustc_middle/traits/select.rs (renamed from src/librustc/traits/select.rs)0
-rw-r--r--src/librustc_middle/traits/specialization_graph.rs (renamed from src/librustc/traits/specialization_graph.rs)70
-rw-r--r--src/librustc_middle/traits/structural_impls.rs (renamed from src/librustc/traits/structural_impls.rs)0
-rw-r--r--src/librustc_middle/ty/_match.rs (renamed from src/librustc/ty/_match.rs)0
-rw-r--r--src/librustc_middle/ty/adjustment.rs (renamed from src/librustc/ty/adjustment.rs)0
-rw-r--r--src/librustc_middle/ty/binding.rs (renamed from src/librustc/ty/binding.rs)0
-rw-r--r--src/librustc_middle/ty/cast.rs (renamed from src/librustc/ty/cast.rs)0
-rw-r--r--src/librustc_middle/ty/codec.rs (renamed from src/librustc/ty/codec.rs)0
-rw-r--r--src/librustc_middle/ty/context.rs (renamed from src/librustc/ty/context.rs)12
-rw-r--r--src/librustc_middle/ty/diagnostics.rs (renamed from src/librustc/ty/diagnostics.rs)0
-rw-r--r--src/librustc_middle/ty/erase_regions.rs (renamed from src/librustc/ty/erase_regions.rs)0
-rw-r--r--src/librustc_middle/ty/error.rs (renamed from src/librustc/ty/error.rs)0
-rw-r--r--src/librustc_middle/ty/fast_reject.rs (renamed from src/librustc/ty/fast_reject.rs)0
-rw-r--r--src/librustc_middle/ty/flags.rs (renamed from src/librustc/ty/flags.rs)16
-rw-r--r--src/librustc_middle/ty/fold.rs (renamed from src/librustc/ty/fold.rs)7
-rw-r--r--src/librustc_middle/ty/free_region_map.rs (renamed from src/librustc/ty/free_region_map.rs)0
-rw-r--r--src/librustc_middle/ty/inhabitedness/def_id_forest.rs (renamed from src/librustc/ty/inhabitedness/def_id_forest.rs)0
-rw-r--r--src/librustc_middle/ty/inhabitedness/mod.rs (renamed from src/librustc/ty/inhabitedness/mod.rs)0
-rw-r--r--src/librustc_middle/ty/instance.rs (renamed from src/librustc/ty/instance.rs)2
-rw-r--r--src/librustc_middle/ty/layout.rs (renamed from src/librustc/ty/layout.rs)191
-rw-r--r--src/librustc_middle/ty/mod.rs (renamed from src/librustc/ty/mod.rs)116
-rw-r--r--src/librustc_middle/ty/normalize_erasing_regions.rs (renamed from src/librustc/ty/normalize_erasing_regions.rs)0
-rw-r--r--src/librustc_middle/ty/outlives.rs (renamed from src/librustc/ty/outlives.rs)0
-rw-r--r--src/librustc_middle/ty/print/mod.rs (renamed from src/librustc/ty/print/mod.rs)0
-rw-r--r--src/librustc_middle/ty/print/obsolete.rs (renamed from src/librustc/ty/print/obsolete.rs)6
-rw-r--r--src/librustc_middle/ty/print/pretty.rs (renamed from src/librustc/ty/print/pretty.rs)36
-rw-r--r--src/librustc_middle/ty/query/README.md (renamed from src/librustc/ty/query/README.md)0
-rw-r--r--src/librustc_middle/ty/query/job.rs (renamed from src/librustc/ty/query/job.rs)0
-rw-r--r--src/librustc_middle/ty/query/keys.rs (renamed from src/librustc/ty/query/keys.rs)0
-rw-r--r--src/librustc_middle/ty/query/mod.rs (renamed from src/librustc/ty/query/mod.rs)4
-rw-r--r--src/librustc_middle/ty/query/on_disk_cache.rs (renamed from src/librustc/ty/query/on_disk_cache.rs)0
-rw-r--r--src/librustc_middle/ty/query/plumbing.rs (renamed from src/librustc/ty/query/plumbing.rs)0
-rw-r--r--src/librustc_middle/ty/query/profiling_support.rs (renamed from src/librustc/ty/query/profiling_support.rs)0
-rw-r--r--src/librustc_middle/ty/query/stats.rs (renamed from src/librustc/ty/query/stats.rs)0
-rw-r--r--src/librustc_middle/ty/query/values.rs (renamed from src/librustc/ty/query/values.rs)0
-rw-r--r--src/librustc_middle/ty/relate.rs (renamed from src/librustc/ty/relate.rs)0
-rw-r--r--src/librustc_middle/ty/steal.rs (renamed from src/librustc/ty/steal.rs)0
-rw-r--r--src/librustc_middle/ty/structural_impls.rs (renamed from src/librustc/ty/structural_impls.rs)2
-rw-r--r--src/librustc_middle/ty/sty.rs (renamed from src/librustc/ty/sty.rs)9
-rw-r--r--src/librustc_middle/ty/subst.rs (renamed from src/librustc/ty/subst.rs)0
-rw-r--r--src/librustc_middle/ty/trait_def.rs (renamed from src/librustc/ty/trait_def.rs)0
-rw-r--r--src/librustc_middle/ty/util.rs (renamed from src/librustc/ty/util.rs)6
-rw-r--r--src/librustc_middle/ty/walk.rs (renamed from src/librustc/ty/walk.rs)0
-rw-r--r--src/librustc_middle/util/bug.rs (renamed from src/librustc/util/bug.rs)0
-rw-r--r--src/librustc_middle/util/common.rs (renamed from src/librustc/util/common.rs)2
-rw-r--r--src/librustc_middle/util/common/tests.rs (renamed from src/librustc/util/common/tests.rs)0
-rw-r--r--src/librustc_mir/Cargo.toml2
-rw-r--r--src/librustc_mir/borrow_check/borrow_set.rs12
-rw-r--r--src/librustc_mir/borrow_check/constraint_generation.rs22
-rw-r--r--src/librustc_mir/borrow_check/constraints/graph.rs4
-rw-r--r--src/librustc_mir/borrow_check/constraints/mod.rs4
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs90
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs51
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/find_use.rs6
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/mod.rs14
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/move_errors.rs32
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs110
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs2
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/region_errors.rs4
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/region_name.rs6
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/var_name.rs4
-rw-r--r--src/librustc_mir/borrow_check/facts.rs4
-rw-r--r--src/librustc_mir/borrow_check/invalidation.rs72
-rw-r--r--src/librustc_mir/borrow_check/location.rs2
-rw-r--r--src/librustc_mir/borrow_check/member_constraints.rs6
-rw-r--r--src/librustc_mir/borrow_check/mod.rs92
-rw-r--r--src/librustc_mir/borrow_check/nll.rs12
-rw-r--r--src/librustc_mir/borrow_check/path_utils.rs12
-rw-r--r--src/librustc_mir/borrow_check/place_ext.rs6
-rw-r--r--src/librustc_mir/borrow_check/places_conflict.rs12
-rw-r--r--src/librustc_mir/borrow_check/prefixes.rs4
-rw-r--r--src/librustc_mir/borrow_check/region_infer/mod.rs12
-rw-r--r--src/librustc_mir/borrow_check/region_infer/opaque_types.rs2
-rw-r--r--src/librustc_mir/borrow_check/region_infer/reverse_sccs.rs2
-rw-r--r--src/librustc_mir/borrow_check/region_infer/values.rs4
-rw-r--r--src/librustc_mir/borrow_check/renumber.rs8
-rw-r--r--src/librustc_mir/borrow_check/type_check/constraint_conversion.rs6
-rw-r--r--src/librustc_mir/borrow_check/type_check/free_region_relations.rs8
-rw-r--r--src/librustc_mir/borrow_check/type_check/input_output.rs4
-rw-r--r--src/librustc_mir/borrow_check/type_check/liveness/local_use_map.rs6
-rw-r--r--src/librustc_mir/borrow_check/type_check/liveness/mod.rs4
-rw-r--r--src/librustc_mir/borrow_check/type_check/liveness/polonius.rs10
-rw-r--r--src/librustc_mir/borrow_check/type_check/liveness/trace.rs4
-rw-r--r--src/librustc_mir/borrow_check/type_check/mod.rs34
-rw-r--r--src/librustc_mir/borrow_check/type_check/relate_tys.rs6
-rw-r--r--src/librustc_mir/borrow_check/universal_regions.rs8
-rw-r--r--src/librustc_mir/borrow_check/used_muts.rs27
-rw-r--r--src/librustc_mir/const_eval/error.rs6
-rw-r--r--src/librustc_mir/const_eval/eval_queries.rs22
-rw-r--r--src/librustc_mir/const_eval/fn_queries.rs6
-rw-r--r--src/librustc_mir/const_eval/machine.rs21
-rw-r--r--src/librustc_mir/const_eval/mod.rs6
-rw-r--r--src/librustc_mir/dataflow/drop_flag_effects.rs8
-rw-r--r--src/librustc_mir/dataflow/framework/cursor.rs6
-rw-r--r--src/librustc_mir/dataflow/framework/engine.rs39
-rw-r--r--src/librustc_mir/dataflow/framework/graphviz.rs38
-rw-r--r--src/librustc_mir/dataflow/framework/mod.rs24
-rw-r--r--src/librustc_mir/dataflow/framework/tests.rs6
-rw-r--r--src/librustc_mir/dataflow/framework/visitor.rs2
-rw-r--r--src/librustc_mir/dataflow/graphviz.rs277
-rw-r--r--src/librustc_mir/dataflow/impls/borrowed_locals.rs26
-rw-r--r--src/librustc_mir/dataflow/impls/borrows.rs20
-rw-r--r--src/librustc_mir/dataflow/impls/mod.rs37
-rw-r--r--src/librustc_mir/dataflow/impls/storage_liveness.rs14
-rw-r--r--src/librustc_mir/dataflow/mod.rs2
-rw-r--r--src/librustc_mir/dataflow/move_paths/abs_domain.rs4
-rw-r--r--src/librustc_mir/dataflow/move_paths/builder.rs53
-rw-r--r--src/librustc_mir/dataflow/move_paths/mod.rs4
-rw-r--r--src/librustc_mir/interpret/cast.rs38
-rw-r--r--src/librustc_mir/interpret/eval_context.rs121
-rw-r--r--src/librustc_mir/interpret/intern.rs4
-rw-r--r--src/librustc_mir/interpret/intrinsics.rs22
-rw-r--r--src/librustc_mir/interpret/intrinsics/caller_location.rs31
-rw-r--r--src/librustc_mir/interpret/intrinsics/type_name.rs13
-rw-r--r--src/librustc_mir/interpret/machine.rs8
-rw-r--r--src/librustc_mir/interpret/memory.rs7
-rw-r--r--src/librustc_mir/interpret/mod.rs20
-rw-r--r--src/librustc_mir/interpret/operand.rs102
-rw-r--r--src/librustc_mir/interpret/operator.rs34
-rw-r--r--src/librustc_mir/interpret/place.rs71
-rw-r--r--src/librustc_mir/interpret/step.rs42
-rw-r--r--src/librustc_mir/interpret/terminator.rs53
-rw-r--r--src/librustc_mir/interpret/traits.rs6
-rw-r--r--src/librustc_mir/interpret/validity.rs27
-rw-r--r--src/librustc_mir/interpret/visitor.rs23
-rw-r--r--src/librustc_mir/lib.rs4
-rw-r--r--src/librustc_mir/monomorphize/collector.rs33
-rw-r--r--src/librustc_mir/monomorphize/mod.rs6
-rw-r--r--src/librustc_mir/monomorphize/partitioning.rs98
-rw-r--r--src/librustc_mir/shim.rs12
-rw-r--r--src/librustc_mir/transform/add_call_guards.rs4
-rw-r--r--src/librustc_mir/transform/add_moves_for_packed_drops.rs6
-rw-r--r--src/librustc_mir/transform/add_retag.rs4
-rw-r--r--src/librustc_mir/transform/check_consts/mod.rs4
-rw-r--r--src/librustc_mir/transform/check_consts/qualifs.rs4
-rw-r--r--src/librustc_mir/transform/check_consts/resolver.rs10
-rw-r--r--src/librustc_mir/transform/check_consts/validation.rs18
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs78
-rw-r--r--src/librustc_mir/transform/cleanup_post_borrowck.rs16
-rw-r--r--src/librustc_mir/transform/const_prop.rs65
-rw-r--r--src/librustc_mir/transform/copy_prop.rs13
-rw-r--r--src/librustc_mir/transform/deaggregator.rs4
-rw-r--r--src/librustc_mir/transform/dump_mir.rs6
-rw-r--r--src/librustc_mir/transform/elaborate_drops.rs16
-rw-r--r--src/librustc_mir/transform/generator.rs25
-rw-r--r--src/librustc_mir/transform/inline.rs14
-rw-r--r--src/librustc_mir/transform/instcombine.rs12
-rw-r--r--src/librustc_mir/transform/mod.rs8
-rw-r--r--src/librustc_mir/transform/no_landing_pads.rs6
-rw-r--r--src/librustc_mir/transform/promote_consts.rs38
-rw-r--r--src/librustc_mir/transform/qualify_min_const_fn.rs24
-rw-r--r--src/librustc_mir/transform/remove_noop_landing_pads.rs19
-rw-r--r--src/librustc_mir/transform/rustc_peek.rs12
-rw-r--r--src/librustc_mir/transform/simplify.rs34
-rw-r--r--src/librustc_mir/transform/simplify_branches.rs4
-rw-r--r--src/librustc_mir/transform/simplify_try.rs10
-rw-r--r--src/librustc_mir/transform/uninhabited_enum_branching.rs9
-rw-r--r--src/librustc_mir/transform/unreachable_prop.rs4
-rw-r--r--src/librustc_mir/util/aggregate.rs6
-rw-r--r--src/librustc_mir/util/alignment.rs8
-rw-r--r--src/librustc_mir/util/borrowck_errors.rs2
-rw-r--r--src/librustc_mir/util/collect_writes.rs11
-rw-r--r--src/librustc_mir/util/def_use.rs10
-rw-r--r--src/librustc_mir/util/elaborate_drops.rs87
-rw-r--r--src/librustc_mir/util/graphviz.rs4
-rw-r--r--src/librustc_mir/util/liveness.rs14
-rw-r--r--src/librustc_mir/util/patch.rs4
-rw-r--r--src/librustc_mir/util/pretty.rs25
-rw-r--r--src/librustc_mir_build/Cargo.toml2
-rw-r--r--src/librustc_mir_build/build/block.rs6
-rw-r--r--src/librustc_mir_build/build/cfg.rs10
-rw-r--r--src/librustc_mir_build/build/expr/as_constant.rs4
-rw-r--r--src/librustc_mir_build/build/expr/as_operand.rs4
-rw-r--r--src/librustc_mir_build/build/expr/as_place.rs14
-rw-r--r--src/librustc_mir_build/build/expr/as_rvalue.rs31
-rw-r--r--src/librustc_mir_build/build/expr/as_temp.rs6
-rw-r--r--src/librustc_mir_build/build/expr/into.rs21
-rw-r--r--src/librustc_mir_build/build/expr/stmt.rs8
-rw-r--r--src/librustc_mir_build/build/into.rs10
-rw-r--r--src/librustc_mir_build/build/matches/mod.rs28
-rw-r--r--src/librustc_mir_build/build/matches/simplify.rs9
-rw-r--r--src/librustc_mir_build/build/matches/test.rs20
-rw-r--r--src/librustc_mir_build/build/matches/util.rs4
-rw-r--r--src/librustc_mir_build/build/misc.rs6
-rw-r--r--src/librustc_mir_build/build/mod.rs14
-rw-r--r--src/librustc_mir_build/build/scope.rs8
-rw-r--r--src/librustc_mir_build/hair/constant.rs7
-rw-r--r--src/librustc_mir_build/hair/cx/block.rs4
-rw-r--r--src/librustc_mir_build/hair/cx/expr.rs16
-rw-r--r--src/librustc_mir_build/hair/cx/mod.rs12
-rw-r--r--src/librustc_mir_build/hair/mod.rs14
-rw-r--r--src/librustc_mir_build/hair/pattern/_match.rs31
-rw-r--r--src/librustc_mir_build/hair/pattern/check_match.rs6
-rw-r--r--src/librustc_mir_build/hair/pattern/const_to_pat.rs4
-rw-r--r--src/librustc_mir_build/hair/pattern/mod.rs41
-rw-r--r--src/librustc_mir_build/hair/util.rs2
-rw-r--r--src/librustc_mir_build/lib.rs4
-rw-r--r--src/librustc_mir_build/lints.rs8
-rw-r--r--src/librustc_parse/lexer/mod.rs96
-rw-r--r--src/librustc_parse/lib.rs1
-rw-r--r--src/librustc_parse/parser/diagnostics.rs33
-rw-r--r--src/librustc_parse/parser/expr.rs1
-rw-r--r--src/librustc_parse/parser/item.rs4
-rw-r--r--src/librustc_parse/parser/stmt.rs6
-rw-r--r--src/librustc_parse/parser/ty.rs44
-rw-r--r--src/librustc_passes/Cargo.toml2
-rw-r--r--src/librustc_passes/check_attr.rs6
-rw-r--r--src/librustc_passes/check_const.rs6
-rw-r--r--src/librustc_passes/dead.rs17
-rw-r--r--src/librustc_passes/diagnostic_items.rs4
-rw-r--r--src/librustc_passes/entry.rs6
-rw-r--r--src/librustc_passes/hir_id_validator.rs4
-rw-r--r--src/librustc_passes/hir_stats.rs4
-rw-r--r--src/librustc_passes/intrinsicck.rs7
-rw-r--r--src/librustc_passes/lang_items.rs6
-rw-r--r--src/librustc_passes/layout_test.rs16
-rw-r--r--src/librustc_passes/lib.rs4
-rw-r--r--src/librustc_passes/lib_features.rs8
-rw-r--r--src/librustc_passes/liveness.rs6
-rw-r--r--src/librustc_passes/loops.rs6
-rw-r--r--src/librustc_passes/reachable.rs8
-rw-r--r--src/librustc_passes/region.rs10
-rw-r--r--src/librustc_passes/stability.rs12
-rw-r--r--src/librustc_passes/upvars.rs4
-rw-r--r--src/librustc_passes/weak_lang_items.rs6
-rw-r--r--src/librustc_plugin_impl/Cargo.toml2
-rw-r--r--src/librustc_plugin_impl/build.rs4
-rw-r--r--src/librustc_plugin_impl/load.rs2
-rw-r--r--src/librustc_privacy/Cargo.toml2
-rw-r--r--src/librustc_privacy/lib.rs82
-rw-r--r--src/librustc_query_system/dep_graph/dep_node.rs2
-rw-r--r--src/librustc_query_system/query/config.rs4
-rw-r--r--src/librustc_resolve/Cargo.toml2
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs8
-rw-r--r--src/librustc_resolve/check_unused.rs2
-rw-r--r--src/librustc_resolve/diagnostics.rs4
-rw-r--r--src/librustc_resolve/imports.rs6
-rw-r--r--src/librustc_resolve/late.rs18
-rw-r--r--src/librustc_resolve/late/lifetimes.rs8
-rw-r--r--src/librustc_resolve/lib.rs13
-rw-r--r--src/librustc_resolve/macros.rs4
-rw-r--r--src/librustc_save_analysis/Cargo.toml2
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs11
-rw-r--r--src/librustc_save_analysis/lib.rs10
-rw-r--r--src/librustc_session/config.rs2
-rw-r--r--src/librustc_session/filesearch.rs4
-rw-r--r--src/librustc_session/lint.rs5
-rw-r--r--src/librustc_session/options.rs2
-rw-r--r--src/librustc_session/session.rs37
-rw-r--r--src/librustc_span/lib.rs2
-rw-r--r--src/librustc_symbol_mangling/Cargo.toml2
-rw-r--r--src/librustc_symbol_mangling/legacy.rs17
-rw-r--r--src/librustc_symbol_mangling/lib.rs12
-rw-r--r--src/librustc_symbol_mangling/test.rs2
-rw-r--r--src/librustc_symbol_mangling/v0.rs6
-rw-r--r--src/librustc_target/abi/call/aarch64.rs18
-rw-r--r--src/librustc_target/abi/call/amdgpu.rs14
-rw-r--r--src/librustc_target/abi/call/arm.rs18
-rw-r--r--src/librustc_target/abi/call/mips.rs8
-rw-r--r--src/librustc_target/abi/call/mips64.rs26
-rw-r--r--src/librustc_target/abi/call/mod.rs26
-rw-r--r--src/librustc_target/abi/call/powerpc64.rs18
-rw-r--r--src/librustc_target/abi/call/riscv.rs53
-rw-r--r--src/librustc_target/abi/call/s390x.rs18
-rw-r--r--src/librustc_target/abi/call/sparc.rs8
-rw-r--r--src/librustc_target/abi/call/sparc64.rs18
-rw-r--r--src/librustc_target/abi/call/wasm32.rs18
-rw-r--r--src/librustc_target/abi/call/x86.rs12
-rw-r--r--src/librustc_target/abi/call/x86_64.rs16
-rw-r--r--src/librustc_target/abi/mod.rs73
-rw-r--r--src/librustc_target/lib.rs2
-rw-r--r--src/librustc_target/spec/i686_apple_darwin.rs2
-rw-r--r--src/librustc_target/spec/windows_base.rs2
-rw-r--r--src/librustc_target/spec/x86_64_apple_darwin.rs2
-rw-r--r--src/librustc_trait_selection/Cargo.toml2
-rw-r--r--src/librustc_trait_selection/infer.rs10
-rw-r--r--src/librustc_trait_selection/lib.rs3
-rw-r--r--src/librustc_trait_selection/opaque_types.rs8
-rw-r--r--src/librustc_trait_selection/traits/auto_trait.rs159
-rw-r--r--src/librustc_trait_selection/traits/codegen/mod.rs4
-rw-r--r--src/librustc_trait_selection/traits/coherence.rs6
-rw-r--r--src/librustc_trait_selection/traits/engine.rs2
-rw-r--r--src/librustc_trait_selection/traits/error_reporting/mod.rs203
-rw-r--r--src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs11
-rw-r--r--src/librustc_trait_selection/traits/error_reporting/suggestions.rs115
-rw-r--r--src/librustc_trait_selection/traits/fulfill.rs4
-rw-r--r--src/librustc_trait_selection/traits/misc.rs2
-rw-r--r--src/librustc_trait_selection/traits/mod.rs14
-rw-r--r--src/librustc_trait_selection/traits/object_safety.rs6
-rw-r--r--src/librustc_trait_selection/traits/on_unimplemented.rs6
-rw-r--r--src/librustc_trait_selection/traits/project.rs60
-rw-r--r--src/librustc_trait_selection/traits/query/dropck_outlives.rs6
-rw-r--r--src/librustc_trait_selection/traits/query/method_autoderef.rs4
-rw-r--r--src/librustc_trait_selection/traits/query/mod.rs2
-rw-r--r--src/librustc_trait_selection/traits/query/normalize.rs8
-rw-r--r--src/librustc_trait_selection/traits/query/outlives_bounds.rs4
-rw-r--r--src/librustc_trait_selection/traits/query/type_op/ascribe_user_type.rs4
-rw-r--r--src/librustc_trait_selection/traits/query/type_op/eq.rs4
-rw-r--r--src/librustc_trait_selection/traits/query/type_op/implied_outlives_bounds.rs2
-rw-r--r--src/librustc_trait_selection/traits/query/type_op/mod.rs6
-rw-r--r--src/librustc_trait_selection/traits/query/type_op/normalize.rs6
-rw-r--r--src/librustc_trait_selection/traits/query/type_op/outlives.rs2
-rw-r--r--src/librustc_trait_selection/traits/query/type_op/prove_predicate.rs4
-rw-r--r--src/librustc_trait_selection/traits/query/type_op/subtype.rs4
-rw-r--r--src/librustc_trait_selection/traits/select.rs16
-rw-r--r--src/librustc_trait_selection/traits/specialize/mod.rs48
-rw-r--r--src/librustc_trait_selection/traits/specialize/specialization_graph.rs6
-rw-r--r--src/librustc_trait_selection/traits/structural_match.rs2
-rw-r--r--src/librustc_trait_selection/traits/util.rs316
-rw-r--r--src/librustc_trait_selection/traits/wf.rs21
-rw-r--r--src/librustc_traits/Cargo.toml2
-rw-r--r--src/librustc_traits/dropck_outlives.rs6
-rw-r--r--src/librustc_traits/evaluate_obligation.rs4
-rw-r--r--src/librustc_traits/implied_outlives_bounds.rs9
-rw-r--r--src/librustc_traits/lib.rs4
-rw-r--r--src/librustc_traits/lowering/environment.rs8
-rw-r--r--src/librustc_traits/lowering/mod.rs18
-rw-r--r--src/librustc_traits/normalize_erasing_regions.rs8
-rw-r--r--src/librustc_traits/normalize_projection_ty.rs4
-rw-r--r--src/librustc_traits/type_op.rs10
-rw-r--r--src/librustc_ty/Cargo.toml2
-rw-r--r--src/librustc_ty/common_traits.rs4
-rw-r--r--src/librustc_ty/instance.rs57
-rw-r--r--src/librustc_ty/lib.rs4
-rw-r--r--src/librustc_ty/needs_drop.rs6
-rw-r--r--src/librustc_ty/ty.rs17
-rw-r--r--src/librustc_typeck/Cargo.toml2
-rw-r--r--src/librustc_typeck/astconv.rs21
-rw-r--r--src/librustc_typeck/check/_match.rs2
-rw-r--r--src/librustc_typeck/check/autoderef.rs6
-rw-r--r--src/librustc_typeck/check/callee.rs8
-rw-r--r--src/librustc_typeck/check/cast.rs19
-rw-r--r--src/librustc_typeck/check/closure.rs22
-rw-r--r--src/librustc_typeck/check/coercion.rs16
-rw-r--r--src/librustc_typeck/check/compare_method.rs11
-rw-r--r--src/librustc_typeck/check/demand.rs4
-rw-r--r--src/librustc_typeck/check/dropck.rs13
-rw-r--r--src/librustc_typeck/check/expr.rs18
-rw-r--r--src/librustc_typeck/check/generator_interior.rs6
-rw-r--r--src/librustc_typeck/check/intrinsic.rs8
-rw-r--r--src/librustc_typeck/check/method/confirm.rs21
-rw-r--r--src/librustc_typeck/check/method/mod.rs8
-rw-r--r--src/librustc_typeck/check/method/probe.rs12
-rw-r--r--src/librustc_typeck/check/method/suggest.rs43
-rw-r--r--src/librustc_typeck/check/mod.rs47
-rw-r--r--src/librustc_typeck/check/op.rs40
-rw-r--r--src/librustc_typeck/check/pat.rs49
-rw-r--r--src/librustc_typeck/check/regionck.rs6
-rw-r--r--src/librustc_typeck/check/upvar.rs2
-rw-r--r--src/librustc_typeck/check/wfcheck.rs12
-rw-r--r--src/librustc_typeck/check/writeback.rs29
-rw-r--r--src/librustc_typeck/check_unused.rs2
-rw-r--r--src/librustc_typeck/coherence/builtin.rs10
-rw-r--r--src/librustc_typeck/coherence/inherent_impls.rs2
-rw-r--r--src/librustc_typeck/coherence/inherent_impls_overlap.rs2
-rw-r--r--src/librustc_typeck/coherence/mod.rs4
-rw-r--r--src/librustc_typeck/coherence/orphan.rs2
-rw-r--r--src/librustc_typeck/coherence/unsafety.rs2
-rw-r--r--src/librustc_typeck/collect.rs26
-rw-r--r--src/librustc_typeck/collect/type_of.rs14
-rw-r--r--src/librustc_typeck/constrained_generic_params.rs4
-rw-r--r--src/librustc_typeck/expr_use_visitor.rs2
-rw-r--r--src/librustc_typeck/impl_wf_check.rs4
-rw-r--r--src/librustc_typeck/impl_wf_check/min_specialization.rs8
-rw-r--r--src/librustc_typeck/lib.rs15
-rw-r--r--src/librustc_typeck/mem_categorization.rs6
-rw-r--r--src/librustc_typeck/outlives/explicit.rs2
-rw-r--r--src/librustc_typeck/outlives/implicit_infer.rs4
-rw-r--r--src/librustc_typeck/outlives/mod.rs6
-rw-r--r--src/librustc_typeck/outlives/test.rs2
-rw-r--r--src/librustc_typeck/outlives/utils.rs6
-rw-r--r--src/librustc_typeck/structured_errors.rs2
-rw-r--r--src/librustc_typeck/variance/constraints.rs4
-rw-r--r--src/librustc_typeck/variance/mod.rs4
-rw-r--r--src/librustc_typeck/variance/solve.rs2
-rw-r--r--src/librustc_typeck/variance/terms.rs2
-rw-r--r--src/librustc_typeck/variance/test.rs2
-rw-r--r--src/librustc_typeck/variance/xform.rs2
-rw-r--r--src/librustdoc/clean/auto_trait.rs10
-rw-r--r--src/librustdoc/clean/blanket_impl.rs4
-rw-r--r--src/librustdoc/clean/inline.rs4
-rw-r--r--src/librustdoc/clean/mod.rs49
-rw-r--r--src/librustdoc/clean/simplify.rs4
-rw-r--r--src/librustdoc/clean/types.rs6
-rw-r--r--src/librustdoc/clean/utils.rs37
-rw-r--r--src/librustdoc/core.rs8
-rw-r--r--src/librustdoc/html/markdown.rs123
-rw-r--r--src/librustdoc/html/render.rs17
-rw-r--r--src/librustdoc/html/render/cache.rs4
-rw-r--r--src/librustdoc/lib.rs2
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs4
-rw-r--r--src/librustdoc/passes/mod.rs2
-rw-r--r--src/librustdoc/test.rs107
-rw-r--r--src/librustdoc/theme.rs20
-rw-r--r--src/librustdoc/visit_ast.rs4
-rw-r--r--src/librustdoc/visit_lib.rs4
-rw-r--r--src/libstd/alloc.rs111
-rw-r--r--src/libstd/error.rs9
-rw-r--r--src/libstd/f32.rs4
-rw-r--r--src/libstd/f64.rs4
-rw-r--r--src/libstd/fs.rs14
-rw-r--r--src/libstd/io/stdio.rs4
-rw-r--r--src/libstd/sys/cloudabi/stack_overflow.rs8
-rw-r--r--src/libstd/sys/cloudabi/thread.rs15
-rw-r--r--src/libstd/sys/hermit/stack_overflow.rs8
-rw-r--r--src/libstd/sys/hermit/thread.rs17
-rw-r--r--src/libstd/sys/sgx/stack_overflow.rs8
-rw-r--r--src/libstd/sys/unix/process/process_unix.rs2
-rw-r--r--src/libstd/sys/unix/thread.rs21
-rw-r--r--src/libstd/sys/vxworks/thread.rs21
-rw-r--r--src/libstd/sys/wasi/alloc.rs2
-rw-r--r--src/libstd/sys/wasm/stack_overflow.rs8
-rw-r--r--src/libstd/sys/windows/handle.rs5
-rw-r--r--src/libstd/sys/windows/os.rs2
-rw-r--r--src/libstd/sys/windows/thread.rs17
-rw-r--r--src/libstd/sys_common/thread.rs11
m---------src/llvm-project0
-rw-r--r--src/test/codegen-units/partitioning/incremental-merging.rs42
-rw-r--r--src/test/incremental/const-generics/issue-61516.rs2
-rw-r--r--src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs12
-rw-r--r--src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/rustc.map.SimplifyLocals.diff37
-rw-r--r--src/test/mir-opt/simplify_try.rs16
-rw-r--r--src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs13
-rw-r--r--src/test/ui-fulldeps/auxiliary/lto-syntax-extension-plugin.rs2
-rw-r--r--src/test/ui-fulldeps/auxiliary/outlive-expansion-phase.rs2
-rw-r--r--src/test/ui-fulldeps/auxiliary/rlib-crate-test.rs2
-rw-r--r--src/test/ui-fulldeps/hash-stable-is-unstable.rs2
-rw-r--r--src/test/ui-fulldeps/hash-stable-is-unstable.stderr4
-rw-r--r--src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs2
-rw-r--r--src/test/ui-fulldeps/internal-lints/pass_ty_by_ref.rs4
-rw-r--r--src/test/ui-fulldeps/internal-lints/qualified_ty_ty_ctxt.rs4
-rw-r--r--src/test/ui-fulldeps/internal-lints/ty_tykind_usage.rs4
-rw-r--r--src/test/ui-fulldeps/pathless-extern-unstable.rs6
-rw-r--r--src/test/ui-fulldeps/pathless-extern-unstable.stderr4
-rw-r--r--src/test/ui-fulldeps/undef_mask.rs7
-rw-r--r--src/test/ui/allocator/custom.rs14
-rw-r--r--src/test/ui/allocator/xcrate-use.rs16
-rw-r--r--src/test/ui/array-slice-vec/infer_array_len.rs21
-rw-r--r--src/test/ui/array-slice-vec/infer_array_len.stderr11
-rw-r--r--src/test/ui/array-slice-vec/match_arr_unknown_len.rs11
-rw-r--r--src/test/ui/array-slice-vec/match_arr_unknown_len.stderr20
-rw-r--r--src/test/ui/array-slice-vec/vec-fixed-length.rs2
-rw-r--r--src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr7
-rw-r--r--src/test/ui/associated-const/associated-const-type-parameter-arrays.stderr7
-rw-r--r--src/test/ui/associated-const/issue-69020-assoc-const-arith-overflow.noopt.stderr54
-rw-r--r--src/test/ui/associated-const/issue-69020-assoc-const-arith-overflow.opt.stderr54
-rw-r--r--src/test/ui/associated-const/issue-69020-assoc-const-arith-overflow.opt_with_overflow_checks.stderr54
-rw-r--r--src/test/ui/associated-const/issue-69020-assoc-const-arith-overflow.rs (renamed from src/test/ui/consts/issue-69020.rs)25
-rw-r--r--src/test/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr7
-rw-r--r--src/test/ui/associated-types/associated-types-no-suitable-bound.stderr7
-rw-r--r--src/test/ui/associated-types/defaults-suitability.stderr16
-rw-r--r--src/test/ui/associated-types/defaults-unsound-62211-1.stderr28
-rw-r--r--src/test/ui/associated-types/defaults-unsound-62211-2.stderr28
-rw-r--r--src/test/ui/async-await/issue-70594.rs12
-rw-r--r--src/test/ui/async-await/issue-70594.stderr44
-rw-r--r--src/test/ui/async-await/issues/issue-62009-1.rs4
-rw-r--r--src/test/ui/async-await/issues/issue-62009-1.stderr12
-rw-r--r--src/test/ui/bad/bad-method-typaram-kind.stderr7
-rw-r--r--src/test/ui/binop/binop-consume-args.stderr140
-rw-r--r--src/test/ui/binop/binop-move-semantics.stderr14
-rw-r--r--src/test/ui/block-fn-coerce.rs1
-rw-r--r--src/test/ui/borrowck/borrowck-unboxed-closures.stderr7
-rw-r--r--src/test/ui/bound-suggestions.fixed4
-rw-r--r--src/test/ui/bound-suggestions.stderr54
-rw-r--r--src/test/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr18
-rw-r--r--src/test/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr9
-rw-r--r--src/test/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr7
-rw-r--r--src/test/ui/cleanup-rvalue-scopes.rs2
-rw-r--r--src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr7
-rw-r--r--src/test/ui/closures/closure-bounds-subtype.stderr7
-rw-r--r--src/test/ui/closures/closure-expected-type/expect-region-supply-region.polonius.stderr6
-rw-r--r--src/test/ui/closures/closure-move-sync.rs4
-rw-r--r--src/test/ui/closures/closure-move-sync.stderr8
-rw-r--r--src/test/ui/closures/issue-67123.stderr9
-rw-r--r--src/test/ui/coerce/coerce-expect-unsized.rs1
-rw-r--r--src/test/ui/coerce/coerce-overloaded-autoderef.rs1
-rw-r--r--src/test/ui/const-generics/infer_arg_from_pat.rs27
-rw-r--r--src/test/ui/const-generics/infer_arg_from_pat.stderr8
-rw-r--r--src/test/ui/const-generics/infer_arr_len_from_pat.rs13
-rw-r--r--src/test/ui/const-generics/infer_arr_len_from_pat.stderr8
-rw-r--r--src/test/ui/const-generics/issues/issue-61336-2.stderr9
-rw-r--r--src/test/ui/const-generics/issues/issue-61336.stderr9
-rw-r--r--src/test/ui/const-generics/issues/issue-62220.rs22
-rw-r--r--src/test/ui/const-generics/issues/issue-62504.rs4
-rw-r--r--src/test/ui/const-generics/issues/issue-70125-2.rs2
-rw-r--r--src/test/ui/const-generics/unused_braces.rs13
-rw-r--r--src/test/ui/const-generics/unused_braces.stderr20
-rw-r--r--src/test/ui/consts/const-block.rs2
-rw-r--r--src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr3
-rw-r--r--src/test/ui/consts/const-size_of-cycle.rs4
-rw-r--r--src/test/ui/consts/const-size_of-cycle.stderr8
-rw-r--r--src/test/ui/consts/issue-69020.noopt.stderr30
-rw-r--r--src/test/ui/consts/issue-69020.opt.stderr30
-rw-r--r--src/test/ui/consts/issue-69020.opt_with_overflow_checks.stderr30
-rw-r--r--src/test/ui/consts/miri_unleashed/abi-mismatch.stderr3
-rw-r--r--src/test/ui/consts/miri_unleashed/drop.rs4
-rw-r--r--src/test/ui/consts/miri_unleashed/drop.stderr11
-rw-r--r--src/test/ui/consts/offset_from_ub.rs5
-rw-r--r--src/test/ui/consts/offset_from_ub.stderr25
-rw-r--r--src/test/ui/consts/uninhabited-const-issue-61744.stderr194
-rw-r--r--src/test/ui/copy-a-resource.rs5
-rw-r--r--src/test/ui/copy-a-resource.stderr2
-rw-r--r--src/test/ui/derives/derive-assoc-type-not-impl.rs5
-rw-r--r--src/test/ui/derives/derive-assoc-type-not-impl.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Clone-enum-struct-variant.rs4
-rw-r--r--src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Clone-enum.rs4
-rw-r--r--src/test/ui/derives/derives-span-Clone-enum.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Clone-struct.rs4
-rw-r--r--src/test/ui/derives/derives-span-Clone-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Clone-tuple-struct.rs4
-rw-r--r--src/test/ui/derives/derives-span-Clone-tuple-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Debug-enum-struct-variant.rs4
-rw-r--r--src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Debug-enum.rs4
-rw-r--r--src/test/ui/derives/derives-span-Debug-enum.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Debug-struct.rs4
-rw-r--r--src/test/ui/derives/derives-span-Debug-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Debug-tuple-struct.rs4
-rw-r--r--src/test/ui/derives/derives-span-Debug-tuple-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Default-struct.rs4
-rw-r--r--src/test/ui/derives/derives-span-Default-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Default-tuple-struct.rs4
-rw-r--r--src/test/ui/derives/derives-span-Default-tuple-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Eq-enum-struct-variant.rs4
-rw-r--r--src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Eq-enum.rs4
-rw-r--r--src/test/ui/derives/derives-span-Eq-enum.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Eq-struct.rs4
-rw-r--r--src/test/ui/derives/derives-span-Eq-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Eq-tuple-struct.rs4
-rw-r--r--src/test/ui/derives/derives-span-Eq-tuple-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs4
-rw-r--r--src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Hash-enum.rs4
-rw-r--r--src/test/ui/derives/derives-span-Hash-enum.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Hash-struct.rs4
-rw-r--r--src/test/ui/derives/derives-span-Hash-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Hash-tuple-struct.rs4
-rw-r--r--src/test/ui/derives/derives-span-Hash-tuple-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Ord-enum-struct-variant.rs4
-rw-r--r--src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Ord-enum.rs4
-rw-r--r--src/test/ui/derives/derives-span-Ord-enum.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Ord-struct.rs4
-rw-r--r--src/test/ui/derives/derives-span-Ord-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Ord-tuple-struct.rs4
-rw-r--r--src/test/ui/derives/derives-span-Ord-tuple-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs4
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr4
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum.rs4
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum.stderr4
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-struct.rs4
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-struct.stderr4
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs4
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr4
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs4
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr10
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-enum.rs4
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-enum.stderr10
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-struct.rs4
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-struct.stderr10
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-tuple-struct.rs4
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr10
-rw-r--r--src/test/ui/derives/deriving-meta-unknown-trait.rs4
-rw-r--r--src/test/ui/derives/deriving-meta-unknown-trait.stderr4
-rw-r--r--src/test/ui/error-codes/E0004-2.rs5
-rw-r--r--src/test/ui/error-codes/E0004-2.stderr2
-rw-r--r--src/test/ui/error-codes/E0005.rs5
-rw-r--r--src/test/ui/error-codes/E0005.stderr2
-rw-r--r--src/test/ui/error-codes/E0297.rs5
-rw-r--r--src/test/ui/error-codes/E0297.stderr2
-rw-r--r--src/test/ui/error-codes/E0730.rs2
-rw-r--r--src/test/ui/error-codes/E0730.stderr4
-rw-r--r--src/test/ui/expr-block-generic-unique1.rs2
-rw-r--r--src/test/ui/expr-block-generic-unique2.rs2
-rw-r--r--src/test/ui/expr-block-generic.rs1
-rw-r--r--src/test/ui/expr-block-unique.rs2
-rw-r--r--src/test/ui/expr-block.rs5
-rw-r--r--src/test/ui/expr-fn.rs1
-rw-r--r--src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs5
-rw-r--r--src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-link_cfg.stderr2
-rw-r--r--src/test/ui/functions-closures/closure-inference.rs2
-rw-r--r--src/test/ui/functions-closures/closure-inference2.rs2
-rw-r--r--src/test/ui/generic-associated-types/impl_bounds.stderr9
-rw-r--r--src/test/ui/generic-associated-types/iterable.rs5
-rw-r--r--src/test/ui/generic-associated-types/iterable.stderr8
-rw-r--r--src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr7
-rw-r--r--src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr14
-rw-r--r--src/test/ui/hrtb/hrtb-perfect-forwarding.polonius.stderr3
-rw-r--r--src/test/ui/impl-trait/impl-generic-mismatch.rs5
-rw-r--r--src/test/ui/impl-trait/impl-generic-mismatch.stderr6
-rw-r--r--src/test/ui/impl-trait/issue-55872-1.stderr18
-rw-r--r--src/test/ui/impl-trait/multiple-lifetimes/error-handling.polonius.stderr7
-rw-r--r--src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs4
-rw-r--r--src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr6
-rw-r--r--src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs4
-rw-r--r--src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr2
-rw-r--r--src/test/ui/interior-mutability/interior-mutability.rs4
-rw-r--r--src/test/ui/interior-mutability/interior-mutability.stderr4
-rw-r--r--src/test/ui/intrinsics/intrinsic-alignment.rs10
-rw-r--r--src/test/ui/intrinsics/intrinsic-move-val-cleanups.rs1
-rw-r--r--src/test/ui/issues/issue-17546.rs4
-rw-r--r--src/test/ui/issues/issue-17546.stderr8
-rw-r--r--src/test/ui/issues/issue-21160.rs4
-rw-r--r--src/test/ui/issues/issue-21160.stderr2
-rw-r--r--src/test/ui/issues/issue-21837.stderr7
-rw-r--r--src/test/ui/issues/issue-23898.rs1
-rw-r--r--src/test/ui/issues/issue-27033.rs4
-rw-r--r--src/test/ui/issues/issue-27033.stderr4
-rw-r--r--src/test/ui/issues/issue-2823.rs5
-rw-r--r--src/test/ui/issues/issue-2823.stderr2
-rw-r--r--src/test/ui/issues/issue-28777.rs1
-rw-r--r--src/test/ui/issues/issue-31173.rs4
-rw-r--r--src/test/ui/issues/issue-31173.stderr18
-rw-r--r--src/test/ui/issues/issue-34721.fixed2
-rw-r--r--src/test/ui/issues/issue-34721.stderr7
-rw-r--r--src/test/ui/issues/issue-38857.rs5
-rw-r--r--src/test/ui/issues/issue-38857.stderr4
-rw-r--r--src/test/ui/issues/issue-43784-associated-type.stderr7
-rw-r--r--src/test/ui/issues/issue-43784-supertrait.stderr7
-rw-r--r--src/test/ui/issues/issue-69725.rs5
-rw-r--r--src/test/ui/issues/issue-69725.stderr2
-rw-r--r--src/test/ui/issues/issue-69841.rs30
-rw-r--r--src/test/ui/issues/issue-70673.rs12
-rw-r--r--src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.rs10
-rw-r--r--src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr41
-rw-r--r--src/test/ui/issues/issue-7607-1.rs4
-rw-r--r--src/test/ui/issues/issue-7607-1.stderr2
-rw-r--r--src/test/ui/keyword/extern/keyword-extern-as-identifier-type.rs2
-rw-r--r--src/test/ui/keyword/extern/keyword-extern-as-identifier-type.stderr6
-rw-r--r--src/test/ui/kindck/kindck-impl-type-params.nll.stderr36
-rw-r--r--src/test/ui/kindck/kindck-impl-type-params.stderr36
-rw-r--r--src/test/ui/lint/lint-unnecessary-parens.rs6
-rw-r--r--src/test/ui/lint/lint-unnecessary-parens.stderr6
-rw-r--r--src/test/ui/lint/unused_braces.rs31
-rw-r--r--src/test/ui/lint/unused_braces.stderr36
-rw-r--r--src/test/ui/lint/unused_parens_borrow.rs22
-rw-r--r--src/test/ui/lint/unused_parens_borrow.stderr12
-rw-r--r--src/test/ui/lint/unused_parens_remove_json_suggestion.stderr4
-rw-r--r--src/test/ui/macros/macro-name-typo.rs4
-rw-r--r--src/test/ui/macros/macro-name-typo.stderr2
-rw-r--r--src/test/ui/macros/macro-path-prelude-fail-3.rs4
-rw-r--r--src/test/ui/macros/macro-path-prelude-fail-3.stderr2
-rw-r--r--src/test/ui/macros/unknown-builtin.rs5
-rw-r--r--src/test/ui/macros/unknown-builtin.stderr2
-rw-r--r--src/test/ui/malformed/malformed-regressions.stderr4
-rw-r--r--src/test/ui/mismatched_types/issue-36053-2.rs4
-rw-r--r--src/test/ui/mismatched_types/issue-36053-2.stderr20
-rw-r--r--src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr7
-rw-r--r--src/test/ui/nll/outlives-suggestion-simple.polonius.stderr10
-rw-r--r--src/test/ui/nll/user-annotations/closure-substs.polonius.stderr2
-rw-r--r--src/test/ui/no-send-res-ports.rs4
-rw-r--r--src/test/ui/no-send-res-ports.stderr8
-rw-r--r--src/test/ui/non-copyable-void.rs5
-rw-r--r--src/test/ui/non-copyable-void.stderr2
-rw-r--r--src/test/ui/noncopyable-class.rs5
-rw-r--r--src/test/ui/noncopyable-class.stderr2
-rw-r--r--src/test/ui/once-cant-call-twice-on-heap.stderr7
-rw-r--r--src/test/ui/parser/issue-62894.rs5
-rw-r--r--src/test/ui/parser/issue-62894.stderr8
-rw-r--r--src/test/ui/parser/issue-63116.stderr2
-rw-r--r--src/test/ui/parser/issue-70549-resolve-after-recovered-self-ctor.rs18
-rw-r--r--src/test/ui/parser/issue-70549-resolve-after-recovered-self-ctor.stderr56
-rw-r--r--src/test/ui/parser/issue-70552-ascription-in-parens-after-call.rs3
-rw-r--r--src/test/ui/parser/issue-70552-ascription-in-parens-after-call.stderr8
-rw-r--r--src/test/ui/parser/raw-str-unbalanced.rs4
-rw-r--r--src/test/ui/parser/raw-str-unbalanced.stderr8
-rw-r--r--src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.rs5
-rw-r--r--src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.stderr9
-rw-r--r--src/test/ui/parser/raw/raw-byte-string-eof.rs (renamed from src/test/ui/parser/raw-byte-string-eof.rs)0
-rw-r--r--src/test/ui/parser/raw/raw-byte-string-eof.stderr (renamed from src/test/ui/parser/raw-byte-string-eof.stderr)4
-rw-r--r--src/test/ui/parser/raw/raw-byte-string-literals.rs (renamed from src/test/ui/parser/raw-byte-string-literals.rs)0
-rw-r--r--src/test/ui/parser/raw/raw-byte-string-literals.stderr (renamed from src/test/ui/parser/raw-byte-string-literals.stderr)0
-rw-r--r--src/test/ui/parser/raw/raw-str-delim.rs (renamed from src/test/ui/parser/raw-str-delim.rs)0
-rw-r--r--src/test/ui/parser/raw/raw-str-delim.stderr (renamed from src/test/ui/parser/raw-str-delim.stderr)0
-rw-r--r--src/test/ui/parser/raw/raw-str-in-macro-call.rs14
-rw-r--r--src/test/ui/parser/raw/raw-str-unbalanced.rs4
-rw-r--r--src/test/ui/parser/raw/raw-str-unbalanced.stderr10
-rw-r--r--src/test/ui/parser/raw/raw-str-unterminated.rs (renamed from src/test/ui/parser/raw-str-unterminated.rs)0
-rw-r--r--src/test/ui/parser/raw/raw-str-unterminated.stderr (renamed from src/test/ui/parser/raw-str-unterminated.stderr)0
-rw-r--r--src/test/ui/parser/raw/raw-string-2.rs4
-rw-r--r--src/test/ui/parser/raw/raw-string-2.stderr11
-rw-r--r--src/test/ui/parser/raw/raw-string.rs (renamed from src/test/ui/parser/raw/raw_string.rs)0
-rw-r--r--src/test/ui/parser/raw/raw-string.stderr (renamed from src/test/ui/parser/raw/raw_string.stderr)6
-rw-r--r--src/test/ui/parser/recover-const-async-fn-ptr.rs25
-rw-r--r--src/test/ui/parser/recover-const-async-fn-ptr.stderr155
-rw-r--r--src/test/ui/pattern/usefulness/match-arm-statics-2.rs5
-rw-r--r--src/test/ui/pattern/usefulness/match-arm-statics-2.stderr6
-rw-r--r--src/test/ui/pattern/usefulness/match-privately-empty.rs5
-rw-r--r--src/test/ui/pattern/usefulness/match-privately-empty.stderr2
-rw-r--r--src/test/ui/pattern/usefulness/non-exhaustive-match.rs5
-rw-r--r--src/test/ui/pattern/usefulness/non-exhaustive-match.stderr16
-rw-r--r--src/test/ui/phantom-oibit.stderr18
-rw-r--r--src/test/ui/proc-macro/parent-source-spans.rs4
-rw-r--r--src/test/ui/proc-macro/parent-source-spans.stderr42
-rw-r--r--src/test/ui/proc-macro/resolve-error.rs4
-rw-r--r--src/test/ui/proc-macro/resolve-error.stderr28
-rw-r--r--src/test/ui/range.rs2
-rw-r--r--src/test/ui/range_inclusive.rs2
-rw-r--r--src/test/ui/realloc-16687.rs88
-rw-r--r--src/test/ui/recursion/recursive-types-are-not-uninhabited.rs5
-rw-r--r--src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr2
-rw-r--r--src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr4
-rw-r--r--src/test/ui/regions/regions-mock-codegen.rs16
-rw-r--r--src/test/ui/resolve/levenshtein.rs4
-rw-r--r--src/test/ui/resolve/levenshtein.stderr16
-rw-r--r--src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs4
-rw-r--r--src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr2
-rw-r--r--src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr7
-rw-r--r--src/test/ui/specialization/issue-70442.rs23
-rw-r--r--src/test/ui/stability-in-private-module.rs5
-rw-r--r--src/test/ui/stability-in-private-module.stderr2
-rw-r--r--src/test/ui/structs-enums/empty-tag.rs1
-rw-r--r--src/test/ui/structs-enums/rec-align-u64.rs7
-rw-r--r--src/test/ui/suggestions/attribute-typos.rs4
-rw-r--r--src/test/ui/suggestions/attribute-typos.stderr8
-rw-r--r--src/test/ui/suggestions/const-no-type.rs5
-rw-r--r--src/test/ui/suggestions/const-no-type.stderr12
-rw-r--r--src/test/ui/suggestions/imm-ref-trait-object.rs5
-rw-r--r--src/test/ui/suggestions/imm-ref-trait-object.stderr2
-rw-r--r--src/test/ui/suggestions/mut-borrow-needed-by-trait.rs4
-rw-r--r--src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr8
-rw-r--r--src/test/ui/suggestions/restrict-type-argument.stderr42
-rw-r--r--src/test/ui/traits/impl_trait_as_trait_return_position.rs17
-rw-r--r--src/test/ui/traits/trait-alias/trait-alias-object-fail.rs5
-rw-r--r--src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr4
-rw-r--r--src/test/ui/traits/trait-alias/trait-alias-wf.stderr7
-rw-r--r--src/test/ui/traits/trait-bounds-on-structs-and-enums.stderr21
-rw-r--r--src/test/ui/traits/trait-suggest-where-clause.rs4
-rw-r--r--src/test/ui/traits/trait-suggest-where-clause.stderr14
-rw-r--r--src/test/ui/traits/traits-repeated-supertrait-ambig.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/assoc-type-const.rs8
-rw-r--r--src/test/ui/type-alias-impl-trait/bound_reduction2.stderr7
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr9
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr18
-rw-r--r--src/test/ui/type/type-check-defaults.stderr7
-rw-r--r--src/test/ui/type_length_limit.rs4
-rw-r--r--src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr7
-rw-r--r--src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs5
-rw-r--r--src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr14
-rw-r--r--src/test/ui/union/union-derive-clone.rs5
-rw-r--r--src/test/ui/union/union-derive-clone.stderr4
-rw-r--r--src/test/ui/unique-object-noncopyable.rs4
-rw-r--r--src/test/ui/unique-object-noncopyable.stderr2
-rw-r--r--src/test/ui/unique-pinned-nocopy.rs4
-rw-r--r--src/test/ui/unique-pinned-nocopy.stderr2
-rw-r--r--src/test/ui/unop-move-semantics.stderr7
-rw-r--r--src/test/ui/unsized-locals/unsized-exprs-rpass.rs3
-rw-r--r--src/test/ui/weird-exprs.rs2
-rw-r--r--src/test/ui/wf/wf-enum-bound.stderr7
-rw-r--r--src/test/ui/wf/wf-enum-fields-struct-variant.stderr7
-rw-r--r--src/test/ui/wf/wf-enum-fields.stderr7
-rw-r--r--src/test/ui/wf/wf-fn-where-clause.stderr7
-rw-r--r--src/test/ui/wf/wf-impl-associated-type-trait.stderr7
-rw-r--r--src/test/ui/wf/wf-in-fn-arg.stderr7
-rw-r--r--src/test/ui/wf/wf-in-fn-ret.stderr7
-rw-r--r--src/test/ui/wf/wf-in-fn-type-arg.stderr7
-rw-r--r--src/test/ui/wf/wf-in-fn-type-ret.stderr7
-rw-r--r--src/test/ui/wf/wf-in-fn-where-clause.stderr7
-rw-r--r--src/test/ui/wf/wf-in-obj-type-trait.stderr7
-rw-r--r--src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr7
-rw-r--r--src/test/ui/wf/wf-inherent-impl-where-clause.stderr7
-rw-r--r--src/test/ui/wf/wf-struct-bound.stderr7
-rw-r--r--src/test/ui/wf/wf-struct-field.stderr7
-rw-r--r--src/test/ui/wf/wf-trait-associated-type-bound.stderr7
-rw-r--r--src/test/ui/wf/wf-trait-bound.stderr7
-rw-r--r--src/test/ui/wf/wf-trait-superbound.stderr7
-rw-r--r--src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr7
-rw-r--r--src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr7
-rw-r--r--src/test/ui/zero-sized/zero-sized-tuple-struct.rs1
-rw-r--r--src/tools/build-manifest/src/main.rs2
m---------src/tools/cargo0
-rw-r--r--src/tools/cargotest/main.rs7
m---------src/tools/clippy20
-rw-r--r--src/tools/compiletest/src/runtest.rs24
m---------src/tools/miri14
-rw-r--r--src/tools/rustdoc-js-common/lib.js319
-rw-r--r--src/tools/rustdoc-js-std/tester.js320
-rw-r--r--src/tools/rustdoc-js/tester.js301
-rw-r--r--src/tools/tidy/src/deps.rs2
1103 files changed, 11520 insertions, 10030 deletions
diff --git a/.github/ISSUE_TEMPLATE/ice.md b/.github/ISSUE_TEMPLATE/ice.md
index e669e4912f8..03bc4bab451 100644
--- a/.github/ISSUE_TEMPLATE/ice.md
+++ b/.github/ISSUE_TEMPLATE/ice.md
@@ -14,7 +14,7 @@ http://blog.pnkfx.org/blog/2019/11/18/rust-bug-minimization-patterns/
 
 ### Code
 
-```
+```Rust
 <code>
 ```
 
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d1261f04b82..fd3da15a21b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -63,7 +63,7 @@ jobs:
         uses: rust-lang/simpleinfra/github-actions/cancel-outdated-builds@master
         with:
           github_token: "${{ secrets.github_token }}"
-        if: success() && !env.SKIP_JOB
+        if: "success() && !env.SKIP_JOB && github.ref != 'refs/heads/try'"
       - name: add extra environment variables
         run: src/ci/scripts/setup-environment.sh
         env:
@@ -196,7 +196,7 @@ jobs:
         uses: rust-lang/simpleinfra/github-actions/cancel-outdated-builds@master
         with:
           github_token: "${{ secrets.github_token }}"
-        if: success() && !env.SKIP_JOB
+        if: "success() && !env.SKIP_JOB && github.ref != 'refs/heads/try'"
       - name: add extra environment variables
         run: src/ci/scripts/setup-environment.sh
         env:
@@ -626,7 +626,7 @@ jobs:
         uses: rust-lang/simpleinfra/github-actions/cancel-outdated-builds@master
         with:
           github_token: "${{ secrets.github_token }}"
-        if: success() && !env.SKIP_JOB
+        if: "success() && !env.SKIP_JOB && github.ref != 'refs/heads/try'"
       - name: add extra environment variables
         run: src/ci/scripts/setup-environment.sh
         env:
diff --git a/Cargo.lock b/Cargo.lock
index e51eded2200..5b07f4b5492 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2522,9 +2522,9 @@ checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
 
 [[package]]
 name = "polonius-engine"
-version = "0.12.0"
+version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04d8ef65e3f89ecaec9ca7cb0e0911b4617352d4494018bcf934992f03f2024c"
+checksum = "ef2558a4b464e185b36ee08a2937ebb62ea5464c38856cfb1465c97cb38db52d"
 dependencies = [
  "datafrog",
  "log",
@@ -3133,39 +3133,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "rustc"
-version = "0.0.0"
-dependencies = [
- "arena",
- "backtrace",
- "bitflags",
- "byteorder",
- "jobserver",
- "log",
- "measureme",
- "parking_lot 0.10.0",
- "polonius-engine",
- "rustc-rayon",
- "rustc-rayon-core",
- "rustc_apfloat",
- "rustc_ast",
- "rustc_attr",
- "rustc_data_structures",
- "rustc_errors",
- "rustc_feature",
- "rustc_hir",
- "rustc_index",
- "rustc_macros",
- "rustc_query_system",
- "rustc_session",
- "rustc_span",
- "rustc_target",
- "scoped-tls",
- "serialize",
- "smallvec 1.0.0",
-]
-
-[[package]]
 name = "rustc-ap-arena"
 version = "642.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3603,7 +3570,6 @@ dependencies = [
  "libc",
  "log",
  "measureme",
- "rustc",
  "rustc-demangle",
  "rustc_ast",
  "rustc_attr",
@@ -3616,6 +3582,7 @@ dependencies = [
  "rustc_incremental",
  "rustc_index",
  "rustc_llvm",
+ "rustc_middle",
  "rustc_session",
  "rustc_span",
  "rustc_target",
@@ -3634,7 +3601,6 @@ dependencies = [
  "log",
  "memmap",
  "num_cpus",
- "rustc",
  "rustc_apfloat",
  "rustc_ast",
  "rustc_attr",
@@ -3645,6 +3611,7 @@ dependencies = [
  "rustc_incremental",
  "rustc_index",
  "rustc_metadata",
+ "rustc_middle",
  "rustc_session",
  "rustc_span",
  "rustc_symbol_mangling",
@@ -3685,7 +3652,6 @@ dependencies = [
  "env_logger 0.7.1",
  "lazy_static 1.4.0",
  "log",
- "rustc",
  "rustc_ast",
  "rustc_ast_pretty",
  "rustc_codegen_ssa",
@@ -3698,6 +3664,7 @@ dependencies = [
  "rustc_interface",
  "rustc_lint",
  "rustc_metadata",
+ "rustc_middle",
  "rustc_mir",
  "rustc_parse",
  "rustc_plugin_impl",
@@ -3797,11 +3764,11 @@ dependencies = [
  "graphviz",
  "log",
  "rand 0.7.3",
- "rustc",
  "rustc_ast",
  "rustc_data_structures",
  "rustc_fs_util",
  "rustc_hir",
+ "rustc_middle",
  "rustc_session",
  "rustc_span",
  "serialize",
@@ -3821,13 +3788,13 @@ version = "0.0.0"
 dependencies = [
  "graphviz",
  "log",
- "rustc",
  "rustc_ast",
  "rustc_data_structures",
  "rustc_errors",
  "rustc_hir",
  "rustc_index",
  "rustc_macros",
+ "rustc_middle",
  "rustc_session",
  "rustc_span",
  "rustc_target",
@@ -3840,7 +3807,6 @@ version = "0.0.0"
 dependencies = [
  "log",
  "once_cell",
- "rustc",
  "rustc-rayon",
  "rustc_ast",
  "rustc_ast_lowering",
@@ -3857,6 +3823,7 @@ dependencies = [
  "rustc_infer",
  "rustc_lint",
  "rustc_metadata",
+ "rustc_middle",
  "rustc_mir",
  "rustc_mir_build",
  "rustc_parse",
@@ -3890,7 +3857,6 @@ name = "rustc_lint"
 version = "0.0.0"
 dependencies = [
  "log",
- "rustc",
  "rustc_ast",
  "rustc_ast_pretty",
  "rustc_attr",
@@ -3900,6 +3866,7 @@ dependencies = [
  "rustc_hir",
  "rustc_index",
  "rustc_infer",
+ "rustc_middle",
  "rustc_session",
  "rustc_span",
  "rustc_target",
@@ -3933,7 +3900,6 @@ dependencies = [
  "flate2",
  "log",
  "memmap",
- "rustc",
  "rustc_ast",
  "rustc_attr",
  "rustc_data_structures",
@@ -3942,6 +3908,7 @@ dependencies = [
  "rustc_hir",
  "rustc_hir_pretty",
  "rustc_index",
+ "rustc_middle",
  "rustc_session",
  "rustc_span",
  "rustc_target",
@@ -3952,6 +3919,39 @@ dependencies = [
 ]
 
 [[package]]
+name = "rustc_middle"
+version = "0.0.0"
+dependencies = [
+ "arena",
+ "backtrace",
+ "bitflags",
+ "byteorder",
+ "jobserver",
+ "log",
+ "measureme",
+ "parking_lot 0.10.0",
+ "polonius-engine",
+ "rustc-rayon",
+ "rustc-rayon-core",
+ "rustc_apfloat",
+ "rustc_ast",
+ "rustc_attr",
+ "rustc_data_structures",
+ "rustc_errors",
+ "rustc_feature",
+ "rustc_hir",
+ "rustc_index",
+ "rustc_macros",
+ "rustc_query_system",
+ "rustc_session",
+ "rustc_span",
+ "rustc_target",
+ "scoped-tls",
+ "serialize",
+ "smallvec 1.0.0",
+]
+
+[[package]]
 name = "rustc_mir"
 version = "0.0.0"
 dependencies = [
@@ -3961,7 +3961,6 @@ dependencies = [
  "log",
  "log_settings",
  "polonius-engine",
- "rustc",
  "rustc_apfloat",
  "rustc_ast",
  "rustc_ast_pretty",
@@ -3973,6 +3972,7 @@ dependencies = [
  "rustc_infer",
  "rustc_lexer",
  "rustc_macros",
+ "rustc_middle",
  "rustc_session",
  "rustc_span",
  "rustc_target",
@@ -3987,7 +3987,6 @@ version = "0.0.0"
 dependencies = [
  "arena",
  "log",
- "rustc",
  "rustc_apfloat",
  "rustc_ast",
  "rustc_attr",
@@ -3997,6 +3996,7 @@ dependencies = [
  "rustc_index",
  "rustc_infer",
  "rustc_macros",
+ "rustc_middle",
  "rustc_session",
  "rustc_span",
  "rustc_target",
@@ -4028,7 +4028,6 @@ name = "rustc_passes"
 version = "0.0.0"
 dependencies = [
  "log",
- "rustc",
  "rustc_ast",
  "rustc_attr",
  "rustc_data_structures",
@@ -4037,6 +4036,7 @@ dependencies = [
  "rustc_hir",
  "rustc_index",
  "rustc_infer",
+ "rustc_middle",
  "rustc_session",
  "rustc_span",
  "rustc_target",
@@ -4047,12 +4047,12 @@ dependencies = [
 name = "rustc_plugin_impl"
 version = "0.0.0"
 dependencies = [
- "rustc",
  "rustc_ast",
  "rustc_errors",
  "rustc_hir",
  "rustc_lint",
  "rustc_metadata",
+ "rustc_middle",
  "rustc_session",
  "rustc_span",
 ]
@@ -4062,12 +4062,12 @@ name = "rustc_privacy"
 version = "0.0.0"
 dependencies = [
  "log",
- "rustc",
  "rustc_ast",
  "rustc_attr",
  "rustc_data_structures",
  "rustc_errors",
  "rustc_hir",
+ "rustc_middle",
  "rustc_session",
  "rustc_span",
  "rustc_typeck",
@@ -4096,7 +4096,6 @@ dependencies = [
  "arena",
  "bitflags",
  "log",
- "rustc",
  "rustc_ast",
  "rustc_ast_lowering",
  "rustc_ast_pretty",
@@ -4107,6 +4106,7 @@ dependencies = [
  "rustc_feature",
  "rustc_hir",
  "rustc_metadata",
+ "rustc_middle",
  "rustc_session",
  "rustc_span",
  "smallvec 1.0.0",
@@ -4119,12 +4119,12 @@ dependencies = [
  "log",
  "rls-data",
  "rls-span",
- "rustc",
  "rustc_ast",
  "rustc_ast_pretty",
  "rustc_data_structures",
  "rustc_hir",
  "rustc_hir_pretty",
+ "rustc_middle",
  "rustc_parse",
  "rustc_session",
  "rustc_span",
@@ -4169,12 +4169,12 @@ version = "0.0.0"
 dependencies = [
  "log",
  "punycode",
- "rustc",
  "rustc-demangle",
  "rustc_ast",
  "rustc_data_structures",
  "rustc_hir",
  "rustc_metadata",
+ "rustc_middle",
  "rustc_session",
  "rustc_span",
  "rustc_target",
@@ -4209,7 +4209,6 @@ version = "0.0.0"
 dependencies = [
  "fmt_macros",
  "log",
- "rustc",
  "rustc_ast",
  "rustc_attr",
  "rustc_data_structures",
@@ -4218,6 +4217,7 @@ dependencies = [
  "rustc_index",
  "rustc_infer",
  "rustc_macros",
+ "rustc_middle",
  "rustc_session",
  "rustc_span",
  "rustc_target",
@@ -4229,12 +4229,12 @@ name = "rustc_traits"
 version = "0.0.0"
 dependencies = [
  "log",
- "rustc",
  "rustc_ast",
  "rustc_data_structures",
  "rustc_hir",
  "rustc_infer",
  "rustc_macros",
+ "rustc_middle",
  "rustc_span",
  "rustc_target",
  "rustc_trait_selection",
@@ -4246,10 +4246,10 @@ name = "rustc_ty"
 version = "0.0.0"
 dependencies = [
  "log",
- "rustc",
  "rustc_data_structures",
  "rustc_hir",
  "rustc_infer",
+ "rustc_middle",
  "rustc_session",
  "rustc_span",
  "rustc_target",
@@ -4262,7 +4262,6 @@ version = "0.0.0"
 dependencies = [
  "arena",
  "log",
- "rustc",
  "rustc_ast",
  "rustc_attr",
  "rustc_data_structures",
@@ -4270,6 +4269,7 @@ dependencies = [
  "rustc_hir",
  "rustc_index",
  "rustc_infer",
+ "rustc_middle",
  "rustc_session",
  "rustc_span",
  "rustc_target",
diff --git a/README.md b/README.md
index 1cd9b8a3a2a..6f184e25218 100644
--- a/README.md
+++ b/README.md
@@ -256,7 +256,7 @@ Also, you may find the [rustdocs for the compiler itself][rustdocs] useful.
 
 [rust-discord]: https://discord.gg/rust-lang
 [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/about-this-guide.html
-[rustdocs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/
+[rustdocs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/
 
 ## License
 
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 243cd3fa199..b14352d7f4b 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -1022,8 +1022,13 @@ impl<'a> Builder<'a> {
             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 ad494b88b3a..32ce170a5a1 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -22,7 +22,7 @@ use serde::Deserialize;
 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 @@ impl Step for Sysroot {
         };
         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 @@ pub fn stream_cargo(
     }
     // 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 56164b74f30..133709421a5 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -48,6 +48,7 @@ pub struct Config {
     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 @@ impl Config {
         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 eda26f7df1f..5d6e401d5b3 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -31,6 +31,7 @@ pub struct Flags {
     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 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
             "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 @@ Arguments:
             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 6436fa75655..31bbd92cd62 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -740,19 +740,18 @@ impl Build {
         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 @@ impl Build {
             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 5b946b05735..2499856235f 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -21,7 +21,7 @@ use crate::flags::Subcommand;
 use crate::native;
 use crate::tool::{self, SourceType, Tool};
 use crate::toolstate::ToolState;
-use crate::util::{self, dylib_path, dylib_path_var};
+use crate::util::{self, add_link_lib_path, dylib_path, dylib_path_var};
 use crate::Crate as CargoCrate;
 use crate::{envify, DocTests, GitRepo, Mode};
 
@@ -1178,6 +1178,15 @@ impl Step for Compiletest {
                 cmd.arg("--system-llvm");
             }
 
+            // Tests that use compiler libraries may inherit the `-lLLVM` link
+            // requirement, but the `-L` library path is not propagated across
+            // separate compilations. We can add LLVM's library path to the
+            // platform-specific environment variable as a workaround.
+            if !builder.config.dry_run && suite.ends_with("fulldeps") {
+                let llvm_libdir = output(Command::new(&llvm_config).arg("--libdir"));
+                add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cmd);
+            }
+
             // Only pass correct values for these flags for the `run-make` suite as it
             // requires that a C++ compiler was configured which isn't always the case.
             if !builder.config.dry_run && suite == "run-make-fulldeps" {
diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md
index 872f2c3467d..95936d65432 100644
--- a/src/ci/docker/README.md
+++ b/src/ci/docker/README.md
@@ -138,15 +138,14 @@ $category > $option = $value -- $comment
 For targets: `arm-unknown-linux-gnueabi`
 
 - Path and misc options > Prefix directory = /x-tools/${CT\_TARGET}
-- Path and misc options > Patches origin = Bundled, then local
-- Path and misc options > Local patch directory = /tmp/patches
+- Path and misc options > Patches origin = Bundled only
 - Target options > Target Architecture = arm
 - Target options > Architecture level = armv6 -- (+)
 - Target options > Floating point = software (no FPU) -- (\*)
 - Operating System > Target OS = linux
-- Operating System > Linux kernel version = 3.2.72 -- Precise kernel
-- C-library > glibc version = 2.16.0
-- C compiler > gcc version = 5.2.0
+- Operating System > Linux kernel version = 3.2.101
+- C-library > glibc version = 2.17.0
+- C compiler > gcc version = 8.3.0
 - C compiler > C++ = ENABLE -- to cross compile LLVM
 
 ### `arm-linux-gnueabihf.config`
@@ -154,17 +153,16 @@ For targets: `arm-unknown-linux-gnueabi`
 For targets: `arm-unknown-linux-gnueabihf`
 
 - Path and misc options > Prefix directory = /x-tools/${CT\_TARGET}
-- Path and misc options > Patches origin = Bundled, then local
-- Path and misc options > Local patch directory = /tmp/patches
+- Path and misc options > Patches origin = Bundled only
 - Target options > Target Architecture = arm
 - Target options > Architecture level = armv6 -- (+)
 - Target options > Use specific FPU = vfp -- (+)
 - Target options > Floating point = hardware (FPU) -- (\*)
 - Target options > Default instruction set mode = arm -- (+)
 - Operating System > Target OS = linux
-- Operating System > Linux kernel version = 3.2.72 -- Precise kernel
-- C-library > glibc version = 2.16.0
-- C compiler > gcc version = 5.2.0
+- Operating System > Linux kernel version = 3.2.101
+- C-library > glibc version = 2.17.0
+- C compiler > gcc version = 8.3.0
 - C compiler > C++ = ENABLE -- to cross compile LLVM
 
 ### `armv7-linux-gnueabihf.config`
diff --git a/src/ci/docker/dist-arm-linux/Dockerfile b/src/ci/docker/dist-arm-linux/Dockerfile
index 48851ae232c..50f7ca74e54 100644
--- a/src/ci/docker/dist-arm-linux/Dockerfile
+++ b/src/ci/docker/dist-arm-linux/Dockerfile
@@ -3,20 +3,14 @@ FROM ubuntu:16.04
 COPY scripts/cross-apt-packages.sh /scripts/
 RUN sh /scripts/cross-apt-packages.sh
 
-# Ubuntu 16.04 (this container) ships with make 4, but something in the
-# toolchains we build below chokes on that, so go back to make 3
-COPY scripts/make3.sh /scripts/
-RUN sh /scripts/make3.sh
-
-COPY scripts/crosstool-ng.sh /scripts/
-RUN sh /scripts/crosstool-ng.sh
+COPY scripts/crosstool-ng-1.24.sh /scripts/
+RUN sh /scripts/crosstool-ng-1.24.sh
 
 COPY scripts/rustbuild-setup.sh /scripts/
 RUN sh /scripts/rustbuild-setup.sh
 USER rustbuild
 WORKDIR /tmp
 
-COPY dist-arm-linux/patches/ /tmp/patches/
 COPY dist-arm-linux/arm-linux-gnueabi.config dist-arm-linux/build-toolchains.sh /tmp/
 RUN ./build-toolchains.sh
 
diff --git a/src/ci/docker/dist-arm-linux/arm-linux-gnueabi.config b/src/ci/docker/dist-arm-linux/arm-linux-gnueabi.config
index 4185112d8be..1dcdbd1a900 100644
--- a/src/ci/docker/dist-arm-linux/arm-linux-gnueabi.config
+++ b/src/ci/docker/dist-arm-linux/arm-linux-gnueabi.config
@@ -1,9 +1,29 @@
 #
 # Automatically generated file; DO NOT EDIT.
-# Crosstool-NG Configuration
-#
-CT_CONFIGURE_has_make381=y
-CT_CONFIGURE_has_xz=y
+# crosstool-NG  Configuration
+#
+CT_CONFIGURE_has_static_link=y
+CT_CONFIGURE_has_cxx11=y
+CT_CONFIGURE_has_wget=y
+CT_CONFIGURE_has_curl=y
+CT_CONFIGURE_has_make_3_81_or_newer=y
+CT_CONFIGURE_has_make_4_0_or_newer=y
+CT_CONFIGURE_has_libtool_2_4_or_newer=y
+CT_CONFIGURE_has_libtoolize_2_4_or_newer=y
+CT_CONFIGURE_has_autoconf_2_65_or_newer=y
+CT_CONFIGURE_has_autoreconf_2_65_or_newer=y
+CT_CONFIGURE_has_automake_1_15_or_newer=y
+CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y
+CT_CONFIGURE_has_bison_2_7_or_newer=y
+CT_CONFIGURE_has_python=y
+CT_CONFIGURE_has_git=y
+CT_CONFIGURE_has_md5sum=y
+CT_CONFIGURE_has_sha1sum=y
+CT_CONFIGURE_has_sha256sum=y
+CT_CONFIGURE_has_sha512sum=y
+CT_CONFIGURE_has_install_with_strip_program=y
+CT_CONFIG_VERSION_CURRENT="3"
+CT_CONFIG_VERSION="3"
 CT_MODULES=y
 
 #
@@ -20,41 +40,48 @@ CT_MODULES=y
 #
 # Paths
 #
-CT_LOCAL_TARBALLS_DIR=""
+CT_LOCAL_TARBALLS_DIR="${HOME}/src"
+CT_SAVE_TARBALLS=y
+# CT_TARBALLS_BUILDROOT_LAYOUT is not set
 CT_WORK_DIR="${CT_TOP_DIR}/.build"
+CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}"
 CT_PREFIX_DIR="/x-tools/${CT_TARGET}"
-CT_INSTALL_DIR="${CT_PREFIX_DIR}"
 CT_RM_RF_PREFIX_DIR=y
 CT_REMOVE_DOCS=y
-CT_INSTALL_DIR_RO=y
+CT_INSTALL_LICENSES=y
+CT_PREFIX_DIR_RO=y
 CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y
 # CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set
 
 #
 # Downloading
 #
+CT_DOWNLOAD_AGENT_WGET=y
+# CT_DOWNLOAD_AGENT_CURL is not set
+# CT_DOWNLOAD_AGENT_NONE is not set
 # CT_FORBID_DOWNLOAD is not set
 # CT_FORCE_DOWNLOAD is not set
 CT_CONNECT_TIMEOUT=10
+CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary"
 # CT_ONLY_DOWNLOAD is not set
 # CT_USE_MIRROR is not set
+CT_VERIFY_DOWNLOAD_DIGEST=y
+CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y
+# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set
+# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set
+# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set
+CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512"
+# CT_VERIFY_DOWNLOAD_SIGNATURE is not set
 
 #
 # Extracting
 #
 # CT_FORCE_EXTRACT is not set
-CT_OVERIDE_CONFIG_GUESS_SUB=y
+CT_OVERRIDE_CONFIG_GUESS_SUB=y
 # CT_ONLY_EXTRACT is not set
-# CT_PATCH_BUNDLED is not set
-# CT_PATCH_LOCAL is not set
-CT_PATCH_BUNDLED_LOCAL=y
-# CT_PATCH_LOCAL_BUNDLED is not set
-# CT_PATCH_BUNDLED_FALLBACK_LOCAL is not set
-# CT_PATCH_LOCAL_FALLBACK_BUNDLED is not set
-# CT_PATCH_NONE is not set
-CT_PATCH_ORDER="bundled,local"
-CT_PATCH_USE_LOCAL=y
-CT_LOCAL_PATCH_DIR="/tmp/patches"
+CT_PATCH_BUNDLED=y
+# CT_PATCH_BUNDLED_LOCAL is not set
+CT_PATCH_ORDER="bundled"
 
 #
 # Build behavior
@@ -77,11 +104,11 @@ CT_CONFIG_SHELL="${bash}"
 #
 # CT_LOG_ERROR is not set
 # CT_LOG_WARN is not set
-CT_LOG_INFO=y
-# CT_LOG_EXTRA is not set
+# CT_LOG_INFO is not set
+CT_LOG_EXTRA=y
 # CT_LOG_ALL is not set
 # CT_LOG_DEBUG is not set
-CT_LOG_LEVEL_MAX="INFO"
+CT_LOG_LEVEL_MAX="EXTRA"
 # CT_LOG_SEE_TOOLS_WARN is not set
 CT_LOG_PROGRESS_BAR=y
 CT_LOG_TO_FILE=y
@@ -90,86 +117,87 @@ CT_LOG_FILE_COMPRESS=y
 #
 # Target options
 #
+# CT_ARCH_ALPHA is not set
+# CT_ARCH_ARC is not set
+CT_ARCH_ARM=y
+# CT_ARCH_AVR is not set
+# CT_ARCH_M68K is not set
+# CT_ARCH_MIPS is not set
+# CT_ARCH_NIOS2 is not set
+# CT_ARCH_POWERPC is not set
+# CT_ARCH_S390 is not set
+# CT_ARCH_SH is not set
+# CT_ARCH_SPARC is not set
+# CT_ARCH_X86 is not set
+# CT_ARCH_XTENSA is not set
 CT_ARCH="arm"
-CT_ARCH_SUPPORTS_BOTH_MMU=y
-CT_ARCH_SUPPORTS_BOTH_ENDIAN=y
-CT_ARCH_SUPPORTS_32=y
-CT_ARCH_SUPPORTS_64=y
-CT_ARCH_SUPPORTS_WITH_ARCH=y
-CT_ARCH_SUPPORTS_WITH_CPU=y
-CT_ARCH_SUPPORTS_WITH_TUNE=y
-CT_ARCH_SUPPORTS_WITH_FLOAT=y
-CT_ARCH_SUPPORTS_WITH_FPU=y
-CT_ARCH_SUPPORTS_SOFTFP=y
-CT_ARCH_DEFAULT_HAS_MMU=y
-CT_ARCH_DEFAULT_LE=y
-CT_ARCH_DEFAULT_32=y
-CT_ARCH_ARCH="armv6"
+CT_ARCH_CHOICE_KSYM="ARM"
+# CT_ARCH_ALPHA_EV4 is not set
+# CT_ARCH_ALPHA_EV45 is not set
+# CT_ARCH_ALPHA_EV5 is not set
+# CT_ARCH_ALPHA_EV56 is not set
+# CT_ARCH_ALPHA_EV6 is not set
+# CT_ARCH_ALPHA_EV67 is not set
 CT_ARCH_CPU=""
 CT_ARCH_TUNE=""
-CT_ARCH_FPU=""
-# CT_ARCH_BE is not set
-CT_ARCH_LE=y
-CT_ARCH_32=y
-# CT_ARCH_64 is not set
-CT_ARCH_BITNESS=32
-# CT_ARCH_FLOAT_HW is not set
-CT_ARCH_FLOAT_SW=y
-CT_TARGET_CFLAGS=""
-CT_TARGET_LDFLAGS=""
-# CT_ARCH_alpha is not set
-CT_ARCH_arm=y
-# CT_ARCH_avr is not set
-# CT_ARCH_m68k is not set
-# CT_ARCH_mips is not set
-# CT_ARCH_nios2 is not set
-# CT_ARCH_powerpc is not set
-# CT_ARCH_s390 is not set
-# CT_ARCH_sh is not set
-# CT_ARCH_sparc is not set
-# CT_ARCH_x86 is not set
-# CT_ARCH_xtensa is not set
-CT_ARCH_alpha_AVAILABLE=y
-CT_ARCH_arm_AVAILABLE=y
-CT_ARCH_avr_AVAILABLE=y
-CT_ARCH_m68k_AVAILABLE=y
-CT_ARCH_microblaze_AVAILABLE=y
-CT_ARCH_mips_AVAILABLE=y
-CT_ARCH_nios2_AVAILABLE=y
-CT_ARCH_powerpc_AVAILABLE=y
-CT_ARCH_s390_AVAILABLE=y
-CT_ARCH_sh_AVAILABLE=y
-CT_ARCH_sparc_AVAILABLE=y
-CT_ARCH_x86_AVAILABLE=y
-CT_ARCH_xtensa_AVAILABLE=y
+CT_ARCH_ARM_SHOW=y
+
+#
+# Options for arm
+#
+CT_ARCH_ARM_PKG_KSYM=""
+CT_ARCH_ARM_MODE="arm"
+CT_ARCH_ARM_MODE_ARM=y
+# CT_ARCH_ARM_MODE_THUMB is not set
+# CT_ARCH_ARM_INTERWORKING is not set
+CT_ARCH_ARM_EABI_FORCE=y
+CT_ARCH_ARM_EABI=y
+CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA"
 CT_ARCH_SUFFIX=""
+# CT_OMIT_TARGET_VENDOR is not set
 
 #
 # Generic target options
 #
 # CT_MULTILIB is not set
+CT_DEMULTILIB=y
+CT_ARCH_SUPPORTS_BOTH_MMU=y
+CT_ARCH_DEFAULT_HAS_MMU=y
 CT_ARCH_USE_MMU=y
+CT_ARCH_SUPPORTS_FLAT_FORMAT=y
+CT_ARCH_SUPPORTS_EITHER_ENDIAN=y
+CT_ARCH_DEFAULT_LE=y
+# CT_ARCH_BE is not set
+CT_ARCH_LE=y
 CT_ARCH_ENDIAN="little"
+CT_ARCH_SUPPORTS_32=y
+CT_ARCH_SUPPORTS_64=y
+CT_ARCH_DEFAULT_32=y
+CT_ARCH_BITNESS=32
+CT_ARCH_32=y
+# CT_ARCH_64 is not set
 
 #
 # Target optimisations
 #
+CT_ARCH_SUPPORTS_WITH_ARCH=y
+CT_ARCH_SUPPORTS_WITH_CPU=y
+CT_ARCH_SUPPORTS_WITH_TUNE=y
+CT_ARCH_SUPPORTS_WITH_FLOAT=y
+CT_ARCH_SUPPORTS_WITH_FPU=y
+CT_ARCH_SUPPORTS_SOFTFP=y
 CT_ARCH_EXCLUSIVE_WITH_CPU=y
+CT_ARCH_ARCH="armv6"
+CT_ARCH_FPU=""
 # CT_ARCH_FLOAT_AUTO is not set
+# CT_ARCH_FLOAT_HW is not set
 # CT_ARCH_FLOAT_SOFTFP is not set
+CT_ARCH_FLOAT_SW=y
+CT_TARGET_CFLAGS=""
+CT_TARGET_LDFLAGS=""
 CT_ARCH_FLOAT="soft"
 
 #
-# arm other options
-#
-CT_ARCH_ARM_MODE="arm"
-CT_ARCH_ARM_MODE_ARM=y
-# CT_ARCH_ARM_MODE_THUMB is not set
-# CT_ARCH_ARM_INTERWORKING is not set
-CT_ARCH_ARM_EABI_FORCE=y
-CT_ARCH_ARM_EABI=y
-
-#
 # Toolchain options
 #
 
@@ -181,7 +209,9 @@ CT_USE_SYSROOT=y
 CT_SYSROOT_NAME="sysroot"
 CT_SYSROOT_DIR_PREFIX=""
 CT_WANTS_STATIC_LINK=y
+CT_WANTS_STATIC_LINK_CXX=y
 # CT_STATIC_TOOLCHAIN is not set
+CT_SHOW_CT_VERSION=y
 CT_TOOLCHAIN_PKGVERSION=""
 CT_TOOLCHAIN_BUGURL=""
 
@@ -215,126 +245,215 @@ CT_BUILD_SUFFIX=""
 # Operating System
 #
 CT_KERNEL_SUPPORTS_SHARED_LIBS=y
+# CT_KERNEL_BARE_METAL is not set
+CT_KERNEL_LINUX=y
 CT_KERNEL="linux"
-CT_KERNEL_VERSION="3.2.72"
-# CT_KERNEL_bare_metal is not set
-CT_KERNEL_linux=y
-CT_KERNEL_bare_metal_AVAILABLE=y
-CT_KERNEL_linux_AVAILABLE=y
-# CT_KERNEL_V_4_3 is not set
-# CT_KERNEL_V_4_2 is not set
-# CT_KERNEL_V_4_1 is not set
-# CT_KERNEL_V_3_18 is not set
-# CT_KERNEL_V_3_14 is not set
-# CT_KERNEL_V_3_12 is not set
-# CT_KERNEL_V_3_10 is not set
-# CT_KERNEL_V_3_4 is not set
-CT_KERNEL_V_3_2=y
-# CT_KERNEL_V_2_6_32 is not set
-# CT_KERNEL_LINUX_CUSTOM is not set
-CT_KERNEL_windows_AVAILABLE=y
-
-#
-# Common kernel options
-#
-CT_SHARED_LIBS=y
-
-#
-# linux other options
-#
+CT_KERNEL_CHOICE_KSYM="LINUX"
+CT_KERNEL_LINUX_SHOW=y
+
+#
+# Options for linux
+#
+CT_KERNEL_LINUX_PKG_KSYM="LINUX"
+CT_LINUX_DIR_NAME="linux"
+CT_LINUX_PKG_NAME="linux"
+CT_LINUX_SRC_RELEASE=y
+CT_LINUX_PATCH_ORDER="global"
+# CT_LINUX_V_4_20 is not set
+# CT_LINUX_V_4_19 is not set
+# CT_LINUX_V_4_18 is not set
+# CT_LINUX_V_4_17 is not set
+# CT_LINUX_V_4_16 is not set
+# CT_LINUX_V_4_15 is not set
+# CT_LINUX_V_4_14 is not set
+# CT_LINUX_V_4_13 is not set
+# CT_LINUX_V_4_12 is not set
+# CT_LINUX_V_4_11 is not set
+# CT_LINUX_V_4_10 is not set
+# CT_LINUX_V_4_9 is not set
+# CT_LINUX_V_4_4 is not set
+# CT_LINUX_V_4_1 is not set
+# CT_LINUX_V_3_16 is not set
+# CT_LINUX_V_3_13 is not set
+# CT_LINUX_V_3_12 is not set
+# CT_LINUX_V_3_10 is not set
+# CT_LINUX_V_3_4 is not set
+CT_LINUX_V_3_2=y
+# CT_LINUX_V_2_6_32 is not set
+# CT_LINUX_NO_VERSIONS is not set
+CT_LINUX_VERSION="3.2.101"
+CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})"
+CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz"
+CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign"
+CT_LINUX_4_8_or_older=y
+CT_LINUX_older_than_4_8=y
+CT_LINUX_3_7_or_older=y
+CT_LINUX_older_than_3_7=y
+CT_LINUX_later_than_3_2=y
+CT_LINUX_3_2_or_later=y
 CT_KERNEL_LINUX_VERBOSITY_0=y
 # CT_KERNEL_LINUX_VERBOSITY_1 is not set
 # CT_KERNEL_LINUX_VERBOSITY_2 is not set
 CT_KERNEL_LINUX_VERBOSE_LEVEL=0
 CT_KERNEL_LINUX_INSTALL_CHECK=y
+CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS"
+
+#
+# Common kernel options
+#
+CT_SHARED_LIBS=y
 
 #
 # Binary utilities
 #
 CT_ARCH_BINFMT_ELF=y
+CT_BINUTILS_BINUTILS=y
 CT_BINUTILS="binutils"
-CT_BINUTILS_binutils=y
+CT_BINUTILS_CHOICE_KSYM="BINUTILS"
+CT_BINUTILS_BINUTILS_SHOW=y
+
+#
+# Options for binutils
+#
+CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS"
+CT_BINUTILS_DIR_NAME="binutils"
+CT_BINUTILS_USE_GNU=y
+CT_BINUTILS_USE="BINUTILS"
+CT_BINUTILS_PKG_NAME="binutils"
+CT_BINUTILS_SRC_RELEASE=y
+CT_BINUTILS_PATCH_ORDER="global"
+CT_BINUTILS_V_2_32=y
+# CT_BINUTILS_V_2_31 is not set
+# CT_BINUTILS_V_2_30 is not set
+# CT_BINUTILS_V_2_29 is not set
+# CT_BINUTILS_V_2_28 is not set
+# CT_BINUTILS_V_2_27 is not set
+# CT_BINUTILS_V_2_26 is not set
+# CT_BINUTILS_NO_VERSIONS is not set
+CT_BINUTILS_VERSION="2.32"
+CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)"
+CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
+CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig"
+CT_BINUTILS_later_than_2_30=y
+CT_BINUTILS_2_30_or_later=y
+CT_BINUTILS_later_than_2_27=y
+CT_BINUTILS_2_27_or_later=y
+CT_BINUTILS_later_than_2_25=y
+CT_BINUTILS_2_25_or_later=y
+CT_BINUTILS_later_than_2_23=y
+CT_BINUTILS_2_23_or_later=y
 
 #
 # GNU binutils
 #
-# CT_CC_BINUTILS_SHOW_LINARO is not set
-CT_BINUTILS_V_2_25_1=y
-# CT_BINUTILS_V_2_25 is not set
-# CT_BINUTILS_V_2_24 is not set
-# CT_BINUTILS_V_2_23_2 is not set
-# CT_BINUTILS_V_2_23_1 is not set
-# CT_BINUTILS_V_2_22 is not set
-# CT_BINUTILS_V_2_21_53 is not set
-# CT_BINUTILS_V_2_21_1a is not set
-# CT_BINUTILS_V_2_20_1a is not set
-# CT_BINUTILS_V_2_19_1a is not set
-# CT_BINUTILS_V_2_18a is not set
-CT_BINUTILS_VERSION="2.25.1"
-CT_BINUTILS_2_25_1_or_later=y
-CT_BINUTILS_2_25_or_later=y
-CT_BINUTILS_2_24_or_later=y
-CT_BINUTILS_2_23_or_later=y
-CT_BINUTILS_2_22_or_later=y
-CT_BINUTILS_2_21_or_later=y
-CT_BINUTILS_2_20_or_later=y
-CT_BINUTILS_2_19_or_later=y
-CT_BINUTILS_2_18_or_later=y
 CT_BINUTILS_HAS_HASH_STYLE=y
 CT_BINUTILS_HAS_GOLD=y
-CT_BINUTILS_GOLD_SUPPORTS_ARCH=y
-CT_BINUTILS_GOLD_SUPPORT=y
 CT_BINUTILS_HAS_PLUGINS=y
 CT_BINUTILS_HAS_PKGVERSION_BUGURL=y
-CT_BINUTILS_FORCE_LD_BFD=y
+CT_BINUTILS_GOLD_SUPPORTS_ARCH=y
+CT_BINUTILS_GOLD_SUPPORT=y
+CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y
 CT_BINUTILS_LINKER_LD=y
 # CT_BINUTILS_LINKER_LD_GOLD is not set
-# CT_BINUTILS_LINKER_GOLD_LD is not set
 CT_BINUTILS_LINKERS_LIST="ld"
 CT_BINUTILS_LINKER_DEFAULT="bfd"
 # CT_BINUTILS_PLUGINS is not set
+CT_BINUTILS_RELRO=m
 CT_BINUTILS_EXTRA_CONFIG_ARRAY=""
 # CT_BINUTILS_FOR_TARGET is not set
-
-#
-# binutils other options
-#
+CT_ALL_BINUTILS_CHOICES="BINUTILS"
 
 #
 # C-library
 #
+CT_LIBC_GLIBC=y
+# CT_LIBC_NEWLIB is not set
+# CT_LIBC_NONE is not set
+# CT_LIBC_UCLIBC is not set
 CT_LIBC="glibc"
-CT_LIBC_VERSION="2.16.0"
-CT_LIBC_glibc=y
-# CT_LIBC_musl is not set
-# CT_LIBC_uClibc is not set
-CT_LIBC_avr_libc_AVAILABLE=y
-CT_LIBC_glibc_AVAILABLE=y
+CT_LIBC_CHOICE_KSYM="GLIBC"
 CT_THREADS="nptl"
-# CT_CC_GLIBC_SHOW_LINARO is not set
-# CT_LIBC_GLIBC_V_2_22 is not set
-# CT_LIBC_GLIBC_V_2_21 is not set
-# CT_LIBC_GLIBC_V_2_20 is not set
-# CT_LIBC_GLIBC_V_2_19 is not set
-# CT_LIBC_GLIBC_V_2_18 is not set
-# CT_LIBC_GLIBC_V_2_17 is not set
-CT_LIBC_GLIBC_V_2_16_0=y
-# CT_LIBC_GLIBC_V_2_15 is not set
-# CT_LIBC_GLIBC_V_2_14_1 is not set
-# CT_LIBC_GLIBC_V_2_14 is not set
-# CT_LIBC_GLIBC_V_2_13 is not set
-# CT_LIBC_GLIBC_V_2_12_2 is not set
-# CT_LIBC_GLIBC_V_2_12_1 is not set
-# CT_LIBC_GLIBC_V_2_11_1 is not set
-# CT_LIBC_GLIBC_V_2_11 is not set
-# CT_LIBC_GLIBC_V_2_10_1 is not set
-# CT_LIBC_GLIBC_V_2_9 is not set
-# CT_LIBC_GLIBC_V_2_8 is not set
-CT_LIBC_mingw_AVAILABLE=y
-CT_LIBC_musl_AVAILABLE=y
-CT_LIBC_newlib_AVAILABLE=y
-CT_LIBC_none_AVAILABLE=y
-CT_LIBC_uClibc_AVAILABLE=y
+CT_LIBC_GLIBC_SHOW=y
+
+#
+# Options for glibc
+#
+CT_LIBC_GLIBC_PKG_KSYM="GLIBC"
+CT_GLIBC_DIR_NAME="glibc"
+CT_GLIBC_USE_GNU=y
+CT_GLIBC_USE="GLIBC"
+CT_GLIBC_PKG_NAME="glibc"
+CT_GLIBC_SRC_RELEASE=y
+CT_GLIBC_PATCH_ORDER="global"
+# CT_GLIBC_V_2_28 is not set
+# CT_GLIBC_V_2_27 is not set
+# CT_GLIBC_V_2_26 is not set
+# CT_GLIBC_V_2_25 is not set
+# CT_GLIBC_V_2_24 is not set
+# CT_GLIBC_V_2_23 is not set
+# CT_GLIBC_V_2_19 is not set
+CT_GLIBC_V_2_17=y
+# CT_GLIBC_V_2_12_1 is not set
+# CT_GLIBC_NO_VERSIONS is not set
+CT_GLIBC_VERSION="2.17"
+CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)"
+CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
+CT_GLIBC_SIGNATURE_FORMAT="packed/.sig"
+CT_GLIBC_2_29_or_older=y
+CT_GLIBC_older_than_2_29=y
+CT_GLIBC_REQUIRE_older_than_2_29=y
+CT_GLIBC_2_27_or_older=y
+CT_GLIBC_older_than_2_27=y
+CT_GLIBC_2_26_or_older=y
+CT_GLIBC_older_than_2_26=y
+CT_GLIBC_2_25_or_older=y
+CT_GLIBC_older_than_2_25=y
+CT_GLIBC_2_24_or_older=y
+CT_GLIBC_older_than_2_24=y
+CT_GLIBC_2_23_or_older=y
+CT_GLIBC_older_than_2_23=y
+CT_GLIBC_2_20_or_older=y
+CT_GLIBC_older_than_2_20=y
+CT_GLIBC_2_17_or_later=y
+CT_GLIBC_2_17_or_older=y
+CT_GLIBC_later_than_2_14=y
+CT_GLIBC_2_14_or_later=y
+CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y
+CT_GLIBC_DEP_BINUTILS=y
+CT_GLIBC_DEP_GCC=y
+CT_GLIBC_DEP_PYTHON=y
+CT_GLIBC_HAS_NPTL_ADDON=y
+CT_GLIBC_HAS_PORTS_ADDON=y
+CT_GLIBC_HAS_LIBIDN_ADDON=y
+CT_GLIBC_USE_PORTS_ADDON=y
+CT_GLIBC_USE_NPTL_ADDON=y
+# CT_GLIBC_USE_LIBIDN_ADDON is not set
+CT_GLIBC_HAS_OBSOLETE_RPC=y
+CT_GLIBC_EXTRA_CONFIG_ARRAY=""
+CT_GLIBC_CONFIGPARMS=""
+CT_GLIBC_EXTRA_CFLAGS=""
+CT_GLIBC_ENABLE_OBSOLETE_RPC=y
+# CT_GLIBC_DISABLE_VERSIONING is not set
+CT_GLIBC_OLDEST_ABI=""
+CT_GLIBC_FORCE_UNWIND=y
+# CT_GLIBC_LOCALES is not set
+# CT_GLIBC_KERNEL_VERSION_NONE is not set
+CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y
+# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set
+CT_GLIBC_MIN_KERNEL="3.2.101"
+# CT_GLIBC_SSP_DEFAULT is not set
+# CT_GLIBC_SSP_NO is not set
+# CT_GLIBC_SSP_YES is not set
+# CT_GLIBC_SSP_ALL is not set
+# CT_GLIBC_SSP_STRONG is not set
+# CT_NEWLIB_USE_REDHAT is not set
+CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC"
 CT_LIBC_SUPPORT_THREADS_ANY=y
 CT_LIBC_SUPPORT_THREADS_NATIVE=y
 
@@ -342,100 +461,71 @@ CT_LIBC_SUPPORT_THREADS_NATIVE=y
 # Common C library options
 #
 CT_THREADS_NATIVE=y
+# CT_CREATE_LDSO_CONF is not set
 CT_LIBC_XLDD=y
 
 #
-# glibc other options
-#
-CT_LIBC_GLIBC_PORTS_EXTERNAL=y
-CT_LIBC_GLIBC_MAY_FORCE_PORTS=y
-CT_LIBC_glibc_familly=y
-CT_LIBC_GLIBC_EXTRA_CONFIG_ARRAY=""
-CT_LIBC_GLIBC_CONFIGPARMS=""
-CT_LIBC_GLIBC_EXTRA_CFLAGS=""
-CT_LIBC_EXTRA_CC_ARGS=""
-# CT_LIBC_DISABLE_VERSIONING is not set
-CT_LIBC_OLDEST_ABI=""
-CT_LIBC_GLIBC_FORCE_UNWIND=y
-CT_LIBC_GLIBC_USE_PORTS=y
-CT_LIBC_ADDONS_LIST=""
-
-#
-# WARNING !!!                                            
-#
-
-#
-#   For glibc >= 2.8, it can happen that the tarballs    
-#
-
-#
-#   for the addons are not available for download.       
-#
-
-#
-#   If that happens, bad luck... Try a previous version  
-#
-
-#
-#   or try again later... :-(                            
-#
-# CT_LIBC_LOCALES is not set
-# CT_LIBC_GLIBC_KERNEL_VERSION_NONE is not set
-CT_LIBC_GLIBC_KERNEL_VERSION_AS_HEADERS=y
-# CT_LIBC_GLIBC_KERNEL_VERSION_CHOSEN is not set
-CT_LIBC_GLIBC_MIN_KERNEL="3.2.72"
-
-#
 # C compiler
 #
-CT_CC="gcc"
 CT_CC_CORE_PASSES_NEEDED=y
 CT_CC_CORE_PASS_1_NEEDED=y
 CT_CC_CORE_PASS_2_NEEDED=y
-CT_CC_gcc=y
-# CT_CC_GCC_SHOW_LINARO is not set
-CT_CC_GCC_V_5_2_0=y
-# CT_CC_GCC_V_4_9_3 is not set
-# CT_CC_GCC_V_4_8_5 is not set
-# CT_CC_GCC_V_4_7_4 is not set
-# CT_CC_GCC_V_4_6_4 is not set
-# CT_CC_GCC_V_4_5_4 is not set
-# CT_CC_GCC_V_4_4_7 is not set
-# CT_CC_GCC_V_4_3_6 is not set
-# CT_CC_GCC_V_4_2_4 is not set
-CT_CC_GCC_4_2_or_later=y
-CT_CC_GCC_4_3_or_later=y
-CT_CC_GCC_4_4_or_later=y
-CT_CC_GCC_4_5_or_later=y
-CT_CC_GCC_4_6_or_later=y
-CT_CC_GCC_4_7_or_later=y
-CT_CC_GCC_4_8_or_later=y
-CT_CC_GCC_4_9_or_later=y
-CT_CC_GCC_5=y
-CT_CC_GCC_5_or_later=y
-CT_CC_GCC_HAS_GRAPHITE=y
-CT_CC_GCC_USE_GRAPHITE=y
-CT_CC_GCC_HAS_LTO=y
-CT_CC_GCC_USE_LTO=y
-CT_CC_GCC_HAS_PKGVERSION_BUGURL=y
-CT_CC_GCC_HAS_BUILD_ID=y
-CT_CC_GCC_HAS_LNK_HASH_STYLE=y
-CT_CC_GCC_USE_GMP_MPFR=y
-CT_CC_GCC_USE_MPC=y
-CT_CC_GCC_HAS_LIBQUADMATH=y
-CT_CC_GCC_HAS_LIBSANITIZER=y
-CT_CC_GCC_VERSION="5.2.0"
-# CT_CC_LANG_FORTRAN is not set
+CT_CC_SUPPORT_CXX=y
+CT_CC_SUPPORT_FORTRAN=y
+CT_CC_SUPPORT_ADA=y
+CT_CC_SUPPORT_OBJC=y
+CT_CC_SUPPORT_OBJCXX=y
+CT_CC_SUPPORT_GOLANG=y
+CT_CC_GCC=y
+CT_CC="gcc"
+CT_CC_CHOICE_KSYM="GCC"
+CT_CC_GCC_SHOW=y
+
+#
+# Options for gcc
+#
+CT_CC_GCC_PKG_KSYM="GCC"
+CT_GCC_DIR_NAME="gcc"
+CT_GCC_USE_GNU=y
+CT_GCC_USE="GCC"
+CT_GCC_PKG_NAME="gcc"
+CT_GCC_SRC_RELEASE=y
+CT_GCC_PATCH_ORDER="global"
+CT_GCC_V_8=y
+# CT_GCC_V_7 is not set
+# CT_GCC_V_6 is not set
+# CT_GCC_V_5 is not set
+# CT_GCC_V_4_9 is not set
+# CT_GCC_NO_VERSIONS is not set
+CT_GCC_VERSION="8.3.0"
+CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})"
+CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz"
+CT_GCC_SIGNATURE_FORMAT=""
+CT_GCC_later_than_7=y
+CT_GCC_7_or_later=y
+CT_GCC_later_than_6=y
+CT_GCC_6_or_later=y
+CT_GCC_later_than_5=y
+CT_GCC_5_or_later=y
+CT_GCC_later_than_4_9=y
+CT_GCC_4_9_or_later=y
+CT_GCC_later_than_4_8=y
+CT_GCC_4_8_or_later=y
+CT_CC_GCC_HAS_LIBMPX=y
 CT_CC_GCC_ENABLE_CXX_FLAGS=""
 CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY=""
 CT_CC_GCC_EXTRA_CONFIG_ARRAY=""
-CT_CC_GCC_EXTRA_ENV_ARRAY=""
 CT_CC_GCC_STATIC_LIBSTDCXX=y
 # CT_CC_GCC_SYSTEM_ZLIB is not set
+CT_CC_GCC_CONFIG_TLS=m
 
 #
 # Optimisation features
 #
+CT_CC_GCC_USE_GRAPHITE=y
+CT_CC_GCC_USE_LTO=y
 
 #
 # Settings for libraries running on target
@@ -464,97 +554,208 @@ CT_CC_GCC_DEC_FLOAT_AUTO=y
 # CT_CC_GCC_DEC_FLOAT_BID is not set
 # CT_CC_GCC_DEC_FLOAT_DPD is not set
 # CT_CC_GCC_DEC_FLOATS_NO is not set
-CT_CC_SUPPORT_CXX=y
-CT_CC_SUPPORT_FORTRAN=y
-CT_CC_SUPPORT_JAVA=y
-CT_CC_SUPPORT_ADA=y
-CT_CC_SUPPORT_OBJC=y
-CT_CC_SUPPORT_OBJCXX=y
-CT_CC_SUPPORT_GOLANG=y
+CT_ALL_CC_CHOICES="GCC"
 
 #
 # Additional supported languages:
 #
 CT_CC_LANG_CXX=y
-# CT_CC_LANG_JAVA is not set
+# CT_CC_LANG_FORTRAN is not set
 
 #
 # Debug facilities
 #
-# CT_DEBUG_dmalloc is not set
-# CT_DEBUG_duma is not set
-# CT_DEBUG_gdb is not set
-# CT_DEBUG_ltrace is not set
-# CT_DEBUG_strace is not set
+# CT_DEBUG_DUMA is not set
+# CT_DEBUG_GDB is not set
+# CT_DEBUG_LTRACE is not set
+# CT_DEBUG_STRACE is not set
+CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE"
 
 #
 # Companion libraries
 #
-CT_COMPLIBS_NEEDED=y
+# CT_COMPLIBS_CHECK is not set
+# CT_COMP_LIBS_CLOOG is not set
+# CT_COMP_LIBS_EXPAT is not set
+CT_COMP_LIBS_GETTEXT=y
+CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT"
+CT_GETTEXT_DIR_NAME="gettext"
+CT_GETTEXT_PKG_NAME="gettext"
+CT_GETTEXT_SRC_RELEASE=y
+CT_GETTEXT_PATCH_ORDER="global"
+CT_GETTEXT_V_0_19_8_1=y
+# CT_GETTEXT_NO_VERSIONS is not set
+CT_GETTEXT_VERSION="0.19.8.1"
+CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)"
+CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz"
+CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig"
+CT_COMP_LIBS_GMP=y
+CT_COMP_LIBS_GMP_PKG_KSYM="GMP"
+CT_GMP_DIR_NAME="gmp"
+CT_GMP_PKG_NAME="gmp"
+CT_GMP_SRC_RELEASE=y
+CT_GMP_PATCH_ORDER="global"
+CT_GMP_V_6_1=y
+# CT_GMP_NO_VERSIONS is not set
+CT_GMP_VERSION="6.1.2"
+CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)"
+CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2"
+CT_GMP_SIGNATURE_FORMAT="packed/.sig"
+CT_GMP_later_than_5_1_0=y
+CT_GMP_5_1_0_or_later=y
+CT_GMP_later_than_5_0_0=y
+CT_GMP_5_0_0_or_later=y
+CT_GMP_REQUIRE_5_0_0_or_later=y
+CT_COMP_LIBS_ISL=y
+CT_COMP_LIBS_ISL_PKG_KSYM="ISL"
+CT_ISL_DIR_NAME="isl"
+CT_ISL_PKG_NAME="isl"
+CT_ISL_SRC_RELEASE=y
+CT_ISL_PATCH_ORDER="global"
+CT_ISL_V_0_20=y
+# CT_ISL_V_0_19 is not set
+# CT_ISL_V_0_18 is not set
+# CT_ISL_V_0_17 is not set
+# CT_ISL_V_0_16 is not set
+# CT_ISL_V_0_15 is not set
+# CT_ISL_NO_VERSIONS is not set
+CT_ISL_VERSION="0.20"
+CT_ISL_MIRRORS="http://isl.gforge.inria.fr"
+CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
+CT_ISL_SIGNATURE_FORMAT=""
+CT_ISL_later_than_0_18=y
+CT_ISL_0_18_or_later=y
+CT_ISL_later_than_0_15=y
+CT_ISL_0_15_or_later=y
+CT_ISL_REQUIRE_0_15_or_later=y
+CT_ISL_later_than_0_14=y
+CT_ISL_0_14_or_later=y
+CT_ISL_REQUIRE_0_14_or_later=y
+CT_ISL_later_than_0_13=y
+CT_ISL_0_13_or_later=y
+CT_ISL_later_than_0_12=y
+CT_ISL_0_12_or_later=y
+CT_ISL_REQUIRE_0_12_or_later=y
+# CT_COMP_LIBS_LIBELF is not set
+CT_COMP_LIBS_LIBICONV=y
+CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV"
+CT_LIBICONV_DIR_NAME="libiconv"
+CT_LIBICONV_PKG_NAME="libiconv"
+CT_LIBICONV_SRC_RELEASE=y
+CT_LIBICONV_PATCH_ORDER="global"
+CT_LIBICONV_V_1_15=y
+# CT_LIBICONV_NO_VERSIONS is not set
+CT_LIBICONV_VERSION="1.15"
+CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)"
+CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz"
+CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig"
+CT_COMP_LIBS_MPC=y
+CT_COMP_LIBS_MPC_PKG_KSYM="MPC"
+CT_MPC_DIR_NAME="mpc"
+CT_MPC_PKG_NAME="mpc"
+CT_MPC_SRC_RELEASE=y
+CT_MPC_PATCH_ORDER="global"
+CT_MPC_V_1_1=y
+# CT_MPC_V_1_0 is not set
+# CT_MPC_NO_VERSIONS is not set
+CT_MPC_VERSION="1.1.0"
+CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)"
+CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_MPC_ARCHIVE_FORMATS=".tar.gz"
+CT_MPC_SIGNATURE_FORMAT="packed/.sig"
+CT_MPC_1_1_0_or_later=y
+CT_MPC_1_1_0_or_older=y
+CT_COMP_LIBS_MPFR=y
+CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR"
+CT_MPFR_DIR_NAME="mpfr"
+CT_MPFR_PKG_NAME="mpfr"
+CT_MPFR_SRC_RELEASE=y
+CT_MPFR_PATCH_ORDER="global"
+CT_MPFR_V_4_0=y
+# CT_MPFR_V_3_1 is not set
+# CT_MPFR_NO_VERSIONS is not set
+CT_MPFR_VERSION="4.0.2"
+CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)"
+CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip"
+CT_MPFR_SIGNATURE_FORMAT="packed/.asc"
+CT_MPFR_later_than_4_0_0=y
+CT_MPFR_4_0_0_or_later=y
+CT_MPFR_later_than_3_0_0=y
+CT_MPFR_3_0_0_or_later=y
+CT_MPFR_REQUIRE_3_0_0_or_later=y
+CT_COMP_LIBS_NCURSES=y
+CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES"
+CT_NCURSES_DIR_NAME="ncurses"
+CT_NCURSES_PKG_NAME="ncurses"
+CT_NCURSES_SRC_RELEASE=y
+CT_NCURSES_PATCH_ORDER="global"
+CT_NCURSES_V_6_1=y
+# CT_NCURSES_V_6_0 is not set
+# CT_NCURSES_NO_VERSIONS is not set
+CT_NCURSES_VERSION="6.1"
+CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)"
+CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_NCURSES_ARCHIVE_FORMATS=".tar.gz"
+CT_NCURSES_SIGNATURE_FORMAT="packed/.sig"
+CT_NCURSES_HOST_CONFIG_ARGS=""
+CT_NCURSES_HOST_DISABLE_DB=y
+CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100"
+CT_NCURSES_TARGET_CONFIG_ARGS=""
+# CT_NCURSES_TARGET_DISABLE_DB is not set
+CT_NCURSES_TARGET_FALLBACKS=""
+CT_COMP_LIBS_ZLIB=y
+CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB"
+CT_ZLIB_DIR_NAME="zlib"
+CT_ZLIB_PKG_NAME="zlib"
+CT_ZLIB_SRC_RELEASE=y
+CT_ZLIB_PATCH_ORDER="global"
+CT_ZLIB_V_1_2_11=y
+# CT_ZLIB_NO_VERSIONS is not set
+CT_ZLIB_VERSION="1.2.11"
+CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}"
+CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz"
+CT_ZLIB_SIGNATURE_FORMAT="packed/.asc"
+CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB"
 CT_LIBICONV_NEEDED=y
 CT_GETTEXT_NEEDED=y
 CT_GMP_NEEDED=y
 CT_MPFR_NEEDED=y
 CT_ISL_NEEDED=y
 CT_MPC_NEEDED=y
-CT_COMPLIBS=y
+CT_NCURSES_NEEDED=y
+CT_ZLIB_NEEDED=y
 CT_LIBICONV=y
 CT_GETTEXT=y
 CT_GMP=y
 CT_MPFR=y
 CT_ISL=y
 CT_MPC=y
-CT_LIBICONV_V_1_14=y
-CT_LIBICONV_VERSION="1.14"
-CT_GETTEXT_V_0_19_6=y
-CT_GETTEXT_VERSION="0.19.6"
-CT_GMP_V_6_0_0=y
-# CT_GMP_V_5_1_3 is not set
-# CT_GMP_V_5_1_1 is not set
-# CT_GMP_V_5_0_2 is not set
-# CT_GMP_V_5_0_1 is not set
-# CT_GMP_V_4_3_2 is not set
-# CT_GMP_V_4_3_1 is not set
-# CT_GMP_V_4_3_0 is not set
-CT_GMP_5_0_2_or_later=y
-CT_GMP_VERSION="6.0.0a"
-CT_MPFR_V_3_1_3=y
-# CT_MPFR_V_3_1_2 is not set
-# CT_MPFR_V_3_1_0 is not set
-# CT_MPFR_V_3_0_1 is not set
-# CT_MPFR_V_3_0_0 is not set
-# CT_MPFR_V_2_4_2 is not set
-# CT_MPFR_V_2_4_1 is not set
-# CT_MPFR_V_2_4_0 is not set
-CT_MPFR_VERSION="3.1.3"
-CT_ISL_V_0_14=y
-# CT_ISL_V_0_12_2 is not set
-CT_ISL_V_0_14_or_later=y
-CT_ISL_V_0_12_or_later=y
-CT_ISL_VERSION="0.14"
-# CT_CLOOG_V_0_18_4 is not set
-# CT_CLOOG_V_0_18_1 is not set
-# CT_CLOOG_V_0_18_0 is not set
-CT_MPC_V_1_0_3=y
-# CT_MPC_V_1_0_2 is not set
-# CT_MPC_V_1_0_1 is not set
-# CT_MPC_V_1_0 is not set
-# CT_MPC_V_0_9 is not set
-# CT_MPC_V_0_8_2 is not set
-# CT_MPC_V_0_8_1 is not set
-# CT_MPC_V_0_7 is not set
-CT_MPC_VERSION="1.0.3"
-
-#
-# Companion libraries common options
-#
-# CT_COMPLIBS_CHECK is not set
+CT_NCURSES=y
+CT_ZLIB=y
 
 #
 # Companion tools
 #
-
-#
-# READ HELP before you say 'Y' below !!!
-#
-# CT_COMP_TOOLS is not set
+# CT_COMP_TOOLS_FOR_HOST is not set
+# CT_COMP_TOOLS_AUTOCONF is not set
+# CT_COMP_TOOLS_AUTOMAKE is not set
+# CT_COMP_TOOLS_BISON is not set
+# CT_COMP_TOOLS_DTC is not set
+# CT_COMP_TOOLS_LIBTOOL is not set
+# CT_COMP_TOOLS_M4 is not set
+# CT_COMP_TOOLS_MAKE is not set
+CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE"
diff --git a/src/ci/docker/dist-arm-linux/patches/glibc/ports-2.16.0/001-arm-libgcc_s_resume-used.patch b/src/ci/docker/dist-arm-linux/patches/glibc/ports-2.16.0/001-arm-libgcc_s_resume-used.patch
deleted file mode 100644
index 871d5225c0f..00000000000
--- a/src/ci/docker/dist-arm-linux/patches/glibc/ports-2.16.0/001-arm-libgcc_s_resume-used.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-commit bdb24c2851fd5f0ad9b82d7ea1db911d334b02d2
-Author: Joseph Myers <joseph@codesourcery.com>
-Date:   Tue May 20 21:27:13 2014 +0000
-
-    Fix ARM build with GCC trunk.
-    
-    sysdeps/unix/sysv/linux/arm/unwind-resume.c and
-    sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c have static
-    variables that are written in C code but only read from toplevel asms.
-    Current GCC trunk now optimizes away such apparently write-only static
-    variables, so causing a build failure.  This patch marks those
-    variables with __attribute_used__ to avoid that optimization.
-    
-    Tested that this fixes the build for ARM.
-    
-            * sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c
-            (libgcc_s_resume): Use __attribute_used__.
-            * sysdeps/unix/sysv/linux/arm/unwind-resume.c (libgcc_s_resume):
-            Likewise.
-
-diff --git a/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c b/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
-index 29e2c2b00b04..e848bfeffdcb 100644
---- a/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
-+++ b/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
-@@ -22,7 +22,8 @@
- #include <pthreadP.h>
- 
- static void *libgcc_s_handle;
--static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
-+static void (*libgcc_s_resume) (struct _Unwind_Exception *exc)
-+  __attribute_used__;
- static _Unwind_Reason_Code (*libgcc_s_personality)
-   (_Unwind_State, struct _Unwind_Exception *, struct _Unwind_Context *);
- static _Unwind_Reason_Code (*libgcc_s_forcedunwind)
-diff --git a/sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c b/sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c
-index 285b99b5ed0d..48d00fc83641 100644
---- a/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c
-+++ b/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c
-@@ -20,7 +20,8 @@
- #include <stdio.h>
- #include <unwind.h>
- 
--static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
-+static void (*libgcc_s_resume) (struct _Unwind_Exception *exc)
-+  __attribute_used__;
- static _Unwind_Reason_Code (*libgcc_s_personality)
-   (_Unwind_State, struct _Unwind_Exception *, struct _Unwind_Context *);
- 
diff --git a/src/ci/docker/dist-armhf-linux/Dockerfile b/src/ci/docker/dist-armhf-linux/Dockerfile
index d1dd9faaa10..209b6c166eb 100644
--- a/src/ci/docker/dist-armhf-linux/Dockerfile
+++ b/src/ci/docker/dist-armhf-linux/Dockerfile
@@ -3,20 +3,14 @@ FROM ubuntu:16.04
 COPY scripts/cross-apt-packages.sh /scripts/
 RUN sh /scripts/cross-apt-packages.sh
 
-# Ubuntu 16.04 (this container) ships with make 4, but something in the
-# toolchains we build below chokes on that, so go back to make 3
-COPY scripts/make3.sh /scripts/
-RUN sh /scripts/make3.sh
-
-COPY scripts/crosstool-ng.sh /scripts/
-RUN sh /scripts/crosstool-ng.sh
+COPY scripts/crosstool-ng-1.24.sh /scripts/
+RUN sh /scripts/crosstool-ng-1.24.sh
 
 COPY scripts/rustbuild-setup.sh /scripts/
 RUN sh /scripts/rustbuild-setup.sh
 USER rustbuild
 WORKDIR /tmp
 
-COPY dist-armhf-linux/patches/ /tmp/patches/
 COPY dist-armhf-linux/arm-linux-gnueabihf.config dist-armhf-linux/build-toolchains.sh /tmp/
 RUN ./build-toolchains.sh
 
diff --git a/src/ci/docker/dist-armhf-linux/arm-linux-gnueabihf.config b/src/ci/docker/dist-armhf-linux/arm-linux-gnueabihf.config
index bebbcd1670a..a3dcff1c936 100644
--- a/src/ci/docker/dist-armhf-linux/arm-linux-gnueabihf.config
+++ b/src/ci/docker/dist-armhf-linux/arm-linux-gnueabihf.config
@@ -1,9 +1,29 @@
 #
 # Automatically generated file; DO NOT EDIT.
-# Crosstool-NG Configuration
-#
-CT_CONFIGURE_has_make381=y
-CT_CONFIGURE_has_xz=y
+# crosstool-NG  Configuration
+#
+CT_CONFIGURE_has_static_link=y
+CT_CONFIGURE_has_cxx11=y
+CT_CONFIGURE_has_wget=y
+CT_CONFIGURE_has_curl=y
+CT_CONFIGURE_has_make_3_81_or_newer=y
+CT_CONFIGURE_has_make_4_0_or_newer=y
+CT_CONFIGURE_has_libtool_2_4_or_newer=y
+CT_CONFIGURE_has_libtoolize_2_4_or_newer=y
+CT_CONFIGURE_has_autoconf_2_65_or_newer=y
+CT_CONFIGURE_has_autoreconf_2_65_or_newer=y
+CT_CONFIGURE_has_automake_1_15_or_newer=y
+CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y
+CT_CONFIGURE_has_bison_2_7_or_newer=y
+CT_CONFIGURE_has_python=y
+CT_CONFIGURE_has_git=y
+CT_CONFIGURE_has_md5sum=y
+CT_CONFIGURE_has_sha1sum=y
+CT_CONFIGURE_has_sha256sum=y
+CT_CONFIGURE_has_sha512sum=y
+CT_CONFIGURE_has_install_with_strip_program=y
+CT_CONFIG_VERSION_CURRENT="3"
+CT_CONFIG_VERSION="3"
 CT_MODULES=y
 
 #
@@ -20,41 +40,48 @@ CT_MODULES=y
 #
 # Paths
 #
-CT_LOCAL_TARBALLS_DIR=""
+CT_LOCAL_TARBALLS_DIR="${HOME}/src"
+CT_SAVE_TARBALLS=y
+# CT_TARBALLS_BUILDROOT_LAYOUT is not set
 CT_WORK_DIR="${CT_TOP_DIR}/.build"
+CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}"
 CT_PREFIX_DIR="/x-tools/${CT_TARGET}"
-CT_INSTALL_DIR="${CT_PREFIX_DIR}"
 CT_RM_RF_PREFIX_DIR=y
 CT_REMOVE_DOCS=y
-CT_INSTALL_DIR_RO=y
+CT_INSTALL_LICENSES=y
+CT_PREFIX_DIR_RO=y
 CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y
 # CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set
 
 #
 # Downloading
 #
+CT_DOWNLOAD_AGENT_WGET=y
+# CT_DOWNLOAD_AGENT_CURL is not set
+# CT_DOWNLOAD_AGENT_NONE is not set
 # CT_FORBID_DOWNLOAD is not set
 # CT_FORCE_DOWNLOAD is not set
 CT_CONNECT_TIMEOUT=10
+CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary"
 # CT_ONLY_DOWNLOAD is not set
 # CT_USE_MIRROR is not set
+CT_VERIFY_DOWNLOAD_DIGEST=y
+CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y
+# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set
+# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set
+# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set
+CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512"
+# CT_VERIFY_DOWNLOAD_SIGNATURE is not set
 
 #
 # Extracting
 #
 # CT_FORCE_EXTRACT is not set
-CT_OVERIDE_CONFIG_GUESS_SUB=y
+CT_OVERRIDE_CONFIG_GUESS_SUB=y
 # CT_ONLY_EXTRACT is not set
-# CT_PATCH_BUNDLED is not set
-# CT_PATCH_LOCAL is not set
-CT_PATCH_BUNDLED_LOCAL=y
-# CT_PATCH_LOCAL_BUNDLED is not set
-# CT_PATCH_BUNDLED_FALLBACK_LOCAL is not set
-# CT_PATCH_LOCAL_FALLBACK_BUNDLED is not set
-# CT_PATCH_NONE is not set
-CT_PATCH_ORDER="bundled,local"
-CT_PATCH_USE_LOCAL=y
-CT_LOCAL_PATCH_DIR="/tmp/patches"
+CT_PATCH_BUNDLED=y
+# CT_PATCH_BUNDLED_LOCAL is not set
+CT_PATCH_ORDER="bundled"
 
 #
 # Build behavior
@@ -77,11 +104,11 @@ CT_CONFIG_SHELL="${bash}"
 #
 # CT_LOG_ERROR is not set
 # CT_LOG_WARN is not set
-CT_LOG_INFO=y
-# CT_LOG_EXTRA is not set
+# CT_LOG_INFO is not set
+CT_LOG_EXTRA=y
 # CT_LOG_ALL is not set
 # CT_LOG_DEBUG is not set
-CT_LOG_LEVEL_MAX="INFO"
+CT_LOG_LEVEL_MAX="EXTRA"
 # CT_LOG_SEE_TOOLS_WARN is not set
 CT_LOG_PROGRESS_BAR=y
 CT_LOG_TO_FILE=y
@@ -90,87 +117,88 @@ CT_LOG_FILE_COMPRESS=y
 #
 # Target options
 #
+# CT_ARCH_ALPHA is not set
+# CT_ARCH_ARC is not set
+CT_ARCH_ARM=y
+# CT_ARCH_AVR is not set
+# CT_ARCH_M68K is not set
+# CT_ARCH_MIPS is not set
+# CT_ARCH_NIOS2 is not set
+# CT_ARCH_POWERPC is not set
+# CT_ARCH_S390 is not set
+# CT_ARCH_SH is not set
+# CT_ARCH_SPARC is not set
+# CT_ARCH_X86 is not set
+# CT_ARCH_XTENSA is not set
 CT_ARCH="arm"
-CT_ARCH_SUPPORTS_BOTH_MMU=y
-CT_ARCH_SUPPORTS_BOTH_ENDIAN=y
-CT_ARCH_SUPPORTS_32=y
-CT_ARCH_SUPPORTS_64=y
-CT_ARCH_SUPPORTS_WITH_ARCH=y
-CT_ARCH_SUPPORTS_WITH_CPU=y
-CT_ARCH_SUPPORTS_WITH_TUNE=y
-CT_ARCH_SUPPORTS_WITH_FLOAT=y
-CT_ARCH_SUPPORTS_WITH_FPU=y
-CT_ARCH_SUPPORTS_SOFTFP=y
-CT_ARCH_DEFAULT_HAS_MMU=y
-CT_ARCH_DEFAULT_LE=y
-CT_ARCH_DEFAULT_32=y
-CT_ARCH_ARCH="armv6"
+CT_ARCH_CHOICE_KSYM="ARM"
+# CT_ARCH_ALPHA_EV4 is not set
+# CT_ARCH_ALPHA_EV45 is not set
+# CT_ARCH_ALPHA_EV5 is not set
+# CT_ARCH_ALPHA_EV56 is not set
+# CT_ARCH_ALPHA_EV6 is not set
+# CT_ARCH_ALPHA_EV67 is not set
 CT_ARCH_CPU=""
 CT_ARCH_TUNE=""
-CT_ARCH_FPU="vfp"
-# CT_ARCH_BE is not set
-CT_ARCH_LE=y
-CT_ARCH_32=y
-# CT_ARCH_64 is not set
-CT_ARCH_BITNESS=32
-CT_ARCH_FLOAT_HW=y
-# CT_ARCH_FLOAT_SW is not set
-CT_TARGET_CFLAGS=""
-CT_TARGET_LDFLAGS=""
-# CT_ARCH_alpha is not set
-CT_ARCH_arm=y
-# CT_ARCH_avr is not set
-# CT_ARCH_m68k is not set
-# CT_ARCH_mips is not set
-# CT_ARCH_nios2 is not set
-# CT_ARCH_powerpc is not set
-# CT_ARCH_s390 is not set
-# CT_ARCH_sh is not set
-# CT_ARCH_sparc is not set
-# CT_ARCH_x86 is not set
-# CT_ARCH_xtensa is not set
-CT_ARCH_alpha_AVAILABLE=y
-CT_ARCH_arm_AVAILABLE=y
-CT_ARCH_avr_AVAILABLE=y
-CT_ARCH_m68k_AVAILABLE=y
-CT_ARCH_microblaze_AVAILABLE=y
-CT_ARCH_mips_AVAILABLE=y
-CT_ARCH_nios2_AVAILABLE=y
-CT_ARCH_powerpc_AVAILABLE=y
-CT_ARCH_s390_AVAILABLE=y
-CT_ARCH_sh_AVAILABLE=y
-CT_ARCH_sparc_AVAILABLE=y
-CT_ARCH_x86_AVAILABLE=y
-CT_ARCH_xtensa_AVAILABLE=y
+CT_ARCH_ARM_SHOW=y
+
+#
+# Options for arm
+#
+CT_ARCH_ARM_PKG_KSYM=""
+CT_ARCH_ARM_MODE="arm"
+CT_ARCH_ARM_MODE_ARM=y
+# CT_ARCH_ARM_MODE_THUMB is not set
+# CT_ARCH_ARM_INTERWORKING is not set
+CT_ARCH_ARM_EABI_FORCE=y
+CT_ARCH_ARM_EABI=y
+CT_ARCH_ARM_TUPLE_USE_EABIHF=y
+CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA"
 CT_ARCH_SUFFIX=""
+# CT_OMIT_TARGET_VENDOR is not set
 
 #
 # Generic target options
 #
 # CT_MULTILIB is not set
+CT_DEMULTILIB=y
+CT_ARCH_SUPPORTS_BOTH_MMU=y
+CT_ARCH_DEFAULT_HAS_MMU=y
 CT_ARCH_USE_MMU=y
+CT_ARCH_SUPPORTS_FLAT_FORMAT=y
+CT_ARCH_SUPPORTS_EITHER_ENDIAN=y
+CT_ARCH_DEFAULT_LE=y
+# CT_ARCH_BE is not set
+CT_ARCH_LE=y
 CT_ARCH_ENDIAN="little"
+CT_ARCH_SUPPORTS_32=y
+CT_ARCH_SUPPORTS_64=y
+CT_ARCH_DEFAULT_32=y
+CT_ARCH_BITNESS=32
+CT_ARCH_32=y
+# CT_ARCH_64 is not set
 
 #
 # Target optimisations
 #
+CT_ARCH_SUPPORTS_WITH_ARCH=y
+CT_ARCH_SUPPORTS_WITH_CPU=y
+CT_ARCH_SUPPORTS_WITH_TUNE=y
+CT_ARCH_SUPPORTS_WITH_FLOAT=y
+CT_ARCH_SUPPORTS_WITH_FPU=y
+CT_ARCH_SUPPORTS_SOFTFP=y
 CT_ARCH_EXCLUSIVE_WITH_CPU=y
+CT_ARCH_ARCH="armv6"
+CT_ARCH_FPU="vfp"
 # CT_ARCH_FLOAT_AUTO is not set
+CT_ARCH_FLOAT_HW=y
 # CT_ARCH_FLOAT_SOFTFP is not set
+# CT_ARCH_FLOAT_SW is not set
+CT_TARGET_CFLAGS=""
+CT_TARGET_LDFLAGS=""
 CT_ARCH_FLOAT="hard"
 
 #
-# arm other options
-#
-CT_ARCH_ARM_MODE="arm"
-CT_ARCH_ARM_MODE_ARM=y
-# CT_ARCH_ARM_MODE_THUMB is not set
-# CT_ARCH_ARM_INTERWORKING is not set
-CT_ARCH_ARM_EABI_FORCE=y
-CT_ARCH_ARM_EABI=y
-CT_ARCH_ARM_TUPLE_USE_EABIHF=y
-
-#
 # Toolchain options
 #
 
@@ -182,7 +210,9 @@ CT_USE_SYSROOT=y
 CT_SYSROOT_NAME="sysroot"
 CT_SYSROOT_DIR_PREFIX=""
 CT_WANTS_STATIC_LINK=y
+CT_WANTS_STATIC_LINK_CXX=y
 # CT_STATIC_TOOLCHAIN is not set
+CT_SHOW_CT_VERSION=y
 CT_TOOLCHAIN_PKGVERSION=""
 CT_TOOLCHAIN_BUGURL=""
 
@@ -216,126 +246,215 @@ CT_BUILD_SUFFIX=""
 # Operating System
 #
 CT_KERNEL_SUPPORTS_SHARED_LIBS=y
+# CT_KERNEL_BARE_METAL is not set
+CT_KERNEL_LINUX=y
 CT_KERNEL="linux"
-CT_KERNEL_VERSION="3.2.72"
-# CT_KERNEL_bare_metal is not set
-CT_KERNEL_linux=y
-CT_KERNEL_bare_metal_AVAILABLE=y
-CT_KERNEL_linux_AVAILABLE=y
-# CT_KERNEL_V_4_3 is not set
-# CT_KERNEL_V_4_2 is not set
-# CT_KERNEL_V_4_1 is not set
-# CT_KERNEL_V_3_18 is not set
-# CT_KERNEL_V_3_14 is not set
-# CT_KERNEL_V_3_12 is not set
-# CT_KERNEL_V_3_10 is not set
-# CT_KERNEL_V_3_4 is not set
-CT_KERNEL_V_3_2=y
-# CT_KERNEL_V_2_6_32 is not set
-# CT_KERNEL_LINUX_CUSTOM is not set
-CT_KERNEL_windows_AVAILABLE=y
-
-#
-# Common kernel options
-#
-CT_SHARED_LIBS=y
-
-#
-# linux other options
-#
+CT_KERNEL_CHOICE_KSYM="LINUX"
+CT_KERNEL_LINUX_SHOW=y
+
+#
+# Options for linux
+#
+CT_KERNEL_LINUX_PKG_KSYM="LINUX"
+CT_LINUX_DIR_NAME="linux"
+CT_LINUX_PKG_NAME="linux"
+CT_LINUX_SRC_RELEASE=y
+CT_LINUX_PATCH_ORDER="global"
+# CT_LINUX_V_4_20 is not set
+# CT_LINUX_V_4_19 is not set
+# CT_LINUX_V_4_18 is not set
+# CT_LINUX_V_4_17 is not set
+# CT_LINUX_V_4_16 is not set
+# CT_LINUX_V_4_15 is not set
+# CT_LINUX_V_4_14 is not set
+# CT_LINUX_V_4_13 is not set
+# CT_LINUX_V_4_12 is not set
+# CT_LINUX_V_4_11 is not set
+# CT_LINUX_V_4_10 is not set
+# CT_LINUX_V_4_9 is not set
+# CT_LINUX_V_4_4 is not set
+# CT_LINUX_V_4_1 is not set
+# CT_LINUX_V_3_16 is not set
+# CT_LINUX_V_3_13 is not set
+# CT_LINUX_V_3_12 is not set
+# CT_LINUX_V_3_10 is not set
+# CT_LINUX_V_3_4 is not set
+CT_LINUX_V_3_2=y
+# CT_LINUX_V_2_6_32 is not set
+# CT_LINUX_NO_VERSIONS is not set
+CT_LINUX_VERSION="3.2.101"
+CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})"
+CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz"
+CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign"
+CT_LINUX_4_8_or_older=y
+CT_LINUX_older_than_4_8=y
+CT_LINUX_3_7_or_older=y
+CT_LINUX_older_than_3_7=y
+CT_LINUX_later_than_3_2=y
+CT_LINUX_3_2_or_later=y
 CT_KERNEL_LINUX_VERBOSITY_0=y
 # CT_KERNEL_LINUX_VERBOSITY_1 is not set
 # CT_KERNEL_LINUX_VERBOSITY_2 is not set
 CT_KERNEL_LINUX_VERBOSE_LEVEL=0
 CT_KERNEL_LINUX_INSTALL_CHECK=y
+CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS"
+
+#
+# Common kernel options
+#
+CT_SHARED_LIBS=y
 
 #
 # Binary utilities
 #
 CT_ARCH_BINFMT_ELF=y
+CT_BINUTILS_BINUTILS=y
 CT_BINUTILS="binutils"
-CT_BINUTILS_binutils=y
+CT_BINUTILS_CHOICE_KSYM="BINUTILS"
+CT_BINUTILS_BINUTILS_SHOW=y
+
+#
+# Options for binutils
+#
+CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS"
+CT_BINUTILS_DIR_NAME="binutils"
+CT_BINUTILS_USE_GNU=y
+CT_BINUTILS_USE="BINUTILS"
+CT_BINUTILS_PKG_NAME="binutils"
+CT_BINUTILS_SRC_RELEASE=y
+CT_BINUTILS_PATCH_ORDER="global"
+CT_BINUTILS_V_2_32=y
+# CT_BINUTILS_V_2_31 is not set
+# CT_BINUTILS_V_2_30 is not set
+# CT_BINUTILS_V_2_29 is not set
+# CT_BINUTILS_V_2_28 is not set
+# CT_BINUTILS_V_2_27 is not set
+# CT_BINUTILS_V_2_26 is not set
+# CT_BINUTILS_NO_VERSIONS is not set
+CT_BINUTILS_VERSION="2.32"
+CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)"
+CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
+CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig"
+CT_BINUTILS_later_than_2_30=y
+CT_BINUTILS_2_30_or_later=y
+CT_BINUTILS_later_than_2_27=y
+CT_BINUTILS_2_27_or_later=y
+CT_BINUTILS_later_than_2_25=y
+CT_BINUTILS_2_25_or_later=y
+CT_BINUTILS_later_than_2_23=y
+CT_BINUTILS_2_23_or_later=y
 
 #
 # GNU binutils
 #
-# CT_CC_BINUTILS_SHOW_LINARO is not set
-CT_BINUTILS_V_2_25_1=y
-# CT_BINUTILS_V_2_25 is not set
-# CT_BINUTILS_V_2_24 is not set
-# CT_BINUTILS_V_2_23_2 is not set
-# CT_BINUTILS_V_2_23_1 is not set
-# CT_BINUTILS_V_2_22 is not set
-# CT_BINUTILS_V_2_21_53 is not set
-# CT_BINUTILS_V_2_21_1a is not set
-# CT_BINUTILS_V_2_20_1a is not set
-# CT_BINUTILS_V_2_19_1a is not set
-# CT_BINUTILS_V_2_18a is not set
-CT_BINUTILS_VERSION="2.25.1"
-CT_BINUTILS_2_25_1_or_later=y
-CT_BINUTILS_2_25_or_later=y
-CT_BINUTILS_2_24_or_later=y
-CT_BINUTILS_2_23_or_later=y
-CT_BINUTILS_2_22_or_later=y
-CT_BINUTILS_2_21_or_later=y
-CT_BINUTILS_2_20_or_later=y
-CT_BINUTILS_2_19_or_later=y
-CT_BINUTILS_2_18_or_later=y
 CT_BINUTILS_HAS_HASH_STYLE=y
 CT_BINUTILS_HAS_GOLD=y
-CT_BINUTILS_GOLD_SUPPORTS_ARCH=y
-CT_BINUTILS_GOLD_SUPPORT=y
 CT_BINUTILS_HAS_PLUGINS=y
 CT_BINUTILS_HAS_PKGVERSION_BUGURL=y
-CT_BINUTILS_FORCE_LD_BFD=y
+CT_BINUTILS_GOLD_SUPPORTS_ARCH=y
+CT_BINUTILS_GOLD_SUPPORT=y
+CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y
 CT_BINUTILS_LINKER_LD=y
 # CT_BINUTILS_LINKER_LD_GOLD is not set
-# CT_BINUTILS_LINKER_GOLD_LD is not set
 CT_BINUTILS_LINKERS_LIST="ld"
 CT_BINUTILS_LINKER_DEFAULT="bfd"
 # CT_BINUTILS_PLUGINS is not set
+CT_BINUTILS_RELRO=m
 CT_BINUTILS_EXTRA_CONFIG_ARRAY=""
 # CT_BINUTILS_FOR_TARGET is not set
-
-#
-# binutils other options
-#
+CT_ALL_BINUTILS_CHOICES="BINUTILS"
 
 #
 # C-library
 #
+CT_LIBC_GLIBC=y
+# CT_LIBC_NEWLIB is not set
+# CT_LIBC_NONE is not set
+# CT_LIBC_UCLIBC is not set
 CT_LIBC="glibc"
-CT_LIBC_VERSION="2.16.0"
-CT_LIBC_glibc=y
-# CT_LIBC_musl is not set
-# CT_LIBC_uClibc is not set
-CT_LIBC_avr_libc_AVAILABLE=y
-CT_LIBC_glibc_AVAILABLE=y
+CT_LIBC_CHOICE_KSYM="GLIBC"
 CT_THREADS="nptl"
-# CT_CC_GLIBC_SHOW_LINARO is not set
-# CT_LIBC_GLIBC_V_2_22 is not set
-# CT_LIBC_GLIBC_V_2_21 is not set
-# CT_LIBC_GLIBC_V_2_20 is not set
-# CT_LIBC_GLIBC_V_2_19 is not set
-# CT_LIBC_GLIBC_V_2_18 is not set
-# CT_LIBC_GLIBC_V_2_17 is not set
-CT_LIBC_GLIBC_V_2_16_0=y
-# CT_LIBC_GLIBC_V_2_15 is not set
-# CT_LIBC_GLIBC_V_2_14_1 is not set
-# CT_LIBC_GLIBC_V_2_14 is not set
-# CT_LIBC_GLIBC_V_2_13 is not set
-# CT_LIBC_GLIBC_V_2_12_2 is not set
-# CT_LIBC_GLIBC_V_2_12_1 is not set
-# CT_LIBC_GLIBC_V_2_11_1 is not set
-# CT_LIBC_GLIBC_V_2_11 is not set
-# CT_LIBC_GLIBC_V_2_10_1 is not set
-# CT_LIBC_GLIBC_V_2_9 is not set
-# CT_LIBC_GLIBC_V_2_8 is not set
-CT_LIBC_mingw_AVAILABLE=y
-CT_LIBC_musl_AVAILABLE=y
-CT_LIBC_newlib_AVAILABLE=y
-CT_LIBC_none_AVAILABLE=y
-CT_LIBC_uClibc_AVAILABLE=y
+CT_LIBC_GLIBC_SHOW=y
+
+#
+# Options for glibc
+#
+CT_LIBC_GLIBC_PKG_KSYM="GLIBC"
+CT_GLIBC_DIR_NAME="glibc"
+CT_GLIBC_USE_GNU=y
+CT_GLIBC_USE="GLIBC"
+CT_GLIBC_PKG_NAME="glibc"
+CT_GLIBC_SRC_RELEASE=y
+CT_GLIBC_PATCH_ORDER="global"
+# CT_GLIBC_V_2_28 is not set
+# CT_GLIBC_V_2_27 is not set
+# CT_GLIBC_V_2_26 is not set
+# CT_GLIBC_V_2_25 is not set
+# CT_GLIBC_V_2_24 is not set
+# CT_GLIBC_V_2_23 is not set
+# CT_GLIBC_V_2_19 is not set
+CT_GLIBC_V_2_17=y
+# CT_GLIBC_V_2_12_1 is not set
+# CT_GLIBC_NO_VERSIONS is not set
+CT_GLIBC_VERSION="2.17"
+CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)"
+CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
+CT_GLIBC_SIGNATURE_FORMAT="packed/.sig"
+CT_GLIBC_2_29_or_older=y
+CT_GLIBC_older_than_2_29=y
+CT_GLIBC_REQUIRE_older_than_2_29=y
+CT_GLIBC_2_27_or_older=y
+CT_GLIBC_older_than_2_27=y
+CT_GLIBC_2_26_or_older=y
+CT_GLIBC_older_than_2_26=y
+CT_GLIBC_2_25_or_older=y
+CT_GLIBC_older_than_2_25=y
+CT_GLIBC_2_24_or_older=y
+CT_GLIBC_older_than_2_24=y
+CT_GLIBC_2_23_or_older=y
+CT_GLIBC_older_than_2_23=y
+CT_GLIBC_2_20_or_older=y
+CT_GLIBC_older_than_2_20=y
+CT_GLIBC_2_17_or_later=y
+CT_GLIBC_2_17_or_older=y
+CT_GLIBC_later_than_2_14=y
+CT_GLIBC_2_14_or_later=y
+CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y
+CT_GLIBC_DEP_BINUTILS=y
+CT_GLIBC_DEP_GCC=y
+CT_GLIBC_DEP_PYTHON=y
+CT_GLIBC_HAS_NPTL_ADDON=y
+CT_GLIBC_HAS_PORTS_ADDON=y
+CT_GLIBC_HAS_LIBIDN_ADDON=y
+CT_GLIBC_USE_PORTS_ADDON=y
+CT_GLIBC_USE_NPTL_ADDON=y
+# CT_GLIBC_USE_LIBIDN_ADDON is not set
+CT_GLIBC_HAS_OBSOLETE_RPC=y
+CT_GLIBC_EXTRA_CONFIG_ARRAY=""
+CT_GLIBC_CONFIGPARMS=""
+CT_GLIBC_EXTRA_CFLAGS=""
+CT_GLIBC_ENABLE_OBSOLETE_RPC=y
+# CT_GLIBC_DISABLE_VERSIONING is not set
+CT_GLIBC_OLDEST_ABI=""
+CT_GLIBC_FORCE_UNWIND=y
+# CT_GLIBC_LOCALES is not set
+# CT_GLIBC_KERNEL_VERSION_NONE is not set
+CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y
+# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set
+CT_GLIBC_MIN_KERNEL="3.2.101"
+# CT_GLIBC_SSP_DEFAULT is not set
+# CT_GLIBC_SSP_NO is not set
+# CT_GLIBC_SSP_YES is not set
+# CT_GLIBC_SSP_ALL is not set
+# CT_GLIBC_SSP_STRONG is not set
+# CT_NEWLIB_USE_REDHAT is not set
+CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC"
 CT_LIBC_SUPPORT_THREADS_ANY=y
 CT_LIBC_SUPPORT_THREADS_NATIVE=y
 
@@ -343,100 +462,71 @@ CT_LIBC_SUPPORT_THREADS_NATIVE=y
 # Common C library options
 #
 CT_THREADS_NATIVE=y
+# CT_CREATE_LDSO_CONF is not set
 CT_LIBC_XLDD=y
 
 #
-# glibc other options
-#
-CT_LIBC_GLIBC_PORTS_EXTERNAL=y
-CT_LIBC_GLIBC_MAY_FORCE_PORTS=y
-CT_LIBC_glibc_familly=y
-CT_LIBC_GLIBC_EXTRA_CONFIG_ARRAY=""
-CT_LIBC_GLIBC_CONFIGPARMS=""
-CT_LIBC_GLIBC_EXTRA_CFLAGS=""
-CT_LIBC_EXTRA_CC_ARGS=""
-# CT_LIBC_DISABLE_VERSIONING is not set
-CT_LIBC_OLDEST_ABI=""
-CT_LIBC_GLIBC_FORCE_UNWIND=y
-CT_LIBC_GLIBC_USE_PORTS=y
-CT_LIBC_ADDONS_LIST=""
-
-#
-# WARNING !!!                                            
-#
-
-#
-#   For glibc >= 2.8, it can happen that the tarballs    
-#
-
-#
-#   for the addons are not available for download.       
-#
-
-#
-#   If that happens, bad luck... Try a previous version  
-#
-
-#
-#   or try again later... :-(                            
-#
-# CT_LIBC_LOCALES is not set
-# CT_LIBC_GLIBC_KERNEL_VERSION_NONE is not set
-CT_LIBC_GLIBC_KERNEL_VERSION_AS_HEADERS=y
-# CT_LIBC_GLIBC_KERNEL_VERSION_CHOSEN is not set
-CT_LIBC_GLIBC_MIN_KERNEL="3.2.72"
-
-#
 # C compiler
 #
-CT_CC="gcc"
 CT_CC_CORE_PASSES_NEEDED=y
 CT_CC_CORE_PASS_1_NEEDED=y
 CT_CC_CORE_PASS_2_NEEDED=y
-CT_CC_gcc=y
-# CT_CC_GCC_SHOW_LINARO is not set
-CT_CC_GCC_V_5_2_0=y
-# CT_CC_GCC_V_4_9_3 is not set
-# CT_CC_GCC_V_4_8_5 is not set
-# CT_CC_GCC_V_4_7_4 is not set
-# CT_CC_GCC_V_4_6_4 is not set
-# CT_CC_GCC_V_4_5_4 is not set
-# CT_CC_GCC_V_4_4_7 is not set
-# CT_CC_GCC_V_4_3_6 is not set
-# CT_CC_GCC_V_4_2_4 is not set
-CT_CC_GCC_4_2_or_later=y
-CT_CC_GCC_4_3_or_later=y
-CT_CC_GCC_4_4_or_later=y
-CT_CC_GCC_4_5_or_later=y
-CT_CC_GCC_4_6_or_later=y
-CT_CC_GCC_4_7_or_later=y
-CT_CC_GCC_4_8_or_later=y
-CT_CC_GCC_4_9_or_later=y
-CT_CC_GCC_5=y
-CT_CC_GCC_5_or_later=y
-CT_CC_GCC_HAS_GRAPHITE=y
-CT_CC_GCC_USE_GRAPHITE=y
-CT_CC_GCC_HAS_LTO=y
-CT_CC_GCC_USE_LTO=y
-CT_CC_GCC_HAS_PKGVERSION_BUGURL=y
-CT_CC_GCC_HAS_BUILD_ID=y
-CT_CC_GCC_HAS_LNK_HASH_STYLE=y
-CT_CC_GCC_USE_GMP_MPFR=y
-CT_CC_GCC_USE_MPC=y
-CT_CC_GCC_HAS_LIBQUADMATH=y
-CT_CC_GCC_HAS_LIBSANITIZER=y
-CT_CC_GCC_VERSION="5.2.0"
-# CT_CC_LANG_FORTRAN is not set
+CT_CC_SUPPORT_CXX=y
+CT_CC_SUPPORT_FORTRAN=y
+CT_CC_SUPPORT_ADA=y
+CT_CC_SUPPORT_OBJC=y
+CT_CC_SUPPORT_OBJCXX=y
+CT_CC_SUPPORT_GOLANG=y
+CT_CC_GCC=y
+CT_CC="gcc"
+CT_CC_CHOICE_KSYM="GCC"
+CT_CC_GCC_SHOW=y
+
+#
+# Options for gcc
+#
+CT_CC_GCC_PKG_KSYM="GCC"
+CT_GCC_DIR_NAME="gcc"
+CT_GCC_USE_GNU=y
+CT_GCC_USE="GCC"
+CT_GCC_PKG_NAME="gcc"
+CT_GCC_SRC_RELEASE=y
+CT_GCC_PATCH_ORDER="global"
+CT_GCC_V_8=y
+# CT_GCC_V_7 is not set
+# CT_GCC_V_6 is not set
+# CT_GCC_V_5 is not set
+# CT_GCC_V_4_9 is not set
+# CT_GCC_NO_VERSIONS is not set
+CT_GCC_VERSION="8.3.0"
+CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})"
+CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz"
+CT_GCC_SIGNATURE_FORMAT=""
+CT_GCC_later_than_7=y
+CT_GCC_7_or_later=y
+CT_GCC_later_than_6=y
+CT_GCC_6_or_later=y
+CT_GCC_later_than_5=y
+CT_GCC_5_or_later=y
+CT_GCC_later_than_4_9=y
+CT_GCC_4_9_or_later=y
+CT_GCC_later_than_4_8=y
+CT_GCC_4_8_or_later=y
+CT_CC_GCC_HAS_LIBMPX=y
 CT_CC_GCC_ENABLE_CXX_FLAGS=""
 CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY=""
 CT_CC_GCC_EXTRA_CONFIG_ARRAY=""
-CT_CC_GCC_EXTRA_ENV_ARRAY=""
 CT_CC_GCC_STATIC_LIBSTDCXX=y
 # CT_CC_GCC_SYSTEM_ZLIB is not set
+CT_CC_GCC_CONFIG_TLS=m
 
 #
 # Optimisation features
 #
+CT_CC_GCC_USE_GRAPHITE=y
+CT_CC_GCC_USE_LTO=y
 
 #
 # Settings for libraries running on target
@@ -465,97 +555,208 @@ CT_CC_GCC_DEC_FLOAT_AUTO=y
 # CT_CC_GCC_DEC_FLOAT_BID is not set
 # CT_CC_GCC_DEC_FLOAT_DPD is not set
 # CT_CC_GCC_DEC_FLOATS_NO is not set
-CT_CC_SUPPORT_CXX=y
-CT_CC_SUPPORT_FORTRAN=y
-CT_CC_SUPPORT_JAVA=y
-CT_CC_SUPPORT_ADA=y
-CT_CC_SUPPORT_OBJC=y
-CT_CC_SUPPORT_OBJCXX=y
-CT_CC_SUPPORT_GOLANG=y
+CT_ALL_CC_CHOICES="GCC"
 
 #
 # Additional supported languages:
 #
 CT_CC_LANG_CXX=y
-# CT_CC_LANG_JAVA is not set
+# CT_CC_LANG_FORTRAN is not set
 
 #
 # Debug facilities
 #
-# CT_DEBUG_dmalloc is not set
-# CT_DEBUG_duma is not set
-# CT_DEBUG_gdb is not set
-# CT_DEBUG_ltrace is not set
-# CT_DEBUG_strace is not set
+# CT_DEBUG_DUMA is not set
+# CT_DEBUG_GDB is not set
+# CT_DEBUG_LTRACE is not set
+# CT_DEBUG_STRACE is not set
+CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE"
 
 #
 # Companion libraries
 #
-CT_COMPLIBS_NEEDED=y
+# CT_COMPLIBS_CHECK is not set
+# CT_COMP_LIBS_CLOOG is not set
+# CT_COMP_LIBS_EXPAT is not set
+CT_COMP_LIBS_GETTEXT=y
+CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT"
+CT_GETTEXT_DIR_NAME="gettext"
+CT_GETTEXT_PKG_NAME="gettext"
+CT_GETTEXT_SRC_RELEASE=y
+CT_GETTEXT_PATCH_ORDER="global"
+CT_GETTEXT_V_0_19_8_1=y
+# CT_GETTEXT_NO_VERSIONS is not set
+CT_GETTEXT_VERSION="0.19.8.1"
+CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)"
+CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz"
+CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig"
+CT_COMP_LIBS_GMP=y
+CT_COMP_LIBS_GMP_PKG_KSYM="GMP"
+CT_GMP_DIR_NAME="gmp"
+CT_GMP_PKG_NAME="gmp"
+CT_GMP_SRC_RELEASE=y
+CT_GMP_PATCH_ORDER="global"
+CT_GMP_V_6_1=y
+# CT_GMP_NO_VERSIONS is not set
+CT_GMP_VERSION="6.1.2"
+CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)"
+CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2"
+CT_GMP_SIGNATURE_FORMAT="packed/.sig"
+CT_GMP_later_than_5_1_0=y
+CT_GMP_5_1_0_or_later=y
+CT_GMP_later_than_5_0_0=y
+CT_GMP_5_0_0_or_later=y
+CT_GMP_REQUIRE_5_0_0_or_later=y
+CT_COMP_LIBS_ISL=y
+CT_COMP_LIBS_ISL_PKG_KSYM="ISL"
+CT_ISL_DIR_NAME="isl"
+CT_ISL_PKG_NAME="isl"
+CT_ISL_SRC_RELEASE=y
+CT_ISL_PATCH_ORDER="global"
+CT_ISL_V_0_20=y
+# CT_ISL_V_0_19 is not set
+# CT_ISL_V_0_18 is not set
+# CT_ISL_V_0_17 is not set
+# CT_ISL_V_0_16 is not set
+# CT_ISL_V_0_15 is not set
+# CT_ISL_NO_VERSIONS is not set
+CT_ISL_VERSION="0.20"
+CT_ISL_MIRRORS="http://isl.gforge.inria.fr"
+CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
+CT_ISL_SIGNATURE_FORMAT=""
+CT_ISL_later_than_0_18=y
+CT_ISL_0_18_or_later=y
+CT_ISL_later_than_0_15=y
+CT_ISL_0_15_or_later=y
+CT_ISL_REQUIRE_0_15_or_later=y
+CT_ISL_later_than_0_14=y
+CT_ISL_0_14_or_later=y
+CT_ISL_REQUIRE_0_14_or_later=y
+CT_ISL_later_than_0_13=y
+CT_ISL_0_13_or_later=y
+CT_ISL_later_than_0_12=y
+CT_ISL_0_12_or_later=y
+CT_ISL_REQUIRE_0_12_or_later=y
+# CT_COMP_LIBS_LIBELF is not set
+CT_COMP_LIBS_LIBICONV=y
+CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV"
+CT_LIBICONV_DIR_NAME="libiconv"
+CT_LIBICONV_PKG_NAME="libiconv"
+CT_LIBICONV_SRC_RELEASE=y
+CT_LIBICONV_PATCH_ORDER="global"
+CT_LIBICONV_V_1_15=y
+# CT_LIBICONV_NO_VERSIONS is not set
+CT_LIBICONV_VERSION="1.15"
+CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)"
+CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz"
+CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig"
+CT_COMP_LIBS_MPC=y
+CT_COMP_LIBS_MPC_PKG_KSYM="MPC"
+CT_MPC_DIR_NAME="mpc"
+CT_MPC_PKG_NAME="mpc"
+CT_MPC_SRC_RELEASE=y
+CT_MPC_PATCH_ORDER="global"
+CT_MPC_V_1_1=y
+# CT_MPC_V_1_0 is not set
+# CT_MPC_NO_VERSIONS is not set
+CT_MPC_VERSION="1.1.0"
+CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)"
+CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_MPC_ARCHIVE_FORMATS=".tar.gz"
+CT_MPC_SIGNATURE_FORMAT="packed/.sig"
+CT_MPC_1_1_0_or_later=y
+CT_MPC_1_1_0_or_older=y
+CT_COMP_LIBS_MPFR=y
+CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR"
+CT_MPFR_DIR_NAME="mpfr"
+CT_MPFR_PKG_NAME="mpfr"
+CT_MPFR_SRC_RELEASE=y
+CT_MPFR_PATCH_ORDER="global"
+CT_MPFR_V_4_0=y
+# CT_MPFR_V_3_1 is not set
+# CT_MPFR_NO_VERSIONS is not set
+CT_MPFR_VERSION="4.0.2"
+CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)"
+CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip"
+CT_MPFR_SIGNATURE_FORMAT="packed/.asc"
+CT_MPFR_later_than_4_0_0=y
+CT_MPFR_4_0_0_or_later=y
+CT_MPFR_later_than_3_0_0=y
+CT_MPFR_3_0_0_or_later=y
+CT_MPFR_REQUIRE_3_0_0_or_later=y
+CT_COMP_LIBS_NCURSES=y
+CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES"
+CT_NCURSES_DIR_NAME="ncurses"
+CT_NCURSES_PKG_NAME="ncurses"
+CT_NCURSES_SRC_RELEASE=y
+CT_NCURSES_PATCH_ORDER="global"
+CT_NCURSES_V_6_1=y
+# CT_NCURSES_V_6_0 is not set
+# CT_NCURSES_NO_VERSIONS is not set
+CT_NCURSES_VERSION="6.1"
+CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)"
+CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_NCURSES_ARCHIVE_FORMATS=".tar.gz"
+CT_NCURSES_SIGNATURE_FORMAT="packed/.sig"
+CT_NCURSES_HOST_CONFIG_ARGS=""
+CT_NCURSES_HOST_DISABLE_DB=y
+CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100"
+CT_NCURSES_TARGET_CONFIG_ARGS=""
+# CT_NCURSES_TARGET_DISABLE_DB is not set
+CT_NCURSES_TARGET_FALLBACKS=""
+CT_COMP_LIBS_ZLIB=y
+CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB"
+CT_ZLIB_DIR_NAME="zlib"
+CT_ZLIB_PKG_NAME="zlib"
+CT_ZLIB_SRC_RELEASE=y
+CT_ZLIB_PATCH_ORDER="global"
+CT_ZLIB_V_1_2_11=y
+# CT_ZLIB_NO_VERSIONS is not set
+CT_ZLIB_VERSION="1.2.11"
+CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}"
+CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz"
+CT_ZLIB_SIGNATURE_FORMAT="packed/.asc"
+CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB"
 CT_LIBICONV_NEEDED=y
 CT_GETTEXT_NEEDED=y
 CT_GMP_NEEDED=y
 CT_MPFR_NEEDED=y
 CT_ISL_NEEDED=y
 CT_MPC_NEEDED=y
-CT_COMPLIBS=y
+CT_NCURSES_NEEDED=y
+CT_ZLIB_NEEDED=y
 CT_LIBICONV=y
 CT_GETTEXT=y
 CT_GMP=y
 CT_MPFR=y
 CT_ISL=y
 CT_MPC=y
-CT_LIBICONV_V_1_14=y
-CT_LIBICONV_VERSION="1.14"
-CT_GETTEXT_V_0_19_6=y
-CT_GETTEXT_VERSION="0.19.6"
-CT_GMP_V_6_0_0=y
-# CT_GMP_V_5_1_3 is not set
-# CT_GMP_V_5_1_1 is not set
-# CT_GMP_V_5_0_2 is not set
-# CT_GMP_V_5_0_1 is not set
-# CT_GMP_V_4_3_2 is not set
-# CT_GMP_V_4_3_1 is not set
-# CT_GMP_V_4_3_0 is not set
-CT_GMP_5_0_2_or_later=y
-CT_GMP_VERSION="6.0.0a"
-CT_MPFR_V_3_1_3=y
-# CT_MPFR_V_3_1_2 is not set
-# CT_MPFR_V_3_1_0 is not set
-# CT_MPFR_V_3_0_1 is not set
-# CT_MPFR_V_3_0_0 is not set
-# CT_MPFR_V_2_4_2 is not set
-# CT_MPFR_V_2_4_1 is not set
-# CT_MPFR_V_2_4_0 is not set
-CT_MPFR_VERSION="3.1.3"
-CT_ISL_V_0_14=y
-# CT_ISL_V_0_12_2 is not set
-CT_ISL_V_0_14_or_later=y
-CT_ISL_V_0_12_or_later=y
-CT_ISL_VERSION="0.14"
-# CT_CLOOG_V_0_18_4 is not set
-# CT_CLOOG_V_0_18_1 is not set
-# CT_CLOOG_V_0_18_0 is not set
-CT_MPC_V_1_0_3=y
-# CT_MPC_V_1_0_2 is not set
-# CT_MPC_V_1_0_1 is not set
-# CT_MPC_V_1_0 is not set
-# CT_MPC_V_0_9 is not set
-# CT_MPC_V_0_8_2 is not set
-# CT_MPC_V_0_8_1 is not set
-# CT_MPC_V_0_7 is not set
-CT_MPC_VERSION="1.0.3"
-
-#
-# Companion libraries common options
-#
-# CT_COMPLIBS_CHECK is not set
+CT_NCURSES=y
+CT_ZLIB=y
 
 #
 # Companion tools
 #
-
-#
-# READ HELP before you say 'Y' below !!!
-#
-# CT_COMP_TOOLS is not set
+# CT_COMP_TOOLS_FOR_HOST is not set
+# CT_COMP_TOOLS_AUTOCONF is not set
+# CT_COMP_TOOLS_AUTOMAKE is not set
+# CT_COMP_TOOLS_BISON is not set
+# CT_COMP_TOOLS_DTC is not set
+# CT_COMP_TOOLS_LIBTOOL is not set
+# CT_COMP_TOOLS_M4 is not set
+# CT_COMP_TOOLS_MAKE is not set
+CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE"
diff --git a/src/ci/docker/dist-armhf-linux/patches/glibc/ports-2.16.0/001-arm-libgcc_s_resume-used.patch b/src/ci/docker/dist-armhf-linux/patches/glibc/ports-2.16.0/001-arm-libgcc_s_resume-used.patch
deleted file mode 100644
index 871d5225c0f..00000000000
--- a/src/ci/docker/dist-armhf-linux/patches/glibc/ports-2.16.0/001-arm-libgcc_s_resume-used.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-commit bdb24c2851fd5f0ad9b82d7ea1db911d334b02d2
-Author: Joseph Myers <joseph@codesourcery.com>
-Date:   Tue May 20 21:27:13 2014 +0000
-
-    Fix ARM build with GCC trunk.
-    
-    sysdeps/unix/sysv/linux/arm/unwind-resume.c and
-    sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c have static
-    variables that are written in C code but only read from toplevel asms.
-    Current GCC trunk now optimizes away such apparently write-only static
-    variables, so causing a build failure.  This patch marks those
-    variables with __attribute_used__ to avoid that optimization.
-    
-    Tested that this fixes the build for ARM.
-    
-            * sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c
-            (libgcc_s_resume): Use __attribute_used__.
-            * sysdeps/unix/sysv/linux/arm/unwind-resume.c (libgcc_s_resume):
-            Likewise.
-
-diff --git a/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c b/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
-index 29e2c2b00b04..e848bfeffdcb 100644
---- a/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
-+++ b/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
-@@ -22,7 +22,8 @@
- #include <pthreadP.h>
- 
- static void *libgcc_s_handle;
--static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
-+static void (*libgcc_s_resume) (struct _Unwind_Exception *exc)
-+  __attribute_used__;
- static _Unwind_Reason_Code (*libgcc_s_personality)
-   (_Unwind_State, struct _Unwind_Exception *, struct _Unwind_Context *);
- static _Unwind_Reason_Code (*libgcc_s_forcedunwind)
-diff --git a/sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c b/sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c
-index 285b99b5ed0d..48d00fc83641 100644
---- a/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c
-+++ b/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c
-@@ -20,7 +20,8 @@
- #include <stdio.h>
- #include <unwind.h>
- 
--static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
-+static void (*libgcc_s_resume) (struct _Unwind_Exception *exc)
-+  __attribute_used__;
- static _Unwind_Reason_Code (*libgcc_s_personality)
-   (_Unwind_State, struct _Unwind_Exception *, struct _Unwind_Context *);
- 
diff --git a/src/ci/docker/dist-armv7-linux/Dockerfile b/src/ci/docker/dist-armv7-linux/Dockerfile
index 417171a861d..f42a2bd8122 100644
--- a/src/ci/docker/dist-armv7-linux/Dockerfile
+++ b/src/ci/docker/dist-armv7-linux/Dockerfile
@@ -3,8 +3,8 @@ FROM ubuntu:16.04
 COPY scripts/cross-apt-packages.sh /scripts/
 RUN sh /scripts/cross-apt-packages.sh
 
-COPY dist-armv7-linux/crosstool-ng.sh /scripts/
-RUN sh /scripts/crosstool-ng.sh
+COPY scripts/crosstool-ng-1.24.sh /scripts/
+RUN sh /scripts/crosstool-ng-1.24.sh
 
 COPY scripts/rustbuild-setup.sh /scripts/
 RUN sh /scripts/rustbuild-setup.sh
diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile
index 2a68a25be21..4ac5e23d683 100644
--- a/src/ci/docker/dist-various-1/Dockerfile
+++ b/src/ci/docker/dist-various-1/Dockerfile
@@ -72,6 +72,9 @@ RUN ./install-mips-musl.sh
 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-gnueabi
 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 @@ ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \
     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 00000000000..d72976c2858
--- /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/dist-armv7-linux/crosstool-ng.sh b/src/ci/docker/scripts/crosstool-ng-1.24.sh
index fb067a79a5c..fb067a79a5c 100644
--- a/src/ci/docker/dist-armv7-linux/crosstool-ng.sh
+++ b/src/ci/docker/scripts/crosstool-ng-1.24.sh
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 81a334cd487..813c35cb9d5 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -103,6 +103,7 @@ x--expand-yaml-anchors--remove:
         uses: rust-lang/simpleinfra/github-actions/cancel-outdated-builds@master
         with:
           github_token: "${{ secrets.github_token }}"
+        if: success() && !env.SKIP_JOB && github.ref != 'refs/heads/try'
         <<: *step
 
       - name: add extra environment variables
diff --git a/src/doc/book b/src/doc/book
-Subproject 6fb3705e5230311b096d47f7e2c91f9ce24393d
+Subproject c8841f2841a2d26124319ddadd1b6a245f9a185
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject 9f797e65e6bcc79419975b17aff8e21c9adc039
+Subproject 411197b0e77590c967e37e8f6ec681abd359afe
diff --git a/src/doc/reference b/src/doc/reference
-Subproject e2f11fe4d6a5ecb471c70323197da43c70cb96b
+Subproject 89dd146154474559536d5d4049a03831c501dee
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject cb369ae95ca36b841960182d26f6d5d9b2e3cc1
+Subproject edd2a7e687358712608896730c083cb76c7b401
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index 0dc81378e05..8dc6257ce2e 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -257,9 +257,8 @@ them in parallel. Increasing parallelism may speed up compile times, but may
 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/book.toml b/src/doc/unstable-book/book.toml
index 5b2e19bd7aa..0cd56d09404 100644
--- a/src/doc/unstable-book/book.toml
+++ b/src/doc/unstable-book/book.toml
@@ -1,3 +1,6 @@
 [book]
 title = "The Rust Unstable Book"
 author = "The Rust Community"
+
+[output.html]
+git-repository-url = "https://github.com/rust-lang/rust/tree/master/src/doc/unstable-book"
diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md
index 414ac7e63a3..7ebd8054ba0 100644
--- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md
+++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md
@@ -6,73 +6,78 @@ The tracking issue for this feature is: [#39699](https://github.com/rust-lang/ru
 
 This feature allows for use of one of following sanitizers:
 
-* [AddressSanitizer][clang-asan] a faster memory error detector. Can
-  detect out-of-bounds access to heap, stack, and globals, use after free, use
-  after return, double free, invalid free, memory leaks.
+* [AddressSanitizer][clang-asan] a fast memory error detector.
 * [LeakSanitizer][clang-lsan] a run-time memory leak detector.
 * [MemorySanitizer][clang-msan] a detector of uninitialized reads.
 * [ThreadSanitizer][clang-tsan] a fast data race detector.
 
-To enable a sanitizer compile with `-Zsanitizer=...` option, where value is one
-of `address`, `leak`, `memory` or `thread`.
+To enable a sanitizer compile with `-Zsanitizer=address`, `-Zsanitizer=leak`,
+`-Zsanitizer=memory` or `-Zsanitizer=thread`. Only a single sanitizer can be
+enabled at a time.
 
-# Examples
+# AddressSanitizer
 
-This sections show various issues that can be detected with sanitizers.  For
-simplicity, the examples are prepared under assumption that optimization level
-used is zero.
+AddressSanitizer is a memory error detector. It can detect the following types
+of bugs:
 
-## AddressSanitizer
+* Out of bound accesses to heap, stack and globals
+* Use after free
+* Use after return (runtime flag `ASAN_OPTIONS=detect_stack_use_after_return=1`)
+* Use after scope
+* Double-free, invalid free
+* Memory leaks
+
+AddressSanitizer is supported on the following targets:
+
+* `x86_64-apple-darwin`
+* `x86_64-unknown-linux-gnu`
+
+AddressSanitizer works with non-instrumented code although it will impede its
+ability to detect some bugs.  It is not expected to produce false positive
+reports.
+
+## Examples
 
 Stack buffer overflow:
 
-```shell
-$ cat a.rs
+```rust
 fn main() {
     let xs = [0, 1, 2, 3];
     let _y = unsafe { *xs.as_ptr().offset(4) };
 }
-$ rustc -Zsanitizer=address a.rs
-$ ./a
-=================================================================
-==10029==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffcc15f43d0 at pc 0x55f77dc015c5 bp 0x7ffcc15f4390 sp 0x7ffcc15f4388
-READ of size 4 at 0x7ffcc15f43d0 thread T0
-    #0 0x55f77dc015c4 in a::main::hab3bd2a745c2d0ac (/tmp/a+0xa5c4)
-    #1 0x55f77dc01cdb in std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::haa8c76d1faa7b7ca (/tmp/a+0xacdb)
-    #2 0x55f77dc90f02 in std::rt::lang_start_internal::_$u7b$$u7b$closure$u7d$$u7d$::hfeb9a1aef9ac820d /rustc/c27f7568bc74c418996892028a629eed5a7f5f00/src/libstd/rt.rs:48:12
-    #3 0x55f77dc90f02 in std::panicking::try::do_call::h12f0919717b8e0a6 /rustc/c27f7568bc74c418996892028a629eed5a7f5f00/src/libstd/panicking.rs:288:39
-    #4 0x55f77dc926c9 in __rust_maybe_catch_panic /rustc/c27f7568bc74c418996892028a629eed5a7f5f00/src/libpanic_unwind/lib.rs:80:7
-    #5 0x55f77dc9197c in std::panicking::try::h413b21cdcd6cfd86 /rustc/c27f7568bc74c418996892028a629eed5a7f5f00/src/libstd/panicking.rs:267:12
-    #6 0x55f77dc9197c in std::panic::catch_unwind::hc5cc8ef2fd73424d /rustc/c27f7568bc74c418996892028a629eed5a7f5f00/src/libstd/panic.rs:396:8
-    #7 0x55f77dc9197c in std::rt::lang_start_internal::h2039f418ab92218f /rustc/c27f7568bc74c418996892028a629eed5a7f5f00/src/libstd/rt.rs:47:24
-    #8 0x55f77dc01c61 in std::rt::lang_start::ha905d28f6b61d691 (/tmp/a+0xac61)
-    #9 0x55f77dc0163a in main (/tmp/a+0xa63a)
-    #10 0x7f9b3cf5bbba in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26bba)
-    #11 0x55f77dc01289 in _start (/tmp/a+0xa289)
-
-Address 0x7ffcc15f43d0 is located in stack of thread T0 at offset 48 in frame
-    #0 0x55f77dc0135f in a::main::hab3bd2a745c2d0ac (/tmp/a+0xa35f)
+```
+
+```shell
+$ export RUSTFLAGS=-Zsanitizer=address RUSTDOCFLAGS=-Zsanitizer=address
+$ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
+==37882==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffe400e6250 at pc 0x5609a841fb20 bp 0x7ffe400e6210 sp 0x7ffe400e6208
+READ of size 4 at 0x7ffe400e6250 thread T0
+    #0 0x5609a841fb1f in example::main::h628ffc6626ed85b2 /.../src/main.rs:3:23
+    ...
+
+Address 0x7ffe400e6250 is located in stack of thread T0 at offset 48 in frame
+    #0 0x5609a841f8af in example::main::h628ffc6626ed85b2 /.../src/main.rs:1
 
   This frame has 1 object(s):
-    [32, 48) 'xs' <== Memory access at offset 48 overflows this variable
+    [32, 48) 'xs' (line 2) <== Memory access at offset 48 overflows this variable
 HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
       (longjmp and C++ exceptions *are* supported)
-SUMMARY: AddressSanitizer: stack-buffer-overflow (/tmp/a+0xa5c4) in a::main::hab3bd2a745c2d0ac
+SUMMARY: AddressSanitizer: stack-buffer-overflow /.../src/main.rs:3:23 in example::main::h628ffc6626ed85b2
 Shadow bytes around the buggy address:
-  0x1000182b6820: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-  0x1000182b6830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-  0x1000182b6840: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-  0x1000182b6850: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-  0x1000182b6860: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-=>0x1000182b6870: 00 00 00 00 f1 f1 f1 f1 00 00[f3]f3 00 00 00 00
-  0x1000182b6880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-  0x1000182b6890: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-  0x1000182b68a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-  0x1000182b68b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-  0x1000182b68c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+  0x100048014bf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+  0x100048014c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+  0x100048014c10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+  0x100048014c20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+  0x100048014c30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+=>0x100048014c40: 00 00 00 00 f1 f1 f1 f1 00 00[f3]f3 00 00 00 00
+  0x100048014c50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+  0x100048014c60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+  0x100048014c70: f1 f1 f1 f1 00 00 f3 f3 00 00 00 00 00 00 00 00
+  0x100048014c80: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
+  0x100048014c90: 00 00 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
 Shadow byte legend (one shadow byte represents 8 application bytes):
   Addressable:           00
-  Partially addressable: 01 02 03 04 05 06 07 
+  Partially addressable: 01 02 03 04 05 06 07
   Heap left redzone:       fa
   Freed heap region:       fd
   Stack left redzone:      f1
@@ -90,13 +95,12 @@ Shadow byte legend (one shadow byte represents 8 application bytes):
   Left alloca redzone:     ca
   Right alloca redzone:    cb
   Shadow gap:              cc
-==10029==ABORTING
+==37882==ABORTING
 ```
 
 Use of a stack object after its scope has already ended:
 
-```shell
-$ cat b.rs
+```rust
 static mut P: *mut usize = std::ptr::null_mut();
 
 fn main() {
@@ -108,42 +112,38 @@ fn main() {
         std::ptr::write_volatile(P, 123);
     }
 }
-$ rustc -Zsanitizer=address b.rs
-$./b
+```
+
+```shell
+$ export RUSTFLAGS=-Zsanitizer=address RUSTDOCFLAGS=-Zsanitizer=address
+$ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
 =================================================================
-==424427==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7fff67be6be0 at pc 0x5647a3ea4658 bp 0x7fff67be6b90 sp 0x7fff67be6b88
-WRITE of size 8 at 0x7fff67be6be0 thread T0
-    #0 0x5647a3ea4657 in core::ptr::write_volatile::h4b04601757d0376d (/tmp/b+0xb8657)
-    #1 0x5647a3ea4432 in b::main::h5574a756e615c9cf (/tmp/b+0xb8432)
-    #2 0x5647a3ea480b in std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::hd57e7ee01866077e (/tmp/b+0xb880b)
-    #3 0x5647a3eab412 in std::panicking::try::do_call::he0421ca82dd11ba3 (.llvm.8083791802951296215) (/tmp/b+0xbf412)
-    #4 0x5647a3eacb26 in __rust_maybe_catch_panic (/tmp/b+0xc0b26)
-    #5 0x5647a3ea5b66 in std::rt::lang_start_internal::h19bc96b28f670a64 (/tmp/b+0xb9b66)
-    #6 0x5647a3ea4788 in std::rt::lang_start::h642d10b4b6965fb8 (/tmp/b+0xb8788)
-    #7 0x5647a3ea449a in main (/tmp/b+0xb849a)
-    #8 0x7fd1d18b3bba in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26bba)
-    #9 0x5647a3df7299 in _start (/tmp/b+0xb299)
-
-Address 0x7fff67be6be0 is located in stack of thread T0 at offset 32 in frame
-    #0 0x5647a3ea433f in b::main::h5574a756e615c9cf (/tmp/b+0xb833f)
+==39249==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffc7ed3e1a0 at pc 0x55c98b262a8e bp 0x7ffc7ed3e050 sp 0x7ffc7ed3e048
+WRITE of size 8 at 0x7ffc7ed3e1a0 thread T0
+    #0 0x55c98b262a8d in core::ptr::write_volatile::he21f1df5a82f329a /.../src/rust/src/libcore/ptr/mod.rs:1048:5
+    #1 0x55c98b262cd2 in example::main::h628ffc6626ed85b2 /.../src/main.rs:9:9
+    ...
+
+Address 0x7ffc7ed3e1a0 is located in stack of thread T0 at offset 32 in frame
+    #0 0x55c98b262bdf in example::main::h628ffc6626ed85b2 /.../src/main.rs:3
 
   This frame has 1 object(s):
-    [32, 40) 'x' <== Memory access at offset 32 is inside this variable
+    [32, 40) 'x' (line 6) <== Memory access at offset 32 is inside this variable
 HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
       (longjmp and C++ exceptions *are* supported)
-SUMMARY: AddressSanitizer: stack-use-after-scope (/tmp/b+0xb8657) in core::ptr::write_volatile::h4b04601757d0376d
+SUMMARY: AddressSanitizer: stack-use-after-scope /.../src/rust/src/libcore/ptr/mod.rs:1048:5 in core::ptr::write_volatile::he21f1df5a82f329a
 Shadow bytes around the buggy address:
-  0x10006cf74d20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-  0x10006cf74d30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-  0x10006cf74d40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-  0x10006cf74d50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-  0x10006cf74d60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-=>0x10006cf74d70: 00 00 00 00 00 00 00 00 f1 f1 f1 f1[f8]f3 f3 f3
-  0x10006cf74d80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-  0x10006cf74d90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-  0x10006cf74da0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-  0x10006cf74db0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-  0x10006cf74dc0: f1 f1 f1 f1 00 f3 f3 f3 00 00 00 00 00 00 00 00
+  0x10000fd9fbe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+  0x10000fd9fbf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+  0x10000fd9fc00: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
+  0x10000fd9fc10: f8 f8 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
+  0x10000fd9fc20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+=>0x10000fd9fc30: f1 f1 f1 f1[f8]f3 f3 f3 00 00 00 00 00 00 00 00
+  0x10000fd9fc40: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
+  0x10000fd9fc50: 00 00 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
+  0x10000fd9fc60: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 f3 f3
+  0x10000fd9fc70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+  0x10000fd9fc80: 00 00 00 00 f1 f1 f1 f1 00 00 f3 f3 00 00 00 00
 Shadow byte legend (one shadow byte represents 8 application bytes):
   Addressable:           00
   Partially addressable: 01 02 03 04 05 06 07
@@ -164,17 +164,26 @@ Shadow byte legend (one shadow byte represents 8 application bytes):
   Left alloca redzone:     ca
   Right alloca redzone:    cb
   Shadow gap:              cc
-==424427==ABORTING
+==39249==ABORTING
 ```
 
-## MemorySanitizer
+# MemorySanitizer
+
+MemorySanitizer is detector of uninitialized reads. It is only supported on the
+`x86_64-unknown-linux-gnu` target.
+
+MemorySanitizer requires all program code to be instrumented. C/C++ dependencies
+need to be recompiled using Clang with `-fsanitize=memory` option. Failing to
+achieve that will result in false positive reports.
+
+## Example
 
-Use of uninitialized memory. Note that we are using `-Zbuild-std` to instrument
-the standard library, and passing `-Zsanitizer-track-origins` to track the
+Detecting the use of uninitialized memory. The `-Zbuild-std` flag rebuilds and
+instruments the standard library, and is strictly necessary for the correct
+operation of the tool. The `-Zsanitizer-track-origins` enables tracking of the
 origins of uninitialized memory:
 
-```shell
-$ cat src/main.rs
+```rust
 use std::mem::MaybeUninit;
 
 fn main() {
@@ -184,7 +193,9 @@ fn main() {
         println!("{}", a[2]);
     }
 }
+```
 
+```shell
 $ export \
   CC=clang \
   CXX=clang++ \
@@ -193,7 +204,7 @@ $ export \
   RUSTFLAGS='-Zsanitizer=memory -Zsanitizer-memory-track-origins' \
   RUSTDOCFLAGS='-Zsanitizer=memory -Zsanitizer-memory-track-origins'
 $ cargo clean
-$ cargo -Zbuild-std run --target x86_64-unknown-linux-gnu
+$ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
 ==9416==WARNING: MemorySanitizer: use-of-uninitialized-value
     #0 0x560c04f7488a in core::fmt::num::imp::fmt_u64::haa293b0b098501ca $RUST/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/src/rust/src/libcore/fmt/num.rs:202:16
 ...
@@ -205,6 +216,55 @@ $ cargo -Zbuild-std run --target x86_64-unknown-linux-gnu
     #0 0x560c04b2bc50 in memory::main::hd2333c1899d997f5 $CWD/src/main.rs:3
 ```
 
+# ThreadSanitizer
+
+ThreadSanitizer is a data race detection tool. It is supported on the following
+targets:
+
+* `x86_64-apple-darwin`
+* `x86_64-unknown-linux-gnu`
+
+To work correctly ThreadSanitizer needs to be "aware" of all synchronization
+operations in a program. It generally achieves that through combination of
+library interception (for example synchronization performed through
+`pthread_mutex_lock` / `pthread_mutex_unlock`) and compile time instrumentation
+(e.g. atomic operations). Using it without instrumenting all the program code
+can lead to false positive reports.
+
+ThreadSanitizer does not support atomic fences `std::sync::atomic::fence`,
+nor synchronization performed using inline assembly code.
+
+## Example
+
+```rust
+static mut A: usize = 0;
+
+fn main() {
+    let t = std::thread::spawn(|| {
+        unsafe { A += 1 };
+    });
+    unsafe { A += 1 };
+
+    t.join().unwrap();
+}
+```
+
+```shell
+$ export RUSTFLAGS=-Zsanitizer=thread RUSTDOCFLAGS=-Zsanitizer=thread
+$ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
+==================
+WARNING: ThreadSanitizer: data race (pid=10574)
+  Read of size 8 at 0x5632dfe3d030 by thread T1:
+    #0 example::main::_$u7b$$u7b$closure$u7d$$u7d$::h23f64b0b2f8c9484 ../src/main.rs:5:18 (example+0x86cec)
+    ...
+
+  Previous write of size 8 at 0x5632dfe3d030 by main thread:
+    #0 example::main::h628ffc6626ed85b2 /.../src/main.rs:7:14 (example+0x868c8)
+    ...
+    #11 main <null> (example+0x86a1a)
+
+  Location is global 'example::A::h43ac149ddf992709' of size 8 at 0x5632dfe3d030 (example+0x000000bd9030)
+```
 
 # Instrumentation of external dependencies and std
 
@@ -231,6 +291,10 @@ In more practical terms when using cargo always remember to pass `--target`
 flag, so that rustflags will not be applied to build scripts and procedural
 macros.
 
+# Symbolizing the Reports
+
+Sanitizers produce symbolized stacktraces when llvm-symbolizer binary is in `PATH`.
+
 # Additional Information
 
 * [Sanitizers project page](https://github.com/google/sanitizers/wiki/)
diff --git a/src/doc/unstable-book/src/language-features/generators.md b/src/doc/unstable-book/src/language-features/generators.md
index 8bc62418b39..7b865c9c679 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 @@ Feedback on the design and usage is always appreciated!
 
 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 @@ point for executing the `Generator` itself.
 
 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 e07f716e567..da01d9228f1 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 @@ llvm_asm!("xor %eax, %eax" ::: "eax");
 
 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 c42f942c63c..a0ba47e1dbe 100755
--- a/src/etc/generate-deriving-span-tests.py
+++ b/src/etc/generate-deriving-span-tests.py
@@ -15,9 +15,6 @@ TEST_DIR = os.path.abspath(
     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/liballoc/alloc.rs b/src/liballoc/alloc.rs
index 9f82b2c6fa6..66575e3ef55 100644
--- a/src/liballoc/alloc.rs
+++ b/src/liballoc/alloc.rs
@@ -2,7 +2,7 @@
 
 #![stable(feature = "alloc_module", since = "1.28.0")]
 
-use core::intrinsics::{min_align_of_val, size_of_val};
+use core::intrinsics::{self, min_align_of_val, size_of_val};
 use core::ptr::{NonNull, Unique};
 use core::usize;
 
@@ -165,11 +165,19 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
 #[unstable(feature = "allocator_api", issue = "32838")]
 unsafe impl AllocRef for Global {
     #[inline]
-    fn alloc(&mut self, layout: Layout) -> Result<(NonNull<u8>, usize), AllocErr> {
-        if layout.size() == 0 {
-            Ok((layout.dangling(), 0))
-        } else {
-            unsafe { NonNull::new(alloc(layout)).ok_or(AllocErr).map(|p| (p, layout.size())) }
+    fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr> {
+        unsafe {
+            let size = layout.size();
+            if size == 0 {
+                Ok(MemoryBlock { ptr: layout.dangling(), size: 0 })
+            } else {
+                let raw_ptr = match init {
+                    AllocInit::Uninitialized => alloc(layout),
+                    AllocInit::Zeroed => alloc_zeroed(layout),
+                };
+                let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
+                Ok(MemoryBlock { ptr, size })
+            }
         }
     }
 
@@ -181,32 +189,71 @@ unsafe impl AllocRef for Global {
     }
 
     #[inline]
-    unsafe fn realloc(
+    unsafe fn grow(
         &mut self,
         ptr: NonNull<u8>,
         layout: Layout,
         new_size: usize,
-    ) -> Result<(NonNull<u8>, usize), AllocErr> {
-        match (layout.size(), new_size) {
-            (0, 0) => Ok((layout.dangling(), 0)),
-            (0, _) => self.alloc(Layout::from_size_align_unchecked(new_size, layout.align())),
-            (_, 0) => {
-                self.dealloc(ptr, layout);
-                Ok((layout.dangling(), 0))
+        placement: ReallocPlacement,
+        init: AllocInit,
+    ) -> Result<MemoryBlock, AllocErr> {
+        let size = layout.size();
+        debug_assert!(
+            new_size >= size,
+            "`new_size` must be greater than or equal to `memory.size()`"
+        );
+
+        if size == new_size {
+            return Ok(MemoryBlock { ptr, size });
+        }
+
+        match placement {
+            ReallocPlacement::InPlace => Err(AllocErr),
+            ReallocPlacement::MayMove if layout.size() == 0 => {
+                let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
+                self.alloc(new_layout, init)
+            }
+            ReallocPlacement::MayMove => {
+                // `realloc` probably checks for `new_size > size` or something similar.
+                intrinsics::assume(new_size > size);
+                let ptr = realloc(ptr.as_ptr(), layout, new_size);
+                let memory =
+                    MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size };
+                init.init_offset(memory, size);
+                Ok(memory)
             }
-            (_, _) => NonNull::new(realloc(ptr.as_ptr(), layout, new_size))
-                .ok_or(AllocErr)
-                .map(|p| (p, new_size)),
         }
     }
 
     #[inline]
-    fn alloc_zeroed(&mut self, layout: Layout) -> Result<(NonNull<u8>, usize), AllocErr> {
-        if layout.size() == 0 {
-            Ok((layout.dangling(), 0))
-        } else {
-            unsafe {
-                NonNull::new(alloc_zeroed(layout)).ok_or(AllocErr).map(|p| (p, layout.size()))
+    unsafe fn shrink(
+        &mut self,
+        ptr: NonNull<u8>,
+        layout: Layout,
+        new_size: usize,
+        placement: ReallocPlacement,
+    ) -> Result<MemoryBlock, AllocErr> {
+        let size = layout.size();
+        debug_assert!(
+            new_size <= size,
+            "`new_size` must be smaller than or equal to `memory.size()`"
+        );
+
+        if size == new_size {
+            return Ok(MemoryBlock { ptr, size });
+        }
+
+        match placement {
+            ReallocPlacement::InPlace => Err(AllocErr),
+            ReallocPlacement::MayMove if new_size == 0 => {
+                self.dealloc(ptr, layout);
+                Ok(MemoryBlock { ptr: layout.dangling(), size: 0 })
+            }
+            ReallocPlacement::MayMove => {
+                // `realloc` probably checks for `new_size < size` or something similar.
+                intrinsics::assume(new_size < size);
+                let ptr = realloc(ptr.as_ptr(), layout, new_size);
+                Ok(MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size })
             }
         }
     }
@@ -218,14 +265,10 @@ unsafe impl AllocRef for Global {
 #[lang = "exchange_malloc"]
 #[inline]
 unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
-    if size == 0 {
-        align as *mut u8
-    } else {
-        let layout = Layout::from_size_align_unchecked(size, align);
-        match Global.alloc(layout) {
-            Ok((ptr, _)) => ptr.as_ptr(),
-            Err(_) => handle_alloc_error(layout),
-        }
+    let layout = Layout::from_size_align_unchecked(size, align);
+    match Global.alloc(layout, AllocInit::Uninitialized) {
+        Ok(memory) => memory.ptr.as_ptr(),
+        Err(_) => handle_alloc_error(layout),
     }
 }
 
@@ -239,11 +282,8 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
 pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
     let size = size_of_val(ptr.as_ref());
     let align = min_align_of_val(ptr.as_ref());
-    // We do not allocate for Box<T> when T is ZST, so deallocation is also not necessary.
-    if size != 0 {
-        let layout = Layout::from_size_align_unchecked(size, align);
-        Global.dealloc(ptr.cast().into(), layout);
-    }
+    let layout = Layout::from_size_align_unchecked(size, align);
+    Global.dealloc(ptr.cast().into(), layout)
 }
 
 /// Abort on memory allocation error or failure.
diff --git a/src/liballoc/alloc/tests.rs b/src/liballoc/alloc/tests.rs
index 55944398e16..1ad40eca93b 100644
--- a/src/liballoc/alloc/tests.rs
+++ b/src/liballoc/alloc/tests.rs
@@ -8,16 +8,17 @@ use test::Bencher;
 fn allocate_zeroed() {
     unsafe {
         let layout = Layout::from_size_align(1024, 1).unwrap();
-        let (ptr, _) =
-            Global.alloc_zeroed(layout.clone()).unwrap_or_else(|_| handle_alloc_error(layout));
+        let memory = Global
+            .alloc(layout.clone(), AllocInit::Zeroed)
+            .unwrap_or_else(|_| handle_alloc_error(layout));
 
-        let mut i = ptr.cast::<u8>().as_ptr();
+        let mut i = memory.ptr.cast::<u8>().as_ptr();
         let end = i.add(layout.size());
         while i < end {
             assert_eq!(*i, 0);
             i = i.offset(1);
         }
-        Global.dealloc(ptr, layout);
+        Global.dealloc(memory.ptr, layout);
     }
 }
 
diff --git a/src/liballoc/benches/btree/set.rs b/src/liballoc/benches/btree/set.rs
index d9e75ab7fa4..2518506b9b5 100644
--- a/src/liballoc/benches/btree/set.rs
+++ b/src/liballoc/benches/btree/set.rs
@@ -63,6 +63,22 @@ pub fn clone_100_and_clear(b: &mut Bencher) {
 }
 
 #[bench]
+pub fn clone_100_and_drain_all(b: &mut Bencher) {
+    let src = pos(100);
+    b.iter(|| src.clone().drain_filter(|_| true).count())
+}
+
+#[bench]
+pub fn clone_100_and_drain_half(b: &mut Bencher) {
+    let src = pos(100);
+    b.iter(|| {
+        let mut set = src.clone();
+        assert_eq!(set.drain_filter(|i| i % 2 == 0).count(), 100 / 2);
+        assert_eq!(set.len(), 100 / 2);
+    })
+}
+
+#[bench]
 pub fn clone_100_and_into_iter(b: &mut Bencher) {
     let src = pos(100);
     b.iter(|| src.clone().into_iter().count())
@@ -116,6 +132,22 @@ pub fn clone_10k_and_clear(b: &mut Bencher) {
 }
 
 #[bench]
+pub fn clone_10k_and_drain_all(b: &mut Bencher) {
+    let src = pos(10_000);
+    b.iter(|| src.clone().drain_filter(|_| true).count())
+}
+
+#[bench]
+pub fn clone_10k_and_drain_half(b: &mut Bencher) {
+    let src = pos(10_000);
+    b.iter(|| {
+        let mut set = src.clone();
+        assert_eq!(set.drain_filter(|i| i % 2 == 0).count(), 10_000 / 2);
+        assert_eq!(set.len(), 10_000 / 2);
+    })
+}
+
+#[bench]
 pub fn clone_10k_and_into_iter(b: &mut Bencher) {
     let src = pos(10_000);
     b.iter(|| src.clone().into_iter().count())
diff --git a/src/liballoc/benches/lib.rs b/src/liballoc/benches/lib.rs
index 951477a24c8..f31717d9fd5 100644
--- a/src/liballoc/benches/lib.rs
+++ b/src/liballoc/benches/lib.rs
@@ -1,3 +1,4 @@
+#![feature(btree_drain_filter)]
 #![feature(map_first_last)]
 #![feature(repr_simd)]
 #![feature(test)]
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 36641284a76..5406956a528 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -143,10 +143,9 @@ use core::ops::{
 };
 use core::pin::Pin;
 use core::ptr::{self, NonNull, Unique};
-use core::slice;
 use core::task::{Context, Poll};
 
-use crate::alloc::{self, AllocRef, Global};
+use crate::alloc::{self, AllocInit, AllocRef, Global};
 use crate::raw_vec::RawVec;
 use crate::str::from_boxed_utf8_unchecked;
 use crate::vec::Vec;
@@ -196,14 +195,12 @@ impl<T> Box<T> {
     #[unstable(feature = "new_uninit", issue = "63291")]
     pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
         let layout = alloc::Layout::new::<mem::MaybeUninit<T>>();
-        unsafe {
-            let ptr = if layout.size() == 0 {
-                NonNull::dangling()
-            } else {
-                Global.alloc(layout).unwrap_or_else(|_| alloc::handle_alloc_error(layout)).0.cast()
-            };
-            Box::from_raw(ptr.as_ptr())
-        }
+        let ptr = Global
+            .alloc(layout, AllocInit::Uninitialized)
+            .unwrap_or_else(|_| alloc::handle_alloc_error(layout))
+            .ptr
+            .cast();
+        unsafe { Box::from_raw(ptr.as_ptr()) }
     }
 
     /// Constructs a new `Box` with uninitialized contents, with the memory
@@ -226,11 +223,13 @@ impl<T> Box<T> {
     /// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed
     #[unstable(feature = "new_uninit", issue = "63291")]
     pub fn new_zeroed() -> Box<mem::MaybeUninit<T>> {
-        unsafe {
-            let mut uninit = Self::new_uninit();
-            ptr::write_bytes::<T>(uninit.as_mut_ptr(), 0, 1);
-            uninit
-        }
+        let layout = alloc::Layout::new::<mem::MaybeUninit<T>>();
+        let ptr = Global
+            .alloc(layout, AllocInit::Zeroed)
+            .unwrap_or_else(|_| alloc::handle_alloc_error(layout))
+            .ptr
+            .cast();
+        unsafe { Box::from_raw(ptr.as_ptr()) }
     }
 
     /// Constructs a new `Pin<Box<T>>`. If `T` does not implement `Unpin`, then
@@ -265,15 +264,7 @@ impl<T> Box<[T]> {
     /// ```
     #[unstable(feature = "new_uninit", issue = "63291")]
     pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
-        let layout = alloc::Layout::array::<mem::MaybeUninit<T>>(len).unwrap();
-        unsafe {
-            let ptr = if layout.size() == 0 {
-                NonNull::dangling()
-            } else {
-                Global.alloc(layout).unwrap_or_else(|_| alloc::handle_alloc_error(layout)).0.cast()
-            };
-            Box::from_raw(slice::from_raw_parts_mut(ptr.as_ptr(), len))
-        }
+        unsafe { RawVec::with_capacity(len).into_box(len) }
     }
 }
 
@@ -778,7 +769,7 @@ impl<T: Copy> From<&[T]> for Box<[T]> {
         let buf = RawVec::with_capacity(len);
         unsafe {
             ptr::copy_nonoverlapping(slice.as_ptr(), buf.ptr(), len);
-            buf.into_box()
+            buf.into_box(slice.len()).assume_init()
         }
     }
 }
diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs
index bde66c406af..bbeced1751d 100644
--- a/src/liballoc/collections/btree/map.rs
+++ b/src/liballoc/collections/btree/map.rs
@@ -1256,6 +1256,48 @@ impl<K: Ord, V> BTreeMap<K, V> {
         right
     }
 
+    /// Creates an iterator which uses a closure to determine if an element should be removed.
+    ///
+    /// If the closure returns true, the element is removed from the map and yielded.
+    /// If the closure returns false, or panics, the element remains in the map and will not be
+    /// yielded.
+    ///
+    /// Note that `drain_filter` lets you mutate every value in the filter closure, regardless of
+    /// whether you choose to keep or remove it.
+    ///
+    /// If the iterator is only partially consumed or not consumed at all, each of the remaining
+    /// elements will still be subjected to the closure and removed and dropped if it returns true.
+    ///
+    /// It is unspecified how many more elements will be subjected to the closure
+    /// if a panic occurs in the closure, or a panic occurs while dropping an element,
+    /// or if the `DrainFilter` value is leaked.
+    ///
+    /// # Examples
+    ///
+    /// Splitting a map into even and odd keys, reusing the original map:
+    ///
+    /// ```
+    /// #![feature(btree_drain_filter)]
+    /// use std::collections::BTreeMap;
+    ///
+    /// let mut map: BTreeMap<i32, i32> = (0..8).map(|x| (x, x)).collect();
+    /// let evens: BTreeMap<_, _> = map.drain_filter(|k, _v| k % 2 == 0).collect();
+    /// let odds = map;
+    /// assert_eq!(evens.keys().copied().collect::<Vec<_>>(), vec![0, 2, 4, 6]);
+    /// assert_eq!(odds.keys().copied().collect::<Vec<_>>(), vec![1, 3, 5, 7]);
+    /// ```
+    #[unstable(feature = "btree_drain_filter", issue = "70530")]
+    pub fn drain_filter<F>(&mut self, pred: F) -> DrainFilter<'_, K, V, F>
+    where
+        F: FnMut(&K, &mut V) -> bool,
+    {
+        DrainFilter { pred, inner: self.drain_filter_inner() }
+    }
+    pub(super) fn drain_filter_inner(&mut self) -> DrainFilterInner<'_, K, V> {
+        let front = self.root.as_mut().map(|r| r.as_mut().first_leaf_edge());
+        DrainFilterInner { length: &mut self.length, cur_leaf_edge: front }
+    }
+
     /// Calculates the number of elements if it is incorrect.
     fn recalc_length(&mut self) {
         fn dfs<'a, K, V>(node: NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal>) -> usize
@@ -1653,6 +1695,124 @@ impl<K, V> Clone for Values<'_, K, V> {
     }
 }
 
+/// An iterator produced by calling `drain_filter` on BTreeMap.
+#[unstable(feature = "btree_drain_filter", issue = "70530")]
+pub struct DrainFilter<'a, K, V, F>
+where
+    K: 'a + Ord, // This Ord bound should be removed before stabilization.
+    V: 'a,
+    F: 'a + FnMut(&K, &mut V) -> bool,
+{
+    pred: F,
+    inner: DrainFilterInner<'a, K, V>,
+}
+pub(super) struct DrainFilterInner<'a, K, V>
+where
+    K: 'a + Ord,
+    V: 'a,
+{
+    length: &'a mut usize,
+    cur_leaf_edge: Option<Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>>,
+}
+
+#[unstable(feature = "btree_drain_filter", issue = "70530")]
+impl<'a, K, V, F> Drop for DrainFilter<'a, K, V, F>
+where
+    K: 'a + Ord,
+    V: 'a,
+    F: 'a + FnMut(&K, &mut V) -> bool,
+{
+    fn drop(&mut self) {
+        self.for_each(drop);
+    }
+}
+
+#[unstable(feature = "btree_drain_filter", issue = "70530")]
+impl<'a, K, V, F> fmt::Debug for DrainFilter<'a, K, V, F>
+where
+    K: 'a + fmt::Debug + Ord,
+    V: 'a + fmt::Debug,
+    F: 'a + FnMut(&K, &mut V) -> bool,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_tuple("DrainFilter").field(&self.inner.peek()).finish()
+    }
+}
+
+#[unstable(feature = "btree_drain_filter", issue = "70530")]
+impl<'a, K, V, F> Iterator for DrainFilter<'a, K, V, F>
+where
+    K: 'a + Ord,
+    V: 'a,
+    F: 'a + FnMut(&K, &mut V) -> bool,
+{
+    type Item = (K, V);
+
+    fn next(&mut self) -> Option<(K, V)> {
+        self.inner.next(&mut self.pred)
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.inner.size_hint()
+    }
+}
+
+impl<'a, K, V> DrainFilterInner<'a, K, V>
+where
+    K: 'a + Ord,
+    V: 'a,
+{
+    /// Allow Debug implementations to predict the next element.
+    pub(super) fn peek(&self) -> Option<(&K, &V)> {
+        let edge = self.cur_leaf_edge.as_ref()?;
+        edge.reborrow().next_kv().ok().map(|kv| kv.into_kv())
+    }
+
+    unsafe fn next_kv(
+        &mut self,
+    ) -> Option<Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV>> {
+        let edge = self.cur_leaf_edge.as_ref()?;
+        ptr::read(edge).next_kv().ok()
+    }
+
+    /// Implementation of a typical `DrainFilter::next` method, given the predicate.
+    pub(super) fn next<F>(&mut self, pred: &mut F) -> Option<(K, V)>
+    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();
+            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),
+                    }
+                };
+                return Some((k, v));
+            }
+            self.cur_leaf_edge = Some(kv.next_leaf_edge());
+        }
+        None
+    }
+
+    /// Implementation of a typical `DrainFilter::size_hint` method.
+    pub(super) fn size_hint(&self) -> (usize, Option<usize>) {
+        (0, Some(*self.length))
+    }
+}
+
+#[unstable(feature = "btree_drain_filter", issue = "70530")]
+impl<K, V, F> FusedIterator for DrainFilter<'_, K, V, F>
+where
+    K: Ord,
+    F: FnMut(&K, &mut V) -> bool,
+{
+}
+
 #[stable(feature = "btree_range", since = "1.17.0")]
 impl<'a, K, V> Iterator for Range<'a, K, V> {
     type Item = (&'a K, &'a V);
@@ -2531,12 +2691,31 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
     fn remove_kv(self) -> (K, V) {
         *self.length -= 1;
 
-        let (small_leaf, old_key, old_val) = match self.handle.force() {
+        let (old_key, old_val, _) = self.handle.remove_kv_tracking();
+        (old_key, old_val)
+    }
+}
+
+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.
+    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() {
             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)
             }
             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;
 
@@ -2556,27 +2735,39 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
         let mut cur_node = small_leaf.forget_type();
         while cur_node.len() < node::MIN_LEN {
             match handle_underfull_node(cur_node) {
-                AtRoot => break,
+                AtRoot(root) => {
+                    cur_node = root;
+                    break;
+                }
                 EmptyParent(_) => unreachable!(),
                 Merged(parent) => {
+                    levels_down_handled -= 1;
                     if parent.len() == 0 {
                         // We must be at the root
-                        parent.into_root_mut().pop_level();
+                        let root = parent.into_root_mut();
+                        root.pop_level();
+                        cur_node = root.as_mut();
                         break;
                     } else {
                         cur_node = parent.forget_type();
                     }
                 }
-                Stole(_) => break,
+                Stole(internal_node) => {
+                    levels_down_handled -= 1;
+                    cur_node = internal_node.forget_type();
+                    // This internal node might be underfull, but only if it's the root.
+                    break;
+                }
             }
         }
 
-        (old_key, old_val)
+        let leaf_edge_location = if levels_down_handled > 0 { None } else { Some(cur_node) };
+        (old_key, old_val, leaf_edge_location)
     }
 }
 
 enum UnderflowResult<'a, K, V> {
-    AtRoot,
+    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>),
@@ -2585,10 +2776,9 @@ enum UnderflowResult<'a, K, V> {
 fn handle_underfull_node<K, V>(
     node: NodeRef<marker::Mut<'_>, K, V, marker::LeafOrInternal>,
 ) -> UnderflowResult<'_, K, V> {
-    let parent = if let Ok(parent) = node.ascend() {
-        parent
-    } else {
-        return AtRoot;
+    let parent = match node.ascend() {
+        Ok(parent) => parent,
+        Err(root) => return AtRoot(root),
     };
 
     let (is_left, mut handle) = match parent.left_kv() {
diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs
index 6ebb98c42cd..11c14299573 100644
--- a/src/liballoc/collections/btree/node.rs
+++ b/src/liballoc/collections/btree/node.rs
@@ -1142,7 +1142,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
 
             (*left_node.as_leaf_mut()).len += right_len as u16 + 1;
 
-            if self.node.height > 1 {
+            let layout = if self.node.height > 1 {
                 ptr::copy_nonoverlapping(
                     right_node.cast_unchecked().as_internal().edges.as_ptr(),
                     left_node
@@ -1159,10 +1159,11 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
                         .correct_parent_link();
                 }
 
-                Global.dealloc(right_node.node.cast(), Layout::new::<InternalNode<K, V>>());
+                Layout::new::<InternalNode<K, V>>()
             } else {
-                Global.dealloc(right_node.node.cast(), Layout::new::<LeafNode<K, V>>());
-            }
+                Layout::new::<LeafNode<K, V>>()
+            };
+            Global.dealloc(right_node.node.cast(), layout);
 
             Handle::new_edge(self.node, self.idx)
         }
diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs
index b100ce754ca..0b02223def4 100644
--- a/src/liballoc/collections/btree/set.rs
+++ b/src/liballoc/collections/btree/set.rs
@@ -8,8 +8,8 @@ use core::fmt::{self, Debug};
 use core::iter::{FromIterator, FusedIterator, Peekable};
 use core::ops::{BitAnd, BitOr, BitXor, RangeBounds, Sub};
 
+use super::map::{BTreeMap, Keys};
 use super::Recover;
-use crate::collections::btree_map::{self, BTreeMap, Keys};
 
 // FIXME(conventions): implement bounded iterators
 
@@ -102,7 +102,7 @@ impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Debug)]
 pub struct IntoIter<T> {
-    iter: btree_map::IntoIter<T, ()>,
+    iter: super::map::IntoIter<T, ()>,
 }
 
 /// An iterator over a sub-range of items in a `BTreeSet`.
@@ -115,7 +115,7 @@ pub struct IntoIter<T> {
 #[derive(Debug)]
 #[stable(feature = "btree_range", since = "1.17.0")]
 pub struct Range<'a, T: 'a> {
-    iter: btree_map::Range<'a, T, ()>,
+    iter: super::map::Range<'a, T, ()>,
 }
 
 /// Core of SymmetricDifference and Union.
@@ -944,6 +944,41 @@ impl<T: Ord> BTreeSet<T> {
     {
         BTreeSet { map: self.map.split_off(key) }
     }
+
+    /// Creates an iterator which uses a closure to determine if a value should be removed.
+    ///
+    /// If the closure returns true, then the value is removed and yielded.
+    /// If the closure returns false, the value will remain in the list and will not be yielded
+    /// by the iterator.
+    ///
+    /// If the iterator is only partially consumed or not consumed at all, each of the remaining
+    /// values will still be subjected to the closure and removed and dropped if it returns true.
+    ///
+    /// It is unspecified how many more values will be subjected to the closure
+    /// if a panic occurs in the closure, or if a panic occurs while dropping a value, or if the
+    /// `DrainFilter` itself is leaked.
+    ///
+    /// # Examples
+    ///
+    /// Splitting a set into even and odd values, reusing the original set:
+    ///
+    /// ```
+    /// #![feature(btree_drain_filter)]
+    /// use std::collections::BTreeSet;
+    ///
+    /// let mut set: BTreeSet<i32> = (0..8).collect();
+    /// let evens: BTreeSet<_> = set.drain_filter(|v| v % 2 == 0).collect();
+    /// let odds = set;
+    /// assert_eq!(evens.into_iter().collect::<Vec<_>>(), vec![0, 2, 4, 6]);
+    /// assert_eq!(odds.into_iter().collect::<Vec<_>>(), vec![1, 3, 5, 7]);
+    /// ```
+    #[unstable(feature = "btree_drain_filter", issue = "70530")]
+    pub fn drain_filter<'a, F>(&'a mut self, pred: F) -> DrainFilter<'a, T, F>
+    where
+        F: 'a + FnMut(&T) -> bool,
+    {
+        DrainFilter { pred, inner: self.map.drain_filter_inner() }
+    }
 }
 
 impl<T> BTreeSet<T> {
@@ -1055,6 +1090,66 @@ impl<'a, T> IntoIterator for &'a BTreeSet<T> {
     }
 }
 
+/// An iterator produced by calling `drain_filter` on BTreeSet.
+#[unstable(feature = "btree_drain_filter", issue = "70530")]
+pub struct DrainFilter<'a, T, F>
+where
+    T: 'a + Ord,
+    F: 'a + FnMut(&T) -> bool,
+{
+    pred: F,
+    inner: super::map::DrainFilterInner<'a, T, ()>,
+}
+
+#[unstable(feature = "btree_drain_filter", issue = "70530")]
+impl<'a, T, F> Drop for DrainFilter<'a, T, F>
+where
+    T: 'a + Ord,
+    F: 'a + FnMut(&T) -> bool,
+{
+    fn drop(&mut self) {
+        self.for_each(drop);
+    }
+}
+
+#[unstable(feature = "btree_drain_filter", issue = "70530")]
+impl<'a, T, F> fmt::Debug for DrainFilter<'a, T, F>
+where
+    T: 'a + Ord + fmt::Debug,
+    F: 'a + FnMut(&T) -> bool,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_tuple("DrainFilter").field(&self.inner.peek().map(|(k, _)| k)).finish()
+    }
+}
+
+#[unstable(feature = "btree_drain_filter", issue = "70530")]
+impl<'a, 'f, T, F> Iterator for DrainFilter<'a, T, F>
+where
+    T: 'a + Ord,
+    F: 'a + 'f + FnMut(&T) -> bool,
+{
+    type Item = T;
+
+    fn next(&mut self) -> Option<T> {
+        let pred = &mut self.pred;
+        let mut mapped_pred = |k: &T, _v: &mut ()| pred(k);
+        self.inner.next(&mut mapped_pred).map(|(k, _)| k)
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.inner.size_hint()
+    }
+}
+
+#[unstable(feature = "btree_drain_filter", issue = "70530")]
+impl<'a, T, F> FusedIterator for DrainFilter<'a, T, F>
+where
+    T: 'a + Ord,
+    F: 'a + FnMut(&T) -> bool,
+{
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Ord> Extend<T> for BTreeSet<T> {
     #[inline]
diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs
index 69284fbf1b3..94532521a90 100644
--- a/src/liballoc/collections/vec_deque.rs
+++ b/src/liballoc/collections/vec_deque.rs
@@ -959,6 +959,9 @@ impl<T> VecDeque<T> {
     /// Returns a pair of slices which contain, in order, the contents of the
     /// `VecDeque`.
     ///
+    /// If [`make_contiguous`](#method.make_contiguous) was previously called, all elements
+    /// of the `VecDeque` will be in the first slice and the second slice will be empty.
+    ///
     /// # Examples
     ///
     /// ```
@@ -989,6 +992,9 @@ impl<T> VecDeque<T> {
     /// Returns a pair of slices which contain, in order, the contents of the
     /// `VecDeque`.
     ///
+    /// If [`make_contiguous`](#method.make_contiguous) was previously called, all elements
+    /// of the `VecDeque` will be in the first slice and the second slice will be empty.
+    ///
     /// # Examples
     ///
     /// ```
@@ -2044,6 +2050,148 @@ impl<T> VecDeque<T> {
         }
     }
 
+    /// Rearranges the internal storage of this deque so it is one contiguous slice, which is then returned.
+    ///
+    /// This method does not allocate and does not change the order of the inserted elements.
+    /// As it returns a mutable slice, this can be used to sort or binary search a deque.
+    ///
+    /// Once the internal storage is contiguous, the [`as_slices`](#method.as_slices) and
+    /// [`as_mut_slices`](#method.as_mut_slices) methods will return the entire contents of the
+    /// `VecDeque` in a single slice.
+    ///
+    /// # Examples
+    ///
+    /// Sorting the content of a deque.
+    ///
+    /// ```
+    /// #![feature(deque_make_contiguous)]
+    ///
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::with_capacity(15);
+    ///
+    /// buf.push_back(2);
+    /// buf.push_back(1);
+    /// buf.push_front(3);
+    ///
+    /// // sorting the deque
+    /// buf.make_contiguous().sort();
+    /// assert_eq!(buf.as_slices(), (&[1, 2, 3] as &[_], &[] as &[_]));
+    ///
+    /// // sorting it in reverse order
+    /// buf.make_contiguous().sort_by(|a, b| b.cmp(a));
+    /// assert_eq!(buf.as_slices(), (&[3, 2, 1] as &[_], &[] as &[_]));
+    /// ```
+    ///
+    /// Getting immutable access to the contiguous slice.
+    ///
+    /// ```rust
+    /// #![feature(deque_make_contiguous)]
+    ///
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::new();
+    ///
+    /// buf.push_back(2);
+    /// buf.push_back(1);
+    /// buf.push_front(3);
+    ///
+    /// buf.make_contiguous();
+    /// if let (slice, &[]) = buf.as_slices() {
+    ///     // we can now be sure that `slice` contains all elements of the deque,
+    ///     // while still having immutable access to `buf`.
+    ///     assert_eq!(buf.len(), slice.len());
+    ///     assert_eq!(slice, &[3, 2, 1] as &[_]);
+    /// }
+    /// ```
+    #[unstable(feature = "deque_make_contiguous", issue = "none")]
+    pub fn make_contiguous(&mut self) -> &mut [T] {
+        if self.is_contiguous() {
+            let tail = self.tail;
+            let head = self.head;
+            return unsafe { &mut self.buffer_as_mut_slice()[tail..head] };
+        }
+
+        let buf = self.buf.ptr();
+        let cap = self.cap();
+        let len = self.len();
+
+        let free = self.tail - self.head;
+        let tail_len = cap - self.tail;
+
+        if free >= tail_len {
+            // there is enough free space to copy the tail in one go,
+            // this means that we first shift the head backwards, and then
+            // copy the tail to the correct position.
+            //
+            // from: DEFGH....ABC
+            // to:   ABCDEFGH....
+            unsafe {
+                ptr::copy(buf, buf.add(tail_len), self.head);
+                // ...DEFGH.ABC
+                ptr::copy_nonoverlapping(buf.add(self.tail), buf, tail_len);
+                // ABCDEFGH....
+
+                self.tail = 0;
+                self.head = len;
+            }
+        } else if free >= self.head {
+            // there is enough free space to copy the head in one go,
+            // this means that we first shift the tail forwards, and then
+            // copy the head to the correct position.
+            //
+            // from: FGH....ABCDE
+            // to:   ...ABCDEFGH.
+            unsafe {
+                ptr::copy(buf.add(self.tail), buf.add(self.head), tail_len);
+                // FGHABCDE....
+                ptr::copy_nonoverlapping(buf, buf.add(self.head + tail_len), self.head);
+                // ...ABCDEFGH.
+
+                self.tail = self.head;
+                self.head = self.tail + len;
+            }
+        } else {
+            // free is smaller than both head and tail,
+            // this means we have to slowly "swap" the tail and the head.
+            //
+            // from: EFGHI...ABCD or HIJK.ABCDEFG
+            // to:   ABCDEFGHI... or ABCDEFGHIJK.
+            let mut left_edge: usize = 0;
+            let mut right_edge: usize = self.tail;
+            unsafe {
+                // The general problem looks like this
+                // GHIJKLM...ABCDEF - before any swaps
+                // ABCDEFM...GHIJKL - after 1 pass of swaps
+                // ABCDEFGHIJM...KL - swap until the left edge reaches the temp store
+                //                  - then restart the algorithm with a new (smaller) store
+                // Sometimes the temp store is reached when the right edge is at the end
+                // of the buffer - this means we've hit the right order with fewer swaps!
+                // E.g
+                // EF..ABCD
+                // ABCDEF.. - after four only swaps we've finished
+                while left_edge < len && right_edge != cap {
+                    let mut right_offset = 0;
+                    for i in left_edge..right_edge {
+                        right_offset = (i - left_edge) % (cap - right_edge);
+                        let src: isize = (right_edge + right_offset) as isize;
+                        ptr::swap(buf.add(i), buf.offset(src));
+                    }
+                    let n_ops = right_edge - left_edge;
+                    left_edge += n_ops;
+                    right_edge += right_offset + 1;
+                }
+
+                self.tail = 0;
+                self.head = len;
+            }
+        }
+
+        let tail = self.tail;
+        let head = self.head;
+        unsafe { &mut self.buffer_as_mut_slice()[tail..head] }
+    }
+
     /// Rotates the double-ended queue `mid` places to the left.
     ///
     /// Equivalently,
@@ -2803,63 +2951,16 @@ impl<T> From<VecDeque<T>> for Vec<T> {
     /// assert_eq!(vec, [8, 9, 1, 2, 3, 4]);
     /// assert_eq!(vec.as_ptr(), ptr);
     /// ```
-    fn from(other: VecDeque<T>) -> Self {
+    fn from(mut other: VecDeque<T>) -> Self {
+        other.make_contiguous();
+
         unsafe {
             let buf = other.buf.ptr();
             let len = other.len();
-            let tail = other.tail;
-            let head = other.head;
             let cap = other.cap();
 
-            // Need to move the ring to the front of the buffer, as vec will expect this.
-            if other.is_contiguous() {
-                ptr::copy(buf.add(tail), buf, len);
-            } else {
-                if (tail - head) >= cmp::min(cap - tail, head) {
-                    // There is enough free space in the centre for the shortest block so we can
-                    // do this in at most three copy moves.
-                    if (cap - tail) > head {
-                        // right hand block is the long one; move that enough for the left
-                        ptr::copy(buf.add(tail), buf.add(tail - head), cap - tail);
-                        // copy left in the end
-                        ptr::copy(buf, buf.add(cap - head), head);
-                        // shift the new thing to the start
-                        ptr::copy(buf.add(tail - head), buf, len);
-                    } else {
-                        // left hand block is the long one, we can do it in two!
-                        ptr::copy(buf, buf.add(cap - tail), head);
-                        ptr::copy(buf.add(tail), buf, cap - tail);
-                    }
-                } else {
-                    // Need to use N swaps to move the ring
-                    // We can use the space at the end of the ring as a temp store
-
-                    let mut left_edge: usize = 0;
-                    let mut right_edge: usize = tail;
-
-                    // The general problem looks like this
-                    // GHIJKLM...ABCDEF - before any swaps
-                    // ABCDEFM...GHIJKL - after 1 pass of swaps
-                    // ABCDEFGHIJM...KL - swap until the left edge reaches the temp store
-                    //                  - then restart the algorithm with a new (smaller) store
-                    // Sometimes the temp store is reached when the right edge is at the end
-                    // of the buffer - this means we've hit the right order with fewer swaps!
-                    // E.g
-                    // EF..ABCD
-                    // ABCDEF.. - after four only swaps we've finished
-
-                    while left_edge < len && right_edge != cap {
-                        let mut right_offset = 0;
-                        for i in left_edge..right_edge {
-                            right_offset = (i - left_edge) % (cap - right_edge);
-                            let src: isize = (right_edge + right_offset) as isize;
-                            ptr::swap(buf.add(i), buf.offset(src));
-                        }
-                        let n_ops = right_edge - left_edge;
-                        left_edge += n_ops;
-                        right_edge += right_offset + 1;
-                    }
-                }
+            if other.head != 0 {
+                ptr::copy(buf.add(other.tail), buf, len);
             }
             let out = Vec::from_raw_parts(buf, len, cap);
             mem::forget(other);
diff --git a/src/liballoc/collections/vec_deque/tests.rs b/src/liballoc/collections/vec_deque/tests.rs
index f2ce5b1d15d..8ef5ec78e05 100644
--- a/src/liballoc/collections/vec_deque/tests.rs
+++ b/src/liballoc/collections/vec_deque/tests.rs
@@ -1,6 +1,6 @@
 use super::*;
 
-use ::test;
+use test;
 
 #[bench]
 #[cfg_attr(miri, ignore)] // Miri does not support benchmarks
@@ -131,6 +131,87 @@ fn test_insert() {
 }
 
 #[test]
+fn make_contiguous_big_tail() {
+    let mut tester = VecDeque::with_capacity(15);
+
+    for i in 0..3 {
+        tester.push_back(i);
+    }
+
+    for i in 3..10 {
+        tester.push_front(i);
+    }
+
+    // 012......9876543
+    assert_eq!(tester.capacity(), 15);
+    assert_eq!((&[9, 8, 7, 6, 5, 4, 3] as &[_], &[0, 1, 2] as &[_]), tester.as_slices());
+
+    let expected_start = tester.head;
+    tester.make_contiguous();
+    assert_eq!(tester.tail, expected_start);
+    assert_eq!((&[9, 8, 7, 6, 5, 4, 3, 0, 1, 2] as &[_], &[] as &[_]), tester.as_slices());
+}
+
+#[test]
+fn make_contiguous_big_head() {
+    let mut tester = VecDeque::with_capacity(15);
+
+    for i in 0..8 {
+        tester.push_back(i);
+    }
+
+    for i in 8..10 {
+        tester.push_front(i);
+    }
+
+    // 01234567......98
+    let expected_start = 0;
+    tester.make_contiguous();
+    assert_eq!(tester.tail, expected_start);
+    assert_eq!((&[9, 8, 0, 1, 2, 3, 4, 5, 6, 7] as &[_], &[] as &[_]), tester.as_slices());
+}
+
+#[test]
+fn make_contiguous_small_free() {
+    let mut tester = VecDeque::with_capacity(15);
+
+    for i in 'A' as u8..'I' as u8 {
+        tester.push_back(i as char);
+    }
+
+    for i in 'I' as u8..'N' as u8 {
+        tester.push_front(i as char);
+    }
+
+    // ABCDEFGH...MLKJI
+    let expected_start = 0;
+    tester.make_contiguous();
+    assert_eq!(tester.tail, expected_start);
+    assert_eq!(
+        (&['M', 'L', 'K', 'J', 'I', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'] as &[_], &[] as &[_]),
+        tester.as_slices()
+    );
+
+    tester.clear();
+    for i in 'I' as u8..'N' as u8 {
+        tester.push_back(i as char);
+    }
+
+    for i in 'A' as u8..'I' as u8 {
+        tester.push_front(i as char);
+    }
+
+    // IJKLM...HGFEDCBA
+    let expected_start = 0;
+    tester.make_contiguous();
+    assert_eq!(tester.tail, expected_start);
+    assert_eq!(
+        (&['H', 'G', 'F', 'E', 'D', 'C', 'B', 'A', 'I', 'J', 'K', 'L', 'M'] as &[_], &[] as &[_]),
+        tester.as_slices()
+    );
+}
+
+#[test]
 fn test_remove() {
     // This test checks that every single combination of tail position, length, and
     // removal position is tested. Capacity 15 should be large enough to cover every case.
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 5857b79d5ee..121c1cde548 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -100,6 +100,7 @@
 #![feature(lang_items)]
 #![feature(libc)]
 #![cfg_attr(not(bootstrap), feature(negative_impls))]
+#![feature(new_uninit)]
 #![feature(nll)]
 #![feature(optin_builtin_traits)]
 #![feature(pattern)]
diff --git a/src/liballoc/macros.rs b/src/liballoc/macros.rs
index 422d3486f92..4bc0c3a079d 100644
--- a/src/liballoc/macros.rs
+++ b/src/liballoc/macros.rs
@@ -36,6 +36,9 @@
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow_internal_unstable(box_syntax)]
 macro_rules! vec {
+    () => (
+        $crate::vec::Vec::new()
+    );
     ($elem:expr; $n:expr) => (
         $crate::vec::from_elem($elem, $n)
     );
@@ -51,6 +54,9 @@ macro_rules! vec {
 // NB see the slice::hack module in slice.rs for more information
 #[cfg(test)]
 macro_rules! vec {
+    () => (
+        $crate::vec::Vec::new()
+    );
     ($elem:expr; $n:expr) => (
         $crate::vec::from_elem($elem, $n)
     );
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index b31fec7f037..2bf40490e78 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -1,13 +1,19 @@
 #![unstable(feature = "raw_vec_internals", reason = "implementation detail", issue = "none")]
 #![doc(hidden)]
 
+use core::alloc::MemoryBlock;
 use core::cmp;
-use core::mem;
+use core::mem::{self, MaybeUninit};
 use core::ops::Drop;
-use core::ptr::{self, NonNull, Unique};
+use core::ptr::{NonNull, Unique};
 use core::slice;
 
-use crate::alloc::{handle_alloc_error, AllocErr, AllocRef, Global, Layout};
+use crate::alloc::{
+    handle_alloc_error, AllocErr,
+    AllocInit::{self, *},
+    AllocRef, Global, Layout,
+    ReallocPlacement::{self, *},
+};
 use crate::boxed::Box;
 use crate::collections::TryReserveError::{self, *};
 
@@ -21,81 +27,26 @@ mod tests;
 ///
 /// * Produces `Unique::empty()` on zero-sized types.
 /// * Produces `Unique::empty()` on zero-length allocations.
+/// * Avoids freeing `Unique::empty()`.
 /// * Catches all overflows in capacity computations (promotes them to "capacity overflow" panics).
 /// * Guards against 32-bit systems allocating more than isize::MAX bytes.
 /// * Guards against overflowing your length.
-/// * Aborts on OOM or calls `handle_alloc_error` as applicable.
-/// * Avoids freeing `Unique::empty()`.
+/// * Calls `handle_alloc_error` for fallible allocations.
 /// * Contains a `ptr::Unique` and thus endows the user with all related benefits.
+/// * Uses the excess returned from the allocator to use the largest available capacity.
 ///
 /// This type does not in anyway inspect the memory that it manages. When dropped it *will*
 /// free its memory, but it *won't* try to drop its contents. It is up to the user of `RawVec`
 /// to handle the actual things *stored* inside of a `RawVec`.
 ///
-/// Note that a `RawVec` always forces its capacity to be `usize::MAX` for zero-sized types.
-/// This enables you to use capacity-growing logic catch the overflows in your length
-/// that might occur with zero-sized types.
-///
-/// The above means that you need to be careful when round-tripping this type with a
-/// `Box<[T]>`, since `capacity()` won't yield the length. However, `with_capacity`,
-/// `shrink_to_fit`, and `from_box` will actually set `RawVec`'s private capacity
-/// field. This allows zero-sized types to not be special-cased by consumers of
-/// this type.
+/// Note that the excess of a zero-sized types is always infinite, so `capacity()` always returns
+/// `usize::MAX`. This means that you need to be careful when round-tripping this type with a
+/// `Box<[T]>`, since `capacity()` won't yield the length.
 #[allow(missing_debug_implementations)]
 pub struct RawVec<T, A: AllocRef = Global> {
     ptr: Unique<T>,
     cap: usize,
-    a: A,
-}
-
-impl<T, A: AllocRef> RawVec<T, A> {
-    /// Like `new`, but parameterized over the choice of allocator for
-    /// the returned `RawVec`.
-    pub const fn new_in(a: A) -> Self {
-        let cap = if mem::size_of::<T>() == 0 { core::usize::MAX } else { 0 };
-
-        // `Unique::empty()` doubles as "unallocated" and "zero-sized allocation".
-        RawVec { ptr: Unique::empty(), cap, a }
-    }
-
-    /// Like `with_capacity`, but parameterized over the choice of
-    /// allocator for the returned `RawVec`.
-    #[inline]
-    pub fn with_capacity_in(capacity: usize, a: A) -> Self {
-        RawVec::allocate_in(capacity, false, a)
-    }
-
-    /// Like `with_capacity_zeroed`, but parameterized over the choice
-    /// of allocator for the returned `RawVec`.
-    #[inline]
-    pub fn with_capacity_zeroed_in(capacity: usize, a: A) -> Self {
-        RawVec::allocate_in(capacity, true, a)
-    }
-
-    fn allocate_in(mut capacity: usize, zeroed: bool, mut a: A) -> Self {
-        let elem_size = mem::size_of::<T>();
-
-        let alloc_size = capacity.checked_mul(elem_size).unwrap_or_else(|| capacity_overflow());
-        alloc_guard(alloc_size).unwrap_or_else(|_| capacity_overflow());
-
-        // Handles ZSTs and `capacity == 0` alike.
-        let ptr = if alloc_size == 0 {
-            NonNull::<T>::dangling()
-        } else {
-            let align = mem::align_of::<T>();
-            let layout = Layout::from_size_align(alloc_size, align).unwrap();
-            let result = if zeroed { a.alloc_zeroed(layout) } else { a.alloc(layout) };
-            match result {
-                Ok((ptr, size)) => {
-                    capacity = size / elem_size;
-                    ptr.cast()
-                }
-                Err(_) => handle_alloc_error(layout),
-            }
-        };
-
-        RawVec { ptr: ptr.into(), cap: capacity, a }
-    }
+    alloc: A,
 }
 
 impl<T> RawVec<T, Global> {
@@ -138,39 +89,26 @@ impl<T> RawVec<T, Global> {
     /// Aborts on OOM.
     #[inline]
     pub fn with_capacity(capacity: usize) -> Self {
-        RawVec::allocate_in(capacity, false, Global)
+        Self::with_capacity_in(capacity, Global)
     }
 
     /// Like `with_capacity`, but guarantees the buffer is zeroed.
     #[inline]
     pub fn with_capacity_zeroed(capacity: usize) -> Self {
-        RawVec::allocate_in(capacity, true, Global)
+        Self::with_capacity_zeroed_in(capacity, Global)
     }
-}
 
-impl<T, A: AllocRef> RawVec<T, A> {
-    /// Reconstitutes a `RawVec` from a pointer, capacity, and allocator.
-    ///
-    /// # Undefined Behavior
-    ///
-    /// The `ptr` must be allocated (via the given allocator `a`), and with the given `capacity`.
-    /// The `capacity` cannot exceed `isize::MAX` (only a concern on 32-bit systems).
-    /// If the `ptr` and `capacity` come from a `RawVec` created via `a`, then this is guaranteed.
-    pub unsafe fn from_raw_parts_in(ptr: *mut T, capacity: usize, a: A) -> Self {
-        RawVec { ptr: Unique::new_unchecked(ptr), cap: capacity, a }
-    }
-}
-
-impl<T> RawVec<T, Global> {
     /// Reconstitutes a `RawVec` from a pointer and capacity.
     ///
-    /// # Undefined Behavior
+    /// # Safety
     ///
     /// The `ptr` must be allocated (on the system heap), and with the given `capacity`.
-    /// The `capacity` cannot exceed `isize::MAX` (only a concern on 32-bit systems).
+    /// The `capacity` cannot exceed `isize::MAX` for sized types. (only a concern on 32-bit
+    /// systems). ZST vectors may have a capacity up to `usize::MAX`.
     /// If the `ptr` and `capacity` come from a `RawVec`, then this is guaranteed.
+    #[inline]
     pub unsafe fn from_raw_parts(ptr: *mut T, capacity: usize) -> Self {
-        RawVec { ptr: Unique::new_unchecked(ptr), cap: capacity, a: Global }
+        Self::from_raw_parts_in(ptr, capacity, Global)
     }
 
     /// Converts a `Box<[T]>` into a `RawVec<T>`.
@@ -184,6 +122,56 @@ impl<T> RawVec<T, Global> {
 }
 
 impl<T, A: AllocRef> RawVec<T, A> {
+    /// Like `new`, but parameterized over the choice of allocator for
+    /// the returned `RawVec`.
+    pub const fn new_in(alloc: A) -> Self {
+        // `cap: 0` means "unallocated". zero-sized types are ignored.
+        Self { ptr: Unique::empty(), cap: 0, alloc }
+    }
+
+    /// Like `with_capacity`, but parameterized over the choice of
+    /// allocator for the returned `RawVec`.
+    #[inline]
+    pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
+        Self::allocate_in(capacity, Uninitialized, alloc)
+    }
+
+    /// Like `with_capacity_zeroed`, but parameterized over the choice
+    /// of allocator for the returned `RawVec`.
+    #[inline]
+    pub fn with_capacity_zeroed_in(capacity: usize, alloc: A) -> Self {
+        Self::allocate_in(capacity, Zeroed, alloc)
+    }
+
+    fn allocate_in(capacity: usize, init: AllocInit, mut alloc: A) -> Self {
+        if mem::size_of::<T>() == 0 {
+            Self::new_in(alloc)
+        } else {
+            let layout = Layout::array::<T>(capacity).unwrap_or_else(|_| capacity_overflow());
+            alloc_guard(layout.size()).unwrap_or_else(|_| capacity_overflow());
+
+            let memory = alloc.alloc(layout, init).unwrap_or_else(|_| handle_alloc_error(layout));
+            Self {
+                ptr: memory.ptr.cast().into(),
+                cap: Self::capacity_from_bytes(memory.size),
+                alloc,
+            }
+        }
+    }
+
+    /// Reconstitutes a `RawVec` from a pointer, capacity, and allocator.
+    ///
+    /// # Safety
+    ///
+    /// The `ptr` must be allocated (via the given allocator `a`), and with the given `capacity`.
+    /// The `capacity` cannot exceed `isize::MAX` for sized types. (only a concern on 32-bit
+    /// systems). ZST vectors may have a capacity up to `usize::MAX`.
+    /// If the `ptr` and `capacity` come from a `RawVec` created via `a`, then this is guaranteed.
+    #[inline]
+    pub unsafe fn from_raw_parts_in(ptr: *mut T, capacity: usize, a: A) -> Self {
+        Self { ptr: Unique::new_unchecked(ptr), cap: capacity, alloc: a }
+    }
+
     /// Gets a raw pointer to the start of the allocation. Note that this is
     /// `Unique::empty()` if `capacity == 0` or `T` is zero-sized. In the former case, you must
     /// be careful.
@@ -196,21 +184,21 @@ impl<T, A: AllocRef> RawVec<T, A> {
     /// This will always be `usize::MAX` if `T` is zero-sized.
     #[inline(always)]
     pub fn capacity(&self) -> usize {
-        if mem::size_of::<T>() == 0 { !0 } else { self.cap }
+        if mem::size_of::<T>() == 0 { usize::MAX } else { self.cap }
     }
 
     /// Returns a shared reference to the allocator backing this `RawVec`.
     pub fn alloc(&self) -> &A {
-        &self.a
+        &self.alloc
     }
 
     /// Returns a mutable reference to the allocator backing this `RawVec`.
     pub fn alloc_mut(&mut self) -> &mut A {
-        &mut self.a
+        &mut self.alloc
     }
 
-    fn current_layout(&self) -> Option<Layout> {
-        if self.cap == 0 {
+    fn current_memory(&self) -> Option<(NonNull<u8>, Layout)> {
+        if mem::size_of::<T>() == 0 || self.cap == 0 {
             None
         } else {
             // We have an allocated chunk of memory, so we can bypass runtime
@@ -218,7 +206,8 @@ impl<T, A: AllocRef> RawVec<T, A> {
             unsafe {
                 let align = mem::align_of::<T>();
                 let size = mem::size_of::<T>() * self.cap;
-                Some(Layout::from_size_align_unchecked(size, align))
+                let layout = Layout::from_size_align_unchecked(size, align);
+                Some((self.ptr.cast().into(), layout))
             }
         }
     }
@@ -274,50 +263,10 @@ impl<T, A: AllocRef> RawVec<T, A> {
     #[inline(never)]
     #[cold]
     pub fn double(&mut self) {
-        unsafe {
-            let elem_size = mem::size_of::<T>();
-
-            // Since we set the capacity to `usize::MAX` when `elem_size` is
-            // 0, getting to here necessarily means the `RawVec` is overfull.
-            assert!(elem_size != 0, "capacity overflow");
-
-            let (ptr, new_cap) = match self.current_layout() {
-                Some(cur) => {
-                    // Since we guarantee that we never allocate more than
-                    // `isize::MAX` bytes, `elem_size * self.cap <= isize::MAX` as
-                    // a precondition, so this can't overflow. Additionally the
-                    // alignment will never be too large as to "not be
-                    // satisfiable", so `Layout::from_size_align` will always
-                    // return `Some`.
-                    //
-                    // TL;DR, we bypass runtime checks due to dynamic assertions
-                    // in this module, allowing us to use
-                    // `from_size_align_unchecked`.
-                    let new_cap = 2 * self.cap;
-                    let new_size = new_cap * elem_size;
-                    alloc_guard(new_size).unwrap_or_else(|_| capacity_overflow());
-                    let ptr_res = self.a.realloc(NonNull::from(self.ptr).cast(), cur, new_size);
-                    match ptr_res {
-                        Ok((ptr, new_size)) => (ptr, new_size / elem_size),
-                        Err(_) => handle_alloc_error(Layout::from_size_align_unchecked(
-                            new_size,
-                            cur.align(),
-                        )),
-                    }
-                }
-                None => {
-                    // Skip to 4 because tiny `Vec`'s are dumb; but not if that
-                    // would cause overflow.
-                    let new_cap = if elem_size > (!0) / 8 { 1 } else { 4 };
-                    let layout = Layout::array::<T>(new_cap).unwrap();
-                    match self.a.alloc(layout) {
-                        Ok((ptr, new_size)) => (ptr, new_size / elem_size),
-                        Err(_) => handle_alloc_error(layout),
-                    }
-                }
-            };
-            self.ptr = ptr.cast().into();
-            self.cap = new_cap;
+        match self.grow(Double, MayMove, Uninitialized) {
+            Err(CapacityOverflow) => capacity_overflow(),
+            Err(AllocError { layout, .. }) => handle_alloc_error(layout),
+            Ok(()) => { /* yay */ }
         }
     }
 
@@ -336,99 +285,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
     #[inline(never)]
     #[cold]
     pub fn double_in_place(&mut self) -> bool {
-        unsafe {
-            let elem_size = mem::size_of::<T>();
-            let old_layout = match self.current_layout() {
-                Some(layout) => layout,
-                None => return false, // nothing to double
-            };
-
-            // Since we set the capacity to `usize::MAX` when `elem_size` is
-            // 0, getting to here necessarily means the `RawVec` is overfull.
-            assert!(elem_size != 0, "capacity overflow");
-
-            // Since we guarantee that we never allocate more than `isize::MAX`
-            // bytes, `elem_size * self.cap <= isize::MAX` as a precondition, so
-            // this can't overflow.
-            //
-            // Similarly to with `double` above, we can go straight to
-            // `Layout::from_size_align_unchecked` as we know this won't
-            // overflow and the alignment is sufficiently small.
-            let new_cap = 2 * self.cap;
-            let new_size = new_cap * elem_size;
-            alloc_guard(new_size).unwrap_or_else(|_| capacity_overflow());
-            match self.a.grow_in_place(NonNull::from(self.ptr).cast(), old_layout, new_size) {
-                Ok(_) => {
-                    // We can't directly divide `size`.
-                    self.cap = new_cap;
-                    true
-                }
-                Err(_) => false,
-            }
-        }
-    }
-
-    /// The same as `reserve_exact`, but returns on errors instead of panicking or aborting.
-    pub fn try_reserve_exact(
-        &mut self,
-        used_capacity: usize,
-        needed_extra_capacity: usize,
-    ) -> Result<(), TryReserveError> {
-        self.reserve_internal(used_capacity, needed_extra_capacity, Fallible, Exact)
-    }
-
-    /// Ensures that the buffer contains at least enough space to hold
-    /// `used_capacity + needed_extra_capacity` elements. If it doesn't already,
-    /// will reallocate the minimum possible amount of memory necessary.
-    /// Generally this will be exactly the amount of memory necessary,
-    /// but in principle the allocator is free to give back more than
-    /// we asked for.
-    ///
-    /// If `used_capacity` exceeds `self.capacity()`, this may fail to actually allocate
-    /// the requested space. This is not really unsafe, but the unsafe
-    /// code *you* write that relies on the behavior of this function may break.
-    ///
-    /// # Panics
-    ///
-    /// * Panics if the requested capacity exceeds `usize::MAX` bytes.
-    /// * Panics on 32-bit platforms if the requested capacity exceeds
-    ///   `isize::MAX` bytes.
-    ///
-    /// # Aborts
-    ///
-    /// Aborts on OOM.
-    pub fn reserve_exact(&mut self, used_capacity: usize, needed_extra_capacity: usize) {
-        match self.reserve_internal(used_capacity, needed_extra_capacity, Infallible, Exact) {
-            Err(CapacityOverflow) => capacity_overflow(),
-            Err(AllocError { .. }) => unreachable!(),
-            Ok(()) => { /* yay */ }
-        }
-    }
-
-    /// Calculates the buffer's new size given that it'll hold `used_capacity +
-    /// needed_extra_capacity` elements. This logic is used in amortized reserve methods.
-    /// Returns `(new_capacity, new_alloc_size)`.
-    fn amortized_new_size(
-        &self,
-        used_capacity: usize,
-        needed_extra_capacity: usize,
-    ) -> Result<usize, TryReserveError> {
-        // Nothing we can really do about these checks, sadly.
-        let required_cap =
-            used_capacity.checked_add(needed_extra_capacity).ok_or(CapacityOverflow)?;
-        // Cannot overflow, because `cap <= isize::MAX`, and type of `cap` is `usize`.
-        let double_cap = self.cap * 2;
-        // `double_cap` guarantees exponential growth.
-        Ok(cmp::max(double_cap, required_cap))
-    }
-
-    /// The same as `reserve`, but returns on errors instead of panicking or aborting.
-    pub fn try_reserve(
-        &mut self,
-        used_capacity: usize,
-        needed_extra_capacity: usize,
-    ) -> Result<(), TryReserveError> {
-        self.reserve_internal(used_capacity, needed_extra_capacity, Fallible, Amortized)
+        self.grow(Double, InPlace, Uninitialized).is_ok()
     }
 
     /// Ensures that the buffer contains at least enough space to hold
@@ -484,12 +341,26 @@ impl<T, A: AllocRef> RawVec<T, A> {
     /// # }
     /// ```
     pub fn reserve(&mut self, used_capacity: usize, needed_extra_capacity: usize) {
-        match self.reserve_internal(used_capacity, needed_extra_capacity, Infallible, Amortized) {
+        match self.try_reserve(used_capacity, needed_extra_capacity) {
             Err(CapacityOverflow) => capacity_overflow(),
-            Err(AllocError { .. }) => unreachable!(),
+            Err(AllocError { layout, .. }) => handle_alloc_error(layout),
             Ok(()) => { /* yay */ }
         }
     }
+
+    /// The same as `reserve`, but returns on errors instead of panicking or aborting.
+    pub fn try_reserve(
+        &mut self,
+        used_capacity: usize,
+        needed_extra_capacity: usize,
+    ) -> Result<(), TryReserveError> {
+        if self.needs_to_grow(used_capacity, needed_extra_capacity) {
+            self.grow(Amortized { used_capacity, needed_extra_capacity }, MayMove, Uninitialized)
+        } else {
+            Ok(())
+        }
+    }
+
     /// Attempts to ensure that the buffer contains at least enough space to hold
     /// `used_capacity + needed_extra_capacity` elements. If it doesn't already have
     /// enough capacity, will reallocate in place enough space plus comfortable slack
@@ -508,45 +379,54 @@ impl<T, A: AllocRef> RawVec<T, A> {
     /// * Panics on 32-bit platforms if the requested capacity exceeds
     ///   `isize::MAX` bytes.
     pub fn reserve_in_place(&mut self, used_capacity: usize, needed_extra_capacity: usize) -> bool {
-        unsafe {
-            // NOTE: we don't early branch on ZSTs here because we want this
-            // to actually catch "asking for more than usize::MAX" in that case.
-            // If we make it past the first branch then we are guaranteed to
-            // panic.
-
-            // Don't actually need any more capacity. If the current `cap` is 0, we can't
-            // reallocate in place.
-            // Wrapping in case they give a bad `used_capacity`
-            let old_layout = match self.current_layout() {
-                Some(layout) => layout,
-                None => return false,
-            };
-            if self.capacity().wrapping_sub(used_capacity) >= needed_extra_capacity {
-                return false;
-            }
+        // This is more readable than putting this in one line:
+        // `!self.needs_to_grow(...) || self.grow(...).is_ok()`
+        if self.needs_to_grow(used_capacity, needed_extra_capacity) {
+            self.grow(Amortized { used_capacity, needed_extra_capacity }, InPlace, Uninitialized)
+                .is_ok()
+        } else {
+            true
+        }
+    }
 
-            let new_cap = self
-                .amortized_new_size(used_capacity, needed_extra_capacity)
-                .unwrap_or_else(|_| capacity_overflow());
-
-            // Here, `cap < used_capacity + needed_extra_capacity <= new_cap`
-            // (regardless of whether `self.cap - used_capacity` wrapped).
-            // Therefore, we can safely call `grow_in_place`.
-
-            let new_layout = Layout::new::<T>().repeat(new_cap).unwrap().0;
-            // FIXME: may crash and burn on over-reserve
-            alloc_guard(new_layout.size()).unwrap_or_else(|_| capacity_overflow());
-            match self.a.grow_in_place(
-                NonNull::from(self.ptr).cast(),
-                old_layout,
-                new_layout.size(),
-            ) {
-                Ok(_) => {
-                    self.cap = new_cap;
-                    true
-                }
-                Err(_) => false,
-            }
+    /// Ensures that the buffer contains at least enough space to hold
+    /// `used_capacity + needed_extra_capacity` elements. If it doesn't already,
+    /// will reallocate the minimum possible amount of memory necessary.
+    /// Generally this will be exactly the amount of memory necessary,
+    /// but in principle the allocator is free to give back more than
+    /// we asked for.
+    ///
+    /// If `used_capacity` exceeds `self.capacity()`, this may fail to actually allocate
+    /// the requested space. This is not really unsafe, but the unsafe
+    /// code *you* write that relies on the behavior of this function may break.
+    ///
+    /// # Panics
+    ///
+    /// * Panics if the requested capacity exceeds `usize::MAX` bytes.
+    /// * Panics on 32-bit platforms if the requested capacity exceeds
+    ///   `isize::MAX` bytes.
+    ///
+    /// # Aborts
+    ///
+    /// Aborts on OOM.
+    pub fn reserve_exact(&mut self, used_capacity: usize, needed_extra_capacity: usize) {
+        match self.try_reserve_exact(used_capacity, needed_extra_capacity) {
+            Err(CapacityOverflow) => capacity_overflow(),
+            Err(AllocError { layout, .. }) => handle_alloc_error(layout),
+            Ok(()) => { /* yay */ }
+        }
+    }
+
+    /// The same as `reserve_exact`, but returns on errors instead of panicking or aborting.
+    pub fn try_reserve_exact(
+        &mut self,
+        used_capacity: usize,
+        needed_extra_capacity: usize,
+    ) -> Result<(), TryReserveError> {
+        if self.needs_to_grow(used_capacity, needed_extra_capacity) {
+            self.grow(Exact { used_capacity, needed_extra_capacity }, MayMove, Uninitialized)
+        } else {
+            Ok(())
         }
     }
 
@@ -561,166 +441,157 @@ impl<T, A: AllocRef> RawVec<T, A> {
     ///
     /// Aborts on OOM.
     pub fn shrink_to_fit(&mut self, amount: usize) {
-        let elem_size = mem::size_of::<T>();
-
-        // Set the `cap` because they might be about to promote to a `Box<[T]>`
-        if elem_size == 0 {
-            self.cap = amount;
-            return;
-        }
-
-        // This check is my waterloo; it's the only thing `Vec` wouldn't have to do.
-        assert!(self.cap >= amount, "Tried to shrink to a larger capacity");
-
-        if amount == 0 {
-            // We want to create a new zero-length vector within the
-            // same allocator. We use `ptr::write` to avoid an
-            // erroneous attempt to drop the contents, and we use
-            // `ptr::read` to sidestep condition against destructuring
-            // types that implement Drop.
-
-            unsafe {
-                let a = ptr::read(&self.a as *const A);
-                self.dealloc_buffer();
-                ptr::write(self, RawVec::new_in(a));
-            }
-        } else if self.cap != amount {
-            unsafe {
-                // We know here that our `amount` is greater than zero. This
-                // implies, via the assert above, that capacity is also greater
-                // than zero, which means that we've got a current layout that
-                // "fits"
-                //
-                // We also know that `self.cap` is greater than `amount`, and
-                // consequently we don't need runtime checks for creating either
-                // layout.
-                let old_size = elem_size * self.cap;
-                let new_size = elem_size * amount;
-                let align = mem::align_of::<T>();
-                let old_layout = Layout::from_size_align_unchecked(old_size, align);
-                match self.a.realloc(NonNull::from(self.ptr).cast(), old_layout, new_size) {
-                    Ok((ptr, _)) => self.ptr = ptr.cast().into(),
-                    Err(_) => {
-                        handle_alloc_error(Layout::from_size_align_unchecked(new_size, align))
-                    }
-                }
-            }
-            self.cap = amount;
+        match self.shrink(amount, MayMove) {
+            Err(CapacityOverflow) => capacity_overflow(),
+            Err(AllocError { layout, .. }) => handle_alloc_error(layout),
+            Ok(()) => { /* yay */ }
         }
     }
 }
 
-enum Fallibility {
-    Fallible,
-    Infallible,
+#[derive(Copy, Clone)]
+enum Strategy {
+    Double,
+    Amortized { used_capacity: usize, needed_extra_capacity: usize },
+    Exact { used_capacity: usize, needed_extra_capacity: usize },
 }
+use Strategy::*;
 
-use Fallibility::*;
+impl<T, A: AllocRef> RawVec<T, A> {
+    /// Returns if the buffer needs to grow to fulfill the needed extra capacity.
+    /// Mainly used to make inlining reserve-calls possible without inlining `grow`.
+    fn needs_to_grow(&self, used_capacity: usize, needed_extra_capacity: usize) -> bool {
+        needed_extra_capacity > self.capacity().wrapping_sub(used_capacity)
+    }
 
-enum ReserveStrategy {
-    Exact,
-    Amortized,
-}
+    fn capacity_from_bytes(excess: usize) -> usize {
+        debug_assert_ne!(mem::size_of::<T>(), 0);
+        excess / mem::size_of::<T>()
+    }
 
-use ReserveStrategy::*;
+    fn set_memory(&mut self, memory: MemoryBlock) {
+        self.ptr = memory.ptr.cast().into();
+        self.cap = Self::capacity_from_bytes(memory.size);
+    }
 
-impl<T, A: AllocRef> RawVec<T, A> {
-    fn reserve_internal(
+    /// Single method to handle all possibilities of growing the buffer.
+    fn grow(
         &mut self,
-        used_capacity: usize,
-        needed_extra_capacity: usize,
-        fallibility: Fallibility,
-        strategy: ReserveStrategy,
+        strategy: Strategy,
+        placement: ReallocPlacement,
+        init: AllocInit,
     ) -> Result<(), TryReserveError> {
         let elem_size = mem::size_of::<T>();
+        if elem_size == 0 {
+            // Since we return a capacity of `usize::MAX` when `elem_size` is
+            // 0, getting to here necessarily means the `RawVec` is overfull.
+            return Err(CapacityOverflow);
+        }
+        let new_layout = match strategy {
+            Double => unsafe {
+                // Since we guarantee that we never allocate more than `isize::MAX` bytes,
+                // `elem_size * self.cap <= isize::MAX` as a precondition, so this can't overflow.
+                // Additionally the alignment will never be too large as to "not be satisfiable",
+                // so `Layout::from_size_align` will always return `Some`.
+                //
+                // TL;DR, we bypass runtime checks due to dynamic assertions in this module,
+                // allowing us to use `from_size_align_unchecked`.
+                let cap = if self.cap == 0 {
+                    // Skip to 4 because tiny `Vec`'s are dumb; but not if that would cause overflow.
+                    if elem_size > usize::MAX / 8 { 1 } else { 4 }
+                } else {
+                    self.cap * 2
+                };
+                Layout::from_size_align_unchecked(cap * elem_size, mem::align_of::<T>())
+            },
+            Amortized { used_capacity, needed_extra_capacity } => {
+                // Nothing we can really do about these checks, sadly.
+                let required_cap =
+                    used_capacity.checked_add(needed_extra_capacity).ok_or(CapacityOverflow)?;
+                // Cannot overflow, because `cap <= isize::MAX`, and type of `cap` is `usize`.
+                let double_cap = self.cap * 2;
+                // `double_cap` guarantees exponential growth.
+                let cap = cmp::max(double_cap, required_cap);
+                Layout::array::<T>(cap).map_err(|_| CapacityOverflow)?
+            }
+            Exact { used_capacity, needed_extra_capacity } => {
+                let cap =
+                    used_capacity.checked_add(needed_extra_capacity).ok_or(CapacityOverflow)?;
+                Layout::array::<T>(cap).map_err(|_| CapacityOverflow)?
+            }
+        };
+        alloc_guard(new_layout.size())?;
 
-        unsafe {
-            // NOTE: we don't early branch on ZSTs here because we want this
-            // to actually catch "asking for more than usize::MAX" in that case.
-            // If we make it past the first branch then we are guaranteed to
-            // panic.
-
-            // Don't actually need any more capacity.
-            // Wrapping in case they gave a bad `used_capacity`.
-            if self.capacity().wrapping_sub(used_capacity) >= needed_extra_capacity {
-                return Ok(());
+        let memory = if let Some((ptr, old_layout)) = self.current_memory() {
+            debug_assert_eq!(old_layout.align(), new_layout.align());
+            unsafe {
+                self.alloc
+                    .grow(ptr, old_layout, new_layout.size(), placement, init)
+                    .map_err(|_| AllocError { layout: new_layout, non_exhaustive: () })?
+            }
+        } else {
+            match placement {
+                MayMove => self.alloc.alloc(new_layout, init),
+                InPlace => Err(AllocErr),
             }
+            .map_err(|_| AllocError { layout: new_layout, non_exhaustive: () })?
+        };
+        self.set_memory(memory);
+        Ok(())
+    }
 
-            // Nothing we can really do about these checks, sadly.
-            let new_cap = match strategy {
-                Exact => {
-                    used_capacity.checked_add(needed_extra_capacity).ok_or(CapacityOverflow)?
-                }
-                Amortized => self.amortized_new_size(used_capacity, needed_extra_capacity)?,
-            };
-            let new_layout = Layout::array::<T>(new_cap).map_err(|_| CapacityOverflow)?;
+    fn shrink(
+        &mut self,
+        amount: usize,
+        placement: ReallocPlacement,
+    ) -> Result<(), TryReserveError> {
+        assert!(amount <= self.capacity(), "Tried to shrink to a larger capacity");
 
-            alloc_guard(new_layout.size())?;
+        let (ptr, layout) = if let Some(mem) = self.current_memory() { mem } else { return Ok(()) };
+        let new_size = amount * mem::size_of::<T>();
 
-            let res = match self.current_layout() {
-                Some(layout) => {
-                    debug_assert!(new_layout.align() == layout.align());
-                    self.a.realloc(NonNull::from(self.ptr).cast(), layout, new_layout.size())
-                }
-                None => self.a.alloc(new_layout),
-            };
-
-            let (ptr, new_cap) = match (res, fallibility) {
-                (Err(AllocErr), Infallible) => handle_alloc_error(new_layout),
-                (Err(AllocErr), Fallible) => {
-                    return Err(TryReserveError::AllocError {
-                        layout: new_layout,
-                        non_exhaustive: (),
-                    });
+        let memory = unsafe {
+            self.alloc.shrink(ptr, layout, new_size, placement).map_err(|_| {
+                TryReserveError::AllocError {
+                    layout: Layout::from_size_align_unchecked(new_size, layout.align()),
+                    non_exhaustive: (),
                 }
-                (Ok((ptr, new_size)), _) => (ptr, new_size / elem_size),
-            };
-
-            self.ptr = ptr.cast().into();
-            self.cap = new_cap;
-
-            Ok(())
-        }
+            })?
+        };
+        self.set_memory(memory);
+        Ok(())
     }
 }
 
 impl<T> RawVec<T, Global> {
-    /// Converts the entire buffer into `Box<[T]>`.
+    /// Converts the entire buffer into `Box<[MaybeUninit<T>]>` with the specified `len`.
     ///
     /// Note that this will correctly reconstitute any `cap` changes
     /// that may have been performed. (See description of type for details.)
     ///
-    /// # Undefined Behavior
+    /// # Safety
     ///
-    /// All elements of `RawVec<T, Global>` must be initialized. Notice that
-    /// the rules around uninitialized boxed values are not finalized yet,
-    /// but until they are, it is advisable to avoid them.
-    pub unsafe fn into_box(self) -> Box<[T]> {
+    /// `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()`.
+    pub unsafe fn into_box(self, len: usize) -> Box<[MaybeUninit<T>]> {
+        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(), self.cap);
-        let output: Box<[T]> = Box::from_raw(slice);
+        let slice = slice::from_raw_parts_mut(self.ptr() as *mut MaybeUninit<T>, len);
+        let output = Box::from_raw(slice);
         mem::forget(self);
         output
     }
 }
 
-impl<T, A: AllocRef> RawVec<T, A> {
-    /// Frees the memory owned by the `RawVec` *without* trying to drop its contents.
-    pub unsafe fn dealloc_buffer(&mut self) {
-        let elem_size = mem::size_of::<T>();
-        if elem_size != 0 {
-            if let Some(layout) = self.current_layout() {
-                self.a.dealloc(NonNull::from(self.ptr).cast(), layout);
-            }
-        }
-    }
-}
-
 unsafe impl<#[may_dangle] T, A: AllocRef> Drop for RawVec<T, A> {
     /// Frees the memory owned by the `RawVec` *without* trying to drop its contents.
     fn drop(&mut self) {
-        unsafe {
-            self.dealloc_buffer();
+        if let Some((ptr, layout)) = self.current_memory() {
+            unsafe { self.alloc.dealloc(ptr, layout) }
         }
     }
 }
diff --git a/src/liballoc/raw_vec/tests.rs b/src/liballoc/raw_vec/tests.rs
index 21a8a76d0a7..e7ab8a305d2 100644
--- a/src/liballoc/raw_vec/tests.rs
+++ b/src/liballoc/raw_vec/tests.rs
@@ -12,6 +12,7 @@ fn allocator_param() {
     //
     // Instead, this just checks that the `RawVec` methods do at
     // least go through the Allocator API when it reserves
+
     // storage.
 
     // A dumb allocator that consumes a fixed amount of fuel
@@ -20,12 +21,12 @@ fn allocator_param() {
         fuel: usize,
     }
     unsafe impl AllocRef for BoundedAlloc {
-        fn alloc(&mut self, layout: Layout) -> Result<(NonNull<u8>, usize), AllocErr> {
+        fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr> {
             let size = layout.size();
             if size > self.fuel {
                 return Err(AllocErr);
             }
-            match Global.alloc(layout) {
+            match Global.alloc(layout, init) {
                 ok @ Ok(_) => {
                     self.fuel -= size;
                     ok
@@ -40,9 +41,9 @@ fn allocator_param() {
 
     let a = BoundedAlloc { fuel: 500 };
     let mut v: RawVec<u8, _> = RawVec::with_capacity_in(50, a);
-    assert_eq!(v.a.fuel, 450);
+    assert_eq!(v.alloc.fuel, 450);
     v.reserve(50, 150); // (causes a realloc, thus using 50 + 150 = 200 units of fuel)
-    assert_eq!(v.a.fuel, 250);
+    assert_eq!(v.alloc.fuel, 250);
 }
 
 #[test]
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index e7f7608e676..6a78a7398a6 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -252,7 +252,7 @@ use core::ptr::{self, NonNull};
 use core::slice::{self, from_raw_parts_mut};
 use core::usize;
 
-use crate::alloc::{box_free, handle_alloc_error, AllocRef, Global, Layout};
+use crate::alloc::{box_free, handle_alloc_error, AllocInit, AllocRef, Global, Layout};
 use crate::string::String;
 use crate::vec::Vec;
 
@@ -936,10 +936,12 @@ impl<T: ?Sized> Rc<T> {
         let layout = Layout::new::<RcBox<()>>().extend(value_layout).unwrap().0.pad_to_align();
 
         // Allocate for the layout.
-        let (mem, _) = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout));
+        let mem = Global
+            .alloc(layout, AllocInit::Uninitialized)
+            .unwrap_or_else(|_| handle_alloc_error(layout));
 
         // Initialize the RcBox
-        let inner = mem_to_rcbox(mem.as_ptr());
+        let inner = mem_to_rcbox(mem.ptr.as_ptr());
         debug_assert_eq!(Layout::for_value(&*inner), layout);
 
         ptr::write(&mut (*inner).strong, Cell::new(1));
diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs
index d8fc1faca3a..2ce5bc8ed2f 100644
--- a/src/liballoc/slice.rs
+++ b/src/liballoc/slice.rs
@@ -432,7 +432,7 @@ impl<T> [T] {
     ///
     /// ```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 843a2f1f8e9..70860c09a2c 100644
--- a/src/liballoc/str.rs
+++ b/src/liballoc/str.rs
@@ -499,7 +499,7 @@ impl str {
     ///
     /// ```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/string.rs b/src/liballoc/string.rs
index 7c89d38caa4..1e5fe125c55 100644
--- a/src/liballoc/string.rs
+++ b/src/liballoc/string.rs
@@ -1849,6 +1849,21 @@ impl<'a, 'b> Pattern<'a> for &'b String {
     fn is_prefix_of(self, haystack: &'a str) -> bool {
         self[..].is_prefix_of(haystack)
     }
+
+    #[inline]
+    fn strip_prefix_of(self, haystack: &'a str) -> Option<&'a str> {
+        self[..].strip_prefix_of(haystack)
+    }
+
+    #[inline]
+    fn is_suffix_of(self, haystack: &'a str) -> bool {
+        self[..].is_suffix_of(haystack)
+    }
+
+    #[inline]
+    fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str> {
+        self[..].strip_suffix_of(haystack)
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index e8985e20256..111a7651b5e 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -25,7 +25,7 @@ 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, AllocRef, Global, Layout};
+use crate::alloc::{box_free, handle_alloc_error, AllocInit, AllocRef, Global, Layout};
 use crate::boxed::Box;
 use crate::rc::is_dangling;
 use crate::string::String;
@@ -814,10 +814,12 @@ impl<T: ?Sized> Arc<T> {
         // reference (see #54908).
         let layout = Layout::new::<ArcInner<()>>().extend(value_layout).unwrap().0.pad_to_align();
 
-        let (mem, _) = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout));
+        let mem = Global
+            .alloc(layout, AllocInit::Uninitialized)
+            .unwrap_or_else(|_| handle_alloc_error(layout));
 
         // Initialize the ArcInner
-        let inner = mem_to_arcinner(mem.as_ptr());
+        let inner = mem_to_arcinner(mem.ptr.as_ptr());
         debug_assert_eq!(Layout::for_value(&*inner), layout);
 
         ptr::write(&mut (*inner).strong, atomic::AtomicUsize::new(1));
diff --git a/src/liballoc/task.rs b/src/liballoc/task.rs
index 981095302c7..a64d5d7a63b 100644
--- a/src/liballoc/task.rs
+++ b/src/liballoc/task.rs
@@ -12,10 +12,12 @@ use crate::sync::Arc;
 /// 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/btree/map.rs b/src/liballoc/tests/btree/map.rs
index 535b6a9c314..14f12ca2d77 100644
--- a/src/liballoc/tests/btree/map.rs
+++ b/src/liballoc/tests/btree/map.rs
@@ -5,7 +5,7 @@ use std::fmt::Debug;
 use std::iter::FromIterator;
 use std::ops::Bound::{self, Excluded, Included, Unbounded};
 use std::ops::RangeBounds;
-use std::panic::catch_unwind;
+use std::panic::{catch_unwind, AssertUnwindSafe};
 use std::rc::Rc;
 use std::sync::atomic::{AtomicUsize, Ordering};
 
@@ -528,7 +528,7 @@ fn test_range_1000() {
     #[cfg(not(miri))] // Miri is too slow
     let size = 1000;
     #[cfg(miri)]
-    let size = MIN_INSERTS_HEIGHT_2;
+    let size = MIN_INSERTS_HEIGHT_2 as u32;
     let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
 
     fn test(map: &BTreeMap<u32, u32>, size: u32, min: Bound<&u32>, max: Bound<&u32>) {
@@ -609,6 +609,263 @@ fn test_range_mut() {
     }
 }
 
+mod test_drain_filter {
+    use super::*;
+
+    #[test]
+    fn empty() {
+        let mut map: BTreeMap<i32, i32> = BTreeMap::new();
+        map.drain_filter(|_, _| unreachable!("there's nothing to decide on"));
+        assert!(map.is_empty());
+    }
+
+    #[test]
+    fn consuming_nothing() {
+        let pairs = (0..3).map(|i| (i, i));
+        let mut map: BTreeMap<_, _> = pairs.collect();
+        assert!(map.drain_filter(|_, _| false).eq(std::iter::empty()));
+    }
+
+    #[test]
+    fn consuming_all() {
+        let pairs = (0..3).map(|i| (i, i));
+        let mut map: BTreeMap<_, _> = pairs.clone().collect();
+        assert!(map.drain_filter(|_, _| true).eq(pairs));
+    }
+
+    #[test]
+    fn mutating_and_keeping() {
+        let pairs = (0..3).map(|i| (i, i));
+        let mut map: BTreeMap<_, _> = pairs.collect();
+        assert!(
+            map.drain_filter(|_, v| {
+                *v += 6;
+                false
+            })
+            .eq(std::iter::empty())
+        );
+        assert!(map.keys().copied().eq(0..3));
+        assert!(map.values().copied().eq(6..9));
+    }
+
+    #[test]
+    fn mutating_and_removing() {
+        let pairs = (0..3).map(|i| (i, i));
+        let mut map: BTreeMap<_, _> = pairs.collect();
+        assert!(
+            map.drain_filter(|_, v| {
+                *v += 6;
+                true
+            })
+            .eq((0..3).map(|i| (i, i + 6)))
+        );
+        assert!(map.is_empty());
+    }
+
+    #[test]
+    fn underfull_keeping_all() {
+        let pairs = (0..3).map(|i| (i, i));
+        let mut map: BTreeMap<_, _> = pairs.collect();
+        map.drain_filter(|_, _| false);
+        assert!(map.keys().copied().eq(0..3));
+    }
+
+    #[test]
+    fn underfull_removing_one() {
+        let pairs = (0..3).map(|i| (i, i));
+        for doomed in 0..3 {
+            let mut map: BTreeMap<_, _> = pairs.clone().collect();
+            map.drain_filter(|i, _| *i == doomed);
+            assert_eq!(map.len(), 2);
+        }
+    }
+
+    #[test]
+    fn underfull_keeping_one() {
+        let pairs = (0..3).map(|i| (i, i));
+        for sacred in 0..3 {
+            let mut map: BTreeMap<_, _> = pairs.clone().collect();
+            map.drain_filter(|i, _| *i != sacred);
+            assert!(map.keys().copied().eq(sacred..=sacred));
+        }
+    }
+
+    #[test]
+    fn underfull_removing_all() {
+        let pairs = (0..3).map(|i| (i, i));
+        let mut map: BTreeMap<_, _> = pairs.collect();
+        map.drain_filter(|_, _| true);
+        assert!(map.is_empty());
+    }
+
+    #[test]
+    fn height_0_keeping_all() {
+        let pairs = (0..NODE_CAPACITY).map(|i| (i, i));
+        let mut map: BTreeMap<_, _> = pairs.collect();
+        map.drain_filter(|_, _| false);
+        assert!(map.keys().copied().eq(0..NODE_CAPACITY));
+    }
+
+    #[test]
+    fn height_0_removing_one() {
+        let pairs = (0..NODE_CAPACITY).map(|i| (i, i));
+        for doomed in 0..NODE_CAPACITY {
+            let mut map: BTreeMap<_, _> = pairs.clone().collect();
+            map.drain_filter(|i, _| *i == doomed);
+            assert_eq!(map.len(), NODE_CAPACITY - 1);
+        }
+    }
+
+    #[test]
+    fn height_0_keeping_one() {
+        let pairs = (0..NODE_CAPACITY).map(|i| (i, i));
+        for sacred in 0..NODE_CAPACITY {
+            let mut map: BTreeMap<_, _> = pairs.clone().collect();
+            map.drain_filter(|i, _| *i != sacred);
+            assert!(map.keys().copied().eq(sacred..=sacred));
+        }
+    }
+
+    #[test]
+    fn height_0_removing_all() {
+        let pairs = (0..NODE_CAPACITY).map(|i| (i, i));
+        let mut map: BTreeMap<_, _> = pairs.collect();
+        map.drain_filter(|_, _| true);
+        assert!(map.is_empty());
+    }
+
+    #[test]
+    fn height_0_keeping_half() {
+        let mut map: BTreeMap<_, _> = (0..16).map(|i| (i, i)).collect();
+        assert_eq!(map.drain_filter(|i, _| *i % 2 == 0).count(), 8);
+        assert_eq!(map.len(), 8);
+    }
+
+    #[test]
+    fn height_1_removing_all() {
+        let pairs = (0..MIN_INSERTS_HEIGHT_1).map(|i| (i, i));
+        let mut map: BTreeMap<_, _> = pairs.collect();
+        map.drain_filter(|_, _| true);
+        assert!(map.is_empty());
+    }
+
+    #[test]
+    fn height_1_removing_one() {
+        let pairs = (0..MIN_INSERTS_HEIGHT_1).map(|i| (i, i));
+        for doomed in 0..MIN_INSERTS_HEIGHT_1 {
+            let mut map: BTreeMap<_, _> = pairs.clone().collect();
+            map.drain_filter(|i, _| *i == doomed);
+            assert_eq!(map.len(), MIN_INSERTS_HEIGHT_1 - 1);
+        }
+    }
+
+    #[test]
+    fn height_1_keeping_one() {
+        let pairs = (0..MIN_INSERTS_HEIGHT_1).map(|i| (i, i));
+        for sacred in 0..MIN_INSERTS_HEIGHT_1 {
+            let mut map: BTreeMap<_, _> = pairs.clone().collect();
+            map.drain_filter(|i, _| *i != sacred);
+            assert!(map.keys().copied().eq(sacred..=sacred));
+        }
+    }
+
+    #[cfg(not(miri))] // Miri is too slow
+    #[test]
+    fn height_2_removing_one() {
+        let pairs = (0..MIN_INSERTS_HEIGHT_2).map(|i| (i, i));
+        for doomed in (0..MIN_INSERTS_HEIGHT_2).step_by(12) {
+            let mut map: BTreeMap<_, _> = pairs.clone().collect();
+            map.drain_filter(|i, _| *i == doomed);
+            assert_eq!(map.len(), MIN_INSERTS_HEIGHT_2 - 1);
+        }
+    }
+
+    #[cfg(not(miri))] // Miri is too slow
+    #[test]
+    fn height_2_keeping_one() {
+        let pairs = (0..MIN_INSERTS_HEIGHT_2).map(|i| (i, i));
+        for sacred in (0..MIN_INSERTS_HEIGHT_2).step_by(12) {
+            let mut map: BTreeMap<_, _> = pairs.clone().collect();
+            map.drain_filter(|i, _| *i != sacred);
+            assert!(map.keys().copied().eq(sacred..=sacred));
+        }
+    }
+
+    #[test]
+    fn height_2_removing_all() {
+        let pairs = (0..MIN_INSERTS_HEIGHT_2).map(|i| (i, i));
+        let mut map: BTreeMap<_, _> = pairs.collect();
+        map.drain_filter(|_, _| true);
+        assert!(map.is_empty());
+    }
+
+    #[test]
+    fn drop_panic_leak() {
+        static PREDS: AtomicUsize = AtomicUsize::new(0);
+        static DROPS: AtomicUsize = AtomicUsize::new(0);
+
+        struct D;
+        impl Drop for D {
+            fn drop(&mut self) {
+                if DROPS.fetch_add(1, Ordering::SeqCst) == 1 {
+                    panic!("panic in `drop`");
+                }
+            }
+        }
+
+        let mut map = BTreeMap::new();
+        map.insert(0, D);
+        map.insert(4, D);
+        map.insert(8, D);
+
+        catch_unwind(move || {
+            drop(map.drain_filter(|i, _| {
+                PREDS.fetch_add(1usize << i, Ordering::SeqCst);
+                true
+            }))
+        })
+        .ok();
+
+        assert_eq!(PREDS.load(Ordering::SeqCst), 0x011);
+        assert_eq!(DROPS.load(Ordering::SeqCst), 3);
+    }
+
+    #[test]
+    fn pred_panic_leak() {
+        static PREDS: AtomicUsize = AtomicUsize::new(0);
+        static DROPS: AtomicUsize = AtomicUsize::new(0);
+
+        struct D;
+        impl Drop for D {
+            fn drop(&mut self) {
+                DROPS.fetch_add(1, Ordering::SeqCst);
+            }
+        }
+
+        let mut map = BTreeMap::new();
+        map.insert(0, D);
+        map.insert(4, D);
+        map.insert(8, D);
+
+        catch_unwind(AssertUnwindSafe(|| {
+            drop(map.drain_filter(|i, _| {
+                PREDS.fetch_add(1usize << i, Ordering::SeqCst);
+                match i {
+                    0 => true,
+                    _ => panic!(),
+                }
+            }))
+        }))
+        .ok();
+
+        assert_eq!(PREDS.load(Ordering::SeqCst), 0x011);
+        assert_eq!(DROPS.load(Ordering::SeqCst), 1);
+        assert_eq!(map.len(), 2);
+        assert_eq!(map.first_entry().unwrap().key(), &4);
+        assert_eq!(map.last_entry().unwrap().key(), &8);
+    }
+}
+
 #[test]
 fn test_borrow() {
     // make sure these compile -- using the Borrow trait
diff --git a/src/liballoc/tests/btree/set.rs b/src/liballoc/tests/btree/set.rs
index 1a2b62d026b..136018b9f7d 100644
--- a/src/liballoc/tests/btree/set.rs
+++ b/src/liballoc/tests/btree/set.rs
@@ -1,5 +1,7 @@
 use std::collections::BTreeSet;
 use std::iter::FromIterator;
+use std::panic::{catch_unwind, AssertUnwindSafe};
+use std::sync::atomic::{AtomicU32, Ordering};
 
 use super::DeterministicRng;
 
@@ -303,6 +305,85 @@ fn test_is_subset() {
 }
 
 #[test]
+fn test_drain_filter() {
+    let mut x: BTreeSet<_> = [1].iter().copied().collect();
+    let mut y: BTreeSet<_> = [1].iter().copied().collect();
+
+    x.drain_filter(|_| true);
+    y.drain_filter(|_| false);
+    assert_eq!(x.len(), 0);
+    assert_eq!(y.len(), 1);
+}
+
+#[test]
+fn test_drain_filter_drop_panic_leak() {
+    static PREDS: AtomicU32 = AtomicU32::new(0);
+    static DROPS: AtomicU32 = AtomicU32::new(0);
+
+    #[derive(PartialEq, Eq, PartialOrd, Ord)]
+    struct D(i32);
+    impl Drop for D {
+        fn drop(&mut self) {
+            if DROPS.fetch_add(1, Ordering::SeqCst) == 1 {
+                panic!("panic in `drop`");
+            }
+        }
+    }
+
+    let mut set = BTreeSet::new();
+    set.insert(D(0));
+    set.insert(D(4));
+    set.insert(D(8));
+
+    catch_unwind(move || {
+        drop(set.drain_filter(|d| {
+            PREDS.fetch_add(1u32 << d.0, Ordering::SeqCst);
+            true
+        }))
+    })
+    .ok();
+
+    assert_eq!(PREDS.load(Ordering::SeqCst), 0x011);
+    assert_eq!(DROPS.load(Ordering::SeqCst), 3);
+}
+
+#[test]
+fn test_drain_filter_pred_panic_leak() {
+    static PREDS: AtomicU32 = AtomicU32::new(0);
+    static DROPS: AtomicU32 = AtomicU32::new(0);
+
+    #[derive(PartialEq, Eq, PartialOrd, Ord)]
+    struct D(i32);
+    impl Drop for D {
+        fn drop(&mut self) {
+            DROPS.fetch_add(1, Ordering::SeqCst);
+        }
+    }
+
+    let mut set = BTreeSet::new();
+    set.insert(D(0));
+    set.insert(D(4));
+    set.insert(D(8));
+
+    catch_unwind(AssertUnwindSafe(|| {
+        drop(set.drain_filter(|d| {
+            PREDS.fetch_add(1u32 << d.0, Ordering::SeqCst);
+            match d.0 {
+                0 => true,
+                _ => panic!(),
+            }
+        }))
+    }))
+    .ok();
+
+    assert_eq!(PREDS.load(Ordering::SeqCst), 0x011);
+    assert_eq!(DROPS.load(Ordering::SeqCst), 1);
+    assert_eq!(set.len(), 2);
+    assert_eq!(set.first().unwrap().0, 4);
+    assert_eq!(set.last().unwrap().0, 8);
+}
+
+#[test]
 fn test_clear() {
     let mut x = BTreeSet::new();
     x.insert(1);
diff --git a/src/liballoc/tests/heap.rs b/src/liballoc/tests/heap.rs
index d159126f426..62f062b83d7 100644
--- a/src/liballoc/tests/heap.rs
+++ b/src/liballoc/tests/heap.rs
@@ -1,4 +1,4 @@
-use std::alloc::{AllocRef, Global, Layout, System};
+use std::alloc::{AllocInit, AllocRef, Global, Layout, System};
 
 /// Issue #45955 and #62251.
 #[test]
@@ -20,7 +20,13 @@ fn check_overalign_requests<T: AllocRef>(mut allocator: T) {
             unsafe {
                 let pointers: Vec<_> = (0..iterations)
                     .map(|_| {
-                        allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap().0
+                        allocator
+                            .alloc(
+                                Layout::from_size_align(size, align).unwrap(),
+                                AllocInit::Uninitialized,
+                            )
+                            .unwrap()
+                            .ptr
                     })
                     .collect();
                 for &ptr in &pointers {
diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs
index ea75f8903c3..ad6feaeebc6 100644
--- a/src/liballoc/tests/lib.rs
+++ b/src/liballoc/tests/lib.rs
@@ -1,5 +1,6 @@
 #![feature(allocator_api)]
 #![feature(box_syntax)]
+#![feature(btree_drain_filter)]
 #![feature(drain_filter)]
 #![feature(exact_size_is_empty)]
 #![feature(map_first_last)]
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index e171edef736..96a6399d051 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -679,8 +679,9 @@ impl<T> Vec<T> {
         unsafe {
             self.shrink_to_fit();
             let buf = ptr::read(&self.buf);
+            let len = self.len();
             mem::forget(self);
-            buf.into_box()
+            buf.into_box(len).assume_init()
         }
     }
 
diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs
deleted file mode 100644
index be20a1cde36..00000000000
--- a/src/libcore/alloc.rs
+++ /dev/null
@@ -1,1043 +0,0 @@
-//! Memory allocation APIs
-
-// ignore-tidy-undocumented-unsafe
-
-#![stable(feature = "alloc_module", since = "1.28.0")]
-
-use crate::cmp;
-use crate::fmt;
-use crate::mem;
-use crate::num::NonZeroUsize;
-use crate::ptr::{self, NonNull};
-use crate::usize;
-
-const fn size_align<T>() -> (usize, usize) {
-    (mem::size_of::<T>(), mem::align_of::<T>())
-}
-
-/// Layout of a block of memory.
-///
-/// An instance of `Layout` describes a particular layout of memory.
-/// You build a `Layout` up as an input to give to an allocator.
-///
-/// All layouts have an associated non-negative size and a
-/// power-of-two alignment.
-///
-/// (Note however that layouts are *not* required to have positive
-/// size, even though many allocators require that all memory
-/// requests have positive size. A caller to the `AllocRef::alloc`
-/// method must either ensure that conditions like this are met, or
-/// use specific allocators with looser requirements.)
-#[stable(feature = "alloc_layout", since = "1.28.0")]
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-#[lang = "alloc_layout"]
-pub struct Layout {
-    // size of the requested block of memory, measured in bytes.
-    size_: usize,
-
-    // alignment of the requested block of memory, measured in bytes.
-    // we ensure that this is always a power-of-two, because API's
-    // like `posix_memalign` require it and it is a reasonable
-    // constraint to impose on Layout constructors.
-    //
-    // (However, we do not analogously require `align >= sizeof(void*)`,
-    //  even though that is *also* a requirement of `posix_memalign`.)
-    align_: NonZeroUsize,
-}
-
-impl Layout {
-    /// Constructs a `Layout` from a given `size` and `align`,
-    /// or returns `LayoutErr` if any of the following conditions
-    /// are not met:
-    ///
-    /// * `align` must not be zero,
-    ///
-    /// * `align` must be a power of two,
-    ///
-    /// * `size`, when rounded up to the nearest multiple of `align`,
-    ///    must not overflow (i.e., the rounded value must be less than
-    ///    `usize::MAX`).
-    #[stable(feature = "alloc_layout", since = "1.28.0")]
-    #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
-    #[inline]
-    pub const fn from_size_align(size: usize, align: usize) -> Result<Self, LayoutErr> {
-        if !align.is_power_of_two() {
-            return Err(LayoutErr { private: () });
-        }
-
-        // (power-of-two implies align != 0.)
-
-        // Rounded up size is:
-        //   size_rounded_up = (size + align - 1) & !(align - 1);
-        //
-        // We know from above that align != 0. If adding (align - 1)
-        // does not overflow, then rounding up will be fine.
-        //
-        // Conversely, &-masking with !(align - 1) will subtract off
-        // only low-order-bits. Thus if overflow occurs with the sum,
-        // the &-mask cannot subtract enough to undo that overflow.
-        //
-        // Above implies that checking for summation overflow is both
-        // necessary and sufficient.
-        if size > usize::MAX - (align - 1) {
-            return Err(LayoutErr { private: () });
-        }
-
-        unsafe { Ok(Layout::from_size_align_unchecked(size, align)) }
-    }
-
-    /// Creates a layout, bypassing all checks.
-    ///
-    /// # Safety
-    ///
-    /// This function is unsafe as it does not verify the preconditions from
-    /// [`Layout::from_size_align`](#method.from_size_align).
-    #[stable(feature = "alloc_layout", since = "1.28.0")]
-    #[rustc_const_stable(feature = "alloc_layout", since = "1.28.0")]
-    #[inline]
-    pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
-        Layout { size_: size, align_: NonZeroUsize::new_unchecked(align) }
-    }
-
-    /// The minimum size in bytes for a memory block of this layout.
-    #[stable(feature = "alloc_layout", since = "1.28.0")]
-    #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
-    #[inline]
-    pub const fn size(&self) -> usize {
-        self.size_
-    }
-
-    /// The minimum byte alignment for a memory block of this layout.
-    #[stable(feature = "alloc_layout", since = "1.28.0")]
-    #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
-    #[inline]
-    pub const fn align(&self) -> usize {
-        self.align_.get()
-    }
-
-    /// Constructs a `Layout` suitable for holding a value of type `T`.
-    #[stable(feature = "alloc_layout", since = "1.28.0")]
-    #[rustc_const_stable(feature = "alloc_layout_const_new", since = "1.42.0")]
-    #[inline]
-    pub const fn new<T>() -> Self {
-        let (size, align) = size_align::<T>();
-        // Note that the align is guaranteed by rustc to be a power of two and
-        // the size+align combo is guaranteed to fit in our address space. As a
-        // result use the unchecked constructor here to avoid inserting code
-        // that panics if it isn't optimized well enough.
-        unsafe { Layout::from_size_align_unchecked(size, align) }
-    }
-
-    /// Produces layout describing a record that could be used to
-    /// allocate backing structure for `T` (which could be a trait
-    /// or other unsized type like a slice).
-    #[stable(feature = "alloc_layout", since = "1.28.0")]
-    #[inline]
-    pub fn for_value<T: ?Sized>(t: &T) -> Self {
-        let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
-        // See rationale in `new` for why this is using an unsafe variant below
-        debug_assert!(Layout::from_size_align(size, align).is_ok());
-        unsafe { Layout::from_size_align_unchecked(size, align) }
-    }
-
-    /// Produces layout describing a record that could be used to
-    /// allocate backing structure for `T` (which could be a trait
-    /// or other unsized type like a slice).
-    ///
-    /// # Safety
-    ///
-    /// This function is only safe to call if the following conditions hold:
-    ///
-    /// - If `T` is `Sized`, this function is always safe to call.
-    /// - If the unsized tail of `T` is:
-    ///     - a [slice], then the length of the slice tail must be an intialized
-    ///       integer, and the size of the *entire value*
-    ///       (dynamic tail length + statically sized prefix) must fit in `isize`.
-    ///     - a [trait object], then the vtable part of the pointer must point
-    ///       to a valid vtable acquired by an unsizing coersion, and the size
-    ///       of the *entire value* (dynamic tail length + statically sized prefix)
-    ///       must fit in `isize`.
-    ///     - an (unstable) [extern type], then this function is always safe to
-    ///       call, but may panic or otherwise return the wrong value, as the
-    ///       extern type's layout is not known. This is the same behavior as
-    ///       [`Layout::for_value`] on a reference to an extern type tail.
-    ///     - otherwise, it is conservatively not allowed to call this function.
-    ///
-    /// [slice]: ../../std/primitive.slice.html
-    /// [trait object]: ../../book/ch17-02-trait-objects.html
-    /// [extern type]: ../../unstable-book/language-features/extern-types.html
-    #[inline]
-    #[cfg(not(bootstrap))]
-    #[unstable(feature = "layout_for_ptr", issue = "69835")]
-    pub unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self {
-        let (size, align) = (mem::size_of_val_raw(t), mem::align_of_val_raw(t));
-        // See rationale in `new` for why this is using an unsafe variant below
-        debug_assert!(Layout::from_size_align(size, align).is_ok());
-        Layout::from_size_align_unchecked(size, align)
-    }
-
-    /// Creates a `NonNull` that is dangling, but well-aligned for this Layout.
-    ///
-    /// Note that the pointer value may potentially represent a valid pointer,
-    /// which means this must not be used as a "not yet initialized"
-    /// sentinel value. Types that lazily allocate must track initialization by
-    /// some other means.
-    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
-    pub const fn dangling(&self) -> NonNull<u8> {
-        // align is non-zero and a power of two
-        unsafe { NonNull::new_unchecked(self.align() as *mut u8) }
-    }
-
-    /// Creates a layout describing the record that can hold a value
-    /// of the same layout as `self`, but that also is aligned to
-    /// alignment `align` (measured in bytes).
-    ///
-    /// If `self` already meets the prescribed alignment, then returns
-    /// `self`.
-    ///
-    /// Note that this method does not add any padding to the overall
-    /// size, regardless of whether the returned layout has a different
-    /// alignment. In other words, if `K` has size 16, `K.align_to(32)`
-    /// will *still* have size 16.
-    ///
-    /// Returns an error if the combination of `self.size()` and the given
-    /// `align` violates the conditions listed in
-    /// [`Layout::from_size_align`](#method.from_size_align).
-    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
-    #[inline]
-    pub fn align_to(&self, align: usize) -> Result<Self, LayoutErr> {
-        Layout::from_size_align(self.size(), cmp::max(self.align(), align))
-    }
-
-    /// Returns the amount of padding we must insert after `self`
-    /// to ensure that the following address will satisfy `align`
-    /// (measured in bytes).
-    ///
-    /// e.g., if `self.size()` is 9, then `self.padding_needed_for(4)`
-    /// returns 3, because that is the minimum number of bytes of
-    /// padding required to get a 4-aligned address (assuming that the
-    /// corresponding memory block starts at a 4-aligned address).
-    ///
-    /// The return value of this function has no meaning if `align` is
-    /// not a power-of-two.
-    ///
-    /// Note that the utility of the returned value requires `align`
-    /// to be less than or equal to the alignment of the starting
-    /// address for the whole allocated block of memory. One way to
-    /// satisfy this constraint is to ensure `align <= self.align()`.
-    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
-    #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
-    #[inline]
-    pub const fn padding_needed_for(&self, align: usize) -> usize {
-        let len = self.size();
-
-        // Rounded up value is:
-        //   len_rounded_up = (len + align - 1) & !(align - 1);
-        // and then we return the padding difference: `len_rounded_up - len`.
-        //
-        // We use modular arithmetic throughout:
-        //
-        // 1. align is guaranteed to be > 0, so align - 1 is always
-        //    valid.
-        //
-        // 2. `len + align - 1` can overflow by at most `align - 1`,
-        //    so the &-mask with `!(align - 1)` will ensure that in the
-        //    case of overflow, `len_rounded_up` will itself be 0.
-        //    Thus the returned padding, when added to `len`, yields 0,
-        //    which trivially satisfies the alignment `align`.
-        //
-        // (Of course, attempts to allocate blocks of memory whose
-        // size and padding overflow in the above manner should cause
-        // the allocator to yield an error anyway.)
-
-        let len_rounded_up = len.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1);
-        len_rounded_up.wrapping_sub(len)
-    }
-
-    /// Creates a layout by rounding the size of this layout up to a multiple
-    /// of the layout's alignment.
-    ///
-    /// This is equivalent to adding the result of `padding_needed_for`
-    /// to the layout's current size.
-    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
-    #[inline]
-    pub fn pad_to_align(&self) -> Layout {
-        let pad = self.padding_needed_for(self.align());
-        // This cannot overflow. Quoting from the invariant of Layout:
-        // > `size`, when rounded up to the nearest multiple of `align`,
-        // > must not overflow (i.e., the rounded value must be less than
-        // > `usize::MAX`)
-        let new_size = self.size() + pad;
-
-        Layout::from_size_align(new_size, self.align()).unwrap()
-    }
-
-    /// Creates a layout describing the record for `n` instances of
-    /// `self`, with a suitable amount of padding between each to
-    /// ensure that each instance is given its requested size and
-    /// alignment. On success, returns `(k, offs)` where `k` is the
-    /// layout of the array and `offs` is the distance between the start
-    /// of each element in the array.
-    ///
-    /// On arithmetic overflow, returns `LayoutErr`.
-    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
-    #[inline]
-    pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutErr> {
-        // This cannot overflow. Quoting from the invariant of Layout:
-        // > `size`, when rounded up to the nearest multiple of `align`,
-        // > must not overflow (i.e., the rounded value must be less than
-        // > `usize::MAX`)
-        let padded_size = self.size() + self.padding_needed_for(self.align());
-        let alloc_size = padded_size.checked_mul(n).ok_or(LayoutErr { private: () })?;
-
-        unsafe {
-            // self.align is already known to be valid and alloc_size has been
-            // padded already.
-            Ok((Layout::from_size_align_unchecked(alloc_size, self.align()), padded_size))
-        }
-    }
-
-    /// Creates a layout describing the record for `self` followed by
-    /// `next`, including any necessary padding to ensure that `next`
-    /// will be properly aligned. Note that the resulting layout will
-    /// satisfy the alignment properties of both `self` and `next`.
-    ///
-    /// The resulting layout will be the same as that of a C struct containing
-    /// two fields with the layouts of `self` and `next`, in that order.
-    ///
-    /// Returns `Some((k, offset))`, where `k` is layout of the concatenated
-    /// record and `offset` is the relative location, in bytes, of the
-    /// start of the `next` embedded within the concatenated record
-    /// (assuming that the record itself starts at offset 0).
-    ///
-    /// On arithmetic overflow, returns `LayoutErr`.
-    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
-    #[inline]
-    pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutErr> {
-        let new_align = cmp::max(self.align(), next.align());
-        let pad = self.padding_needed_for(next.align());
-
-        let offset = self.size().checked_add(pad).ok_or(LayoutErr { private: () })?;
-        let new_size = offset.checked_add(next.size()).ok_or(LayoutErr { private: () })?;
-
-        let layout = Layout::from_size_align(new_size, new_align)?;
-        Ok((layout, offset))
-    }
-
-    /// Creates a layout describing the record for `n` instances of
-    /// `self`, with no padding between each instance.
-    ///
-    /// Note that, unlike `repeat`, `repeat_packed` does not guarantee
-    /// that the repeated instances of `self` will be properly
-    /// aligned, even if a given instance of `self` is properly
-    /// aligned. In other words, if the layout returned by
-    /// `repeat_packed` is used to allocate an array, it is not
-    /// guaranteed that all elements in the array will be properly
-    /// aligned.
-    ///
-    /// On arithmetic overflow, returns `LayoutErr`.
-    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
-    #[inline]
-    pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutErr> {
-        let size = self.size().checked_mul(n).ok_or(LayoutErr { private: () })?;
-        Layout::from_size_align(size, self.align())
-    }
-
-    /// Creates a layout describing the record for `self` followed by
-    /// `next` with no additional padding between the two. Since no
-    /// padding is inserted, the alignment of `next` is irrelevant,
-    /// and is not incorporated *at all* into the resulting layout.
-    ///
-    /// On arithmetic overflow, returns `LayoutErr`.
-    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
-    #[inline]
-    pub fn extend_packed(&self, next: Self) -> Result<Self, LayoutErr> {
-        let new_size = self.size().checked_add(next.size()).ok_or(LayoutErr { private: () })?;
-        Layout::from_size_align(new_size, self.align())
-    }
-
-    /// Creates a layout describing the record for a `[T; n]`.
-    ///
-    /// On arithmetic overflow, returns `LayoutErr`.
-    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
-    #[inline]
-    pub fn array<T>(n: usize) -> Result<Self, LayoutErr> {
-        Layout::new::<T>().repeat(n).map(|(k, offs)| {
-            debug_assert!(offs == mem::size_of::<T>());
-            k
-        })
-    }
-}
-
-/// The parameters given to `Layout::from_size_align`
-/// or some other `Layout` constructor
-/// do not satisfy its documented constraints.
-#[stable(feature = "alloc_layout", since = "1.28.0")]
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct LayoutErr {
-    private: (),
-}
-
-// (we need this for downstream impl of trait Error)
-#[stable(feature = "alloc_layout", since = "1.28.0")]
-impl fmt::Display for LayoutErr {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str("invalid parameters to Layout::from_size_align")
-    }
-}
-
-/// The `AllocErr` error indicates an allocation failure
-/// that may be due to resource exhaustion or to
-/// something wrong when combining the given input arguments with this
-/// allocator.
-#[unstable(feature = "allocator_api", issue = "32838")]
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct AllocErr;
-
-// (we need this for downstream impl of trait Error)
-#[unstable(feature = "allocator_api", issue = "32838")]
-impl fmt::Display for AllocErr {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str("memory allocation failed")
-    }
-}
-
-/// The `CannotReallocInPlace` error is used when [`grow_in_place`] or
-/// [`shrink_in_place`] were unable to reuse the given memory block for
-/// a requested layout.
-///
-/// [`grow_in_place`]: ./trait.AllocRef.html#method.grow_in_place
-/// [`shrink_in_place`]: ./trait.AllocRef.html#method.shrink_in_place
-#[unstable(feature = "allocator_api", issue = "32838")]
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct CannotReallocInPlace;
-
-#[unstable(feature = "allocator_api", issue = "32838")]
-impl CannotReallocInPlace {
-    pub fn description(&self) -> &str {
-        "cannot reallocate allocator's memory in place"
-    }
-}
-
-// (we need this for downstream impl of trait Error)
-#[unstable(feature = "allocator_api", issue = "32838")]
-impl fmt::Display for CannotReallocInPlace {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", self.description())
-    }
-}
-
-/// A memory allocator that can be registered as the standard library’s default
-/// through the `#[global_allocator]` attribute.
-///
-/// Some of the methods require that a memory block be *currently
-/// allocated* via an allocator. This means that:
-///
-/// * the starting address for that memory block was previously
-///   returned by a previous call to an allocation method
-///   such as `alloc`, and
-///
-/// * the memory block has not been subsequently deallocated, where
-///   blocks are deallocated either by being passed to a deallocation
-///   method such as `dealloc` or by being
-///   passed to a reallocation method that returns a non-null pointer.
-///
-///
-/// # Example
-///
-/// ```no_run
-/// use std::alloc::{GlobalAlloc, Layout, alloc};
-/// use std::ptr::null_mut;
-///
-/// struct MyAllocator;
-///
-/// unsafe impl GlobalAlloc for MyAllocator {
-///     unsafe fn alloc(&self, _layout: Layout) -> *mut u8 { null_mut() }
-///     unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
-/// }
-///
-/// #[global_allocator]
-/// static A: MyAllocator = MyAllocator;
-///
-/// fn main() {
-///     unsafe {
-///         assert!(alloc(Layout::new::<u32>()).is_null())
-///     }
-/// }
-/// ```
-///
-/// # Safety
-///
-/// The `GlobalAlloc` trait is an `unsafe` trait for a number of reasons, and
-/// implementors must ensure that they adhere to these contracts:
-///
-/// * It's undefined behavior if global allocators unwind. This restriction may
-///   be lifted in the future, but currently a panic from any of these
-///   functions may lead to memory unsafety.
-///
-/// * `Layout` queries and calculations in general must be correct. Callers of
-///   this trait are allowed to rely on the contracts defined on each method,
-///   and implementors must ensure such contracts remain true.
-#[stable(feature = "global_alloc", since = "1.28.0")]
-pub unsafe trait GlobalAlloc {
-    /// Allocate memory as described by the given `layout`.
-    ///
-    /// Returns a pointer to newly-allocated memory,
-    /// or null to indicate allocation failure.
-    ///
-    /// # Safety
-    ///
-    /// This function is unsafe because undefined behavior can result
-    /// if the caller does not ensure that `layout` has non-zero size.
-    ///
-    /// (Extension subtraits might provide more specific bounds on
-    /// behavior, e.g., guarantee a sentinel address or a null pointer
-    /// in response to a zero-size allocation request.)
-    ///
-    /// The allocated block of memory may or may not be initialized.
-    ///
-    /// # Errors
-    ///
-    /// Returning a null pointer indicates that either memory is exhausted
-    /// or `layout` does not meet this allocator's size or alignment constraints.
-    ///
-    /// Implementations are encouraged to return null on memory
-    /// exhaustion rather than aborting, but this is not
-    /// a strict requirement. (Specifically: it is *legal* to
-    /// implement this trait atop an underlying native allocation
-    /// library that aborts on memory exhaustion.)
-    ///
-    /// Clients wishing to abort computation in response to an
-    /// allocation error are encouraged to call the [`handle_alloc_error`] function,
-    /// rather than directly invoking `panic!` or similar.
-    ///
-    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
-    #[stable(feature = "global_alloc", since = "1.28.0")]
-    unsafe fn alloc(&self, layout: Layout) -> *mut u8;
-
-    /// Deallocate the block of memory at the given `ptr` pointer with the given `layout`.
-    ///
-    /// # Safety
-    ///
-    /// This function is unsafe because undefined behavior can result
-    /// if the caller does not ensure all of the following:
-    ///
-    /// * `ptr` must denote a block of memory currently allocated via
-    ///   this allocator,
-    ///
-    /// * `layout` must be the same layout that was used
-    ///   to allocate that block of memory,
-    #[stable(feature = "global_alloc", since = "1.28.0")]
-    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout);
-
-    /// Behaves like `alloc`, but also ensures that the contents
-    /// are set to zero before being returned.
-    ///
-    /// # Safety
-    ///
-    /// This function is unsafe for the same reasons that `alloc` is.
-    /// However the allocated block of memory is guaranteed to be initialized.
-    ///
-    /// # Errors
-    ///
-    /// Returning a null pointer indicates that either memory is exhausted
-    /// or `layout` does not meet allocator's size or alignment constraints,
-    /// just as in `alloc`.
-    ///
-    /// Clients wishing to abort computation in response to an
-    /// allocation error are encouraged to call the [`handle_alloc_error`] function,
-    /// rather than directly invoking `panic!` or similar.
-    ///
-    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
-    #[stable(feature = "global_alloc", since = "1.28.0")]
-    unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
-        let size = layout.size();
-        let ptr = self.alloc(layout);
-        if !ptr.is_null() {
-            ptr::write_bytes(ptr, 0, size);
-        }
-        ptr
-    }
-
-    /// Shrink or grow a block of memory to the given `new_size`.
-    /// The block is described by the given `ptr` pointer and `layout`.
-    ///
-    /// If this returns a non-null pointer, then ownership of the memory block
-    /// referenced by `ptr` has been transferred to this allocator.
-    /// The memory may or may not have been deallocated,
-    /// and should be considered unusable (unless of course it was
-    /// transferred back to the caller again via the return value of
-    /// this method). The new memory block is allocated with `layout`, but
-    /// with the `size` updated to `new_size`.
-    ///
-    /// If this method returns null, then ownership of the memory
-    /// block has not been transferred to this allocator, and the
-    /// contents of the memory block are unaltered.
-    ///
-    /// # Safety
-    ///
-    /// This function is unsafe because undefined behavior can result
-    /// if the caller does not ensure all of the following:
-    ///
-    /// * `ptr` must be currently allocated via this allocator,
-    ///
-    /// * `layout` must be the same layout that was used
-    ///   to allocate that block of memory,
-    ///
-    /// * `new_size` must be greater than zero.
-    ///
-    /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`,
-    ///   must not overflow (i.e., the rounded value must be less than `usize::MAX`).
-    ///
-    /// (Extension subtraits might provide more specific bounds on
-    /// behavior, e.g., guarantee a sentinel address or a null pointer
-    /// in response to a zero-size allocation request.)
-    ///
-    /// # Errors
-    ///
-    /// Returns null if the new layout does not meet the size
-    /// and alignment constraints of the allocator, or if reallocation
-    /// otherwise fails.
-    ///
-    /// Implementations are encouraged to return null on memory
-    /// exhaustion rather than panicking or aborting, but this is not
-    /// a strict requirement. (Specifically: it is *legal* to
-    /// implement this trait atop an underlying native allocation
-    /// library that aborts on memory exhaustion.)
-    ///
-    /// Clients wishing to abort computation in response to a
-    /// reallocation error are encouraged to call the [`handle_alloc_error`] function,
-    /// rather than directly invoking `panic!` or similar.
-    ///
-    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
-    #[stable(feature = "global_alloc", since = "1.28.0")]
-    unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
-        let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
-        let new_ptr = self.alloc(new_layout);
-        if !new_ptr.is_null() {
-            ptr::copy_nonoverlapping(ptr, new_ptr, cmp::min(layout.size(), new_size));
-            self.dealloc(ptr, layout);
-        }
-        new_ptr
-    }
-}
-
-/// An implementation of `AllocRef` can allocate, reallocate, and
-/// deallocate arbitrary blocks of data described via `Layout`.
-///
-/// `AllocRef` is designed to be implemented on ZSTs, references, or
-/// smart pointers because having an allocator like `MyAlloc([u8; N])`
-/// cannot be moved, without updating the pointers to the allocated
-/// memory.
-///
-/// Some of the methods require that a memory block be *currently
-/// allocated* via an allocator. This means that:
-///
-/// * the starting address for that memory block was previously
-///   returned by a previous call to an allocation method (`alloc`,
-///   `alloc_zeroed`) or reallocation method (`realloc`), and
-///
-/// * the memory block has not been subsequently deallocated, where
-///   blocks are deallocated either by being passed to a deallocation
-///   method (`dealloc`) or by being passed to a reallocation method
-///  (see above) that returns `Ok`.
-///
-/// 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. In this case [`Layout::dangling()`] can be used to
-/// create a dangling, but aligned `NonNull<u8>`.
-///
-/// Some of the methods require that a layout *fit* a memory block.
-/// What it means for a layout to "fit" a memory block means (or
-/// equivalently, for a memory block to "fit" a layout) is that the
-/// following two conditions must hold:
-///
-/// 1. The block's starting address must be aligned to `layout.align()`.
-///
-/// 2. The block's size must fall in the range `[use_min, use_max]`, where:
-///
-///    * `use_min` is `layout.size()`, and
-///
-///    * `use_max` is the capacity that was returned.
-///
-/// Note that:
-///
-///  * the size of the layout most recently used to allocate the block
-///    is guaranteed to be in the range `[use_min, use_max]`, and
-///
-///  * a lower-bound on `use_max` can be safely approximated by a call to
-///    `usable_size`.
-///
-///  * if a layout `k` fits a memory block (denoted by `ptr`)
-///    currently allocated via an allocator `a`, then it is legal to
-///    use that layout to deallocate it, i.e., `a.dealloc(ptr, k);`.
-///
-///  * if an allocator does not support overallocating, it is fine to
-///    simply return `layout.size()` as the allocated size.
-///
-/// [`GlobalAlloc`]: self::GlobalAlloc
-/// [`Layout::dangling()`]: self::Layout::dangling
-///
-/// # Safety
-///
-/// The `AllocRef` trait is an `unsafe` trait for a number of reasons, and
-/// implementors must ensure that they adhere to these contracts:
-///
-/// * Pointers returned from allocation functions must point to valid memory and
-///   retain their validity until at least one instance of `AllocRef` is dropped
-///   itself.
-///
-/// * Cloning or moving the allocator must not invalidate pointers returned
-///   from this allocator. Cloning must return a reference to the same allocator.
-///
-/// * `Layout` queries and calculations in general must be correct. Callers of
-///   this trait are allowed to rely on the contracts defined on each method,
-///   and implementors must ensure such contracts remain true.
-///
-/// Note that this list may get tweaked over time as clarifications are made in
-/// the future.
-#[unstable(feature = "allocator_api", issue = "32838")]
-pub unsafe trait AllocRef {
-    /// On success, returns a pointer meeting the size and alignment
-    /// guarantees of `layout` and the actual size of the allocated block,
-    /// which must be greater than or equal to `layout.size()`.
-    ///
-    /// If this method returns an `Ok(addr)`, then the `addr` returned
-    /// will be non-null address pointing to a block of storage
-    /// suitable for holding an instance of `layout`.
-    ///
-    /// The returned block of storage may or may not have its contents
-    /// initialized. (Extension subtraits might restrict this
-    /// behavior, e.g., to ensure initialization to particular sets of
-    /// bit patterns.)
-    ///
-    /// # Errors
-    ///
-    /// Returning `Err` indicates that either memory is exhausted or
-    /// `layout` does not meet allocator's size or alignment
-    /// constraints.
-    ///
-    /// 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 this trait atop an underlying native allocation
-    /// library that aborts on memory exhaustion.)
-    ///
-    /// Clients wishing to abort computation in response to an
-    /// allocation error are encouraged to call the [`handle_alloc_error`] function,
-    /// rather than directly invoking `panic!` or similar.
-    ///
-    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
-    fn alloc(&mut self, layout: Layout) -> Result<(NonNull<u8>, usize), AllocErr>;
-
-    /// Deallocate the memory referenced by `ptr`.
-    ///
-    /// # Safety
-    ///
-    /// This function is unsafe because undefined behavior can result
-    /// if the caller does not ensure all of the following:
-    ///
-    /// * `ptr` must denote a block of memory currently allocated via
-    ///   this allocator,
-    ///
-    /// * `layout` must *fit* that block of memory,
-    ///
-    /// * In addition to fitting the block of memory `layout`, the
-    ///   alignment of the `layout` must match the alignment used
-    ///   to allocate that block of memory.
-    unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout);
-
-    /// Behaves like `alloc`, but also ensures that the contents
-    /// are set to zero before being returned.
-    ///
-    /// # Errors
-    ///
-    /// Returning `Err` indicates that either memory is exhausted or
-    /// `layout` does not meet allocator's size or alignment
-    /// constraints, just as in `alloc`.
-    ///
-    /// Clients wishing to abort computation in response to an
-    /// allocation error are encouraged to call the [`handle_alloc_error`] function,
-    /// rather than directly invoking `panic!` or similar.
-    ///
-    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
-    fn alloc_zeroed(&mut self, layout: Layout) -> Result<(NonNull<u8>, usize), AllocErr> {
-        let size = layout.size();
-        let result = self.alloc(layout);
-        if let Ok((p, _)) = result {
-            unsafe { ptr::write_bytes(p.as_ptr(), 0, size) }
-        }
-        result
-    }
-
-    // == METHODS FOR MEMORY REUSE ==
-    // realloc, realloc_zeroed, grow_in_place, grow_in_place_zeroed, shrink_in_place
-
-    /// Returns a pointer suitable for holding data described by
-    /// a new layout with `layout`’s alignment and a size given
-    /// by `new_size` and the actual size of the allocated block.
-    /// The latter is greater than or equal to `layout.size()`.
-    /// To accomplish this, the allocator may extend or shrink
-    /// the allocation referenced by `ptr` to fit the new layout.
-    ///
-    /// If this returns `Ok`, then ownership of the memory block
-    /// referenced by `ptr` has been transferred to this
-    /// allocator. The memory may or may not have been freed, and
-    /// should be considered unusable (unless of course it was
-    /// transferred back to the caller again via the return value of
-    /// this method).
-    ///
-    /// If this method returns `Err`, then ownership of the memory
-    /// block has not been transferred to this allocator, and the
-    /// contents of the memory block are unaltered.
-    ///
-    /// # Safety
-    ///
-    /// This function is unsafe because undefined behavior can result
-    /// if the caller does not ensure all of the following:
-    ///
-    /// * `ptr` must be currently allocated via this allocator,
-    ///
-    /// * `layout` must *fit* the `ptr` (see above). (The `new_size`
-    ///   argument need not fit it.)
-    ///
-    /// * `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`).
-    ///
-    /// (Extension subtraits might provide more specific bounds on
-    /// behavior, e.g., guarantee a sentinel address or a null pointer
-    /// in response to a zero-size allocation request.)
-    ///
-    /// # Errors
-    ///
-    /// Returns `Err` only if the new layout
-    /// does not meet the allocator's size
-    /// and alignment constraints of the allocator, or if reallocation
-    /// 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 this trait atop an underlying native allocation
-    /// library that aborts on memory exhaustion.)
-    ///
-    /// Clients wishing to abort computation in response to a
-    /// reallocation error are encouraged to call the [`handle_alloc_error`] function,
-    /// rather than directly invoking `panic!` or similar.
-    ///
-    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
-    unsafe fn realloc(
-        &mut self,
-        ptr: NonNull<u8>,
-        layout: Layout,
-        new_size: usize,
-    ) -> Result<(NonNull<u8>, usize), AllocErr> {
-        let old_size = layout.size();
-
-        if new_size > old_size {
-            if let Ok(size) = self.grow_in_place(ptr, layout, new_size) {
-                return Ok((ptr, size));
-            }
-        } else if new_size < old_size {
-            if let Ok(size) = self.shrink_in_place(ptr, layout, new_size) {
-                return Ok((ptr, size));
-            }
-        } else {
-            return Ok((ptr, new_size));
-        }
-
-        // otherwise, fall back on alloc + copy + dealloc.
-        let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
-        let result = self.alloc(new_layout);
-        if let Ok((new_ptr, _)) = result {
-            ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_ptr(), cmp::min(old_size, new_size));
-            self.dealloc(ptr, layout);
-        }
-        result
-    }
-
-    /// Behaves like `realloc`, but also ensures that the new contents
-    /// are set to zero before being returned.
-    ///
-    /// # Safety
-    ///
-    /// This function is unsafe for the same reasons that `realloc` is.
-    ///
-    /// # Errors
-    ///
-    /// Returns `Err` only if the new layout
-    /// does not meet the allocator's size
-    /// and alignment constraints of the allocator, or if reallocation
-    /// 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 this trait atop an underlying native allocation
-    /// library that aborts on memory exhaustion.)
-    ///
-    /// Clients wishing to abort computation in response to a
-    /// reallocation error are encouraged to call the [`handle_alloc_error`] function,
-    /// rather than directly invoking `panic!` or similar.
-    ///
-    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
-    unsafe fn realloc_zeroed(
-        &mut self,
-        ptr: NonNull<u8>,
-        layout: Layout,
-        new_size: usize,
-    ) -> Result<(NonNull<u8>, usize), AllocErr> {
-        let old_size = layout.size();
-
-        if new_size > old_size {
-            if let Ok(size) = self.grow_in_place_zeroed(ptr, layout, new_size) {
-                return Ok((ptr, size));
-            }
-        } else if new_size < old_size {
-            if let Ok(size) = self.shrink_in_place(ptr, layout, new_size) {
-                return Ok((ptr, size));
-            }
-        } else {
-            return Ok((ptr, new_size));
-        }
-
-        // otherwise, fall back on alloc + copy + dealloc.
-        let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
-        let result = self.alloc_zeroed(new_layout);
-        if let Ok((new_ptr, _)) = result {
-            ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_ptr(), cmp::min(old_size, new_size));
-            self.dealloc(ptr, layout);
-        }
-        result
-    }
-
-    /// Attempts to extend the allocation referenced by `ptr` to fit `new_size`.
-    ///
-    /// If this returns `Ok`, then the allocator has asserted that the
-    /// memory block referenced by `ptr` now fits `new_size`, and thus can
-    /// be used to carry data of a layout of that size and same alignment as
-    /// `layout`. The returned value is the new size of the allocated block.
-    /// (The allocator is allowed to expend effort to accomplish this, such
-    /// as extending the memory block to include successor blocks, or virtual
-    /// memory tricks.)
-    ///
-    /// Regardless of what this method returns, ownership of the
-    /// memory block referenced by `ptr` has not been transferred, and
-    /// the contents of the memory block are unaltered.
-    ///
-    /// # Safety
-    ///
-    /// This function is unsafe because undefined behavior can result
-    /// if the caller does not ensure all of the following:
-    ///
-    /// * `ptr` must be currently allocated via this allocator,
-    ///
-    /// * `layout` must *fit* the `ptr` (see above); note the
-    ///   `new_size` argument need not fit it,
-    ///
-    /// * `new_size` must not be less than `layout.size()`,
-    ///
-    /// # Errors
-    ///
-    /// Returns `Err(CannotReallocInPlace)` when the allocator is
-    /// unable to assert that the memory block referenced by `ptr`
-    /// could fit `layout`.
-    ///
-    /// Note that one cannot pass `CannotReallocInPlace` to the `handle_alloc_error`
-    /// function; clients are expected either to be able to recover from
-    /// `grow_in_place` failures without aborting, or to fall back on
-    /// another reallocation method before resorting to an abort.
-    #[inline]
-    unsafe fn grow_in_place(
-        &mut self,
-        ptr: NonNull<u8>,
-        layout: Layout,
-        new_size: usize,
-    ) -> Result<usize, CannotReallocInPlace> {
-        let _ = ptr;
-        let _ = layout;
-        let _ = new_size;
-        Err(CannotReallocInPlace)
-    }
-
-    /// Behaves like `grow_in_place`, but also ensures that the new
-    /// contents are set to zero before being returned.
-    ///
-    /// # Safety
-    ///
-    /// This function is unsafe for the same reasons that `grow_in_place` is.
-    ///
-    /// # Errors
-    ///
-    /// Returns `Err(CannotReallocInPlace)` when the allocator is
-    /// unable to assert that the memory block referenced by `ptr`
-    /// could fit `layout`.
-    ///
-    /// Note that one cannot pass `CannotReallocInPlace` to the `handle_alloc_error`
-    /// function; clients are expected either to be able to recover from
-    /// `grow_in_place` failures without aborting, or to fall back on
-    /// another reallocation method before resorting to an abort.
-    unsafe fn grow_in_place_zeroed(
-        &mut self,
-        ptr: NonNull<u8>,
-        layout: Layout,
-        new_size: usize,
-    ) -> Result<usize, CannotReallocInPlace> {
-        let size = self.grow_in_place(ptr, layout, new_size)?;
-        ptr.as_ptr().add(layout.size()).write_bytes(0, new_size - layout.size());
-        Ok(size)
-    }
-
-    /// Attempts to shrink the allocation referenced by `ptr` to fit `new_size`.
-    ///
-    /// If this returns `Ok`, then the allocator has asserted that the
-    /// memory block referenced by `ptr` now fits `new_size`, and
-    /// thus can only be used to carry data of that smaller
-    /// layout. The returned value is the new size the allocated block.
-    /// (The allocator is allowed to take advantage of this,
-    /// carving off portions of the block for reuse elsewhere.) The
-    /// truncated contents of the block within the smaller layout are
-    /// unaltered, and ownership of block has not been transferred.
-    ///
-    /// If this returns `Err`, then the memory block is considered to
-    /// still represent the original (larger) `layout`. None of the
-    /// block has been carved off for reuse elsewhere, ownership of
-    /// the memory block has not been transferred, and the contents of
-    /// the memory block are unaltered.
-    ///
-    /// # Safety
-    ///
-    /// This function is unsafe because undefined behavior can result
-    /// if the caller does not ensure all of the following:
-    ///
-    /// * `ptr` must be currently allocated via this allocator,
-    ///
-    /// * `layout` must *fit* the `ptr` (see above); note the
-    ///   `new_size` argument need not fit it,
-    ///
-    /// * `new_size` must not be greater than `layout.size()`,
-    ///
-    /// # Errors
-    ///
-    /// Returns `Err(CannotReallocInPlace)` when the allocator is
-    /// unable to assert that the memory block referenced by `ptr`
-    /// could fit `layout`.
-    ///
-    /// Note that one cannot pass `CannotReallocInPlace` to the `handle_alloc_error`
-    /// function; clients are expected either to be able to recover from
-    /// `shrink_in_place` failures without aborting, or to fall back
-    /// on another reallocation method before resorting to an abort.
-    #[inline]
-    unsafe fn shrink_in_place(
-        &mut self,
-        ptr: NonNull<u8>,
-        layout: Layout,
-        new_size: usize,
-    ) -> Result<usize, CannotReallocInPlace> {
-        let _ = ptr;
-        let _ = layout;
-        let _ = new_size;
-        Err(CannotReallocInPlace)
-    }
-}
diff --git a/src/libcore/alloc/global.rs b/src/libcore/alloc/global.rs
new file mode 100644
index 00000000000..147fe696ac0
--- /dev/null
+++ b/src/libcore/alloc/global.rs
@@ -0,0 +1,198 @@
+use crate::alloc::Layout;
+use crate::cmp;
+use crate::ptr;
+
+/// A memory allocator that can be registered as the standard library’s default
+/// through the `#[global_allocator]` attribute.
+///
+/// Some of the methods require that a memory block be *currently
+/// allocated* via an allocator. This means that:
+///
+/// * the starting address for that memory block was previously
+///   returned by a previous call to an allocation method
+///   such as `alloc`, and
+///
+/// * the memory block has not been subsequently deallocated, where
+///   blocks are deallocated either by being passed to a deallocation
+///   method such as `dealloc` or by being
+///   passed to a reallocation method that returns a non-null pointer.
+///
+///
+/// # Example
+///
+/// ```no_run
+/// use std::alloc::{GlobalAlloc, Layout, alloc};
+/// use std::ptr::null_mut;
+///
+/// struct MyAllocator;
+///
+/// unsafe impl GlobalAlloc for MyAllocator {
+///     unsafe fn alloc(&self, _layout: Layout) -> *mut u8 { null_mut() }
+///     unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
+/// }
+///
+/// #[global_allocator]
+/// static A: MyAllocator = MyAllocator;
+///
+/// fn main() {
+///     unsafe {
+///         assert!(alloc(Layout::new::<u32>()).is_null())
+///     }
+/// }
+/// ```
+///
+/// # Safety
+///
+/// The `GlobalAlloc` trait is an `unsafe` trait for a number of reasons, and
+/// implementors must ensure that they adhere to these contracts:
+///
+/// * It's undefined behavior if global allocators unwind. This restriction may
+///   be lifted in the future, but currently a panic from any of these
+///   functions may lead to memory unsafety.
+///
+/// * `Layout` queries and calculations in general must be correct. Callers of
+///   this trait are allowed to rely on the contracts defined on each method,
+///   and implementors must ensure such contracts remain true.
+#[stable(feature = "global_alloc", since = "1.28.0")]
+pub unsafe trait GlobalAlloc {
+    /// Allocate memory as described by the given `layout`.
+    ///
+    /// Returns a pointer to newly-allocated memory,
+    /// or null to indicate allocation failure.
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe because undefined behavior can result
+    /// if the caller does not ensure that `layout` has non-zero size.
+    ///
+    /// (Extension subtraits might provide more specific bounds on
+    /// behavior, e.g., guarantee a sentinel address or a null pointer
+    /// in response to a zero-size allocation request.)
+    ///
+    /// The allocated block of memory may or may not be initialized.
+    ///
+    /// # Errors
+    ///
+    /// Returning a null pointer indicates that either memory is exhausted
+    /// or `layout` does not meet this allocator's size or alignment constraints.
+    ///
+    /// Implementations are encouraged to return null on memory
+    /// exhaustion rather than aborting, but this is not
+    /// a strict requirement. (Specifically: it is *legal* to
+    /// implement this trait atop an underlying native allocation
+    /// library that aborts on memory exhaustion.)
+    ///
+    /// Clients wishing to abort computation in response to an
+    /// allocation error are encouraged to call the [`handle_alloc_error`] function,
+    /// rather than directly invoking `panic!` or similar.
+    ///
+    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
+    #[stable(feature = "global_alloc", since = "1.28.0")]
+    unsafe fn alloc(&self, layout: Layout) -> *mut u8;
+
+    /// Deallocate the block of memory at the given `ptr` pointer with the given `layout`.
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe because undefined behavior can result
+    /// if the caller does not ensure all of the following:
+    ///
+    /// * `ptr` must denote a block of memory currently allocated via
+    ///   this allocator,
+    ///
+    /// * `layout` must be the same layout that was used
+    ///   to allocate that block of memory,
+    #[stable(feature = "global_alloc", since = "1.28.0")]
+    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout);
+
+    /// Behaves like `alloc`, but also ensures that the contents
+    /// are set to zero before being returned.
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe for the same reasons that `alloc` is.
+    /// However the allocated block of memory is guaranteed to be initialized.
+    ///
+    /// # Errors
+    ///
+    /// Returning a null pointer indicates that either memory is exhausted
+    /// or `layout` does not meet allocator's size or alignment constraints,
+    /// just as in `alloc`.
+    ///
+    /// Clients wishing to abort computation in response to an
+    /// allocation error are encouraged to call the [`handle_alloc_error`] function,
+    /// rather than directly invoking `panic!` or similar.
+    ///
+    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
+    #[stable(feature = "global_alloc", since = "1.28.0")]
+    unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
+        let size = layout.size();
+        let ptr = self.alloc(layout);
+        if !ptr.is_null() {
+            ptr::write_bytes(ptr, 0, size);
+        }
+        ptr
+    }
+
+    /// Shrink or grow a block of memory to the given `new_size`.
+    /// The block is described by the given `ptr` pointer and `layout`.
+    ///
+    /// If this returns a non-null pointer, then ownership of the memory block
+    /// referenced by `ptr` has been transferred to this allocator.
+    /// The memory may or may not have been deallocated,
+    /// and should be considered unusable (unless of course it was
+    /// transferred back to the caller again via the return value of
+    /// this method). The new memory block is allocated with `layout`, but
+    /// with the `size` updated to `new_size`.
+    ///
+    /// If this method returns null, then ownership of the memory
+    /// block has not been transferred to this allocator, and the
+    /// contents of the memory block are unaltered.
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe because undefined behavior can result
+    /// if the caller does not ensure all of the following:
+    ///
+    /// * `ptr` must be currently allocated via this allocator,
+    ///
+    /// * `layout` must be the same layout that was used
+    ///   to allocate that block of memory,
+    ///
+    /// * `new_size` must be greater than zero.
+    ///
+    /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`,
+    ///   must not overflow (i.e., the rounded value must be less than `usize::MAX`).
+    ///
+    /// (Extension subtraits might provide more specific bounds on
+    /// behavior, e.g., guarantee a sentinel address or a null pointer
+    /// in response to a zero-size allocation request.)
+    ///
+    /// # Errors
+    ///
+    /// Returns null if the new layout does not meet the size
+    /// and alignment constraints of the allocator, or if reallocation
+    /// otherwise fails.
+    ///
+    /// Implementations are encouraged to return null on memory
+    /// exhaustion rather than panicking or aborting, but this is not
+    /// a strict requirement. (Specifically: it is *legal* to
+    /// implement this trait atop an underlying native allocation
+    /// library that aborts on memory exhaustion.)
+    ///
+    /// Clients wishing to abort computation in response to a
+    /// reallocation error are encouraged to call the [`handle_alloc_error`] function,
+    /// rather than directly invoking `panic!` or similar.
+    ///
+    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
+    #[stable(feature = "global_alloc", since = "1.28.0")]
+    unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
+        let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
+        let new_ptr = self.alloc(new_layout);
+        if !new_ptr.is_null() {
+            ptr::copy_nonoverlapping(ptr, new_ptr, cmp::min(layout.size(), new_size));
+            self.dealloc(ptr, layout);
+        }
+        new_ptr
+    }
+}
diff --git a/src/libcore/alloc/layout.rs b/src/libcore/alloc/layout.rs
new file mode 100644
index 00000000000..fa644cfe99e
--- /dev/null
+++ b/src/libcore/alloc/layout.rs
@@ -0,0 +1,346 @@
+// ignore-tidy-undocumented-unsafe
+
+use crate::cmp;
+use crate::fmt;
+use crate::mem;
+use crate::num::NonZeroUsize;
+use crate::ptr::NonNull;
+
+const fn size_align<T>() -> (usize, usize) {
+    (mem::size_of::<T>(), mem::align_of::<T>())
+}
+
+/// Layout of a block of memory.
+///
+/// An instance of `Layout` describes a particular layout of memory.
+/// You build a `Layout` up as an input to give to an allocator.
+///
+/// All layouts have an associated size and a power-of-two alignment.
+///
+/// (Note that layouts are *not* required to have non-zero size,
+/// even though `GlobalAlloc` requires that all memory requests
+/// be non-zero in size. A caller must either ensure that conditions
+/// like this are met, use specific allocators with looser
+/// requirements, or use the more lenient `AllocRef` interface.)
+#[stable(feature = "alloc_layout", since = "1.28.0")]
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[lang = "alloc_layout"]
+pub struct Layout {
+    // size of the requested block of memory, measured in bytes.
+    size_: usize,
+
+    // alignment of the requested block of memory, measured in bytes.
+    // we ensure that this is always a power-of-two, because API's
+    // like `posix_memalign` require it and it is a reasonable
+    // constraint to impose on Layout constructors.
+    //
+    // (However, we do not analogously require `align >= sizeof(void*)`,
+    //  even though that is *also* a requirement of `posix_memalign`.)
+    align_: NonZeroUsize,
+}
+
+impl Layout {
+    /// Constructs a `Layout` from a given `size` and `align`,
+    /// or returns `LayoutErr` if any of the following conditions
+    /// are not met:
+    ///
+    /// * `align` must not be zero,
+    ///
+    /// * `align` must be a power of two,
+    ///
+    /// * `size`, when rounded up to the nearest multiple of `align`,
+    ///    must not overflow (i.e., the rounded value must be less than
+    ///    or equal to `usize::MAX`).
+    #[stable(feature = "alloc_layout", since = "1.28.0")]
+    #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
+    #[inline]
+    pub const fn from_size_align(size: usize, align: usize) -> Result<Self, LayoutErr> {
+        if !align.is_power_of_two() {
+            return Err(LayoutErr { private: () });
+        }
+
+        // (power-of-two implies align != 0.)
+
+        // Rounded up size is:
+        //   size_rounded_up = (size + align - 1) & !(align - 1);
+        //
+        // We know from above that align != 0. If adding (align - 1)
+        // does not overflow, then rounding up will be fine.
+        //
+        // Conversely, &-masking with !(align - 1) will subtract off
+        // only low-order-bits. Thus if overflow occurs with the sum,
+        // the &-mask cannot subtract enough to undo that overflow.
+        //
+        // Above implies that checking for summation overflow is both
+        // necessary and sufficient.
+        if size > usize::MAX - (align - 1) {
+            return Err(LayoutErr { private: () });
+        }
+
+        unsafe { Ok(Layout::from_size_align_unchecked(size, align)) }
+    }
+
+    /// Creates a layout, bypassing all checks.
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe as it does not verify the preconditions from
+    /// [`Layout::from_size_align`](#method.from_size_align).
+    #[stable(feature = "alloc_layout", since = "1.28.0")]
+    #[rustc_const_stable(feature = "alloc_layout", since = "1.28.0")]
+    #[inline]
+    pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
+        Layout { size_: size, align_: NonZeroUsize::new_unchecked(align) }
+    }
+
+    /// The minimum size in bytes for a memory block of this layout.
+    #[stable(feature = "alloc_layout", since = "1.28.0")]
+    #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
+    #[inline]
+    pub const fn size(&self) -> usize {
+        self.size_
+    }
+
+    /// The minimum byte alignment for a memory block of this layout.
+    #[stable(feature = "alloc_layout", since = "1.28.0")]
+    #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
+    #[inline]
+    pub const fn align(&self) -> usize {
+        self.align_.get()
+    }
+
+    /// Constructs a `Layout` suitable for holding a value of type `T`.
+    #[stable(feature = "alloc_layout", since = "1.28.0")]
+    #[rustc_const_stable(feature = "alloc_layout_const_new", since = "1.42.0")]
+    #[inline]
+    pub const fn new<T>() -> Self {
+        let (size, align) = size_align::<T>();
+        // Note that the align is guaranteed by rustc to be a power of two and
+        // the size+align combo is guaranteed to fit in our address space. As a
+        // result use the unchecked constructor here to avoid inserting code
+        // that panics if it isn't optimized well enough.
+        unsafe { Layout::from_size_align_unchecked(size, align) }
+    }
+
+    /// Produces layout describing a record that could be used to
+    /// allocate backing structure for `T` (which could be a trait
+    /// or other unsized type like a slice).
+    #[stable(feature = "alloc_layout", since = "1.28.0")]
+    #[inline]
+    pub fn for_value<T: ?Sized>(t: &T) -> Self {
+        let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
+        // See rationale in `new` for why this is using an unsafe variant below
+        debug_assert!(Layout::from_size_align(size, align).is_ok());
+        unsafe { Layout::from_size_align_unchecked(size, align) }
+    }
+
+    /// Creates a `NonNull` that is dangling, but well-aligned for this Layout.
+    ///
+    /// Note that the pointer value may potentially represent a valid pointer,
+    /// which means this must not be used as a "not yet initialized"
+    /// sentinel value. Types that lazily allocate must track initialization by
+    /// some other means.
+    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
+    #[inline]
+    pub const fn dangling(&self) -> NonNull<u8> {
+        // align is non-zero and a power of two
+        unsafe { NonNull::new_unchecked(self.align() as *mut u8) }
+    }
+
+    /// Creates a layout describing the record that can hold a value
+    /// of the same layout as `self`, but that also is aligned to
+    /// alignment `align` (measured in bytes).
+    ///
+    /// If `self` already meets the prescribed alignment, then returns
+    /// `self`.
+    ///
+    /// Note that this method does not add any padding to the overall
+    /// size, regardless of whether the returned layout has a different
+    /// alignment. In other words, if `K` has size 16, `K.align_to(32)`
+    /// will *still* have size 16.
+    ///
+    /// Returns an error if the combination of `self.size()` and the given
+    /// `align` violates the conditions listed in
+    /// [`Layout::from_size_align`](#method.from_size_align).
+    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
+    #[inline]
+    pub fn align_to(&self, align: usize) -> Result<Self, LayoutErr> {
+        Layout::from_size_align(self.size(), cmp::max(self.align(), align))
+    }
+
+    /// Returns the amount of padding we must insert after `self`
+    /// to ensure that the following address will satisfy `align`
+    /// (measured in bytes).
+    ///
+    /// e.g., if `self.size()` is 9, then `self.padding_needed_for(4)`
+    /// returns 3, because that is the minimum number of bytes of
+    /// padding required to get a 4-aligned address (assuming that the
+    /// corresponding memory block starts at a 4-aligned address).
+    ///
+    /// The return value of this function has no meaning if `align` is
+    /// not a power-of-two.
+    ///
+    /// Note that the utility of the returned value requires `align`
+    /// to be less than or equal to the alignment of the starting
+    /// address for the whole allocated block of memory. One way to
+    /// satisfy this constraint is to ensure `align <= self.align()`.
+    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
+    #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
+    #[inline]
+    pub const fn padding_needed_for(&self, align: usize) -> usize {
+        let len = self.size();
+
+        // Rounded up value is:
+        //   len_rounded_up = (len + align - 1) & !(align - 1);
+        // and then we return the padding difference: `len_rounded_up - len`.
+        //
+        // We use modular arithmetic throughout:
+        //
+        // 1. align is guaranteed to be > 0, so align - 1 is always
+        //    valid.
+        //
+        // 2. `len + align - 1` can overflow by at most `align - 1`,
+        //    so the &-mask with `!(align - 1)` will ensure that in the
+        //    case of overflow, `len_rounded_up` will itself be 0.
+        //    Thus the returned padding, when added to `len`, yields 0,
+        //    which trivially satisfies the alignment `align`.
+        //
+        // (Of course, attempts to allocate blocks of memory whose
+        // size and padding overflow in the above manner should cause
+        // the allocator to yield an error anyway.)
+
+        let len_rounded_up = len.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1);
+        len_rounded_up.wrapping_sub(len)
+    }
+
+    /// Creates a layout by rounding the size of this layout up to a multiple
+    /// of the layout's alignment.
+    ///
+    /// This is equivalent to adding the result of `padding_needed_for`
+    /// to the layout's current size.
+    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
+    #[inline]
+    pub fn pad_to_align(&self) -> Layout {
+        let pad = self.padding_needed_for(self.align());
+        // This cannot overflow. Quoting from the invariant of Layout:
+        // > `size`, when rounded up to the nearest multiple of `align`,
+        // > must not overflow (i.e., the rounded value must be less than
+        // > `usize::MAX`)
+        let new_size = self.size() + pad;
+
+        Layout::from_size_align(new_size, self.align()).unwrap()
+    }
+
+    /// Creates a layout describing the record for `n` instances of
+    /// `self`, with a suitable amount of padding between each to
+    /// ensure that each instance is given its requested size and
+    /// alignment. On success, returns `(k, offs)` where `k` is the
+    /// layout of the array and `offs` is the distance between the start
+    /// of each element in the array.
+    ///
+    /// On arithmetic overflow, returns `LayoutErr`.
+    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
+    #[inline]
+    pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutErr> {
+        // This cannot overflow. Quoting from the invariant of Layout:
+        // > `size`, when rounded up to the nearest multiple of `align`,
+        // > must not overflow (i.e., the rounded value must be less than
+        // > `usize::MAX`)
+        let padded_size = self.size() + self.padding_needed_for(self.align());
+        let alloc_size = padded_size.checked_mul(n).ok_or(LayoutErr { private: () })?;
+
+        unsafe {
+            // self.align is already known to be valid and alloc_size has been
+            // padded already.
+            Ok((Layout::from_size_align_unchecked(alloc_size, self.align()), padded_size))
+        }
+    }
+
+    /// Creates a layout describing the record for `self` followed by
+    /// `next`, including any necessary padding to ensure that `next`
+    /// will be properly aligned. Note that the resulting layout will
+    /// satisfy the alignment properties of both `self` and `next`.
+    ///
+    /// The resulting layout will be the same as that of a C struct containing
+    /// two fields with the layouts of `self` and `next`, in that order.
+    ///
+    /// Returns `Some((k, offset))`, where `k` is layout of the concatenated
+    /// record and `offset` is the relative location, in bytes, of the
+    /// start of the `next` embedded within the concatenated record
+    /// (assuming that the record itself starts at offset 0).
+    ///
+    /// On arithmetic overflow, returns `LayoutErr`.
+    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
+    #[inline]
+    pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutErr> {
+        let new_align = cmp::max(self.align(), next.align());
+        let pad = self.padding_needed_for(next.align());
+
+        let offset = self.size().checked_add(pad).ok_or(LayoutErr { private: () })?;
+        let new_size = offset.checked_add(next.size()).ok_or(LayoutErr { private: () })?;
+
+        let layout = Layout::from_size_align(new_size, new_align)?;
+        Ok((layout, offset))
+    }
+
+    /// Creates a layout describing the record for `n` instances of
+    /// `self`, with no padding between each instance.
+    ///
+    /// Note that, unlike `repeat`, `repeat_packed` does not guarantee
+    /// that the repeated instances of `self` will be properly
+    /// aligned, even if a given instance of `self` is properly
+    /// aligned. In other words, if the layout returned by
+    /// `repeat_packed` is used to allocate an array, it is not
+    /// guaranteed that all elements in the array will be properly
+    /// aligned.
+    ///
+    /// On arithmetic overflow, returns `LayoutErr`.
+    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
+    #[inline]
+    pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutErr> {
+        let size = self.size().checked_mul(n).ok_or(LayoutErr { private: () })?;
+        Layout::from_size_align(size, self.align())
+    }
+
+    /// Creates a layout describing the record for `self` followed by
+    /// `next` with no additional padding between the two. Since no
+    /// padding is inserted, the alignment of `next` is irrelevant,
+    /// and is not incorporated *at all* into the resulting layout.
+    ///
+    /// On arithmetic overflow, returns `LayoutErr`.
+    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
+    #[inline]
+    pub fn extend_packed(&self, next: Self) -> Result<Self, LayoutErr> {
+        let new_size = self.size().checked_add(next.size()).ok_or(LayoutErr { private: () })?;
+        Layout::from_size_align(new_size, self.align())
+    }
+
+    /// Creates a layout describing the record for a `[T; n]`.
+    ///
+    /// On arithmetic overflow, returns `LayoutErr`.
+    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
+    #[inline]
+    pub fn array<T>(n: usize) -> Result<Self, LayoutErr> {
+        Layout::new::<T>().repeat(n).map(|(k, offs)| {
+            debug_assert!(offs == mem::size_of::<T>());
+            k
+        })
+    }
+}
+
+/// The parameters given to `Layout::from_size_align`
+/// or some other `Layout` constructor
+/// do not satisfy its documented constraints.
+#[stable(feature = "alloc_layout", since = "1.28.0")]
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub struct LayoutErr {
+    private: (),
+}
+
+// (we need this for downstream impl of trait Error)
+#[stable(feature = "alloc_layout", since = "1.28.0")]
+impl fmt::Display for LayoutErr {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str("invalid parameters to Layout::from_size_align")
+    }
+}
diff --git a/src/libcore/alloc/mod.rs b/src/libcore/alloc/mod.rs
new file mode 100644
index 00000000000..e1892edb7c7
--- /dev/null
+++ b/src/libcore/alloc/mod.rs
@@ -0,0 +1,367 @@
+//! Memory allocation APIs
+
+#![stable(feature = "alloc_module", since = "1.28.0")]
+
+mod global;
+mod layout;
+
+#[stable(feature = "global_alloc", since = "1.28.0")]
+pub use self::global::GlobalAlloc;
+#[stable(feature = "alloc_layout", since = "1.28.0")]
+pub use self::layout::{Layout, LayoutErr};
+
+use crate::fmt;
+use crate::ptr::{self, NonNull};
+
+/// The `AllocErr` error indicates an allocation failure
+/// that may be due to resource exhaustion or to
+/// something wrong when combining the given input arguments with this
+/// allocator.
+#[unstable(feature = "allocator_api", issue = "32838")]
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub struct AllocErr;
+
+// (we need this for downstream impl of trait Error)
+#[unstable(feature = "allocator_api", issue = "32838")]
+impl fmt::Display for AllocErr {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str("memory allocation failed")
+    }
+}
+
+/// A desired initial state for allocated memory.
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+#[unstable(feature = "allocator_api", issue = "32838")]
+pub enum AllocInit {
+    /// The contents of the new memory are uninitialized.
+    Uninitialized,
+    /// The new memory is guaranteed to be zeroed.
+    Zeroed,
+}
+
+impl AllocInit {
+    /// Initialize the specified memory block.
+    ///
+    /// This behaves like calling [`AllocInit::init_offset(memory, 0)`][off].
+    ///
+    /// [off]: AllocInit::init_offset
+    ///
+    /// # Safety
+    ///
+    /// * `memory.ptr` must be [valid] for writes of `memory.size` bytes.
+    ///
+    /// [valid]: ../../core/ptr/index.html#safety
+    #[inline]
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    pub unsafe fn init(self, memory: MemoryBlock) {
+        self.init_offset(memory, 0)
+    }
+
+    /// Initialize the memory block like specified by `init` at the specified `offset`.
+    ///
+    /// This is a no-op for [`AllocInit::Uninitialized`][] and writes zeroes for
+    /// [`AllocInit::Zeroed`][] at `ptr + offset` until `ptr + layout.size()`.
+    ///
+    /// # Safety
+    ///
+    /// * `memory.ptr` must be [valid] for writes of `memory.size` bytes.
+    /// * `offset` must be smaller than or equal to `memory.size`
+    ///
+    /// [valid]: ../../core/ptr/index.html#safety
+    #[inline]
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    pub unsafe fn init_offset(self, memory: MemoryBlock, offset: usize) {
+        debug_assert!(
+            offset <= memory.size,
+            "`offset` must be smaller than or equal to `memory.size`"
+        );
+        match self {
+            AllocInit::Uninitialized => (),
+            AllocInit::Zeroed => {
+                memory.ptr.as_ptr().add(offset).write_bytes(0, memory.size - offset)
+            }
+        }
+    }
+}
+
+/// Represents a block of allocated memory returned by an allocator.
+#[derive(Debug, Copy, Clone)]
+#[unstable(feature = "allocator_api", issue = "32838")]
+pub struct MemoryBlock {
+    pub ptr: NonNull<u8>,
+    pub size: usize,
+}
+
+/// A placement constraint when growing or shrinking an existing allocation.
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+#[unstable(feature = "allocator_api", issue = "32838")]
+pub enum ReallocPlacement {
+    /// The allocator is allowed to move the allocation to a different memory address.
+    // FIXME(wg-allocators#46): Add a section to the module documentation "What is a legal
+    //                          allocator" and link it at "valid location".
+    ///
+    /// If the allocation _does_ move, it's the responsibility of the allocator
+    /// to also move the data from the previous location to the new location.
+    MayMove,
+    /// The address of the new memory must not change.
+    ///
+    /// If the allocation would have to be moved to a new location to fit, the
+    /// reallocation request will fail.
+    InPlace,
+}
+
+/// An implementation of `AllocRef` can allocate, grow, shrink, and deallocate arbitrary blocks of
+/// data described via [`Layout`][].
+///
+/// `AllocRef` is designed to be implemented on ZSTs, references, or smart pointers because having
+/// an allocator like `MyAlloc([u8; N])` cannot be moved, without updating the pointers to the
+/// allocated memory.
+///
+/// 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 must be caught by the implementation.
+///
+/// ### Currently allocated memory
+///
+/// Some of the methods require that a memory block be *currently allocated* via an allocator. This
+/// means that:
+///
+/// * the starting address for that memory block was previously returned by [`alloc`], [`grow`], or
+///   [`shrink`], and
+///
+/// * the memory block has not been subsequently deallocated, where blocks are either deallocated
+///   directly by being passed to [`dealloc`] or were changed by being passed to [`grow`] or
+///   [`shrink`] that returns `Ok`. If `grow` or `shrink` have returned `Err`, the passed pointer
+///   remains valid.
+///
+/// [`alloc`]: AllocRef::alloc
+/// [`grow`]: AllocRef::grow
+/// [`shrink`]: AllocRef::shrink
+/// [`dealloc`]: AllocRef::dealloc
+///
+/// ### Memory fitting
+///
+/// Some of the methods require that a layout *fit* a memory block. What it means for a layout to
+/// "fit" a memory block means (or equivalently, for a memory block to "fit" a layout) is that the
+/// following conditions must hold:
+///
+/// * The block must be allocated with the same alignment as [`layout.align()`], and
+///
+/// * The provided [`layout.size()`] must fall in the range `min ..= max`, where:
+///   - `min` is the size of the layout most recently used to allocate the block, and
+///   - `max` is the latest actual size returned from [`alloc`], [`grow`], or [`shrink`].
+///
+/// [`layout.align()`]: Layout::align
+/// [`layout.size()`]: Layout::size
+///
+/// # 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,
+///
+/// * cloning or moving the allocator must not invalidate memory blocks returned from this
+///   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.
+///
+/// [*currently allocated*]: #currently-allocated-memory
+#[unstable(feature = "allocator_api", issue = "32838")]
+pub unsafe trait AllocRef {
+    /// 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.
+    ///
+    /// [`init`]: AllocInit
+    ///
+    /// # Errors
+    ///
+    /// Returning `Err` indicates that either memory is exhausted or `layout` does not meet
+    /// allocator's size or alignment constraints.
+    ///
+    /// 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
+    /// this trait atop an underlying native allocation library that aborts on memory exhaustion.)
+    ///
+    /// Clients wishing to abort computation in response to an allocation error are encouraged to
+    /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar.
+    ///
+    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
+    fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr>;
+
+    /// Deallocates the memory referenced by `ptr`.
+    ///
+    /// # Safety
+    ///
+    /// * `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 [`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 [`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).
+    ///
+    /// If this method returns `Err`, then ownership of the memory block has not been transferred to
+    /// this allocator, and the contents of the memory block are unaltered.
+    ///
+    /// The memory block will contain the following contents after a successful call to `grow`:
+    ///   * Bytes `0..layout.size()` are preserved from the original allocation.
+    ///   * Bytes `layout.size()..old_size` will either be preserved or initialized according to
+    ///     [`init`], depending on the allocator implementation. `old_size` refers to the size of
+    ///     the `MemoryBlock` prior to the `grow` call, which may be larger than the size
+    ///     that was originally requested when it was allocated.
+    ///   * Bytes `old_size..new_size` are initialized according to [`init`]. `new_size` refers to
+    ///     the size of the `MemoryBlock` returned by the `grow` call.
+    ///
+    /// [`InPlace`]: ReallocPlacement::InPlace
+    /// [`MayMove`]: ReallocPlacement::MayMove
+    /// [`placement`]: ReallocPlacement
+    /// [`init`]: AllocInit
+    ///
+    /// # Safety
+    ///
+    /// * `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()`, 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 or equal to `usize::MAX`).
+    ///
+    /// [*currently allocated*]: #currently-allocated-memory
+    /// [*fit*]: #memory-fitting
+    ///
+    /// # 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.
+    ///
+    /// 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
+    /// this trait atop an underlying native allocation library that aborts on memory exhaustion.)
+    ///
+    /// Clients wishing to abort computation in response to an allocation error are encouraged to
+    /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar.
+    ///
+    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
+    unsafe fn grow(
+        &mut self,
+        ptr: NonNull<u8>,
+        layout: Layout,
+        new_size: usize,
+        placement: ReallocPlacement,
+        init: AllocInit,
+    ) -> Result<MemoryBlock, AllocErr> {
+        match placement {
+            ReallocPlacement::InPlace => Err(AllocErr),
+            ReallocPlacement::MayMove => {
+                let size = layout.size();
+                debug_assert!(
+                    new_size >= size,
+                    "`new_size` must be greater than or equal to `layout.size()`"
+                );
+
+                if new_size == size {
+                    return Ok(MemoryBlock { ptr, size });
+                }
+
+                let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
+                let new_memory = self.alloc(new_layout, init)?;
+                ptr::copy_nonoverlapping(ptr.as_ptr(), new_memory.ptr.as_ptr(), size);
+                self.dealloc(ptr, layout);
+                Ok(new_memory)
+            }
+        }
+    }
+
+    /// Attempts to shrink the memory block.
+    ///
+    /// 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`.
+    ///
+    /// If this returns `Ok`, then ownership of the memory block referenced by `ptr` has been
+    /// transferred to this allocator. The memory may or may not have been freed, and should be
+    /// considered unusable unless it was transferred back to the caller again via the
+    /// return value of this method.
+    ///
+    /// If this method returns `Err`, then ownership of the memory block has not been transferred to
+    /// this allocator, and the contents of the memory block are unaltered.
+    ///
+    /// The behavior of how the allocator tries to shrink the memory is specified by [`placement`].
+    ///
+    /// [`InPlace`]: ReallocPlacement::InPlace
+    /// [`placement`]: ReallocPlacement
+    ///
+    /// # Safety
+    ///
+    /// * `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()`.
+    ///
+    /// [*currently allocated*]: #currently-allocated-memory
+    /// [*fit*]: #memory-fitting
+    ///
+    /// # Errors
+    ///
+    /// Returns `Err` if the new layout does not meet the allocator's size and alignment
+    /// 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
+    /// this trait atop an underlying native allocation library that aborts on memory exhaustion.)
+    ///
+    /// Clients wishing to abort computation in response to an allocation error are encouraged to
+    /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar.
+    ///
+    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
+    unsafe fn shrink(
+        &mut self,
+        ptr: NonNull<u8>,
+        layout: Layout,
+        new_size: usize,
+        placement: ReallocPlacement,
+    ) -> Result<MemoryBlock, AllocErr> {
+        match placement {
+            ReallocPlacement::InPlace => Err(AllocErr),
+            ReallocPlacement::MayMove => {
+                let size = layout.size();
+                debug_assert!(
+                    new_size <= size,
+                    "`new_size` must be smaller than or equal to `layout.size()`"
+                );
+
+                if new_size == size {
+                    return Ok(MemoryBlock { ptr, size });
+                }
+
+                let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
+                let new_memory = self.alloc(new_layout, AllocInit::Uninitialized)?;
+                ptr::copy_nonoverlapping(ptr.as_ptr(), new_memory.ptr.as_ptr(), new_size);
+                self.dealloc(ptr, layout);
+                Ok(new_memory)
+            }
+        }
+    }
+}
diff --git a/src/libcore/array/iter.rs b/src/libcore/array/iter.rs
index 80eaae0d4af..f6b8d4ba081 100644
--- a/src/libcore/array/iter.rs
+++ b/src/libcore/array/iter.rs
@@ -39,7 +39,7 @@ where
     alive: Range<usize>,
 }
 
-impl<T, const N: usize> IntoIter<T, { N }>
+impl<T, const N: usize> IntoIter<T, N>
 where
     [T; N]: LengthAtMost32,
 {
@@ -99,7 +99,7 @@ where
 }
 
 #[stable(feature = "array_value_iter_impls", since = "1.40.0")]
-impl<T, const N: usize> Iterator for IntoIter<T, { N }>
+impl<T, const N: usize> Iterator for IntoIter<T, N>
 where
     [T; N]: LengthAtMost32,
 {
@@ -146,7 +146,7 @@ where
 }
 
 #[stable(feature = "array_value_iter_impls", since = "1.40.0")]
-impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, { N }>
+impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N>
 where
     [T; N]: LengthAtMost32,
 {
@@ -182,7 +182,7 @@ where
 }
 
 #[stable(feature = "array_value_iter_impls", since = "1.40.0")]
-impl<T, const N: usize> Drop for IntoIter<T, { N }>
+impl<T, const N: usize> Drop for IntoIter<T, N>
 where
     [T; N]: LengthAtMost32,
 {
@@ -195,7 +195,7 @@ where
 }
 
 #[stable(feature = "array_value_iter_impls", since = "1.40.0")]
-impl<T, const N: usize> ExactSizeIterator for IntoIter<T, { N }>
+impl<T, const N: usize> ExactSizeIterator for IntoIter<T, N>
 where
     [T; N]: LengthAtMost32,
 {
@@ -210,17 +210,17 @@ where
 }
 
 #[stable(feature = "array_value_iter_impls", since = "1.40.0")]
-impl<T, const N: usize> FusedIterator for IntoIter<T, { N }> where [T; N]: LengthAtMost32 {}
+impl<T, const N: usize> FusedIterator for IntoIter<T, N> where [T; N]: LengthAtMost32 {}
 
 // The iterator indeed reports the correct length. The number of "alive"
 // elements (that will still be yielded) is the length of the range `alive`.
 // This range is decremented in length in either `next` or `next_back`. It is
 // always decremented by 1 in those methods, but only if `Some(_)` is returned.
 #[stable(feature = "array_value_iter_impls", since = "1.40.0")]
-unsafe impl<T, const N: usize> TrustedLen for IntoIter<T, { N }> where [T; N]: LengthAtMost32 {}
+unsafe impl<T, const N: usize> TrustedLen for IntoIter<T, N> where [T; N]: LengthAtMost32 {}
 
 #[stable(feature = "array_value_iter_impls", since = "1.40.0")]
-impl<T: Clone, const N: usize> Clone for IntoIter<T, { N }>
+impl<T: Clone, const N: usize> Clone for IntoIter<T, N>
 where
     [T; N]: LengthAtMost32,
 {
@@ -249,7 +249,7 @@ where
 }
 
 #[stable(feature = "array_value_iter_impls", since = "1.40.0")]
-impl<T: fmt::Debug, const N: usize> fmt::Debug for IntoIter<T, { N }>
+impl<T: fmt::Debug, const N: usize> fmt::Debug for IntoIter<T, N>
 where
     [T; N]: LengthAtMost32,
 {
diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs
index eb101fc72fd..6165941eb3d 100644
--- a/src/libcore/clone.rs
+++ b/src/libcore/clone.rs
@@ -169,7 +169,8 @@ pub struct AssertParamIsCopy<T: Copy + ?Sized> {
 /// Implementations of `Clone` for primitive types.
 ///
 /// Implementations that cannot be described in Rust
-/// are implemented in `SelectionContext::copy_clone_conditions()` in librustc.
+/// 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 604be7d5f68..8c542136a7f 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -817,7 +817,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
     /// 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 47ab8715cfa..eef9ee7cb00 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 @@ impl From<!> for Infallible {
         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 752199c94b8..66ae760fc1f 100644
--- a/src/libcore/convert/num.rs
+++ b/src/libcore/convert/num.rs
@@ -13,9 +13,9 @@ mod private {
 /// 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 @@ macro_rules! impl_float_to_int {
             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 fe728d42c76..95411b525d0 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -852,7 +852,7 @@ pub trait LowerHex {
 ///     }
 /// }
 ///
-/// 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 698c97999c4..d406b3ce6ef 100644
--- a/src/libcore/hint.rs
+++ b/src/libcore/hint.rs
@@ -43,7 +43,7 @@ use crate::intrinsics;
 ///
 /// 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 0c956104221..4a11fb39389 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -1582,8 +1582,16 @@ extern "rust-intrinsic" {
     /// 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 @@ extern "rust-intrinsic" {
     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 @@ extern "rust-intrinsic" {
     #[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 @@ extern "rust-intrinsic" {
     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/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs
index daa880e7cd5..c8829817e19 100644
--- a/src/libcore/iter/traits/iterator.rs
+++ b/src/libcore/iter/traits/iterator.rs
@@ -198,7 +198,7 @@ pub trait Iterator {
     /// // 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 @@ pub trait Iterator {
     /// 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 @@ pub trait Iterator {
     /// 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 @@ pub trait Iterator {
     /// 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 f67762cd043..9c885ef99a9 100644
--- a/src/libcore/macros/mod.rs
+++ b/src/libcore/macros/mod.rs
@@ -1070,8 +1070,10 @@ pub(crate) mod builtin {
 
     /// 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 @@ pub(crate) mod builtin {
 
     /// 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 @@ pub(crate) mod builtin {
     /// 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 b131cf84e18..35bceaa25c3 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -759,7 +759,8 @@ impl<T: ?Sized> Unpin for *mut T {}
 /// Implementations of `Copy` for primitive types.
 ///
 /// Implementations that cannot be described in Rust
-/// are implemented in `SelectionContext::copy_clone_conditions()` in librustc.
+/// 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 3fdc2bae338..4ab82add32b 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -464,15 +464,13 @@ impl f32 {
     /// 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 +480,13 @@ impl f32 {
     /// * 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 129df937c0b..20818a9b750 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -478,15 +478,13 @@ impl f64 {
     /// 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 +494,13 @@ impl f64 {
     /// * 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 853092dd85e..7ba4004d860 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -174,7 +174,7 @@ NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }
 /// 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 @@ impl u8 {
     #[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 @@ impl u8 {
     #[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 adee8cea442..946a765e18f 100644
--- a/src/libcore/ops/range.rs
+++ b/src/libcore/ops/range.rs
@@ -139,10 +139,9 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
     /// ```
     /// #![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 {
@@ -496,10 +495,9 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
     /// ```
     /// #![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:
diff --git a/src/libcore/ptr/const_ptr.rs b/src/libcore/ptr/const_ptr.rs
index a540016854d..52e224d2a02 100644
--- a/src/libcore/ptr/const_ptr.rs
+++ b/src/libcore/ptr/const_ptr.rs
@@ -659,8 +659,8 @@ impl<T: ?Sized> *const T {
     /// `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 01d830ca186..9f85d781d69 100644
--- a/src/libcore/ptr/mut_ptr.rs
+++ b/src/libcore/ptr/mut_ptr.rs
@@ -847,8 +847,8 @@ impl<T: ?Sized> *mut T {
     /// `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 75c329a7d6c..cb0fb8795e5 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::back::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/slice/mod.rs b/src/libcore/slice/mod.rs
index 2140a7be9ef..9be52e2dfb0 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -2588,7 +2588,7 @@ impl<T> [T] {
     /// 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/str/mod.rs b/src/libcore/str/mod.rs
index 013ca182c13..dc7637cfdb9 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -9,7 +9,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use self::pattern::Pattern;
-use self::pattern::{DoubleEndedSearcher, ReverseSearcher, SearchStep, Searcher};
+use self::pattern::{DoubleEndedSearcher, ReverseSearcher, Searcher};
 
 use crate::char;
 use crate::fmt::{self, Write};
@@ -2642,7 +2642,7 @@ impl str {
     /// # Panics
     ///
     /// Panics if `mid` is not on a UTF-8 code point boundary, or if it is
-    /// beyond the last code point of the string slice.
+    /// past the end of the last code point of the string slice.
     ///
     /// # Examples
     ///
@@ -2683,7 +2683,7 @@ impl str {
     /// # Panics
     ///
     /// Panics if `mid` is not on a UTF-8 code point boundary, or if it is
-    /// beyond the last code point of the string slice.
+    /// past the end of the last code point of the string slice.
     ///
     /// # Examples
     ///
@@ -3986,26 +3986,15 @@ impl str {
     /// ```
     /// #![feature(str_strip)]
     ///
-    /// assert_eq!("foobar".strip_prefix("foo"), Some("bar"));
-    /// assert_eq!("foobar".strip_prefix("bar"), None);
+    /// assert_eq!("foo:bar".strip_prefix("foo:"), Some("bar"));
+    /// assert_eq!("foo:bar".strip_prefix("bar"), None);
     /// assert_eq!("foofoo".strip_prefix("foo"), Some("foo"));
     /// ```
     #[must_use = "this returns the remaining substring as a new slice, \
                   without modifying the original"]
     #[unstable(feature = "str_strip", reason = "newly added", issue = "67302")]
     pub fn strip_prefix<'a, P: Pattern<'a>>(&'a self, prefix: P) -> Option<&'a str> {
-        let mut matcher = prefix.into_searcher(self);
-        if let SearchStep::Match(start, len) = matcher.next() {
-            debug_assert_eq!(
-                start, 0,
-                "The first search step from Searcher \
-                 must include the first character"
-            );
-            // SAFETY: `Searcher` is known to return valid indices.
-            unsafe { Some(self.get_unchecked(len..)) }
-        } else {
-            None
-        }
+        prefix.strip_prefix_of(self)
     }
 
     /// Returns a string slice with the suffix removed.
@@ -4020,8 +4009,8 @@ impl str {
     ///
     /// ```
     /// #![feature(str_strip)]
-    /// assert_eq!("barfoo".strip_suffix("foo"), Some("bar"));
-    /// assert_eq!("barfoo".strip_suffix("bar"), None);
+    /// assert_eq!("bar:foo".strip_suffix(":foo"), Some("bar"));
+    /// assert_eq!("bar:foo".strip_suffix("bar"), None);
     /// assert_eq!("foofoo".strip_suffix("foo"), Some("foo"));
     /// ```
     #[must_use = "this returns the remaining substring as a new slice, \
@@ -4032,19 +4021,7 @@ impl str {
         P: Pattern<'a>,
         <P as Pattern<'a>>::Searcher: ReverseSearcher<'a>,
     {
-        let mut matcher = suffix.into_searcher(self);
-        if let SearchStep::Match(start, end) = matcher.next_back() {
-            debug_assert_eq!(
-                end,
-                self.len(),
-                "The first search step from ReverseSearcher \
-                 must include the last character"
-            );
-            // SAFETY: `Searcher` is known to return valid indices.
-            unsafe { Some(self.get_unchecked(..start)) }
-        } else {
-            None
-        }
+        suffix.strip_suffix_of(self)
     }
 
     /// Returns a string slice with all suffixes that match a pattern
diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs
index ffa418cba6c..30fd55f7b7f 100644
--- a/src/libcore/str/pattern.rs
+++ b/src/libcore/str/pattern.rs
@@ -47,6 +47,22 @@ pub trait Pattern<'a>: Sized {
         matches!(self.into_searcher(haystack).next(), SearchStep::Match(0, _))
     }
 
+    /// Removes the pattern from the front of haystack, if it matches.
+    #[inline]
+    fn strip_prefix_of(self, haystack: &'a str) -> Option<&'a str> {
+        if let SearchStep::Match(start, len) = self.into_searcher(haystack).next() {
+            debug_assert_eq!(
+                start, 0,
+                "The first search step from Searcher \
+                 must include the first character"
+            );
+            // SAFETY: `Searcher` is known to return valid indices.
+            unsafe { Some(haystack.get_unchecked(len..)) }
+        } else {
+            None
+        }
+    }
+
     /// Checks whether the pattern matches at the back of the haystack
     #[inline]
     fn is_suffix_of(self, haystack: &'a str) -> bool
@@ -55,6 +71,26 @@ pub trait Pattern<'a>: Sized {
     {
         matches!(self.into_searcher(haystack).next_back(), SearchStep::Match(_, j) if haystack.len() == j)
     }
+
+    /// Removes the pattern from the back of haystack, if it matches.
+    #[inline]
+    fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str>
+    where
+        Self::Searcher: ReverseSearcher<'a>,
+    {
+        if let SearchStep::Match(start, end) = self.into_searcher(haystack).next_back() {
+            debug_assert_eq!(
+                end,
+                haystack.len(),
+                "The first search step from ReverseSearcher \
+                 must include the last character"
+            );
+            // SAFETY: `Searcher` is known to return valid indices.
+            unsafe { Some(haystack.get_unchecked(..start)) }
+        } else {
+            None
+        }
+    }
 }
 
 // Searcher
@@ -449,12 +485,25 @@ impl<'a> Pattern<'a> for char {
     }
 
     #[inline]
+    fn strip_prefix_of(self, haystack: &'a str) -> Option<&'a str> {
+        self.encode_utf8(&mut [0u8; 4]).strip_prefix_of(haystack)
+    }
+
+    #[inline]
     fn is_suffix_of(self, haystack: &'a str) -> bool
     where
         Self::Searcher: ReverseSearcher<'a>,
     {
         self.encode_utf8(&mut [0u8; 4]).is_suffix_of(haystack)
     }
+
+    #[inline]
+    fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str>
+    where
+        Self::Searcher: ReverseSearcher<'a>,
+    {
+        self.encode_utf8(&mut [0u8; 4]).strip_suffix_of(haystack)
+    }
 }
 
 /////////////////////////////////////////////////////////////////////////////
@@ -570,12 +619,25 @@ macro_rules! pattern_methods {
         }
 
         #[inline]
+        fn strip_prefix_of(self, haystack: &'a str) -> Option<&'a str> {
+            ($pmap)(self).strip_prefix_of(haystack)
+        }
+
+        #[inline]
         fn is_suffix_of(self, haystack: &'a str) -> bool
         where
             $t: ReverseSearcher<'a>,
         {
             ($pmap)(self).is_suffix_of(haystack)
         }
+
+        #[inline]
+        fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str>
+        where
+            $t: ReverseSearcher<'a>,
+        {
+            ($pmap)(self).strip_suffix_of(haystack)
+        }
     };
 }
 
@@ -715,11 +777,34 @@ impl<'a, 'b> Pattern<'a> for &'b str {
         haystack.as_bytes().starts_with(self.as_bytes())
     }
 
+    /// Removes the pattern from the front of haystack, if it matches.
+    #[inline]
+    fn strip_prefix_of(self, haystack: &'a str) -> Option<&'a str> {
+        if self.is_prefix_of(haystack) {
+            // SAFETY: prefix was just verified to exist.
+            unsafe { Some(haystack.get_unchecked(self.as_bytes().len()..)) }
+        } else {
+            None
+        }
+    }
+
     /// Checks whether the pattern matches at the back of the haystack
     #[inline]
     fn is_suffix_of(self, haystack: &'a str) -> bool {
         haystack.as_bytes().ends_with(self.as_bytes())
     }
+
+    /// Removes the pattern from the back of haystack, if it matches.
+    #[inline]
+    fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str> {
+        if self.is_suffix_of(haystack) {
+            let i = haystack.len() - self.as_bytes().len();
+            // SAFETY: suffix was just verified to exist.
+            unsafe { Some(haystack.get_unchecked(..i)) }
+        } else {
+            None
+        }
+    }
 }
 
 /////////////////////////////////////////////////////////////////////////////
diff --git a/src/libcore/time.rs b/src/libcore/time.rs
index 2ece2150e6b..924a64847a7 100644
--- a/src/libcore/time.rs
+++ b/src/libcore/time.rs
@@ -389,7 +389,7 @@ impl Duration {
     /// 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 @@ impl Duration {
     /// 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/librustc/arena.rs b/src/librustc/arena.rs
deleted file mode 100644
index ae542cec170..00000000000
--- a/src/librustc/arena.rs
+++ /dev/null
@@ -1,132 +0,0 @@
-/// This declares a list of types which can be allocated by `Arena`.
-///
-/// The `few` modifier will cause allocation to use the shared arena and recording the destructor.
-/// This is faster and more memory efficient if there's only a few allocations of the type.
-/// Leaving `few` out will cause the type to get its own dedicated `TypedArena` which is
-/// faster and more memory efficient if there is lots of allocations.
-///
-/// Specifying the `decode` modifier will add decode impls for &T and &[T] where T is the type
-/// listed. These impls will appear in the implement_ty_decoder! macro.
-#[macro_export]
-macro_rules! arena_types {
-    ($macro:path, $args:tt, $tcx:lifetime) => (
-        $macro!($args, [
-            [] layouts: rustc::ty::layout::Layout,
-            [] generics: rustc::ty::Generics,
-            [] trait_def: rustc::ty::TraitDef,
-            [] adt_def: rustc::ty::AdtDef,
-            [] steal_mir: rustc::ty::steal::Steal<rustc::mir::BodyAndCache<$tcx>>,
-            [] mir: rustc::mir::BodyAndCache<$tcx>,
-            [] steal_promoted: rustc::ty::steal::Steal<
-                rustc_index::vec::IndexVec<
-                    rustc::mir::Promoted,
-                    rustc::mir::BodyAndCache<$tcx>
-                >
-            >,
-            [] promoted: rustc_index::vec::IndexVec<
-                rustc::mir::Promoted,
-                rustc::mir::BodyAndCache<$tcx>
-            >,
-            [decode] tables: rustc::ty::TypeckTables<$tcx>,
-            [decode] borrowck_result: rustc::mir::BorrowCheckResult<$tcx>,
-            [] const_allocs: rustc::mir::interpret::Allocation,
-            [] vtable_method: Option<(
-                rustc_hir::def_id::DefId,
-                rustc::ty::subst::SubstsRef<$tcx>
-            )>,
-            [few, decode] mir_keys: rustc_hir::def_id::DefIdSet,
-            [decode] specialization_graph: rustc::traits::specialization_graph::Graph,
-            [] region_scope_tree: rustc::middle::region::ScopeTree,
-            [] item_local_set: rustc_hir::ItemLocalSet,
-            [decode] mir_const_qualif: rustc_index::bit_set::BitSet<rustc::mir::Local>,
-            [] trait_impls_of: rustc::ty::trait_def::TraitImpls,
-            [] associated_items: rustc::ty::AssociatedItems,
-            [] dropck_outlives:
-                rustc::infer::canonical::Canonical<'tcx,
-                    rustc::infer::canonical::QueryResponse<'tcx,
-                        rustc::traits::query::DropckOutlivesResult<'tcx>
-                    >
-                >,
-            [] normalize_projection_ty:
-                rustc::infer::canonical::Canonical<'tcx,
-                    rustc::infer::canonical::QueryResponse<'tcx,
-                        rustc::traits::query::NormalizationResult<'tcx>
-                    >
-                >,
-            [] implied_outlives_bounds:
-                rustc::infer::canonical::Canonical<'tcx,
-                    rustc::infer::canonical::QueryResponse<'tcx,
-                        Vec<rustc::traits::query::OutlivesBound<'tcx>>
-                    >
-                >,
-            [] type_op_subtype:
-                rustc::infer::canonical::Canonical<'tcx,
-                    rustc::infer::canonical::QueryResponse<'tcx, ()>
-                >,
-            [] type_op_normalize_poly_fn_sig:
-                rustc::infer::canonical::Canonical<'tcx,
-                    rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::PolyFnSig<'tcx>>
-                >,
-            [] type_op_normalize_fn_sig:
-                rustc::infer::canonical::Canonical<'tcx,
-                    rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::FnSig<'tcx>>
-                >,
-            [] type_op_normalize_predicate:
-                rustc::infer::canonical::Canonical<'tcx,
-                    rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::Predicate<'tcx>>
-                >,
-            [] type_op_normalize_ty:
-                rustc::infer::canonical::Canonical<'tcx,
-                    rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::Ty<'tcx>>
-                >,
-            [few] crate_inherent_impls: rustc::ty::CrateInherentImpls,
-            [few] upstream_monomorphizations:
-                rustc_hir::def_id::DefIdMap<
-                    rustc_data_structures::fx::FxHashMap<
-                        rustc::ty::subst::SubstsRef<'tcx>,
-                        rustc_hir::def_id::CrateNum
-                    >
-                >,
-            [few] diagnostic_items: rustc_data_structures::fx::FxHashMap<
-                rustc_span::symbol::Symbol,
-                rustc_hir::def_id::DefId,
-            >,
-            [few] resolve_lifetimes: rustc::middle::resolve_lifetime::ResolveLifetimes,
-            [few] lint_levels: rustc::lint::LintLevelMap,
-            [few] stability_index: rustc::middle::stability::Index<'tcx>,
-            [few] features: rustc_feature::Features,
-            [few] all_traits: Vec<rustc_hir::def_id::DefId>,
-            [few] privacy_access_levels: rustc::middle::privacy::AccessLevels,
-            [few] target_features_whitelist: rustc_data_structures::fx::FxHashMap<
-                String,
-                Option<rustc_span::symbol::Symbol>
-            >,
-            [few] wasm_import_module_map: rustc_data_structures::fx::FxHashMap<
-                rustc_hir::def_id::DefId,
-                String
-            >,
-            [few] get_lib_features: rustc::middle::lib_features::LibFeatures,
-            [few] defined_lib_features: rustc::middle::lang_items::LanguageItems,
-            [few] visible_parent_map: rustc_hir::def_id::DefIdMap<rustc_hir::def_id::DefId>,
-            [few] foreign_module: rustc::middle::cstore::ForeignModule,
-            [few] foreign_modules: Vec<rustc::middle::cstore::ForeignModule>,
-            [few] reachable_non_generics: rustc_hir::def_id::DefIdMap<
-                rustc::middle::exported_symbols::SymbolExportLevel
-            >,
-            [few] crate_variances: rustc::ty::CrateVariancesMap<'tcx>,
-            [few] inferred_outlives_crate: rustc::ty::CratePredicatesMap<'tcx>,
-            [] upvars: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>,
-
-            // Interned types
-            [] tys: rustc::ty::TyS<$tcx>,
-
-            // HIR query types
-            [few] indexed_hir: rustc::hir::map::IndexedHir<$tcx>,
-            [few] hir_definitions: rustc_hir::definitions::Definitions,
-            [] hir_owner: rustc::hir::Owner<$tcx>,
-            [] hir_owner_nodes: rustc::hir::OwnerNodes<$tcx>,
-        ], $tcx);
-    )
-}
-
-arena_types!(arena::declare_arena, [], 'tcx);
diff --git a/src/librustc_ast/entry.rs b/src/librustc_ast/entry.rs
index 0a72019bfe9..90d417a45fd 100644
--- a/src/librustc_ast/entry.rs
+++ b/src/librustc_ast/entry.rs
@@ -10,7 +10,7 @@ pub enum EntryPointType {
     OtherMain, // Not an entry point, but some other function named main
 }
 
-// Beware, this is duplicated in librustc/middle/entry.rs, make sure to keep
+// Beware, this is duplicated in librustc_middle/middle/entry.rs, make sure to keep
 // them in sync.
 pub fn entry_point_type(item: &Item, depth: usize) -> EntryPointType {
     match item.kind {
diff --git a/src/librustc_ast/expand/mod.rs b/src/librustc_ast/expand/mod.rs
index 50df8fa39ed..3c634ff40cc 100644
--- a/src/librustc_ast/expand/mod.rs
+++ b/src/librustc_ast/expand/mod.rs
@@ -1,4 +1,4 @@
-//! Definitions shared by macros / syntax extensions and e.g. librustc.
+//! Definitions shared by macros / syntax extensions and e.g. librustc_middle.
 
 use crate::ast::Attribute;
 use rustc_span::symbol::sym;
diff --git a/src/librustc_ast/lib.rs b/src/librustc_ast/lib.rs
index a93e0fcbd71..1687f828f24 100644
--- a/src/librustc_ast/lib.rs
+++ b/src/librustc_ast/lib.rs
@@ -54,7 +54,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 
 /// Requirements for a `StableHashingContext` to be used in this crate.
 /// This is a hack to allow using the `HashStable_Generic` derive macro
-/// instead of implementing everything in librustc.
+/// instead of implementing everything in librustc_middle.
 pub trait HashStableContext: rustc_span::HashStableContext {
     fn hash_attr(&mut self, _: &ast::Attribute, hasher: &mut StableHasher);
 }
diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs
index 740f62b41a5..6005b607026 100644
--- a/src/librustc_ast_lowering/item.rs
+++ b/src/librustc_ast_lowering/item.rs
@@ -972,8 +972,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
         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
     }
@@ -1332,17 +1334,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
                                         self.resolver.definitions().as_local_node_id(def_id)
                                     {
                                         for param in &generics.params {
-                                            match param.kind {
-                                                GenericParamKind::Type { .. } => {
-                                                    if node_id == param.id {
-                                                        add_bounds
-                                                            .entry(param.id)
-                                                            .or_default()
-                                                            .push(bound.clone());
-                                                        continue 'next_bound;
-                                                    }
+                                            if let GenericParamKind::Type { .. } = param.kind {
+                                                if node_id == param.id {
+                                                    add_bounds
+                                                        .entry(param.id)
+                                                        .or_default()
+                                                        .push(bound.clone());
+                                                    continue 'next_bound;
                                                 }
-                                                _ => {}
                                             }
                                         }
                                     }
diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs
index 45ee7265c15..9028edc73a0 100644
--- a/src/librustc_ast_lowering/lib.rs
+++ b/src/librustc_ast_lowering/lib.rs
@@ -97,7 +97,7 @@ struct LoweringContext<'a, 'hir: 'a> {
 
     /// HACK(Centril): there is a cyclic dependency between the parser and lowering
     /// if we don't have this function pointer. To avoid that dependency so that
-    /// librustc is independent of the parser, we use dynamic dispatch here.
+    /// librustc_middle is independent of the parser, we use dynamic dispatch here.
     nt_to_tokenstream: NtToTokenstream,
 
     /// Used to allocate HIR nodes
diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs
index a0d7b064d0c..76c790f80b8 100644
--- a/src/librustc_ast_passes/feature_gate.rs
+++ b/src/librustc_ast_passes/feature_gate.rs
@@ -516,27 +516,25 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
     }
 
     fn visit_generic_param(&mut self, param: &'a GenericParam) {
-        match param.kind {
-            GenericParamKind::Const { .. } => gate_feature_post!(
+        if let GenericParamKind::Const { .. } = param.kind {
+            gate_feature_post!(
                 &self,
                 const_generics,
                 param.ident.span,
                 "const generics are unstable"
-            ),
-            _ => {}
+            )
         }
         visit::walk_generic_param(self, param)
     }
 
     fn visit_assoc_ty_constraint(&mut self, constraint: &'a AssocTyConstraint) {
-        match constraint.kind {
-            AssocTyConstraintKind::Bound { .. } => gate_feature_post!(
+        if let AssocTyConstraintKind::Bound { .. } = constraint.kind {
+            gate_feature_post!(
                 &self,
                 associated_type_bounds,
                 constraint.span,
                 "associated type bounds are unstable"
-            ),
-            _ => {}
+            )
         }
         visit::walk_assoc_ty_constraint(self, constraint)
     }
diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs
index 4aabbe7efbe..6541ac156b4 100644
--- a/src/librustc_ast_pretty/pprust.rs
+++ b/src/librustc_ast_pretty/pprust.rs
@@ -637,9 +637,8 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
         match tt {
             TokenTree::Token(ref token) => {
                 self.word(token_to_string_ext(&token, convert_dollar_crate));
-                match token.kind {
-                    token::DocComment(..) => self.hardbreak(),
-                    _ => {}
+                if let token::DocComment(..) = token.kind {
+                    self.hardbreak()
                 }
             }
             TokenTree::Delimited(dspan, delim, tts) => {
@@ -1390,13 +1389,10 @@ impl<'a> State<'a> {
         self.print_visibility(&v.vis);
         let generics = ast::Generics::default();
         self.print_struct(&v.data, &generics, v.ident, v.span, false);
-        match v.disr_expr {
-            Some(ref d) => {
-                self.s.space();
-                self.word_space("=");
-                self.print_expr(&d.value)
-            }
-            _ => {}
+        if let Some(ref d) = v.disr_expr {
+            self.s.space();
+            self.word_space("=");
+            self.print_expr(&d.value)
         }
     }
 
@@ -2082,12 +2078,10 @@ impl<'a> State<'a> {
             }
             ast::ExprKind::Yield(ref e) => {
                 self.s.word("yield");
-                match *e {
-                    Some(ref expr) => {
-                        self.s.space();
-                        self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
-                    }
-                    _ => (),
+
+                if let Some(ref expr) = *e {
+                    self.s.space();
+                    self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
                 }
             }
             ast::ExprKind::Try(ref e) => {
@@ -2139,9 +2133,8 @@ impl<'a> State<'a> {
         self.s.word("::");
         let item_segment = path.segments.last().unwrap();
         self.print_ident(item_segment.ident);
-        match item_segment.args {
-            Some(ref args) => self.print_generic_args(args, colons_before_params),
-            None => {}
+        if let Some(ref args) = item_segment.args {
+            self.print_generic_args(args, colons_before_params)
         }
     }
 
diff --git a/src/librustc_attr/builtin.rs b/src/librustc_attr/builtin.rs
index a16b7999391..ab5a844e58f 100644
--- a/src/librustc_attr/builtin.rs
+++ b/src/librustc_attr/builtin.rs
@@ -870,7 +870,7 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec<ReprAttr> {
                     let parse_alignment = |node: &ast::LitKind| -> Result<u32, &'static str> {
                         if let ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed) = node {
                             if literal.is_power_of_two() {
-                                // rustc::ty::layout::Align restricts align to <= 2^29
+                                // rustc_middle::ty::layout::Align restricts align to <= 2^29
                                 if *literal <= 1 << 29 {
                                     Ok(*literal as u32)
                                 } else {
diff --git a/src/librustc_builtin_macros/format_foreign.rs b/src/librustc_builtin_macros/format_foreign.rs
index e6a87e4d825..6b0c9f1018b 100644
--- a/src/librustc_builtin_macros/format_foreign.rs
+++ b/src/librustc_builtin_macros/format_foreign.rs
@@ -27,11 +27,8 @@ pub mod printf {
         }
 
         pub fn set_position(&mut self, start: usize, end: usize) {
-            match self {
-                Substitution::Format(ref mut fmt) => {
-                    fmt.position = InnerSpan::new(start, end);
-                }
-                _ => {}
+            if let Substitution::Format(ref mut fmt) = self {
+                fmt.position = InnerSpan::new(start, end);
             }
         }
 
@@ -311,9 +308,8 @@ pub mod printf {
 
         let at = {
             let start = s.find('%')?;
-            match s[start + 1..].chars().next()? {
-                '%' => return Some((Substitution::Escape, &s[start + 2..])),
-                _ => { /* fall-through */ }
+            if let '%' = s[start + 1..].chars().next()? {
+                return Some((Substitution::Escape, &s[start + 2..]));
             }
 
             Cur::new_at(&s[..], start)
diff --git a/src/librustc_codegen_llvm/Cargo.toml b/src/librustc_codegen_llvm/Cargo.toml
index 16ed0854abe..64e66595d92 100644
--- a/src/librustc_codegen_llvm/Cargo.toml
+++ b/src/librustc_codegen_llvm/Cargo.toml
@@ -16,7 +16,7 @@ flate2 = "1.0"
 libc = "0.2"
 measureme = "0.7.1"
 log = "0.4"
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc-demangle = "0.1"
 rustc_attr = { path = "../librustc_attr" }
 rustc_codegen_ssa = { path = "../librustc_codegen_ssa" }
diff --git a/src/librustc_codegen_llvm/README.md b/src/librustc_codegen_llvm/README.md
index 97d8f76623e..afec60d017e 100644
--- a/src/librustc_codegen_llvm/README.md
+++ b/src/librustc_codegen_llvm/README.md
@@ -4,4 +4,4 @@ that runs towards the end of the compilation process.
 
 For more information about how codegen works, see the [rustc dev guide].
 
-[rustc dev guide]: https://rustc-dev-guide.rust-lang.org/codegen.html
+[rustc dev guide]: https://rustc-dev-guide.rust-lang.org/backend/codegen.html
diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs
index 470a2bb8e1e..8e9c5f25ccb 100644
--- a/src/librustc_codegen_llvm/abi.rs
+++ b/src/librustc_codegen_llvm/abi.rs
@@ -5,22 +5,20 @@ use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
 
-use rustc::bug;
-use rustc::ty::layout::{self};
-use rustc::ty::Ty;
 use rustc_codegen_ssa::mir::operand::OperandValue;
 use rustc_codegen_ssa::mir::place::PlaceRef;
 use rustc_codegen_ssa::traits::*;
 use rustc_codegen_ssa::MemFlags;
+use rustc_middle::bug;
+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};
-
-use libc::c_uint;
-
-pub use rustc::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
 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;
+
 macro_rules! for_each_kind {
     ($flags: ident, $f: ident, $($kind: ident),+) => ({
         $(if $flags.contains(ArgAttribute::$kind) { $f(llvm::Attribute::$kind) })+
@@ -396,6 +394,11 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
             llvm::Attribute::NoReturn.apply_llfn(llvm::AttributePlace::Function, llfn);
         }
 
+        // FIXME(eddyb, wesleywiser): apply this to callsites as well?
+        if !self.can_unwind {
+            llvm::Attribute::NoUnwind.apply_llfn(llvm::AttributePlace::Function, llfn);
+        }
+
         let mut i = 0;
         let mut apply = |attrs: &ArgAttributes, ty: Option<&Type>| {
             attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn, ty);
@@ -431,6 +434,8 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
     }
 
     fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value) {
+        // FIXME(wesleywiser, eddyb): We should apply `nounwind` and `noreturn` as appropriate to this callsite.
+
         let mut i = 0;
         let mut apply = |attrs: &ArgAttributes, ty: Option<&Type>| {
             attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite, ty);
@@ -443,11 +448,11 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
             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/allocator.rs b/src/librustc_codegen_llvm/allocator.rs
index 4e7bc9fa0e2..a78546571e2 100644
--- a/src/librustc_codegen_llvm/allocator.rs
+++ b/src/librustc_codegen_llvm/allocator.rs
@@ -1,8 +1,8 @@
 use crate::attributes;
 use libc::c_uint;
-use rustc::bug;
-use rustc::ty::TyCtxt;
 use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS};
+use rustc_middle::bug;
+use rustc_middle::ty::TyCtxt;
 
 use crate::llvm::{self, False, True};
 use crate::ModuleLlvm;
diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs
index a7417685c5c..784a3a87e98 100644
--- a/src/librustc_codegen_llvm/attributes.rs
+++ b/src/librustc_codegen_llvm/attributes.rs
@@ -2,21 +2,18 @@
 
 use std::ffi::CString;
 
-use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags;
-use rustc::ty::layout::HasTyCtxt;
-use rustc::ty::query::Providers;
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_codegen_ssa::traits::*;
 use rustc_data_structures::const_cstr;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::small_c_str::SmallCStr;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
+use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
+use rustc_middle::ty::layout::HasTyCtxt;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::config::{OptLevel, Sanitizer};
 use rustc_session::Session;
-use rustc_target::abi::call::Conv;
-use rustc_target::spec::PanicStrategy;
 
-use crate::abi::FnAbi;
 use crate::attributes;
 use crate::llvm::AttributePlace::Function;
 use crate::llvm::{self, Attribute};
@@ -77,12 +74,6 @@ pub fn emit_uwtable(val: &'ll Value, emit: bool) {
     Attribute::UWTable.toggle_llfn(Function, val, emit);
 }
 
-/// Tell LLVM whether the function can or cannot unwind.
-#[inline]
-fn unwind(val: &'ll Value, can_unwind: bool) {
-    Attribute::NoUnwind.toggle_llfn(Function, val, !can_unwind);
-}
-
 /// Tell LLVM if this function should be 'naked', i.e., skip the epilogue and prologue.
 #[inline]
 fn naked(val: &'ll Value, is_naked: bool) {
@@ -246,12 +237,7 @@ pub(crate) fn default_optimisation_attrs(sess: &Session, llfn: &'ll Value) {
 
 /// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`)
 /// attributes.
-pub fn from_fn_attrs(
-    cx: &CodegenCx<'ll, 'tcx>,
-    llfn: &'ll Value,
-    instance: ty::Instance<'tcx>,
-    fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
-) {
+pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::Instance<'tcx>) {
     let codegen_fn_attrs = cx.tcx.codegen_fn_attrs(instance.def_id());
 
     match codegen_fn_attrs.optimize {
@@ -315,46 +301,6 @@ pub fn from_fn_attrs(
     }
     sanitize(cx, codegen_fn_attrs.flags, llfn);
 
-    unwind(
-        llfn,
-        if cx.tcx.sess.panic_strategy() != PanicStrategy::Unwind {
-            // In panic=abort mode we assume nothing can unwind anywhere, so
-            // optimize based on this!
-            false
-        } else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::UNWIND) {
-            // If a specific #[unwind] attribute is present, use that.
-            true
-        } else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) {
-            // Special attribute for allocator functions, which can't unwind.
-            false
-        } else {
-            if fn_abi.conv == Conv::Rust {
-                // Any Rust method (or `extern "Rust" fn` or `extern
-                // "rust-call" fn`) is explicitly allowed to unwind
-                // (unless it has no-unwind attribute, handled above).
-                true
-            } else {
-                // Anything else is either:
-                //
-                //  1. A foreign item using a non-Rust ABI (like `extern "C" { fn foo(); }`), or
-                //
-                //  2. A Rust item using a non-Rust ABI (like `extern "C" fn foo() { ... }`).
-                //
-                // Foreign items (case 1) are assumed to not unwind; it is
-                // UB otherwise. (At least for now; see also
-                // rust-lang/rust#63909 and Rust RFC 2753.)
-                //
-                // Items defined in Rust with non-Rust ABIs (case 2) are also
-                // not supposed to unwind. Whether this should be enforced
-                // (versus stating it is UB) and *how* it would be enforced
-                // is currently under discussion; see rust-lang/rust#58794.
-                //
-                // In either case, we mark item as explicitly nounwind.
-                false
-            }
-        },
-    );
-
     // Always annotate functions with the target-cpu they are compiled for.
     // Without this, ThinLTO won't inline Rust functions into Clang generated
     // functions (because Clang annotates functions this way too).
diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs
index 1b64750f51f..816329e06c7 100644
--- a/src/librustc_codegen_llvm/back/lto.rs
+++ b/src/librustc_codegen_llvm/back/lto.rs
@@ -6,9 +6,6 @@ use crate::llvm::archive_ro::ArchiveRO;
 use crate::llvm::{self, False, True};
 use crate::{LlvmCodegenBackend, ModuleLlvm};
 use log::{debug, info};
-use rustc::bug;
-use rustc::dep_graph::WorkProduct;
-use rustc::middle::exported_symbols::SymbolExportLevel;
 use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared};
 use rustc_codegen_ssa::back::symbol_export;
 use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig};
@@ -17,6 +14,9 @@ use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, RLIB_BYTECODE_EXTENSION};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{FatalError, Handler};
 use rustc_hir::def_id::LOCAL_CRATE;
+use rustc_middle::bug;
+use rustc_middle::dep_graph::WorkProduct;
+use rustc_middle::middle::exported_symbols::SymbolExportLevel;
 use rustc_session::cgu_reuse_tracker::CguReuse;
 use rustc_session::config::{self, Lto};
 
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index 77cae038fe5..5708cb4e654 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -14,8 +14,6 @@ use crate::type_::Type;
 use crate::LlvmCodegenBackend;
 use crate::ModuleLlvm;
 use log::debug;
-use rustc::bug;
-use rustc::ty::TyCtxt;
 use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig};
 use rustc_codegen_ssa::traits::*;
 use rustc_codegen_ssa::{CompiledModule, ModuleCodegen, RLIB_BYTECODE_EXTENSION};
@@ -23,6 +21,8 @@ use rustc_data_structures::small_c_str::SmallCStr;
 use rustc_errors::{FatalError, Handler};
 use rustc_fs_util::{link_or_copy, path_to_c_string};
 use rustc_hir::def_id::LOCAL_CRATE;
+use rustc_middle::bug;
+use rustc_middle::ty::TyCtxt;
 use rustc_session::config::{self, Lto, OutputType, Passes, Sanitizer, SwitchWithOptPath};
 use rustc_session::Session;
 
diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs
index 1fb1965484a..e5f73473b72 100644
--- a/src/librustc_codegen_llvm/base.rs
+++ b/src/librustc_codegen_llvm/base.rs
@@ -23,17 +23,17 @@ use crate::llvm;
 use crate::metadata;
 use crate::value::Value;
 
-use rustc::dep_graph;
-use rustc::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
-use rustc::middle::cstore::EncodedMetadata;
-use rustc::middle::exported_symbols;
-use rustc::mir::mono::{Linkage, Visibility};
-use rustc::ty::TyCtxt;
 use rustc_codegen_ssa::base::maybe_create_entry_wrapper;
 use rustc_codegen_ssa::mono_item::MonoItemExt;
 use rustc_codegen_ssa::traits::*;
 use rustc_codegen_ssa::{ModuleCodegen, ModuleKind};
 use rustc_data_structures::small_c_str::SmallCStr;
+use rustc_middle::dep_graph;
+use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
+use rustc_middle::middle::cstore::EncodedMetadata;
+use rustc_middle::middle::exported_symbols;
+use rustc_middle::mir::mono::{Linkage, Visibility};
+use rustc_middle::ty::TyCtxt;
 use rustc_session::config::DebugInfo;
 use rustc_span::symbol::Symbol;
 
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index b37d63fce65..da9060f043f 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -7,8 +7,6 @@ use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
 use libc::{c_char, c_uint};
 use log::debug;
-use rustc::ty::layout::{self, Align, Size, TyLayout};
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_codegen_ssa::base::to_immediate;
 use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, TypeKind};
 use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
@@ -18,7 +16,10 @@ use rustc_codegen_ssa::MemFlags;
 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::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 @@ impl BackendTypes for Builder<'_, 'll, 'tcx> {
     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,11 +85,11 @@ impl HasTargetSpec for Builder<'_, '_, 'tcx> {
     }
 }
 
-impl ty::layout::LayoutOf for Builder<'_, '_, 'tcx> {
+impl abi::LayoutOf for Builder<'_, '_, 'tcx> {
     type Ty = Ty<'tcx>;
-    type TyLayout = TyLayout<'tcx>;
+    type TyAndLayout = TyAndLayout<'tcx>;
 
-    fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
+    fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout {
         self.cx.layout_of(ty)
     }
 }
@@ -302,9 +303,9 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         lhs: Self::Value,
         rhs: Self::Value,
     ) -> (Self::Value, Self::Value) {
-        use rustc::ty::{Int, Uint};
         use rustc_ast::ast::IntTy::*;
         use rustc_ast::ast::UintTy::*;
+        use rustc_middle::ty::{Int, Uint};
 
         let new_kind = match ty.kind {
             Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.ptr_width)),
@@ -435,17 +436,17 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         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 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
             }
             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/callee.rs b/src/librustc_codegen_llvm/callee.rs
index 04d92142266..a36314448b1 100644
--- a/src/librustc_codegen_llvm/callee.rs
+++ b/src/librustc_codegen_llvm/callee.rs
@@ -12,8 +12,8 @@ use crate::value::Value;
 use log::debug;
 use rustc_codegen_ssa::traits::*;
 
-use rustc::ty::layout::{FnAbiExt, HasTyCtxt};
-use rustc::ty::{Instance, TypeFoldable};
+use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt};
+use rustc_middle::ty::{Instance, TypeFoldable};
 
 /// Codegens a reference to a fn/method item, monomorphizing and
 /// inlining as it goes.
@@ -78,7 +78,7 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value
         let llfn = cx.declare_fn(&sym, &fn_abi);
         debug!("get_fn: not casting pointer!");
 
-        attributes::from_fn_attrs(cx, llfn, instance, &fn_abi);
+        attributes::from_fn_attrs(cx, llfn, instance);
 
         let instance_def_id = instance.def_id();
 
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs
index f7206086812..1415fedf11a 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::bug;
-use rustc_codegen_ssa::traits::*;
-
-use crate::consts::const_alloc_to_llvm;
-use rustc::mir::interpret::{Allocation, GlobalAlloc, Scalar};
-use rustc::ty::layout::{self, HasDataLayout, LayoutOf, Size, TyLayout};
-use rustc_codegen_ssa::mir::place::PlaceRef;
-
-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 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         })
     }
 
-    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 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
             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 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                         1,
                     )
                 };
-                if layout.value != layout::Pointer {
+                if layout.value != Pointer {
                     unsafe { llvm::LLVMConstPtrToInt(llval, llty) }
                 } else {
                     self.const_bitcast(llval, llty)
@@ -289,7 +282,7 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
 
     fn from_const_alloc(
         &self,
-        layout: TyLayout<'tcx>,
+        layout: TyAndLayout<'tcx>,
         alloc: &Allocation,
         offset: Size,
     ) -> PlaceRef<'tcx, &'ll Value> {
diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index 619dee29092..9fd22c8b07b 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -7,19 +7,20 @@ use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
 use libc::c_uint;
 use log::debug;
-use rustc::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
-use rustc::mir::interpret::{read_target_uint, Allocation, ConstValue, ErrorHandled, Pointer};
-use rustc::mir::mono::MonoItem;
-use rustc::ty::layout::{self, Align, LayoutOf, Size};
-use rustc::ty::{self, Instance, Ty};
-use rustc::{bug, span_bug};
 use rustc_codegen_ssa::traits::*;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::Node;
+use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
+use rustc_middle::mir::interpret::{
+    read_target_uint, Allocation, ConstValue, ErrorHandled, Pointer,
+};
+use rustc_middle::mir::mono::MonoItem;
+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;
 
@@ -54,7 +55,7 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll
             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;
@@ -435,24 +436,21 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
                 //
                 // 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 7e87f45ba4b..99a825823c3 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -6,22 +6,21 @@ use crate::llvm_util;
 use crate::type_::Type;
 use crate::value::Value;
 
-use rustc::bug;
-use rustc::mir::mono::CodegenUnit;
-use rustc::ty::layout::{
-    HasParamEnv, LayoutError, LayoutOf, PointeeInfo, Size, TyLayout, VariantIdx,
-};
-use rustc::ty::{self, Instance, Ty, TyCtxt};
 use rustc_codegen_ssa::base::wants_msvc_seh;
 use rustc_codegen_ssa::traits::*;
 use rustc_data_structures::base_n;
 use rustc_data_structures::const_cstr;
 use rustc_data_structures::fx::FxHashMap;
 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, 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<'b, 'tcx> CodegenCx<'b, 'tcx> {
     }
 }
 
-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
     }
 }
@@ -837,13 +836,13 @@ impl ty::layout::HasTyCtxt<'tcx> for CodegenCx<'ll, 'tcx> {
 
 impl LayoutOf for CodegenCx<'ll, 'tcx> {
     type Ty = Ty<'tcx>;
-    type TyLayout = TyLayout<'tcx>;
+    type TyAndLayout = TyAndLayout<'tcx>;
 
-    fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
+    fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout {
         self.spanned_layout_of(ty, DUMMY_SP)
     }
 
-    fn spanned_layout_of(&self, ty: Ty<'tcx>, span: Span) -> Self::TyLayout {
+    fn spanned_layout_of(&self, ty: Ty<'tcx>, span: Span) -> Self::TyAndLayout {
         self.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)).unwrap_or_else(|e| {
             if let LayoutError::SizeOverflow(_) = e {
                 self.sess().span_fatal(span, &e.to_string())
diff --git a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs
index 13a36c36a30..e2eae4ac427 100644
--- a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs
+++ b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs
@@ -6,7 +6,7 @@ use rustc_codegen_ssa::traits::*;
 use crate::common::CodegenCx;
 use crate::llvm;
 use crate::llvm::debuginfo::{DIScope, DISubprogram};
-use rustc::mir::{Body, SourceScope};
+use rustc_middle::mir::{Body, SourceScope};
 use rustc_session::config::DebugInfo;
 
 use rustc_index::bit_set::BitSet;
diff --git a/src/librustc_codegen_llvm/debuginfo/gdb.rs b/src/librustc_codegen_llvm/debuginfo/gdb.rs
index dccd287a2e3..64d4076cbf0 100644
--- a/src/librustc_codegen_llvm/debuginfo/gdb.rs
+++ b/src/librustc_codegen_llvm/debuginfo/gdb.rs
@@ -5,8 +5,8 @@ use crate::llvm;
 use crate::builder::Builder;
 use crate::common::CodegenCx;
 use crate::value::Value;
-use rustc::bug;
 use rustc_codegen_ssa::traits::*;
+use rustc_middle::bug;
 use rustc_session::config::DebugInfo;
 
 use rustc_ast::attr;
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index d7a0acb1339..a9e21c056a3 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -20,17 +20,6 @@ use crate::llvm_util;
 use crate::value::Value;
 
 use log::debug;
-use rustc::ich::NodeIdHashingMode;
-use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags;
-use rustc::mir::interpret::truncate;
-use rustc::mir::{self, Field, GeneratorLayout};
-use rustc::ty::layout::{
-    self, Align, Integer, IntegerExt, LayoutOf, PrimitiveExt, Size, TyLayout, VariantIdx,
-};
-use rustc::ty::subst::{GenericArgKind, SubstsRef};
-use rustc::ty::Instance;
-use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
-use rustc::{bug, span_bug};
 use rustc_ast::ast;
 use rustc_codegen_ssa::traits::*;
 use rustc_data_structures::const_cstr;
@@ -41,10 +30,21 @@ use rustc_fs_util::path_to_c_string;
 use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc_index::vec::{Idx, IndexVec};
+use rustc_middle::ich::NodeIdHashingMode;
+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, 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_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;
@@ -1203,7 +1203,7 @@ fn prepare_tuple_metadata(
 //=-----------------------------------------------------------------------------
 
 struct UnionMemberDescriptionFactory<'tcx> {
-    layout: TyLayout<'tcx>,
+    layout: TyAndLayout<'tcx>,
     variant: &'tcx ty::VariantDef,
     span: Span,
 }
@@ -1325,7 +1325,7 @@ fn generator_layout_and_saved_local_names(
 /// offset of zero bytes).
 struct EnumMemberDescriptionFactory<'ll, 'tcx> {
     enum_type: Ty<'tcx>,
-    layout: TyLayout<'tcx>,
+    layout: TyAndLayout<'tcx>,
     discriminant_type_metadata: Option<&'ll DIType>,
     containing_scope: &'ll DIScope,
     span: Span,
@@ -1364,7 +1364,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
         };
 
         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 +1399,8 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
                     discriminant: None,
                 }]
             }
-            layout::Variants::Multiple {
-                discr_kind: layout::DiscriminantKind::Tag,
+            Variants::Multiple {
+                discr_kind: DiscriminantKind::Tag,
                 discr_index,
                 ref variants,
                 ..
@@ -1457,9 +1457,9 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
                     })
                     .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,
@@ -1494,7 +1494,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
                     fn compute_field_path<'a, 'tcx>(
                         cx: &CodegenCx<'a, 'tcx>,
                         name: &mut String,
-                        layout: TyLayout<'tcx>,
+                        layout: TyAndLayout<'tcx>,
                         offset: Size,
                         size: Size,
                     ) {
@@ -1592,7 +1592,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
 // 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,
@@ -1695,7 +1695,7 @@ impl<'tcx> VariantInfo<'_, 'tcx> {
 /// `RecursiveTypeDescription`.
 fn describe_enum_variant(
     cx: &CodegenCx<'ll, 'tcx>,
-    layout: layout::TyLayout<'tcx>,
+    layout: layout::TyAndLayout<'tcx>,
     variant: VariantInfo<'_, 'tcx>,
     discriminant_info: EnumDiscriminantInfo<'ll>,
     containing_scope: &'ll DIScope,
@@ -1777,7 +1777,7 @@ fn prepare_enum_metadata(
     // <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)
@@ -1869,30 +1869,21 @@ fn prepare_enum_metadata(
 
     let layout = cx.layout_of(enum_type);
 
-    match (&layout.abi, &layout.variants) {
-        (
-            &layout::Abi::Scalar(_),
-            &layout::Variants::Multiple {
-                discr_kind: layout::DiscriminantKind::Tag,
-                ref discr,
-                ..
-            },
-        ) => return FinalMetadata(discriminant_type_metadata(discr.value)),
-        _ => {}
+    if let (
+        &Abi::Scalar(_),
+        &Variants::Multiple { discr_kind: DiscriminantKind::Tag, ref discr, .. },
+    ) = (&layout.abi, &layout.variants)
+    {
+        return FinalMetadata(discriminant_type_metadata(discr.value));
     }
 
     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 = {
@@ -1940,10 +1931,10 @@ fn prepare_enum_metadata(
     };
     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,
             ..
@@ -1953,10 +1944,10 @@ fn prepare_enum_metadata(
             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);
 
@@ -1978,11 +1969,8 @@ fn prepare_enum_metadata(
             }
         }
 
-        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);
@@ -2007,8 +1995,8 @@ fn prepare_enum_metadata(
     };
 
     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,
diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs
index 4b8140263f1..f04ac586504 100644
--- a/src/librustc_codegen_llvm/debuginfo/mod.rs
+++ b/src/librustc_codegen_llvm/debuginfo/mod.rs
@@ -8,35 +8,35 @@ use self::namespace::mangled_name_of_instance;
 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::ty::subst::{GenericArgKind, SubstsRef};
-use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE};
-
-use crate::abi::FnAbi;
-use crate::builder::Builder;
-use crate::common::CodegenCx;
 use crate::value::Value;
-use rustc::mir;
-use rustc::ty::{self, Instance, ParamEnv, Ty};
+
+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::ty::layout::{self, HasTyCtxt, LayoutOf, Size};
-use rustc_ast::ast;
-use rustc_codegen_ssa::traits::*;
-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 @@ pub struct CrateDebugContext<'a, 'tcx> {
     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>>,
diff --git a/src/librustc_codegen_llvm/debuginfo/namespace.rs b/src/librustc_codegen_llvm/debuginfo/namespace.rs
index 4e507a569dc..475dea239a7 100644
--- a/src/librustc_codegen_llvm/debuginfo/namespace.rs
+++ b/src/librustc_codegen_llvm/debuginfo/namespace.rs
@@ -1,7 +1,7 @@
 // Namespace Handling.
 
 use super::utils::{debug_context, DIB};
-use rustc::ty::{self, Instance};
+use rustc_middle::ty::{self, Instance};
 
 use crate::common::CodegenCx;
 use crate::llvm;
diff --git a/src/librustc_codegen_llvm/debuginfo/utils.rs b/src/librustc_codegen_llvm/debuginfo/utils.rs
index b42d760a773..ee188e69be1 100644
--- a/src/librustc_codegen_llvm/debuginfo/utils.rs
+++ b/src/librustc_codegen_llvm/debuginfo/utils.rs
@@ -3,8 +3,8 @@
 use super::namespace::item_namespace;
 use super::CrateDebugContext;
 
-use rustc::ty::DefIdTree;
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty::DefIdTree;
 
 use crate::common::CodegenCx;
 use crate::llvm;
diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs
index 236f5bb1bfd..26ab46bde38 100644
--- a/src/librustc_codegen_llvm/declare.rs
+++ b/src/librustc_codegen_llvm/declare.rs
@@ -19,8 +19,8 @@ use crate::llvm::AttributePlace::Function;
 use crate::type_::Type;
 use crate::value::Value;
 use log::debug;
-use rustc::ty::Ty;
 use rustc_codegen_ssa::traits::*;
+use rustc_middle::ty::Ty;
 
 /// Declare a function.
 ///
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index bc25b9496d9..5734eae7d59 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -7,23 +7,22 @@ use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
 use crate::va_arg::emit_va_arg;
 use crate::value::Value;
-use rustc::ty::layout::{self, FnAbiExt, HasTyCtxt, LayoutOf, Primitive};
-use rustc::ty::{self, Ty};
-use rustc::{bug, span_bug};
+
 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_target::abi::HasDataLayout;
-
-use rustc_codegen_ssa::common::span_invalid_monomorphization_error;
-use rustc_codegen_ssa::traits::*;
-
+use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt};
+use rustc_middle::ty::{self, Ty};
+use rustc_middle::{bug, span_bug};
 use rustc_span::Span;
+use rustc_target::abi::{self, HasDataLayout, LayoutOf, Primitive};
 
 use std::cmp::Ordering;
 use std::{i128, iter, u128};
@@ -145,7 +144,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
             }
             "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 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
                 }
             }
 
-            "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 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
                             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
@@ -1390,8 +1389,8 @@ fn generic_simd_intrinsic(
 
     fn simd_simple_float_intrinsic(
         name: &str,
-        in_elem: &::rustc::ty::TyS<'_>,
-        in_ty: &::rustc::ty::TyS<'_>,
+        in_elem: &::rustc_middle::ty::TyS<'_>,
+        in_ty: &::rustc_middle::ty::TyS<'_>,
         in_len: u64,
         bx: &mut Builder<'a, 'll, 'tcx>,
         span: Span,
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index e36c80e15a5..939f9e9c2a0 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -17,17 +17,16 @@
 use back::write::{create_informational_target_machine, create_target_machine};
 
 pub use llvm_util::target_features;
-use rustc::dep_graph::{DepGraph, WorkProduct};
-use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
-use rustc::ty::{self, TyCtxt};
-use rustc::util::common::ErrorReported;
 use rustc_ast::expand::allocator::AllocatorKind;
 use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
 use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig};
 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_serialize::json;
 use rustc_session::config::{self, OptLevel, OutputFilenames, PrintRequest};
 use rustc_session::Session;
diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs
index 2ccc861ddbb..a56c8802f3c 100644
--- a/src/librustc_codegen_llvm/llvm_util.rs
+++ b/src/librustc_codegen_llvm/llvm_util.rs
@@ -1,9 +1,9 @@
 use crate::back::write::create_informational_target_machine;
 use crate::llvm;
 use libc::c_int;
-use rustc::bug;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_feature::UnstableFeatures;
+use rustc_middle::bug;
 use rustc_session::config::PrintRequest;
 use rustc_session::Session;
 use rustc_span::symbol::sym;
diff --git a/src/librustc_codegen_llvm/metadata.rs b/src/librustc_codegen_llvm/metadata.rs
index 0f30c2c020d..6d0612ca075 100644
--- a/src/librustc_codegen_llvm/metadata.rs
+++ b/src/librustc_codegen_llvm/metadata.rs
@@ -1,7 +1,7 @@
 use crate::llvm;
 use crate::llvm::archive_ro::ArchiveRO;
 use crate::llvm::{mk_section_iter, False, ObjectFile};
-use rustc::middle::cstore::MetadataLoader;
+use rustc_middle::middle::cstore::MetadataLoader;
 use rustc_target::spec::Target;
 
 use log::debug;
diff --git a/src/librustc_codegen_llvm/mono_item.rs b/src/librustc_codegen_llvm/mono_item.rs
index 97393e69e99..29389b44adc 100644
--- a/src/librustc_codegen_llvm/mono_item.rs
+++ b/src/librustc_codegen_llvm/mono_item.rs
@@ -5,13 +5,13 @@ use crate::context::CodegenCx;
 use crate::llvm;
 use crate::type_of::LayoutLlvmExt;
 use log::debug;
-use rustc::mir::mono::{Linkage, Visibility};
-use rustc::ty::layout::{FnAbiExt, LayoutOf};
-use rustc::ty::{Instance, TypeFoldable};
 use rustc_codegen_ssa::traits::*;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
-
-pub use rustc::mir::mono::MonoItem;
+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(
@@ -77,7 +77,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
 
         debug!("predefine_fn: instance = {:?}", instance);
 
-        attributes::from_fn_attrs(self, lldecl, instance, &fn_abi);
+        attributes::from_fn_attrs(self, lldecl, instance);
 
         self.instances.borrow_mut().insert(instance, lldecl);
     }
diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs
index 5bc1475df23..854eff31733 100644
--- a/src/librustc_codegen_llvm/type_.rs
+++ b/src/librustc_codegen_llvm/type_.rs
@@ -1,21 +1,21 @@
 pub use crate::llvm::Type;
 
+use crate::abi::{FnAbiLlvmExt, LlvmType};
+use crate::common;
 use crate::context::CodegenCx;
 use crate::llvm;
 use crate::llvm::{Bool, False, True};
-use crate::value::Value;
-use rustc::bug;
-use rustc_codegen_ssa::traits::*;
-
-use crate::abi::{FnAbiLlvmExt, LlvmType};
-use crate::common;
 use crate::type_of::LayoutLlvmExt;
-use rustc::ty::layout::{self, Align, Size, TyLayout};
-use rustc::ty::Ty;
+use crate::value::Value;
 use rustc_ast::ast;
 use rustc_codegen_ssa::common::TypeKind;
+use rustc_codegen_ssa::traits::*;
 use rustc_data_structures::small_c_str::SmallCStr;
+use rustc_middle::bug;
+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;
@@ -115,14 +115,14 @@ impl CodegenCx<'ll, 'tcx> {
 
     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);
@@ -250,24 +250,24 @@ impl Type {
 }
 
 impl LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
-    fn backend_type(&self, layout: TyLayout<'tcx>) -> &'ll Type {
+    fn backend_type(&self, layout: TyAndLayout<'tcx>) -> &'ll Type {
         layout.llvm_type(self)
     }
-    fn immediate_backend_type(&self, layout: TyLayout<'tcx>) -> &'ll Type {
+    fn immediate_backend_type(&self, layout: TyAndLayout<'tcx>) -> &'ll Type {
         layout.immediate_llvm_type(self)
     }
-    fn is_backend_immediate(&self, layout: TyLayout<'tcx>) -> bool {
+    fn is_backend_immediate(&self, layout: TyAndLayout<'tcx>) -> bool {
         layout.is_llvm_immediate()
     }
-    fn is_backend_scalar_pair(&self, layout: TyLayout<'tcx>) -> bool {
+    fn is_backend_scalar_pair(&self, layout: TyAndLayout<'tcx>) -> bool {
         layout.is_llvm_scalar_pair()
     }
-    fn backend_field_index(&self, layout: TyLayout<'tcx>, index: usize) -> u64 {
+    fn backend_field_index(&self, layout: TyAndLayout<'tcx>, index: usize) -> u64 {
         layout.llvm_field_index(index)
     }
     fn scalar_pair_element_backend_type(
         &self,
-        layout: TyLayout<'tcx>,
+        layout: TyAndLayout<'tcx>,
         index: usize,
         immediate: bool,
     ) -> &'ll Type {
diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs
index 3e6c75e4d6f..f475ea741c8 100644
--- a/src/librustc_codegen_llvm/type_of.rs
+++ b/src/librustc_codegen_llvm/type_of.rs
@@ -2,23 +2,25 @@ use crate::abi::FnAbi;
 use crate::common::*;
 use crate::type_::Type;
 use log::debug;
-use rustc::bug;
-use rustc::ty::layout::{self, Align, FnAbiExt, LayoutOf, PointeeInfo, Size, TyLayout};
-use rustc::ty::print::obsolete::DefPathBasedNames;
-use rustc::ty::{self, Ty, TypeFoldable};
 use rustc_codegen_ssa::traits::*;
-use rustc_target::abi::TyLayoutMethods;
+use rustc_middle::bug;
+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::{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;
 
 fn uncached_llvm_type<'a, 'tcx>(
     cx: &CodegenCx<'a, 'tcx>,
-    layout: TyLayout<'tcx>,
-    defer: &mut Option<(&'a Type, TyLayout<'tcx>)>,
+    layout: TyAndLayout<'tcx>,
+    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 @@ fn uncached_llvm_type<'a, 'tcx>(
                 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 @@ fn uncached_llvm_type<'a, 'tcx>(
                 false,
             );
         }
-        layout::Abi::Uninhabited | layout::Abi::Aggregate { .. } => {}
+        Abi::Uninhabited | Abi::Aggregate { .. } => {}
     }
 
     let name = match layout.ty.kind {
@@ -61,14 +63,14 @@ fn uncached_llvm_type<'a, 'tcx>(
             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 @@ fn uncached_llvm_type<'a, 'tcx>(
     };
 
     match layout.fields {
-        layout::FieldPlacement::Union(_) => {
+        FieldsShape::Union(_) => {
             let fill = cx.type_padding_filler(layout.size, layout.align.abi);
             let packed = false;
             match name {
@@ -91,10 +93,8 @@ fn uncached_llvm_type<'a, 'tcx>(
                 }
             }
         }
-        layout::FieldPlacement::Array { count, .. } => {
-            cx.type_array(layout.field(cx, 0).llvm_type(cx), count)
-        }
-        layout::FieldPlacement::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)
@@ -110,7 +110,7 @@ fn uncached_llvm_type<'a, 'tcx>(
 
 fn struct_llfields<'a, 'tcx>(
     cx: &CodegenCx<'a, 'tcx>,
-    layout: TyLayout<'tcx>,
+    layout: TyAndLayout<'tcx>,
 ) -> (Vec<&'a Type>, bool) {
     debug!("struct_llfields: {:#?}", layout);
     let field_count = layout.fields.count();
@@ -189,7 +189,7 @@ pub trait LayoutLlvmExt<'tcx> {
     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>(
@@ -202,26 +202,23 @@ pub trait LayoutLlvmExt<'tcx> {
     fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size) -> Option<PointeeInfo>;
 }
 
-impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
+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,
         }
     }
 
-    /// Gets the LLVM type corresponding to a Rust type, i.e., `rustc::ty::Ty`.
+    /// Gets the LLVM type corresponding to a Rust type, i.e., `rustc_middle::ty::Ty`.
     /// The pointee type of the pointer in `PlaceRef` is always this type.
     /// For sized types, it is also the right LLVM type for an `alloca`
     /// containing a value of that type, and most immediates (except `bool`).
@@ -233,7 +230,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
     /// 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 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
 
         // 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 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
     }
 
     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 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
     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,8 +340,8 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
         }
 
         let (a, b) = match self.abi {
-            layout::Abi::ScalarPair(ref a, ref b) => (a, b),
-            _ => bug!("TyLayout::scalar_pair_element_llty({:?}): not applicable", self),
+            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 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
 
     fn llvm_field_index(&self, index: usize) -> u64 {
         match self.abi {
-            layout::Abi::Scalar(_) | layout::Abi::ScalarPair(..) => {
-                bug!("TyLayout::llvm_field_index({:?}): not applicable", self)
+            Abi::Scalar(_) | Abi::ScalarPair(..) => {
+                bug!("TyAndLayout::llvm_field_index({:?}): not applicable", self)
             }
             _ => {}
         }
         match self.fields {
-            layout::FieldPlacement::Union(_) => {
-                bug!("TyLayout::llvm_field_index({:?}): not applicable", self)
+            FieldsShape::Union(_) => {
+                bug!("TyAndLayout::llvm_field_index({:?}): not applicable", self)
             }
 
-            layout::FieldPlacement::Array { .. } => index as u64,
+            FieldsShape::Array { .. } => index as u64,
 
-            layout::FieldPlacement::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 a552f2cdb78..8bc3579800e 100644
--- a/src/librustc_codegen_llvm/va_arg.rs
+++ b/src/librustc_codegen_llvm/va_arg.rs
@@ -2,12 +2,13 @@ use crate::builder::Builder;
 use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
-use rustc::ty::layout::{Align, HasDataLayout, HasTyCtxt, LayoutOf, Size};
-use rustc::ty::Ty;
 use rustc_codegen_ssa::mir::operand::OperandRef;
 use rustc_codegen_ssa::traits::{
     BaseTypeMethods, BuilderMethods, ConstMethods, DerivedTypeMethods,
 };
+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/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml
index 299f4d2c669..717e32d4a0d 100644
--- a/src/librustc_codegen_ssa/Cargo.toml
+++ b/src/librustc_codegen_ssa/Cargo.toml
@@ -22,7 +22,7 @@ tempfile = "3.1"
 rustc_serialize = { path = "../libserialize", package = "serialize" }
 rustc_ast = { path = "../librustc_ast" }
 rustc_span = { path = "../librustc_span" }
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc_apfloat = { path = "../librustc_apfloat" }
 rustc_attr = { path = "../librustc_attr" }
 rustc_symbol_mangling = { path = "../librustc_symbol_mangling" }
diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index 7169b79c3bc..1e780c5f867 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -1,8 +1,8 @@
-use rustc::middle::cstore::{EncodedMetadata, LibSource, NativeLibrary, NativeLibraryKind};
-use rustc::middle::dependency_format::Linkage;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_fs_util::fix_windows_verbatim_for_gcc;
 use rustc_hir::def_id::CrateNum;
+use rustc_middle::middle::cstore::{EncodedMetadata, LibSource, NativeLibrary, NativeLibraryKind};
+use rustc_middle::middle::dependency_format::Linkage;
 use rustc_session::config::{
     self, CFGuard, DebugInfo, OutputFilenames, OutputType, PrintRequest, Sanitizer,
 };
diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs
index 6b30ae8559d..c0c533524b0 100644
--- a/src/librustc_codegen_ssa/back/linker.rs
+++ b/src/librustc_codegen_ssa/back/linker.rs
@@ -8,10 +8,10 @@ use std::io::prelude::*;
 use std::io::{self, BufWriter};
 use std::path::{Path, PathBuf};
 
-use rustc::middle::dependency_format::Linkage;
-use rustc::ty::TyCtxt;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
+use rustc_middle::middle::dependency_format::Linkage;
+use rustc_middle::ty::TyCtxt;
 use rustc_serialize::{json, Encoder};
 use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel};
 use rustc_session::Session;
diff --git a/src/librustc_codegen_ssa/back/rpath.rs b/src/librustc_codegen_ssa/back/rpath.rs
index 0a0e975e5a5..c02e4f279b1 100644
--- a/src/librustc_codegen_ssa/back/rpath.rs
+++ b/src/librustc_codegen_ssa/back/rpath.rs
@@ -3,8 +3,8 @@ use std::env;
 use std::fs;
 use std::path::{Path, PathBuf};
 
-use rustc::middle::cstore::LibSource;
 use rustc_hir::def_id::CrateNum;
+use rustc_middle::middle::cstore::LibSource;
 
 pub struct RPathConfig<'a> {
     pub used_crates: &'a [(CrateNum, LibSource)],
diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs
index 8a2503ce167..39b70a5f2e7 100644
--- a/src/librustc_codegen_ssa/back/symbol_export.rs
+++ b/src/librustc_codegen_ssa/back/symbol_export.rs
@@ -1,12 +1,6 @@
 use std::collections::hash_map::Entry::*;
 use std::sync::Arc;
 
-use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags;
-use rustc::middle::exported_symbols::{metadata_symbol_name, ExportedSymbol, SymbolExportLevel};
-use rustc::ty::query::Providers;
-use rustc::ty::subst::{GenericArgKind, SubstsRef};
-use rustc::ty::Instance;
-use rustc::ty::{SymbolName, TyCtxt};
 use rustc_ast::expand::allocator::ALLOCATOR_METHODS;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxHashMap;
@@ -14,6 +8,14 @@ use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::Node;
 use rustc_index::vec::IndexVec;
+use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
+use rustc_middle::middle::exported_symbols::{
+    metadata_symbol_name, ExportedSymbol, SymbolExportLevel,
+};
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
+use rustc_middle::ty::Instance;
+use rustc_middle::ty::{SymbolName, TyCtxt};
 use rustc_session::config::{self, Sanitizer};
 
 pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel {
@@ -221,8 +223,8 @@ fn exported_symbols_provider_local(
     }
 
     if tcx.sess.opts.share_generics() && tcx.local_crate_exports_generics() {
-        use rustc::mir::mono::{Linkage, MonoItem, Visibility};
-        use rustc::ty::InstanceDef;
+        use rustc_middle::mir::mono::{Linkage, MonoItem, Visibility};
+        use rustc_middle::ty::InstanceDef;
 
         // Normally, we require that shared monomorphizations are not hidden,
         // because if we want to re-use a monomorphization from a Rust dylib, it
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index 7833f22097c..35c5812e1f3 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -10,10 +10,6 @@ use crate::{
 
 use crate::traits::*;
 use jobserver::{Acquired, Client};
-use rustc::dep_graph::{WorkProduct, WorkProductFileKind, WorkProductId};
-use rustc::middle::cstore::EncodedMetadata;
-use rustc::middle::exported_symbols::SymbolExportLevel;
-use rustc::ty::TyCtxt;
 use rustc_ast::attr;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::profiling::SelfProfilerRef;
@@ -28,6 +24,10 @@ use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_incremental::{
     copy_cgu_workproducts_to_incr_comp_cache_dir, in_incr_comp_dir, in_incr_comp_dir_sess,
 };
+use rustc_middle::dep_graph::{WorkProduct, WorkProductFileKind, WorkProductId};
+use rustc_middle::middle::cstore::EncodedMetadata;
+use rustc_middle::middle::exported_symbols::SymbolExportLevel;
+use rustc_middle::ty::TyCtxt;
 use rustc_session::cgu_reuse_tracker::CguReuseTracker;
 use rustc_session::config::{
     self, Lto, OutputFilenames, OutputType, Passes, Sanitizer, SwitchWithOptPath,
diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs
index 834702a3009..02974151555 100644
--- a/src/librustc_codegen_ssa/base.rs
+++ b/src/librustc_codegen_ssa/base.rs
@@ -25,28 +25,29 @@ use crate::mir::place::PlaceRef;
 use crate::traits::*;
 use crate::{CachedModuleCodegen, CrateInfo, MemFlags, ModuleCodegen, ModuleKind};
 
-use rustc::middle::codegen_fn_attrs::CodegenFnAttrs;
-use rustc::middle::cstore::EncodedMetadata;
-use rustc::middle::cstore::{self, LinkagePreference};
-use rustc::middle::lang_items;
-use rustc::middle::lang_items::StartFnLangItem;
-use rustc::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem};
-use rustc::ty::layout::{self, Align, HasTyCtxt, LayoutOf, TyLayout, VariantIdx};
-use rustc::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
-use rustc::ty::query::Providers;
-use rustc::ty::{self, Instance, Ty, TyCtxt};
 use rustc_attr as attr;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::profiling::print_time_passes_entry;
 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::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem};
+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};
 use rustc_session::cgu_reuse_tracker::CguReuse;
 use rustc_session::config::{self, EntryFnType, Lto};
 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};
@@ -341,9 +342,9 @@ pub fn from_immediate<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 pub fn to_immediate<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     bx: &mut Bx,
     val: Bx::Value,
-    layout: layout::TyLayout<'_>,
+    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<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 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());
@@ -366,7 +367,7 @@ pub fn memcpy_ty<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     dst_align: Align,
     src: Bx::Value,
     src_align: Align,
-    layout: TyLayout<'tcx>,
+    layout: TyAndLayout<'tcx>,
     flags: MemFlags,
 ) {
     let size = layout.size.bytes();
@@ -557,7 +558,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
     // one instead. If nothing exists then it's our job to generate the
     // allocator!
     let any_dynamic_crate = tcx.dependency_formats(LOCAL_CRATE).iter().any(|(_, list)| {
-        use rustc::middle::dependency_format::Linkage;
+        use rustc_middle::middle::dependency_format::Linkage;
         list.iter().any(|&linkage| linkage == Linkage::Dynamic)
     });
     let allocator_module = if any_dynamic_crate {
diff --git a/src/librustc_codegen_ssa/common.rs b/src/librustc_codegen_ssa/common.rs
index 147b2399502..0d0321ec4ae 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::ty::{Ty, TyCtxt};
 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::middle::lang_items::LangItem;
-use rustc_hir::def_id::DefId;
-
 use crate::traits::BuilderMethods;
-use rustc_hir as hir;
+use crate::traits::*;
 
 pub enum IntPredicate {
     IntEQ,
diff --git a/src/librustc_codegen_ssa/debuginfo/type_names.rs b/src/librustc_codegen_ssa/debuginfo/type_names.rs
index 8dd35208bf6..6c0e4128e30 100644
--- a/src/librustc_codegen_ssa/debuginfo/type_names.rs
+++ b/src/librustc_codegen_ssa/debuginfo/type_names.rs
@@ -1,9 +1,9 @@
 // Type Names for Debug Info.
 
-use rustc::ty::{self, subst::SubstsRef, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty::{self, subst::SubstsRef, Ty, TyCtxt};
 
 // Compute the name of the type as it should be stored in debuginfo. Does not do
 // any caching, i.e., calling the function twice with the same type will also do
diff --git a/src/librustc_codegen_ssa/glue.rs b/src/librustc_codegen_ssa/glue.rs
index a43e8427286..5b086bc43ff 100644
--- a/src/librustc_codegen_ssa/glue.rs
+++ b/src/librustc_codegen_ssa/glue.rs
@@ -5,7 +5,7 @@
 use crate::common::IntPredicate;
 use crate::meth;
 use crate::traits::*;
-use rustc::ty::{self, Ty};
+use rustc_middle::ty::{self, Ty};
 
 pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     bx: &mut Bx,
diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs
index d2afbdc23e1..bf8441562c5 100644
--- a/src/librustc_codegen_ssa/lib.rs
+++ b/src/librustc_codegen_ssa/lib.rs
@@ -15,17 +15,17 @@
 #[macro_use]
 extern crate log;
 #[macro_use]
-extern crate rustc;
+extern crate rustc_middle;
 
-use rustc::dep_graph::WorkProduct;
-use rustc::middle::cstore::{CrateSource, LibSource, NativeLibrary};
-use rustc::middle::dependency_format::Dependencies;
-use rustc::middle::lang_items::LangItem;
-use rustc::ty::query::Providers;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 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::ty::query::Providers;
 use rustc_session::config::{OutputFilenames, OutputType, RUST_CGU_EXT};
 use rustc_span::symbol::Symbol;
 use std::path::{Path, PathBuf};
@@ -144,7 +144,7 @@ pub struct CodegenResults {
     pub allocator_module: Option<CompiledModule>,
     pub metadata_module: Option<CompiledModule>,
     pub crate_hash: Svh,
-    pub metadata: rustc::middle::cstore::EncodedMetadata,
+    pub metadata: rustc_middle::middle::cstore::EncodedMetadata,
     pub windows_subsystem: Option<String>,
     pub linker_info: back::linker::LinkerInfo,
     pub crate_info: CrateInfo,
diff --git a/src/librustc_codegen_ssa/meth.rs b/src/librustc_codegen_ssa/meth.rs
index c36ef9b480c..199dd8c7df4 100644
--- a/src/librustc_codegen_ssa/meth.rs
+++ b/src/librustc_codegen_ssa/meth.rs
@@ -1,6 +1,6 @@
 use crate::traits::*;
 
-use rustc::ty::{self, Instance, Ty};
+use rustc_middle::ty::{self, Instance, Ty};
 use rustc_target::abi::call::FnAbi;
 
 #[derive(Copy, Clone, Debug)]
diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs
index 04680a17517..221f36fed36 100644
--- a/src/librustc_codegen_ssa/mir/analyze.rs
+++ b/src/librustc_codegen_ssa/mir/analyze.rs
@@ -3,16 +3,17 @@
 
 use super::FunctionCx;
 use crate::traits::*;
-use rustc::mir::traversal;
-use rustc::mir::visit::{
-    MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext, Visitor,
-};
-use rustc::mir::{self, Location, TerminatorKind};
-use rustc::ty;
-use rustc::ty::layout::{HasTyCtxt, LayoutOf};
 use rustc_data_structures::graph::dominators::Dominators;
 use rustc_index::bit_set::BitSet;
 use rustc_index::vec::{Idx, IndexVec};
+use rustc_middle::mir::traversal;
+use rustc_middle::mir::visit::{
+    MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext, Visitor,
+};
+use rustc_middle::mir::{self, Location, TerminatorKind};
+use rustc_middle::ty;
+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>,
@@ -20,7 +21,7 @@ pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     let mir = fx.mir;
     let mut analyzer = LocalAnalyzer::new(fx);
 
-    analyzer.visit_body(mir);
+    analyzer.visit_body(&mir);
 
     for (local, decl) in mir.local_decls.iter_enumerated() {
         let ty = fx.monomorphize(&decl.ty);
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index 8433f793020..219d5aa77ea 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -9,14 +9,15 @@ use crate::meth;
 use crate::traits::*;
 use crate::MemFlags;
 
-use rustc::middle::lang_items;
-use rustc::mir;
-use rustc::mir::AssertKind;
-use rustc::ty::layout::{self, FnAbiExt, HasTyCtxt, LayoutOf};
-use rustc::ty::{self, Instance, Ty, TypeFoldable};
+use rustc_hir::lang_items;
 use rustc_index::vec::Idx;
+use rustc_middle::mir;
+use rustc_middle::mir::AssertKind;
+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;
@@ -299,7 +300,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         &mut self,
         helper: TerminatorCodegenHelper<'tcx>,
         mut bx: Bx,
-        location: &mir::Place<'tcx>,
+        location: mir::Place<'tcx>,
         target: mir::BasicBlock,
         unwind: Option<mir::BasicBlock>,
     ) {
@@ -580,7 +581,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         if intrinsic == Some("transmute") {
             if let Some(destination_ref) = destination.as_ref() {
-                let &(ref dest, target) = destination_ref;
+                let &(dest, target) = destination_ref;
                 self.codegen_transmute(&mut bx, &args[0], dest);
                 helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
                 helper.funclet_br(self, &mut bx, target);
@@ -591,7 +592,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 // 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;
@@ -619,7 +620,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let mut llargs = Vec::with_capacity(arg_count);
 
         // Prepare the return value destination
-        let ret_dest = if let Some((ref dest, _)) = *destination {
+        let ret_dest = if let Some((dest, _)) = *destination {
             let is_intrinsic = intrinsic.is_some();
             self.make_return_dest(&mut bx, dest, &fn_abi.ret, &mut llargs, is_intrinsic)
         } else {
@@ -873,7 +874,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 bx.unreachable();
             }
 
-            mir::TerminatorKind::Drop { ref location, target, unwind } => {
+            mir::TerminatorKind::Drop { location, target, unwind } => {
                 self.codegen_drop_terminator(helper, bx, location, target, unwind);
             }
 
@@ -994,7 +995,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 // 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);
                     }
@@ -1123,7 +1124,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     fn make_return_dest(
         &mut self,
         bx: &mut Bx,
-        dest: &mir::Place<'tcx>,
+        dest: mir::Place<'tcx>,
         fn_ret: &ArgAbi<'tcx, Ty<'tcx>>,
         llargs: &mut Vec<Bx::Value>,
         is_intrinsic: bool,
@@ -1184,7 +1185,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         }
     }
 
-    fn codegen_transmute(&mut self, bx: &mut Bx, src: &mir::Operand<'tcx>, dst: &mir::Place<'tcx>) {
+    fn codegen_transmute(&mut self, bx: &mut Bx, src: &mir::Operand<'tcx>, dst: mir::Place<'tcx>) {
         if let Some(index) = dst.as_local() {
             match self.locals[index] {
                 LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place),
diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs
index 74a9646a0c0..298aa25f032 100644
--- a/src/librustc_codegen_ssa/mir/constant.rs
+++ b/src/librustc_codegen_ssa/mir/constant.rs
@@ -1,11 +1,12 @@
 use crate::mir::operand::OperandRef;
 use crate::traits::*;
-use rustc::mir;
-use rustc::mir::interpret::{ConstValue, ErrorHandled};
-use rustc::ty::layout::{self, HasTyCtxt};
-use rustc::ty::{self, Ty};
 use rustc_index::vec::Idx;
+use rustc_middle::mir;
+use rustc_middle::mir::interpret::{ConstValue, ErrorHandled};
+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 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         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 cbe5f511152..5501ed5128d 100644
--- a/src/librustc_codegen_ssa/mir/debuginfo.rs
+++ b/src/librustc_codegen_ssa/mir/debuginfo.rs
@@ -1,13 +1,12 @@
 use crate::traits::*;
-use rustc::mir;
-use rustc::ty;
-use rustc::ty::layout::{LayoutOf, Size};
 use rustc_hir::def_id::CrateNum;
 use rustc_index::vec::IndexVec;
+use rustc_middle::mir;
+use rustc_middle::ty;
 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/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs
index 000db0155ad..fd20cf5404c 100644
--- a/src/librustc_codegen_ssa/mir/mod.rs
+++ b/src/librustc_codegen_ssa/mir/mod.rs
@@ -1,8 +1,8 @@
 use crate::base;
 use crate::traits::*;
-use rustc::mir;
-use rustc::ty::layout::{FnAbiExt, HasTyCtxt, TyLayout};
-use rustc::ty::{self, Instance, Ty, TypeFoldable};
+use rustc_middle::mir;
+use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt, TyAndLayout};
+use rustc_middle::ty::{self, Instance, Ty, TypeFoldable};
 use rustc_target::abi::call::{FnAbi, PassMode};
 
 use std::iter;
@@ -13,7 +13,7 @@ use rustc_index::vec::IndexVec;
 use self::analyze::CleanupKind;
 use self::debuginfo::{FunctionDebugContext, PerLocalVarDebugInfo};
 use self::place::PlaceRef;
-use rustc::mir::traversal;
+use rustc_middle::mir::traversal;
 
 use self::operand::{OperandRef, OperandValue};
 
@@ -114,7 +114,7 @@ enum LocalRef<'tcx, V> {
 impl<'a, 'tcx, V: CodegenObject> LocalRef<'tcx, V> {
     fn new_operand<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
         bx: &mut Bx,
-        layout: TyLayout<'tcx>,
+        layout: TyAndLayout<'tcx>,
     ) -> LocalRef<'tcx, V> {
         if layout.is_zst() {
             // Zero-size temporaries aren't always initialized, which
diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs
index 5bb30d03d9f..69f11ed57ac 100644
--- a/src/librustc_codegen_ssa/mir/operand.rs
+++ b/src/librustc_codegen_ssa/mir/operand.rs
@@ -6,10 +6,11 @@ use crate::glue;
 use crate::traits::*;
 use crate::MemFlags;
 
-use rustc::mir;
-use rustc::mir::interpret::{ConstValue, ErrorHandled, Pointer, Scalar};
-use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout};
-use rustc::ty::Ty;
+use rustc_middle::mir;
+use rustc_middle::mir::interpret::{ConstValue, ErrorHandled, Pointer, Scalar};
+use rustc_middle::ty::layout::TyAndLayout;
+use rustc_middle::ty::Ty;
+use rustc_target::abi::{Abi, Align, LayoutOf, Size};
 
 use std::fmt;
 
@@ -43,7 +44,7 @@ pub struct OperandRef<'tcx, V> {
     pub val: OperandValue<V>,
 
     // The layout of value, based on its Rust type.
-    pub layout: TyLayout<'tcx>,
+    pub layout: TyAndLayout<'tcx>,
 }
 
 impl<V: CodegenObject> fmt::Debug for OperandRef<'tcx, V> {
@@ -55,7 +56,7 @@ impl<V: CodegenObject> fmt::Debug for OperandRef<'tcx, V> {
 impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
     pub fn new_zst<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
         bx: &mut Bx,
-        layout: TyLayout<'tcx>,
+        layout: TyAndLayout<'tcx>,
     ) -> OperandRef<'tcx, V> {
         assert!(layout.is_zst());
         OperandRef {
@@ -78,7 +79,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
         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 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
             }
             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(
@@ -159,9 +160,9 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
     pub fn from_immediate_or_packed_pair<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
         bx: &mut Bx,
         llval: V,
-        layout: TyLayout<'tcx>,
+        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 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
             }
 
             // 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 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
             }
 
             // `#[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 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
             }
             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 2eba88c6b5f..461695129c2 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/src/librustc_codegen_ssa/mir/place.rs
@@ -6,10 +6,12 @@ use crate::glue;
 use crate::traits::*;
 use crate::MemFlags;
 
-use rustc::mir;
-use rustc::mir::tcx::PlaceTy;
-use rustc::ty::layout::{self, Align, HasTyCtxt, LayoutOf, TyLayout, VariantIdx};
-use rustc::ty::{self, Ty};
+use rustc_middle::mir;
+use rustc_middle::mir::tcx::PlaceTy;
+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> {
@@ -20,19 +22,23 @@ pub struct PlaceRef<'tcx, V> {
     pub llextra: Option<V>,
 
     /// The monomorphized type of this place, including variant information.
-    pub layout: TyLayout<'tcx>,
+    pub layout: TyAndLayout<'tcx>,
 
     /// The alignment we know for this place.
     pub align: Align,
 }
 
 impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
-    pub fn new_sized(llval: V, layout: TyLayout<'tcx>) -> PlaceRef<'tcx, V> {
+    pub fn new_sized(llval: V, layout: TyAndLayout<'tcx>) -> PlaceRef<'tcx, V> {
         assert!(!layout.is_unsized());
         PlaceRef { llval, llextra: None, layout, align: layout.align.abi }
     }
 
-    pub fn new_sized_aligned(llval: V, layout: TyLayout<'tcx>, align: Align) -> PlaceRef<'tcx, V> {
+    pub fn new_sized_aligned(
+        llval: V,
+        layout: TyAndLayout<'tcx>,
+        align: Align,
+    ) -> PlaceRef<'tcx, V> {
         assert!(!layout.is_unsized());
         PlaceRef { llval, llextra: None, layout, align }
     }
@@ -41,7 +47,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
     // unless LLVM IR names are turned on (e.g. for `--emit=llvm-ir`).
     pub fn alloca<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
         bx: &mut Bx,
-        layout: TyLayout<'tcx>,
+        layout: TyAndLayout<'tcx>,
     ) -> Self {
         assert!(!layout.is_unsized(), "tried to statically allocate unsized place");
         let tmp = bx.alloca(bx.cx().backend_type(layout), layout.align.abi);
@@ -53,7 +59,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
     // unless LLVM IR names are turned on (e.g. for `--emit=llvm-ir`).
     pub fn alloca_unsized_indirect<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
         bx: &mut Bx,
-        layout: TyLayout<'tcx>,
+        layout: TyAndLayout<'tcx>,
     ) -> Self {
         assert!(layout.is_unsized(), "tried to allocate indirect place for sized values");
         let ptr_ty = bx.cx().tcx().mk_mut_ptr(layout.ty);
@@ -62,7 +68,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
     }
 
     pub fn len<Cx: ConstMethods<'tcx, Value = V>>(&self, cx: &Cx) -> V {
-        if let layout::FieldPlacement::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()
@@ -90,7 +96,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
             // 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)
@@ -194,7 +200,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
             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
@@ -202,7 +208,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
                     .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)
             }
         };
@@ -213,22 +219,18 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
 
         // 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);
@@ -307,14 +309,10 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
             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;
@@ -324,9 +322,9 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
                     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 880bce7fde4..33f449ed270 100644
--- a/src/librustc_codegen_ssa/mir/rvalue.rs
+++ b/src/librustc_codegen_ssa/mir/rvalue.rs
@@ -7,14 +7,15 @@ use crate::common::{self, IntPredicate, RealPredicate};
 use crate::traits::*;
 use crate::MemFlags;
 
-use rustc::middle::lang_items::ExchangeMallocFnLangItem;
-use rustc::mir;
-use rustc::ty::cast::{CastTy, IntTy};
-use rustc::ty::layout::{self, HasTyCtxt, LayoutOf};
-use rustc::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt};
 use rustc_apfloat::{ieee, Float, Round, Status};
+use rustc_hir::lang_items::ExchangeMallocFnLangItem;
+use rustc_middle::mir;
+use rustc_middle::ty::cast::{CastTy, IntTy};
+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 rustc_target::abi::{Abi, Int, LayoutOf, Variants};
 
 use std::{i128, u128};
 
@@ -292,7 +293,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         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 +312,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                                     );
                                 }
                             }
-                            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
@@ -383,7 +384,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 (bx, OperandRef { val, layout: cast })
             }
 
-            mir::Rvalue::Ref(_, bk, ref place) => {
+            mir::Rvalue::Ref(_, bk, place) => {
                 let mk_ref = move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| {
                     tcx.mk_ref(
                         tcx.lifetimes.re_erased,
@@ -393,14 +394,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 self.codegen_place_to_pointer(bx, place, mk_ref)
             }
 
-            mir::Rvalue::AddressOf(mutability, ref place) => {
+            mir::Rvalue::AddressOf(mutability, place) => {
                 let mk_ptr = move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| {
                     tcx.mk_ptr(ty::TypeAndMut { ty, mutbl: mutability })
                 };
                 self.codegen_place_to_pointer(bx, place, mk_ptr)
             }
 
-            mir::Rvalue::Len(ref place) => {
+            mir::Rvalue::Len(place) => {
                 let size = self.evaluate_array_len(&mut bx, place);
                 let operand = OperandRef {
                     val: OperandValue::Immediate(size),
@@ -537,7 +538,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         }
     }
 
-    fn evaluate_array_len(&mut self, bx: &mut Bx, place: &mir::Place<'tcx>) -> Bx::Value {
+    fn evaluate_array_len(&mut self, bx: &mut Bx, place: mir::Place<'tcx>) -> Bx::Value {
         // ZST are passed as operands and require special handling
         // because codegen_place() panics if Local is operand.
         if let Some(index) = place.as_local() {
@@ -557,7 +558,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     fn codegen_place_to_pointer(
         &mut self,
         mut bx: Bx,
-        place: &mir::Place<'tcx>,
+        place: mir::Place<'tcx>,
         mk_ptr_ty: impl FnOnce(TyCtxt<'tcx>, Ty<'tcx>) -> Ty<'tcx>,
     ) -> (Bx, OperandRef<'tcx, Bx::Value>) {
         let cg_place = self.codegen_place(&mut bx, place.as_ref());
diff --git a/src/librustc_codegen_ssa/mir/statement.rs b/src/librustc_codegen_ssa/mir/statement.rs
index 5edd9b9f0a0..ddd7447406c 100644
--- a/src/librustc_codegen_ssa/mir/statement.rs
+++ b/src/librustc_codegen_ssa/mir/statement.rs
@@ -1,5 +1,5 @@
-use rustc::mir;
 use rustc_errors::struct_span_err;
+use rustc_middle::mir;
 
 use super::FunctionCx;
 use super::LocalRef;
diff --git a/src/librustc_codegen_ssa/mono_item.rs b/src/librustc_codegen_ssa/mono_item.rs
index ae211cad62d..5994ef2be54 100644
--- a/src/librustc_codegen_ssa/mono_item.rs
+++ b/src/librustc_codegen_ssa/mono_item.rs
@@ -1,10 +1,10 @@
 use crate::base;
 use crate::traits::*;
-use rustc::mir::mono::{Linkage, Visibility};
-use rustc::ty::layout::HasTyCtxt;
 use rustc_hir as hir;
+use rustc_middle::mir::mono::{Linkage, Visibility};
+use rustc_middle::ty::layout::HasTyCtxt;
 
-use rustc::mir::mono::MonoItem;
+use rustc_middle::mir::mono::MonoItem;
 
 pub trait MonoItemExt<'a, 'tcx> {
     fn define<Bx: BuilderMethods<'a, 'tcx>>(&self, cx: &'a Bx::CodegenCx);
diff --git a/src/librustc_codegen_ssa/traits/abi.rs b/src/librustc_codegen_ssa/traits/abi.rs
index c564552fcb4..dd8495850bd 100644
--- a/src/librustc_codegen_ssa/traits/abi.rs
+++ b/src/librustc_codegen_ssa/traits/abi.rs
@@ -1,5 +1,5 @@
 use super::BackendTypes;
-use rustc::ty::Ty;
+use rustc_middle::ty::Ty;
 use rustc_target::abi::call::FnAbi;
 
 pub trait AbiBuilderMethods<'tcx>: BackendTypes {
diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs
index 4e861f45ff7..91be123beb0 100644
--- a/src/librustc_codegen_ssa/traits/backend.rs
+++ b/src/librustc_codegen_ssa/traits/backend.rs
@@ -2,18 +2,19 @@ use super::write::WriteBackendMethods;
 use super::CodegenObject;
 use crate::ModuleCodegen;
 
-use rustc::dep_graph::DepGraph;
-use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
-use rustc::ty::layout::{HasTyCtxt, LayoutOf, TyLayout};
-use rustc::ty::query::Providers;
-use rustc::ty::{Ty, TyCtxt};
-use rustc::util::common::ErrorReported;
 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, TyAndLayout};
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::{Ty, TyCtxt};
 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;
 
@@ -35,12 +36,12 @@ pub trait BackendTypes {
 }
 
 pub trait Backend<'tcx>:
-    Sized + BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
+    Sized + BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>>
 {
 }
 
 impl<'tcx, T> Backend<'tcx> for T where
-    Self: BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
+    Self: BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>>
 {
 }
 
diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs
index b3c830eef86..caba7ebef59 100644
--- a/src/librustc_codegen_ssa/traits/builder.rs
+++ b/src/librustc_codegen_ssa/traits/builder.rs
@@ -12,8 +12,9 @@ use crate::mir::operand::OperandRef;
 use crate::mir::place::PlaceRef;
 use crate::MemFlags;
 
-use rustc::ty::layout::{Align, HasParamEnv, Size};
-use rustc::ty::Ty;
+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 608fa5ef71e..6b58dea794b 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::mir::interpret::Allocation;
-use rustc::mir::interpret::Scalar;
-use rustc::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 @@ pub trait ConstMethods<'tcx>: BackendTypes {
     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::TyLayout<'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 14c5a1b8ee9..34be1cfdd88 100644
--- a/src/librustc_codegen_ssa/traits/debuginfo.rs
+++ b/src/librustc_codegen_ssa/traits/debuginfo.rs
@@ -1,12 +1,12 @@
 use super::BackendTypes;
 use crate::mir::debuginfo::{FunctionDebugContext, VariableKind};
-use rustc::mir;
-use rustc::ty::layout::Size;
-use rustc::ty::{Instance, Ty};
 use rustc_ast::ast::Name;
 use rustc_hir::def_id::CrateNum;
+use rustc_middle::mir;
+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/declare.rs b/src/librustc_codegen_ssa/traits/declare.rs
index c2ab5f50c6f..de63ef79613 100644
--- a/src/librustc_codegen_ssa/traits/declare.rs
+++ b/src/librustc_codegen_ssa/traits/declare.rs
@@ -1,7 +1,7 @@
 use super::BackendTypes;
-use rustc::mir::mono::{Linkage, Visibility};
-use rustc::ty::{Instance, Ty};
 use rustc_hir::def_id::DefId;
+use rustc_middle::mir::mono::{Linkage, Visibility};
+use rustc_middle::ty::{Instance, Ty};
 use rustc_target::abi::call::FnAbi;
 
 pub trait DeclareMethods<'tcx>: BackendTypes {
diff --git a/src/librustc_codegen_ssa/traits/intrinsic.rs b/src/librustc_codegen_ssa/traits/intrinsic.rs
index 482a76932ae..9d48e233de6 100644
--- a/src/librustc_codegen_ssa/traits/intrinsic.rs
+++ b/src/librustc_codegen_ssa/traits/intrinsic.rs
@@ -1,6 +1,6 @@
 use super::BackendTypes;
 use crate::mir::operand::OperandRef;
-use rustc::ty::{self, Ty};
+use rustc_middle::ty::{self, Ty};
 use rustc_span::Span;
 use rustc_target::abi::call::FnAbi;
 
diff --git a/src/librustc_codegen_ssa/traits/misc.rs b/src/librustc_codegen_ssa/traits/misc.rs
index 6863b474cb6..beff9eae859 100644
--- a/src/librustc_codegen_ssa/traits/misc.rs
+++ b/src/librustc_codegen_ssa/traits/misc.rs
@@ -1,7 +1,7 @@
 use super::BackendTypes;
-use rustc::mir::mono::CodegenUnit;
-use rustc::ty::{self, Instance, Ty};
 use rustc_data_structures::fx::FxHashMap;
+use rustc_middle::mir::mono::CodegenUnit;
+use rustc_middle::ty::{self, Instance, Ty};
 use rustc_session::Session;
 use std::cell::RefCell;
 use std::sync::Arc;
diff --git a/src/librustc_codegen_ssa/traits/mod.rs b/src/librustc_codegen_ssa/traits/mod.rs
index 1bc9f297ea1..f4c09a33285 100644
--- a/src/librustc_codegen_ssa/traits/mod.rs
+++ b/src/librustc_codegen_ssa/traits/mod.rs
@@ -42,7 +42,7 @@ pub use self::type_::{
 };
 pub use self::write::{ModuleBufferMethods, ThinBufferMethods, WriteBackendMethods};
 
-use rustc::ty::layout::{HasParamEnv, HasTyCtxt};
+use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt};
 use rustc_target::spec::HasTargetSpec;
 
 use std::fmt;
diff --git a/src/librustc_codegen_ssa/traits/statics.rs b/src/librustc_codegen_ssa/traits/statics.rs
index 40c9dde98c6..a6462b35834 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::ty::layout::Align;
 use rustc_hir::def_id::DefId;
+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 0d644e6dd30..703479b74be 100644
--- a/src/librustc_codegen_ssa/traits/type_.rs
+++ b/src/librustc_codegen_ssa/traits/type_.rs
@@ -3,10 +3,11 @@ use super::Backend;
 use super::HasCodegen;
 use crate::common::TypeKind;
 use crate::mir::place::PlaceRef;
-use rustc::ty::layout::{self, TyLayout};
-use rustc::ty::{self, Ty};
+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 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
         }
     }
 
-    fn type_from_integer(&self, i: layout::Integer) -> Self::Type {
-        use rustc::ty::layout::Integer::*;
+    fn type_from_integer(&self, i: Integer) -> Self::Type {
+        use Integer::*;
         match i {
             I8 => self.type_i8(),
             I16 => self.type_i16(),
@@ -94,17 +95,17 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
 impl<T> DerivedTypeMethods<'tcx> for T where Self: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {}
 
 pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
-    fn backend_type(&self, layout: TyLayout<'tcx>) -> Self::Type;
+    fn backend_type(&self, layout: TyAndLayout<'tcx>) -> Self::Type;
     fn cast_backend_type(&self, ty: &CastTarget) -> Self::Type;
     fn fn_ptr_backend_type(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Self::Type;
     fn reg_backend_type(&self, ty: &Reg) -> Self::Type;
-    fn immediate_backend_type(&self, layout: TyLayout<'tcx>) -> Self::Type;
-    fn is_backend_immediate(&self, layout: TyLayout<'tcx>) -> bool;
-    fn is_backend_scalar_pair(&self, layout: TyLayout<'tcx>) -> bool;
-    fn backend_field_index(&self, layout: TyLayout<'tcx>, index: usize) -> u64;
+    fn immediate_backend_type(&self, layout: TyAndLayout<'tcx>) -> Self::Type;
+    fn is_backend_immediate(&self, layout: TyAndLayout<'tcx>) -> bool;
+    fn is_backend_scalar_pair(&self, layout: TyAndLayout<'tcx>) -> bool;
+    fn backend_field_index(&self, layout: TyAndLayout<'tcx>, index: usize) -> u64;
     fn scalar_pair_element_backend_type(
         &self,
-        layout: TyLayout<'tcx>,
+        layout: TyAndLayout<'tcx>,
         index: usize,
         immediate: bool,
     ) -> Self::Type;
diff --git a/src/librustc_codegen_ssa/traits/write.rs b/src/librustc_codegen_ssa/traits/write.rs
index 382dc14e789..27d52e9b9c5 100644
--- a/src/librustc_codegen_ssa/traits/write.rs
+++ b/src/librustc_codegen_ssa/traits/write.rs
@@ -2,8 +2,8 @@ use crate::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
 use crate::back::write::{CodegenContext, FatLTOInput, ModuleConfig};
 use crate::{CompiledModule, ModuleCodegen};
 
-use rustc::dep_graph::WorkProduct;
 use rustc_errors::{FatalError, Handler};
+use rustc_middle::dep_graph::WorkProduct;
 
 pub trait WriteBackendMethods: 'static + Sized + Clone {
     type Module: Send + Sync;
diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs
index f9f8ff5303e..ba82e58d7a9 100644
--- a/src/librustc_data_structures/lib.rs
+++ b/src/librustc_data_structures/lib.rs
@@ -114,6 +114,6 @@ impl<F: Fn()> Drop for OnDrop<F> {
     }
 }
 
-// See comments in src/librustc/lib.rs
+// See comments in src/librustc_middle/lib.rs
 #[doc(hidden)]
 pub fn __noop_fix_for_27438() {}
diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml
index 3ca39b24c52..652f16c2e08 100644
--- a/src/librustc_driver/Cargo.toml
+++ b/src/librustc_driver/Cargo.toml
@@ -13,7 +13,7 @@ crate-type = ["dylib"]
 lazy_static = "1.0"
 log = "0.4"
 env_logger = { version = "0.7", default-features = false }
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc_ast_pretty = { path = "../librustc_ast_pretty" }
 rustc_target = { path = "../librustc_target" }
 rustc_lint = { path = "../librustc_lint" }
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 9097a72f36f..ccbce01d6c1 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -18,23 +18,20 @@ extern crate lazy_static;
 
 pub extern crate rustc_plugin_impl as plugin;
 
-use rustc::middle::cstore::MetadataLoader;
-use rustc::ty::TyCtxt;
-use rustc::util::common::ErrorReported;
 use rustc_ast::ast;
 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};
 use rustc_interface::{interface, Queries};
 use rustc_lint::LintStore;
 use rustc_metadata::locator;
+use rustc_middle::middle::cstore::MetadataLoader;
+use rustc_middle::ty::TyCtxt;
 use rustc_save_analysis as save;
 use rustc_save_analysis::DumpHandler;
 use rustc_serialize::json::{self, ToJson};
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index a57a70e6b8c..78a271810b2 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -1,13 +1,13 @@
 //! The various pretty-printing routines.
 
-use rustc::hir::map as hir_map;
-use rustc::ty::{self, TyCtxt};
-use rustc::util::common::ErrorReported;
 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_mir::util::{write_mir_graphviz, write_mir_pretty};
 use rustc_session::config::{Input, PpMode, PpSourceMode};
 use rustc_session::Session;
@@ -177,9 +177,8 @@ impl<'hir> PrinterSupport for IdentifiedAnnotation<'hir> {
 
 impl<'hir> pprust::PpAnn for IdentifiedAnnotation<'hir> {
     fn pre(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) {
-        match node {
-            pprust::AnnNode::Expr(_) => s.popen(),
-            _ => {}
+        if let pprust::AnnNode::Expr(_) = node {
+            s.popen();
         }
     }
     fn post(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) {
@@ -232,9 +231,8 @@ impl<'hir> pprust_hir::PpAnn for IdentifiedAnnotation<'hir> {
         }
     }
     fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) {
-        match node {
-            pprust_hir::AnnNode::Expr(_) => s.popen(),
-            _ => {}
+        if let pprust_hir::AnnNode::Expr(_) = node {
+            s.popen();
         }
     }
     fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) {
@@ -339,21 +337,17 @@ impl<'a, 'tcx> pprust_hir::PpAnn for TypedAnnotation<'a, 'tcx> {
         self.tables.set(old_tables);
     }
     fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) {
-        match node {
-            pprust_hir::AnnNode::Expr(_) => s.popen(),
-            _ => {}
+        if let pprust_hir::AnnNode::Expr(_) = node {
+            s.popen();
         }
     }
     fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) {
-        match node {
-            pprust_hir::AnnNode::Expr(expr) => {
-                s.s.space();
-                s.s.word("as");
-                s.s.space();
-                s.s.word(self.tables.get().expr_ty(expr).to_string());
-                s.pclose();
-            }
-            _ => {}
+        if let pprust_hir::AnnNode::Expr(expr) = node {
+            s.s.space();
+            s.s.word("as");
+            s.s.space();
+            s.s.word(self.tables.get().expr_ty(expr).to_string());
+            s.pclose();
         }
     }
 }
diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs
index 2f0a3fc1d1c..6e690655f60 100644
--- a/src/librustc_error_codes/error_codes.rs
+++ b/src/librustc_error_codes/error_codes.rs
@@ -119,6 +119,7 @@ E0222: include_str!("./error_codes/E0222.md"),
 E0223: include_str!("./error_codes/E0223.md"),
 E0224: include_str!("./error_codes/E0224.md"),
 E0225: include_str!("./error_codes/E0225.md"),
+E0226: include_str!("./error_codes/E0226.md"),
 E0229: include_str!("./error_codes/E0229.md"),
 E0230: include_str!("./error_codes/E0230.md"),
 E0231: include_str!("./error_codes/E0231.md"),
@@ -475,7 +476,6 @@ E0751: include_str!("./error_codes/E0751.md"),
 //  E0217, // ambiguous associated type, defined in multiple supertraits
 //  E0218, // no associated type defined
 //  E0219, // associated type defined in higher-ranked supertrait
-    E0226, // only a single explicit lifetime bound is permitted
     E0227, // ambiguous lifetime bound, explicit lifetime bound required
     E0228, // explicit lifetime bound required
 //  E0233,
diff --git a/src/librustc_error_codes/error_codes/E0226.md b/src/librustc_error_codes/error_codes/E0226.md
new file mode 100644
index 00000000000..4e65132ff0d
--- /dev/null
+++ b/src/librustc_error_codes/error_codes/E0226.md
@@ -0,0 +1,21 @@
+More than one explicit lifetime bound was used on a trait object.
+
+Example of erroneous code:
+
+```compile_fail,E0226
+trait Foo {}
+
+type T<'a, 'b> = dyn Foo + 'a + 'b; // error: Trait object `arg` has two
+                                    //        lifetime bound, 'a and 'b.
+```
+
+Here `T` is a trait object with two explicit lifetime bounds, 'a and 'b.
+
+Only a single explicit lifetime bound is permitted on trait objects.
+To fix this error, consider removing one of the lifetime bounds:
+
+```
+trait Foo {}
+
+type T<'a> = dyn Foo + 'a;
+```
diff --git a/src/librustc_error_codes/error_codes/E0264.md b/src/librustc_error_codes/error_codes/E0264.md
index 708eac8837a..e2a27f7b106 100644
--- a/src/librustc_error_codes/error_codes/E0264.md
+++ b/src/librustc_error_codes/error_codes/E0264.md
@@ -12,7 +12,7 @@ extern "C" {
 ```
 
 A list of available external lang items is available in
-`src/librustc/middle/weak_lang_items.rs`. Example:
+`src/librustc_middle/middle/weak_lang_items.rs`. Example:
 
 ```
 #![feature(lang_items)]
diff --git a/src/librustc_error_codes/error_codes/E0466.md b/src/librustc_error_codes/error_codes/E0466.md
index 443b7bae134..7aefedbc087 100644
--- a/src/librustc_error_codes/error_codes/E0466.md
+++ b/src/librustc_error_codes/error_codes/E0466.md
@@ -1,4 +1,4 @@
-Macro import declarations were malformed.
+Macro import declaration was malformed.
 
 Erroneous code examples:
 
diff --git a/src/librustc_error_codes/error_codes/E0468.md b/src/librustc_error_codes/error_codes/E0468.md
index 73e3ebb949a..cf8664718fa 100644
--- a/src/librustc_error_codes/error_codes/E0468.md
+++ b/src/librustc_error_codes/error_codes/E0468.md
@@ -1,4 +1,4 @@
-A non-root module attempts to import macros from another crate.
+A non-root module tried to import macros from another crate.
 
 Example of erroneous code:
 
@@ -17,7 +17,7 @@ Either move the macro import to crate root or do without the foreign macros.
 This will work:
 
 ```
-#[macro_use(debug_assert)]
+#[macro_use(debug_assert)] // ok!
 extern crate core;
 
 mod foo {
diff --git a/src/librustc_error_codes/error_codes/E0502.md b/src/librustc_error_codes/error_codes/E0502.md
index f15c05d558d..b90c59f5807 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_error_codes/error_codes/E0730.md b/src/librustc_error_codes/error_codes/E0730.md
index bf1f72be325..c2a71ca5669 100644
--- a/src/librustc_error_codes/error_codes/E0730.md
+++ b/src/librustc_error_codes/error_codes/E0730.md
@@ -7,8 +7,8 @@ Example of erroneous code:
 
 fn is_123<const N: usize>(x: [u32; N]) -> bool {
     match x {
-        [1, 2, 3] => true, // error: cannot pattern-match on an
-                           //        array without a fixed length
+        [1, 2, ..] => true, // error: cannot pattern-match on an
+                            //        array without a fixed length
         _ => false
     }
 }
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 94053b98cd7..3a7e108ddaf 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -1719,7 +1719,7 @@ impl EmitterWriter {
                 if !self.short_message {
                     for child in children {
                         let span = child.render_span.as_ref().unwrap_or(&child.span);
-                        match self.emit_message_default(
+                        if let Err(err) = self.emit_message_default(
                             &span,
                             &child.styled_message(),
                             &None,
@@ -1727,15 +1727,14 @@ impl EmitterWriter {
                             max_line_num_len,
                             true,
                         ) {
-                            Err(e) => panic!("failed to emit error: {}", e),
-                            _ => (),
+                            panic!("failed to emit error: {}", err);
                         }
                     }
                     for sugg in suggestions {
                         if sugg.style == SuggestionStyle::CompletelyHidden {
                             // do not display this suggestion, it is meant only for tools
                         } else if sugg.style == SuggestionStyle::HideCodeAlways {
-                            match self.emit_message_default(
+                            if let Err(e) = self.emit_message_default(
                                 &MultiSpan::new(),
                                 &[(sugg.msg.to_owned(), Style::HeaderMsg)],
                                 &None,
@@ -1743,16 +1742,13 @@ impl EmitterWriter {
                                 max_line_num_len,
                                 true,
                             ) {
-                                Err(e) => panic!("failed to emit error: {}", e),
-                                _ => (),
+                                panic!("failed to emit error: {}", e);
                             }
-                        } else {
-                            match self.emit_suggestion_default(sugg, &Level::Help, max_line_num_len)
-                            {
-                                Err(e) => panic!("failed to emit error: {}", e),
-                                _ => (),
-                            }
-                        }
+                        } else if let Err(e) =
+                            self.emit_suggestion_default(sugg, &Level::Help, max_line_num_len)
+                        {
+                            panic!("failed to emit error: {}", e);
+                        };
                     }
                 }
             }
@@ -1762,10 +1758,11 @@ impl EmitterWriter {
         let mut dst = self.dst.writable();
         match writeln!(dst) {
             Err(e) => panic!("failed to emit error: {}", e),
-            _ => match dst.flush() {
-                Err(e) => panic!("failed to emit error: {}", e),
-                _ => (),
-            },
+            _ => {
+                if let Err(e) = dst.flush() {
+                    panic!("failed to emit error: {}", e)
+                }
+            }
         }
     }
 }
@@ -2149,11 +2146,8 @@ impl<'a> Write for WritableDst<'a> {
 
 impl<'a> Drop for WritableDst<'a> {
     fn drop(&mut self) {
-        match *self {
-            WritableDst::Buffered(ref mut dst, ref mut buf) => {
-                drop(dst.print(buf));
-            }
-            _ => {}
+        if let WritableDst::Buffered(ref mut dst, ref mut buf) = self {
+            drop(dst.print(buf));
         }
     }
 }
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 6157c46f80c..204fea58c95 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -425,7 +425,7 @@ impl Handler {
     }
 
     // This is here to not allow mutation of flags;
-    // as of this writing it's only used in tests in librustc.
+    // as of this writing it's only used in tests in librustc_middle.
     pub fn can_emit_warnings(&self) -> bool {
         self.flags.can_emit_warnings
     }
diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs
index 0e70fdbd9c1..7d2c4fbf7af 100644
--- a/src/librustc_expand/mbe/macro_rules.rs
+++ b/src/librustc_expand/mbe/macro_rules.rs
@@ -354,20 +354,19 @@ fn generic_extension<'cx>(
                 mbe::TokenTree::Delimited(_, ref delim) => &delim.tts[..],
                 _ => continue,
             };
-            match parse_tt(&mut Cow::Borrowed(&parser_from_cx(sess, arg.clone())), lhs_tt) {
-                Success(_) => {
-                    if comma_span.is_dummy() {
-                        err.note("you might be missing a comma");
-                    } else {
-                        err.span_suggestion_short(
-                            comma_span,
-                            "missing comma here",
-                            ", ".to_string(),
-                            Applicability::MachineApplicable,
-                        );
-                    }
+            if let Success(_) =
+                parse_tt(&mut Cow::Borrowed(&parser_from_cx(sess, arg.clone())), lhs_tt)
+            {
+                if comma_span.is_dummy() {
+                    err.note("you might be missing a comma");
+                } else {
+                    err.span_suggestion_short(
+                        comma_span,
+                        "missing comma here",
+                        ", ".to_string(),
+                        Applicability::MachineApplicable,
+                    );
                 }
-                _ => {}
             }
         }
     }
diff --git a/src/librustc_feature/builtin_attrs.rs b/src/librustc_feature/builtin_attrs.rs
index 2e89f36fea2..e4975aae6b9 100644
--- a/src/librustc_feature/builtin_attrs.rs
+++ b/src/librustc_feature/builtin_attrs.rs
@@ -220,7 +220,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     // ABI, linking, symbols, and FFI
     ungated!(
         link, Whitelisted,
-        template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ cfg = "...""#),
+        template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...""#),
     ),
     ungated!(link_name, Whitelisted, template!(NameValueStr: "name")),
     ungated!(no_link, Normal, template!(Word)),
diff --git a/src/librustc_hir/intravisit.rs b/src/librustc_hir/intravisit.rs
index 5a763e4161b..c8f3edcbda0 100644
--- a/src/librustc_hir/intravisit.rs
+++ b/src/librustc_hir/intravisit.rs
@@ -119,7 +119,7 @@ impl<'a> FnKind<'a> {
     }
 }
 
-/// An abstract representation of the HIR `rustc::hir::map::Map`.
+/// An abstract representation of the HIR `rustc_middle::hir::map::Map`.
 pub trait Map<'hir> {
     /// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
     fn find(&self, hir_id: HirId) -> Option<Node<'hir>>;
diff --git a/src/librustc_hir/stable_hash_impls.rs b/src/librustc_hir/stable_hash_impls.rs
index 996b3108969..1d3f44a0899 100644
--- a/src/librustc_hir/stable_hash_impls.rs
+++ b/src/librustc_hir/stable_hash_impls.rs
@@ -9,7 +9,7 @@ use rustc_span::def_id::{DefPathHash, LocalDefId};
 
 /// Requirements for a `StableHashingContext` to be used in this crate.
 /// This is a hack to allow using the `HashStable_Generic` derive macro
-/// instead of implementing everything in librustc.
+/// instead of implementing everything in librustc_middle.
 pub trait HashStableContext:
     rustc_ast::HashStableContext + rustc_target::HashStableContext
 {
diff --git a/src/librustc_hir_pretty/lib.rs b/src/librustc_hir_pretty/lib.rs
index f30af78659f..8ba14ab5d0b 100644
--- a/src/librustc_hir_pretty/lib.rs
+++ b/src/librustc_hir_pretty/lib.rs
@@ -2036,13 +2036,10 @@ impl<'a> State<'a> {
             }
             GenericParamKind::Type { ref default, .. } => {
                 self.print_bounds(":", param.bounds);
-                match default {
-                    Some(default) => {
-                        self.s.space();
-                        self.word_space("=");
-                        self.print_type(&default)
-                    }
-                    _ => {}
+                if let Some(default) = default {
+                    self.s.space();
+                    self.word_space("=");
+                    self.print_type(&default)
                 }
             }
             GenericParamKind::Const { ref ty } => {
@@ -2145,9 +2142,8 @@ impl<'a> State<'a> {
         }
         self.end();
 
-        match decl.output {
-            hir::FnRetTy::Return(ref output) => self.maybe_print_comment(output.span.lo()),
-            _ => {}
+        if let hir::FnRetTy::Return(ref output) = decl.output {
+            self.maybe_print_comment(output.span.lo())
         }
     }
 
@@ -2222,12 +2218,9 @@ impl<'a> State<'a> {
     }
 
     pub fn print_extern_opt_abi(&mut self, opt_abi: Option<Abi>) {
-        match opt_abi {
-            Some(abi) => {
-                self.word_nbsp("extern");
-                self.word_nbsp(abi.to_string())
-            }
-            None => {}
+        if let Some(abi) = opt_abi {
+            self.word_nbsp("extern");
+            self.word_nbsp(abi.to_string())
         }
     }
 
diff --git a/src/librustc_incremental/Cargo.toml b/src/librustc_incremental/Cargo.toml
index eddfb81ea8b..5caf1d411e6 100644
--- a/src/librustc_incremental/Cargo.toml
+++ b/src/librustc_incremental/Cargo.toml
@@ -13,7 +13,7 @@ doctest = false
 graphviz = { path = "../libgraphviz" }
 log = "0.4"
 rand = "0.7"
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_hir = { path = "../librustc_hir" }
 rustc_serialize = { path = "../libserialize", package = "serialize" }
diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs
index 305e0fcc383..5135820ac50 100644
--- a/src/librustc_incremental/assert_dep_graph.rs
+++ b/src/librustc_incremental/assert_dep_graph.rs
@@ -34,16 +34,16 @@
 //! ```
 
 use graphviz as dot;
-use rustc::dep_graph::debug::{DepNodeFilter, EdgeFilter};
-use rustc::dep_graph::{DepGraphQuery, DepKind, DepNode, DepNodeExt};
-use rustc::hir::map::Map;
-use rustc::ty::TyCtxt;
 use rustc_ast::ast;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::graph::implementation::{Direction, NodeIndex, INCOMING, OUTGOING};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
+use rustc_middle::dep_graph::debug::{DepNodeFilter, EdgeFilter};
+use rustc_middle::dep_graph::{DepGraphQuery, DepKind, DepNode, DepNodeExt};
+use rustc_middle::hir::map::Map;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 
diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs
index c5446116f4c..856edb3725a 100644
--- a/src/librustc_incremental/assert_module_sources.rs
+++ b/src/librustc_incremental/assert_module_sources.rs
@@ -21,10 +21,10 @@
 //! allows for doing a more fine-grained check to see if pre- or post-lto data
 //! was re-used.
 
-use rustc::mir::mono::CodegenUnitNameBuilder;
-use rustc::ty::TyCtxt;
 use rustc_ast::ast;
 use rustc_hir::def_id::LOCAL_CRATE;
+use rustc_middle::mir::mono::CodegenUnitNameBuilder;
+use rustc_middle::ty::TyCtxt;
 use rustc_session::cgu_reuse_tracker::*;
 use rustc_span::symbol::{sym, Symbol};
 use std::collections::BTreeSet;
diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs
index ca824fde7ef..dd715c6c81d 100644
--- a/src/librustc_incremental/lib.rs
+++ b/src/librustc_incremental/lib.rs
@@ -6,7 +6,7 @@
 #![recursion_limit = "256"]
 
 #[macro_use]
-extern crate rustc;
+extern crate rustc_middle;
 #[macro_use]
 extern crate log;
 
diff --git a/src/librustc_incremental/persist/data.rs b/src/librustc_incremental/persist/data.rs
index 49b4bb06114..ea0fd4eb7ee 100644
--- a/src/librustc_incremental/persist/data.rs
+++ b/src/librustc_incremental/persist/data.rs
@@ -1,6 +1,6 @@
 //! The data that we will serialize and deserialize.
 
-use rustc::dep_graph::{WorkProduct, WorkProductId};
+use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
 
 #[derive(Debug, RustcEncodable, RustcDecodable)]
 pub struct SerializedWorkProduct {
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index 9ddd238afff..804d1744d68 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -13,9 +13,6 @@
 //! Errors are reported if we are in the suitable configuration but
 //! the required condition is not met.
 
-use rustc::dep_graph::{label_strs, DepNode, DepNodeExt};
-use rustc::hir::map::Map;
-use rustc::ty::TyCtxt;
 use rustc_ast::ast::{self, Attribute, NestedMetaItem};
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxHashSet;
@@ -25,6 +22,9 @@ use rustc_hir::intravisit;
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_hir::Node as HirNode;
 use rustc_hir::{ImplItemKind, ItemKind as HirItem, TraitItemKind};
+use rustc_middle::dep_graph::{label_strs, DepNode, DepNodeExt};
+use rustc_middle::hir::map::Map;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
 use std::iter::FromIterator;
@@ -306,7 +306,7 @@ impl DirtyCleanVisitor<'tcx> {
                     // michaelwoerister and vitiral came up with a possible solution,
                     // to just do this before every query
                     // ```
-                    // ::rustc::ty::query::plumbing::force_from_dep_node(tcx, dep_node)
+                    // ::rustc_middle::ty::query::plumbing::force_from_dep_node(tcx, dep_node)
                     // ```
                     //
                     // However, this did not seem to work effectively and more bugs were hit.
diff --git a/src/librustc_incremental/persist/load.rs b/src/librustc_incremental/persist/load.rs
index 537906eb871..b75a428c62a 100644
--- a/src/librustc_incremental/persist/load.rs
+++ b/src/librustc_incremental/persist/load.rs
@@ -1,9 +1,9 @@
 //! Code to save/load the dep-graph from files.
 
-use rustc::dep_graph::{PreviousDepGraph, SerializedDepGraph, WorkProduct, WorkProductId};
-use rustc::ty::query::OnDiskCache;
-use rustc::ty::TyCtxt;
 use rustc_data_structures::fx::FxHashMap;
+use rustc_middle::dep_graph::{PreviousDepGraph, SerializedDepGraph, WorkProduct, WorkProductId};
+use rustc_middle::ty::query::OnDiskCache;
+use rustc_middle::ty::TyCtxt;
 use rustc_serialize::opaque::Decoder;
 use rustc_serialize::Decodable as RustcDecodable;
 use rustc_session::Session;
diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs
index 17dbad5c8bb..6d4ba45c2e6 100644
--- a/src/librustc_incremental/persist/save.rs
+++ b/src/librustc_incremental/persist/save.rs
@@ -1,7 +1,7 @@
-use rustc::dep_graph::{DepGraph, DepKind, WorkProduct, WorkProductId};
-use rustc::ty::TyCtxt;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::join;
+use rustc_middle::dep_graph::{DepGraph, DepKind, WorkProduct, WorkProductId};
+use rustc_middle::ty::TyCtxt;
 use rustc_serialize::opaque::Encoder;
 use rustc_serialize::Encodable as RustcEncodable;
 use rustc_session::Session;
diff --git a/src/librustc_incremental/persist/work_product.rs b/src/librustc_incremental/persist/work_product.rs
index aa3588b284b..4dd81b1df57 100644
--- a/src/librustc_incremental/persist/work_product.rs
+++ b/src/librustc_incremental/persist/work_product.rs
@@ -1,8 +1,8 @@
 //! This module contains files for saving intermediate work-products.
 
 use crate::persist::fs::*;
-use rustc::dep_graph::{WorkProduct, WorkProductFileKind, WorkProductId};
 use rustc_fs_util::link_or_copy;
+use rustc_middle::dep_graph::{WorkProduct, WorkProductFileKind, WorkProductId};
 use rustc_session::Session;
 use std::fs as std_fs;
 use std::path::PathBuf;
diff --git a/src/librustc_infer/Cargo.toml b/src/librustc_infer/Cargo.toml
index 9ecd056430c..bc4080ac6c8 100644
--- a/src/librustc_infer/Cargo.toml
+++ b/src/librustc_infer/Cargo.toml
@@ -12,7 +12,7 @@ doctest = false
 [dependencies]
 graphviz = { path = "../libgraphviz" }
 log = { version = "0.4", features = ["release_max_level_info", "std"] }
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors" }
 rustc_hir = { path = "../librustc_hir" }
diff --git a/src/librustc_infer/infer/at.rs b/src/librustc_infer/infer/at.rs
index 04f5b03c0e1..5c62a1298b9 100644
--- a/src/librustc_infer/infer/at.rs
+++ b/src/librustc_infer/infer/at.rs
@@ -27,8 +27,8 @@
 
 use super::*;
 
-use rustc::ty::relate::{Relate, TypeRelation};
-use rustc::ty::Const;
+use rustc_middle::ty::relate::{Relate, TypeRelation};
+use rustc_middle::ty::Const;
 
 pub struct At<'a, 'tcx> {
     pub infcx: &'a InferCtxt<'a, 'tcx>,
diff --git a/src/librustc_infer/infer/canonical/canonicalizer.rs b/src/librustc_infer/infer/canonical/canonicalizer.rs
index 4d9a81d4406..347a5ff6d56 100644
--- a/src/librustc_infer/infer/canonical/canonicalizer.rs
+++ b/src/librustc_infer/infer/canonical/canonicalizer.rs
@@ -10,10 +10,10 @@ use crate::infer::canonical::{
     OriginalQueryValues,
 };
 use crate::infer::InferCtxt;
-use rustc::ty::flags::FlagComputation;
-use rustc::ty::fold::{TypeFoldable, TypeFolder};
-use rustc::ty::subst::GenericArg;
-use rustc::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags};
+use rustc_middle::ty::flags::FlagComputation;
+use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
+use rustc_middle::ty::subst::GenericArg;
+use rustc_middle::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags};
 use std::sync::atomic::Ordering;
 
 use rustc_data_structures::fx::FxHashMap;
diff --git a/src/librustc_infer/infer/canonical/mod.rs b/src/librustc_infer/infer/canonical/mod.rs
index 0e9593e8ea6..b7890cf9e92 100644
--- a/src/librustc_infer/infer/canonical/mod.rs
+++ b/src/librustc_infer/infer/canonical/mod.rs
@@ -23,13 +23,13 @@
 
 use crate::infer::{ConstVariableOrigin, ConstVariableOriginKind};
 use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVariableOriginKind};
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::subst::GenericArg;
-use rustc::ty::{self, BoundVar, List};
 use rustc_index::vec::IndexVec;
+use rustc_middle::ty::fold::TypeFoldable;
+use rustc_middle::ty::subst::GenericArg;
+use rustc_middle::ty::{self, BoundVar, List};
 use rustc_span::source_map::Span;
 
-pub use rustc::infer::canonical::*;
+pub use rustc_middle::infer::canonical::*;
 use substitute::CanonicalExt;
 
 mod canonicalizer;
diff --git a/src/librustc_infer/infer/canonical/query_response.rs b/src/librustc_infer/infer/canonical/query_response.rs
index 9322df48235..79a0a507624 100644
--- a/src/librustc_infer/infer/canonical/query_response.rs
+++ b/src/librustc_infer/infer/canonical/query_response.rs
@@ -18,14 +18,14 @@ use crate::infer::{InferCtxt, InferOk, InferResult, NLLRegionVariableOrigin};
 use crate::traits::query::{Fallible, NoSolution};
 use crate::traits::{DomainGoal, TraitEngine};
 use crate::traits::{Obligation, ObligationCause, PredicateObligation};
-use rustc::arena::ArenaAllocatable;
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::relate::TypeRelation;
-use rustc::ty::subst::{GenericArg, GenericArgKind};
-use rustc::ty::{self, BoundVar, Ty, TyCtxt};
 use rustc_data_structures::captures::Captures;
 use rustc_index::vec::Idx;
 use rustc_index::vec::IndexVec;
+use rustc_middle::arena::ArenaAllocatable;
+use rustc_middle::ty::fold::TypeFoldable;
+use rustc_middle::ty::relate::TypeRelation;
+use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
+use rustc_middle::ty::{self, BoundVar, Ty, TyCtxt};
 use std::fmt::Debug;
 
 impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
diff --git a/src/librustc_infer/infer/canonical/substitute.rs b/src/librustc_infer/infer/canonical/substitute.rs
index afef32c1ffe..55609c080ac 100644
--- a/src/librustc_infer/infer/canonical/substitute.rs
+++ b/src/librustc_infer/infer/canonical/substitute.rs
@@ -7,9 +7,9 @@
 //! [c]: https://rustc-dev-guide.rust-lang.org/traits/canonicalization.html
 
 use crate::infer::canonical::{Canonical, CanonicalVarValues};
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::subst::GenericArgKind;
-use rustc::ty::{self, TyCtxt};
+use rustc_middle::ty::fold::TypeFoldable;
+use rustc_middle::ty::subst::GenericArgKind;
+use rustc_middle::ty::{self, TyCtxt};
 
 pub(super) trait CanonicalExt<'tcx, V> {
     /// Instantiate the wrapped value, replacing each canonical value
diff --git a/src/librustc_infer/infer/combine.rs b/src/librustc_infer/infer/combine.rs
index 0f5d4d30a23..c630f58abf9 100644
--- a/src/librustc_infer/infer/combine.rs
+++ b/src/librustc_infer/infer/combine.rs
@@ -34,13 +34,13 @@ use super::{InferCtxt, MiscVariable, TypeTrace};
 
 use crate::traits::{Obligation, PredicateObligations};
 
-use rustc::ty::error::TypeError;
-use rustc::ty::relate::{self, Relate, RelateResult, TypeRelation};
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::{self, InferConst, Ty, TyCtxt};
-use rustc::ty::{IntType, UintType};
 use rustc_ast::ast;
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty::error::TypeError;
+use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
+use rustc_middle::ty::subst::SubstsRef;
+use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
+use rustc_middle::ty::{IntType, UintType};
 use rustc_span::{Span, DUMMY_SP};
 
 #[derive(Clone)]
diff --git a/src/librustc_infer/infer/equate.rs b/src/librustc_infer/infer/equate.rs
index 8f8fc4f137b..e05094cda27 100644
--- a/src/librustc_infer/infer/equate.rs
+++ b/src/librustc_infer/infer/equate.rs
@@ -1,10 +1,10 @@
 use super::combine::{CombineFields, RelationDir};
 use super::Subtype;
 
-use rustc::ty::relate::{self, Relate, RelateResult, TypeRelation};
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::TyVar;
-use rustc::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
+use rustc_middle::ty::subst::SubstsRef;
+use rustc_middle::ty::TyVar;
+use rustc_middle::ty::{self, Ty, TyCtxt};
 
 use rustc_hir::def_id::DefId;
 
diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs
index 129bc9e22a6..925f92edd7d 100644
--- a/src/librustc_infer/infer/error_reporting/mod.rs
+++ b/src/librustc_infer/infer/error_reporting/mod.rs
@@ -55,19 +55,19 @@ use crate::traits::{
     IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
 };
 
-use rustc::middle::region;
-use rustc::ty::error::TypeError;
-use rustc::ty::{
-    self,
-    subst::{Subst, SubstsRef},
-    Region, Ty, TyCtxt, TypeFoldable,
-};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{pluralize, struct_span_err};
 use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::Node;
+use rustc_middle::middle::region;
+use rustc_middle::ty::error::TypeError;
+use rustc_middle::ty::{
+    self,
+    subst::{Subst, SubstsRef},
+    Region, Ty, TyCtxt, TypeFoldable,
+};
 use rustc_span::{DesugaringKind, Pos, Span};
 use rustc_target::spec::abi;
 use std::{cmp, fmt};
@@ -1386,13 +1386,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
         // For some types of errors, expected-found does not make
         // sense, so just ignore the values we were given.
-        match terr {
-            TypeError::CyclicTy(_) => {
-                values = None;
-            }
-            _ => {}
+        if let TypeError::CyclicTy(_) = terr {
+            values = None;
         }
-
         struct OpaqueTypesVisitor<'tcx> {
             types: FxHashMap<TyCategory, FxHashSet<Span>>,
             expected: FxHashMap<TyCategory, FxHashSet<Span>>,
@@ -1613,60 +1609,57 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         exp_found: &ty::error::ExpectedFound<Ty<'tcx>>,
         diag: &mut DiagnosticBuilder<'tcx>,
     ) {
-        match (&exp_found.expected.kind, &exp_found.found.kind) {
-            (ty::Adt(exp_def, exp_substs), ty::Ref(_, found_ty, _)) => {
-                if let ty::Adt(found_def, found_substs) = found_ty.kind {
-                    let path_str = format!("{:?}", exp_def);
-                    if exp_def == &found_def {
-                        let opt_msg = "you can convert from `&Option<T>` to `Option<&T>` using \
+        if let (ty::Adt(exp_def, exp_substs), ty::Ref(_, found_ty, _)) =
+            (&exp_found.expected.kind, &exp_found.found.kind)
+        {
+            if let ty::Adt(found_def, found_substs) = found_ty.kind {
+                let path_str = format!("{:?}", exp_def);
+                if exp_def == &found_def {
+                    let opt_msg = "you can convert from `&Option<T>` to `Option<&T>` using \
                                        `.as_ref()`";
-                        let result_msg = "you can convert from `&Result<T, E>` to \
+                    let result_msg = "you can convert from `&Result<T, E>` to \
                                           `Result<&T, &E>` using `.as_ref()`";
-                        let have_as_ref = &[
-                            ("std::option::Option", opt_msg),
-                            ("core::option::Option", opt_msg),
-                            ("std::result::Result", result_msg),
-                            ("core::result::Result", result_msg),
-                        ];
-                        if let Some(msg) = have_as_ref
-                            .iter()
-                            .filter_map(
-                                |(path, msg)| if &path_str == path { Some(msg) } else { None },
-                            )
-                            .next()
-                        {
-                            let mut show_suggestion = true;
-                            for (exp_ty, found_ty) in exp_substs.types().zip(found_substs.types()) {
-                                match exp_ty.kind {
-                                    ty::Ref(_, exp_ty, _) => {
-                                        match (&exp_ty.kind, &found_ty.kind) {
-                                            (_, ty::Param(_))
-                                            | (_, ty::Infer(_))
-                                            | (ty::Param(_), _)
-                                            | (ty::Infer(_), _) => {}
-                                            _ if ty::TyS::same_type(exp_ty, found_ty) => {}
-                                            _ => show_suggestion = false,
-                                        };
-                                    }
-                                    ty::Param(_) | ty::Infer(_) => {}
-                                    _ => show_suggestion = false,
+                    let have_as_ref = &[
+                        ("std::option::Option", opt_msg),
+                        ("core::option::Option", opt_msg),
+                        ("std::result::Result", result_msg),
+                        ("core::result::Result", result_msg),
+                    ];
+                    if let Some(msg) = have_as_ref
+                        .iter()
+                        .filter_map(|(path, msg)| if &path_str == path { Some(msg) } else { None })
+                        .next()
+                    {
+                        let mut show_suggestion = true;
+                        for (exp_ty, found_ty) in exp_substs.types().zip(found_substs.types()) {
+                            match exp_ty.kind {
+                                ty::Ref(_, exp_ty, _) => {
+                                    match (&exp_ty.kind, &found_ty.kind) {
+                                        (_, ty::Param(_))
+                                        | (_, ty::Infer(_))
+                                        | (ty::Param(_), _)
+                                        | (ty::Infer(_), _) => {}
+                                        _ if ty::TyS::same_type(exp_ty, found_ty) => {}
+                                        _ => show_suggestion = false,
+                                    };
                                 }
-                            }
-                            if let (Ok(snippet), true) =
-                                (self.tcx.sess.source_map().span_to_snippet(span), show_suggestion)
-                            {
-                                diag.span_suggestion(
-                                    span,
-                                    msg,
-                                    format!("{}.as_ref()", snippet),
-                                    Applicability::MachineApplicable,
-                                );
+                                ty::Param(_) | ty::Infer(_) => {}
+                                _ => show_suggestion = false,
                             }
                         }
+                        if let (Ok(snippet), true) =
+                            (self.tcx.sess.source_map().span_to_snippet(span), show_suggestion)
+                        {
+                            diag.span_suggestion(
+                                span,
+                                msg,
+                                format!("{}.as_ref()", snippet),
+                                Applicability::MachineApplicable,
+                            );
+                        }
                     }
                 }
             }
-            _ => {}
         }
     }
 
@@ -1955,42 +1948,41 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             "...",
         );
 
-        match (&sup_origin, &sub_origin) {
-            (&infer::Subtype(ref sup_trace), &infer::Subtype(ref sub_trace)) => {
-                debug!("report_sub_sup_conflict: var_origin={:?}", var_origin);
-                debug!("report_sub_sup_conflict: sub_region={:?}", sub_region);
-                debug!("report_sub_sup_conflict: sub_origin={:?}", sub_origin);
-                debug!("report_sub_sup_conflict: sup_region={:?}", sup_region);
-                debug!("report_sub_sup_conflict: sup_origin={:?}", sup_origin);
-                debug!("report_sub_sup_conflict: sup_trace={:?}", sup_trace);
-                debug!("report_sub_sup_conflict: sub_trace={:?}", sub_trace);
-                debug!("report_sub_sup_conflict: sup_trace.values={:?}", sup_trace.values);
-                debug!("report_sub_sup_conflict: sub_trace.values={:?}", sub_trace.values);
-
-                if let (Some((sup_expected, sup_found)), Some((sub_expected, sub_found))) =
-                    (self.values_str(&sup_trace.values), self.values_str(&sub_trace.values))
-                {
-                    if sub_expected == sup_expected && sub_found == sup_found {
-                        note_and_explain_region(
-                            self.tcx,
-                            region_scope_tree,
-                            &mut err,
-                            "...but the lifetime must also be valid for ",
-                            sub_region,
-                            "...",
-                        );
-                        err.span_note(
-                            sup_trace.cause.span,
-                            &format!("...so that the {}", sup_trace.cause.as_requirement_str()),
-                        );
+        if let (&infer::Subtype(ref sup_trace), &infer::Subtype(ref sub_trace)) =
+            (&sup_origin, &sub_origin)
+        {
+            debug!("report_sub_sup_conflict: var_origin={:?}", var_origin);
+            debug!("report_sub_sup_conflict: sub_region={:?}", sub_region);
+            debug!("report_sub_sup_conflict: sub_origin={:?}", sub_origin);
+            debug!("report_sub_sup_conflict: sup_region={:?}", sup_region);
+            debug!("report_sub_sup_conflict: sup_origin={:?}", sup_origin);
+            debug!("report_sub_sup_conflict: sup_trace={:?}", sup_trace);
+            debug!("report_sub_sup_conflict: sub_trace={:?}", sub_trace);
+            debug!("report_sub_sup_conflict: sup_trace.values={:?}", sup_trace.values);
+            debug!("report_sub_sup_conflict: sub_trace.values={:?}", sub_trace.values);
+
+            if let (Some((sup_expected, sup_found)), Some((sub_expected, sub_found))) =
+                (self.values_str(&sup_trace.values), self.values_str(&sub_trace.values))
+            {
+                if sub_expected == sup_expected && sub_found == sup_found {
+                    note_and_explain_region(
+                        self.tcx,
+                        region_scope_tree,
+                        &mut err,
+                        "...but the lifetime must also be valid for ",
+                        sub_region,
+                        "...",
+                    );
+                    err.span_note(
+                        sup_trace.cause.span,
+                        &format!("...so that the {}", sup_trace.cause.as_requirement_str()),
+                    );
 
-                        err.note_expected_found(&"", sup_expected, &"", sup_found);
-                        err.emit();
-                        return;
-                    }
+                    err.note_expected_found(&"", sup_expected, &"", sup_found);
+                    err.emit();
+                    return;
                 }
             }
-            _ => {}
         }
 
         self.note_region_origin(&mut err, &sup_origin);
diff --git a/src/librustc_infer/infer/error_reporting/need_type_info.rs b/src/librustc_infer/infer/error_reporting/need_type_info.rs
index fcbe938a8c7..7824855fe05 100644
--- a/src/librustc_infer/infer/error_reporting/need_type_info.rs
+++ b/src/librustc_infer/infer/error_reporting/need_type_info.rs
@@ -1,13 +1,13 @@
 use crate::infer::type_variable::TypeVariableOriginKind;
 use crate::infer::InferCtxt;
-use rustc::hir::map::Map;
-use rustc::ty::print::Print;
-use rustc::ty::{self, DefIdTree, Infer, Ty, TyVar};
 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Namespace};
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::{Body, Expr, ExprKind, FnRetTy, HirId, Local, Pat};
+use rustc_middle::hir::map::Map;
+use rustc_middle::ty::print::Print;
+use rustc_middle::ty::{self, DefIdTree, Infer, Ty, TyVar};
 use rustc_span::source_map::DesugaringKind;
 use rustc_span::symbol::kw;
 use rustc_span::Span;
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 689323ce483..d206a30d526 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::util::AnonymousParamInfo;
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
 use crate::infer::lexical_region_resolve::RegionResolutionError;
 use crate::infer::SubregionOrigin;
-use rustc::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/find_anon_type.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/find_anon_type.rs
index 15acf632b2c..53cab34cd3f 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/find_anon_type.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/find_anon_type.rs
@@ -1,10 +1,10 @@
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use rustc::hir::map::Map;
-use rustc::middle::resolve_lifetime as rl;
-use rustc::ty::{self, Region, TyCtxt};
 use rustc_hir as hir;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::Node;
+use rustc_middle::hir::map::Map;
+use rustc_middle::middle::resolve_lifetime as rl;
+use rustc_middle::ty::{self, Region, TyCtxt};
 
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     /// This function calls the `visit_ty` method for the parameters
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 2357ee689d5..2aed3d9a469 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::ty::{self, TyCtxt};
-use rustc::util::common::ErrorReported;
-use rustc_errors::DiagnosticBuilder;
+use rustc_errors::{DiagnosticBuilder, ErrorReported};
+use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::source_map::Span;
 
 mod different_lifetimes;
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs
index 02ce357967c..b85a4cae2e4 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs
@@ -1,9 +1,9 @@
 //! Error Reporting for Anonymous Region Lifetime Errors
 //! where one region is named and the other is anonymous.
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use rustc::ty;
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
 use rustc_hir::{FnRetTy, TyKind};
+use rustc_middle::ty;
 
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     /// When given a `ConcreteFailure` for a function with parameters containing a named region and
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 d88e6555af9..70c30271043 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::ty::RegionKind;
-use rustc::util::common::ErrorReported;
+use rustc_errors::ErrorReported;
 use rustc_hir::{Expr, ExprKind::Closure, Node};
+use rustc_middle::ty::RegionKind;
 
 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/placeholder_error.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/placeholder_error.rs
index 57313dbab42..2187064ec5e 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/placeholder_error.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/placeholder_error.rs
@@ -3,13 +3,13 @@ use crate::infer::lexical_region_resolve::RegionResolutionError;
 use crate::infer::ValuePairs;
 use crate::infer::{SubregionOrigin, TypeTrace};
 use crate::traits::{ObligationCause, ObligationCauseCode};
-use rustc::ty::error::ExpectedFound;
-use rustc::ty::print::{FmtPrinter, Print, RegionHighlightMode};
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::{self, TyCtxt};
 use rustc_errors::DiagnosticBuilder;
 use rustc_hir::def::Namespace;
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty::error::ExpectedFound;
+use rustc_middle::ty::print::{FmtPrinter, Print, RegionHighlightMode};
+use rustc_middle::ty::subst::SubstsRef;
+use rustc_middle::ty::{self, TyCtxt};
 
 use std::fmt::{self, Write};
 
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 655e28bbd3d..7f3ec852e41 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::ty::{BoundRegion, FreeRegion, RegionKind};
-use rustc::util::common::ErrorReported;
-use rustc_errors::Applicability;
+use rustc_errors::{Applicability, ErrorReported};
+use rustc_middle::ty::{BoundRegion, FreeRegion, RegionKind};
 
 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 f8cab9f84c8..695f3e47fb5 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::error_reporting::nice_region_error::NiceRegionError;
 use crate::infer::lexical_region_resolve::RegionResolutionError;
 use crate::infer::{Subtype, ValuePairs};
 use crate::traits::ObligationCauseCode::CompareImplMethodObligation;
-use rustc::ty::Ty;
-use rustc::util::common::ErrorReported;
+use rustc_errors::ErrorReported;
+use rustc_middle::ty::Ty;
 use rustc_span::Span;
 
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
@@ -22,26 +22,25 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
                 _sup,
             ) = error.clone()
             {
-                match (&sup_origin, &sub_origin) {
-                    (&Subtype(ref sup_trace), &Subtype(ref sub_trace)) => {
-                        if let (
-                            ValuePairs::Types(sub_expected_found),
-                            ValuePairs::Types(sup_expected_found),
-                            CompareImplMethodObligation { trait_item_def_id, .. },
-                        ) = (&sub_trace.values, &sup_trace.values, &sub_trace.cause.code)
-                        {
-                            if sup_expected_found == sub_expected_found {
-                                self.emit_err(
-                                    var_origin.span(),
-                                    sub_expected_found.expected,
-                                    sub_expected_found.found,
-                                    self.tcx().def_span(*trait_item_def_id),
-                                );
-                                return Some(ErrorReported);
-                            }
+                if let (&Subtype(ref sup_trace), &Subtype(ref sub_trace)) =
+                    (&sup_origin, &sub_origin)
+                {
+                    if let (
+                        ValuePairs::Types(sub_expected_found),
+                        ValuePairs::Types(sup_expected_found),
+                        CompareImplMethodObligation { trait_item_def_id, .. },
+                    ) = (&sub_trace.values, &sup_trace.values, &sub_trace.cause.code)
+                    {
+                        if sup_expected_found == sub_expected_found {
+                            self.emit_err(
+                                var_origin.span(),
+                                sub_expected_found.expected,
+                                sub_expected_found.found,
+                                self.tcx().def_span(*trait_item_def_id),
+                            );
+                            return Some(ErrorReported);
                         }
                     }
-                    _ => {}
                 }
             }
         }
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs
index de72c276595..d35a589320b 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs
@@ -2,9 +2,9 @@
 //! anonymous regions.
 
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use rustc::ty::{self, DefIdTree, Region, Ty};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty::{self, DefIdTree, Region, Ty};
 use rustc_span::Span;
 
 // The struct contains the information about the anonymous region
diff --git a/src/librustc_infer/infer/error_reporting/note.rs b/src/librustc_infer/infer/error_reporting/note.rs
index 5c0caa48d0e..81f37831af2 100644
--- a/src/librustc_infer/infer/error_reporting/note.rs
+++ b/src/librustc_infer/infer/error_reporting/note.rs
@@ -1,9 +1,9 @@
 use crate::infer::error_reporting::{note_and_explain_region, ObligationCauseExt};
 use crate::infer::{self, InferCtxt, SubregionOrigin};
-use rustc::middle::region;
-use rustc::ty::error::TypeError;
-use rustc::ty::{self, Region};
 use rustc_errors::{struct_span_err, DiagnosticBuilder};
+use rustc_middle::middle::region;
+use rustc_middle::ty::error::TypeError;
+use rustc_middle::ty::{self, Region};
 
 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     pub(super) fn note_region_origin(
diff --git a/src/librustc_infer/infer/freshen.rs b/src/librustc_infer/infer/freshen.rs
index fa28cf5b454..eeaa4c1661e 100644
--- a/src/librustc_infer/infer/freshen.rs
+++ b/src/librustc_infer/infer/freshen.rs
@@ -31,8 +31,8 @@
 //! variable only once, and it does so as soon as it can, so it is reasonable to ask what the type
 //! inferencer knows "so far".
 
-use rustc::ty::fold::TypeFolder;
-use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
+use rustc_middle::ty::fold::TypeFolder;
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
 
 use rustc_data_structures::fx::FxHashMap;
 
diff --git a/src/librustc_infer/infer/fudge.rs b/src/librustc_infer/infer/fudge.rs
index 16bf0f3d1c6..1a58e100fb3 100644
--- a/src/librustc_infer/infer/fudge.rs
+++ b/src/librustc_infer/infer/fudge.rs
@@ -1,5 +1,5 @@
-use rustc::ty::fold::{TypeFoldable, TypeFolder};
-use rustc::ty::{self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid};
+use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
+use rustc_middle::ty::{self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid};
 
 use super::type_variable::TypeVariableOrigin;
 use super::InferCtxt;
diff --git a/src/librustc_infer/infer/glb.rs b/src/librustc_infer/infer/glb.rs
index 8b26bcef573..f95d74a9340 100644
--- a/src/librustc_infer/infer/glb.rs
+++ b/src/librustc_infer/infer/glb.rs
@@ -4,8 +4,8 @@ use super::InferCtxt;
 use super::Subtype;
 
 use crate::traits::ObligationCause;
-use rustc::ty::relate::{Relate, RelateResult, TypeRelation};
-use rustc::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 
 /// "Greatest lower bound" (common subtype)
 pub struct Glb<'combine, 'infcx, 'tcx> {
diff --git a/src/librustc_infer/infer/higher_ranked/mod.rs b/src/librustc_infer/infer/higher_ranked/mod.rs
index 6a5a1c46d4c..ef18918c177 100644
--- a/src/librustc_infer/infer/higher_ranked/mod.rs
+++ b/src/librustc_infer/infer/higher_ranked/mod.rs
@@ -5,8 +5,8 @@ use super::combine::CombineFields;
 use super::{HigherRankedType, InferCtxt, PlaceholderMap};
 
 use crate::infer::CombinedSnapshot;
-use rustc::ty::relate::{Relate, RelateResult, TypeRelation};
-use rustc::ty::{self, Binder, TypeFoldable};
+use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
+use rustc_middle::ty::{self, Binder, TypeFoldable};
 
 impl<'a, 'tcx> CombineFields<'a, 'tcx> {
     pub fn higher_ranked_sub<T>(
diff --git a/src/librustc_infer/infer/lattice.rs b/src/librustc_infer/infer/lattice.rs
index 42f9b3ab770..c29614b8556 100644
--- a/src/librustc_infer/infer/lattice.rs
+++ b/src/librustc_infer/infer/lattice.rs
@@ -23,9 +23,9 @@ use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use super::InferCtxt;
 
 use crate::traits::ObligationCause;
-use rustc::ty::relate::{RelateResult, TypeRelation};
-use rustc::ty::TyVar;
-use rustc::ty::{self, Ty};
+use rustc_middle::ty::relate::{RelateResult, TypeRelation};
+use rustc_middle::ty::TyVar;
+use rustc_middle::ty::{self, Ty};
 
 pub trait LatticeDir<'f, 'tcx>: TypeRelation<'tcx> {
     fn infcx(&self) -> &'f InferCtxt<'f, 'tcx>;
diff --git a/src/librustc_infer/infer/lexical_region_resolve/graphviz.rs b/src/librustc_infer/infer/lexical_region_resolve/graphviz.rs
index eb52f10e408..141424fc0c7 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::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
@@ -11,11 +11,11 @@ use graphviz as dot;
 use super::Constraint;
 use crate::infer::region_constraints::RegionConstraintData;
 use crate::infer::SubregionOrigin;
-use rustc::middle::free_region::RegionRelations;
-use rustc::middle::region;
-use rustc::ty;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir::def_id::DefIndex;
+use rustc_middle::middle::free_region::RegionRelations;
+use rustc_middle::middle::region;
+use rustc_middle::ty;
 
 use std::borrow::Cow;
 use std::collections::btree_map::BTreeMap;
diff --git a/src/librustc_infer/infer/lexical_region_resolve/mod.rs b/src/librustc_infer/infer/lexical_region_resolve/mod.rs
index d81c7454a0f..8a73c8b880e 100644
--- a/src/librustc_infer/infer/lexical_region_resolve/mod.rs
+++ b/src/librustc_infer/infer/lexical_region_resolve/mod.rs
@@ -9,17 +9,17 @@ use crate::infer::region_constraints::VerifyBound;
 use crate::infer::RegionVariableOrigin;
 use crate::infer::RegionckMode;
 use crate::infer::SubregionOrigin;
-use rustc::middle::free_region::RegionRelations;
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::{self, Ty, TyCtxt};
-use rustc::ty::{ReEarlyBound, ReEmpty, ReErased, ReFree, ReStatic};
-use rustc::ty::{ReLateBound, RePlaceholder, ReScope, ReVar};
-use rustc::ty::{Region, RegionVid};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::graph::implementation::{
     Direction, Graph, NodeIndex, INCOMING, OUTGOING,
 };
 use rustc_index::vec::{Idx, IndexVec};
+use rustc_middle::middle::free_region::RegionRelations;
+use rustc_middle::ty::fold::TypeFoldable;
+use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{ReEarlyBound, ReEmpty, ReErased, ReFree, ReStatic};
+use rustc_middle::ty::{ReLateBound, RePlaceholder, ReScope, ReVar};
+use rustc_middle::ty::{Region, RegionVid};
 use rustc_span::Span;
 use std::fmt;
 
diff --git a/src/librustc_infer/infer/lub.rs b/src/librustc_infer/infer/lub.rs
index 20ddeec6850..492f2b229d3 100644
--- a/src/librustc_infer/infer/lub.rs
+++ b/src/librustc_infer/infer/lub.rs
@@ -4,8 +4,8 @@ use super::InferCtxt;
 use super::Subtype;
 
 use crate::traits::ObligationCause;
-use rustc::ty::relate::{Relate, RelateResult, TypeRelation};
-use rustc::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 
 /// "Least upper bound" (common supertype)
 pub struct Lub<'combine, 'infcx, 'tcx> {
diff --git a/src/librustc_infer/infer/mod.rs b/src/librustc_infer/infer/mod.rs
index dc494b8e413..edaa7a04b34 100644
--- a/src/librustc_infer/infer/mod.rs
+++ b/src/librustc_infer/infer/mod.rs
@@ -8,21 +8,6 @@ pub use self::ValuePairs::*;
 
 use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine};
 
-use rustc::infer::canonical::{Canonical, CanonicalVarValues};
-use rustc::infer::unify_key::{ConstVarValue, ConstVariableValue};
-use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
-use rustc::middle::free_region::RegionRelations;
-use rustc::middle::region;
-use rustc::mir;
-use rustc::mir::interpret::ConstEvalResult;
-use rustc::traits::select;
-use rustc::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
-use rustc::ty::fold::{TypeFoldable, TypeFolder};
-use rustc::ty::relate::RelateResult;
-use rustc::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef};
-pub use rustc::ty::IntVarValue;
-use rustc::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt};
-use rustc::ty::{ConstVid, FloatVid, IntVid, TyVid};
 use rustc_ast::ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::Lrc;
@@ -30,6 +15,21 @@ use rustc_data_structures::unify as ut;
 use rustc_errors::DiagnosticBuilder;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
+use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
+use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
+use rustc_middle::middle::free_region::RegionRelations;
+use rustc_middle::middle::region;
+use rustc_middle::mir;
+use rustc_middle::mir::interpret::ConstEvalResult;
+use rustc_middle::traits::select;
+use rustc_middle::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
+use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
+use rustc_middle::ty::relate::RelateResult;
+use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef};
+pub use rustc_middle::ty::IntVarValue;
+use rustc_middle::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt};
+use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid};
 use rustc_session::config::BorrowckMode;
 use rustc_span::symbol::Symbol;
 use rustc_span::Span;
@@ -65,7 +65,7 @@ mod sub;
 pub mod type_variable;
 
 use crate::infer::canonical::OriginalQueryValues;
-pub use rustc::infer::unify_key;
+pub use rustc_middle::infer::unify_key;
 
 #[must_use]
 #[derive(Debug)]
@@ -672,8 +672,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     }
 
     pub fn type_is_unconstrained_numeric(&'a self, ty: Ty<'_>) -> UnconstrainedNumeric {
-        use rustc::ty::error::UnconstrainedNumeric::Neither;
-        use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
+        use rustc_middle::ty::error::UnconstrainedNumeric::Neither;
+        use rustc_middle::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
         match ty.kind {
             ty::Infer(ty::IntVar(vid)) => {
                 if self.inner.borrow_mut().int_unification_table.probe_value(vid).is_some() {
diff --git a/src/librustc_infer/infer/nll_relate/mod.rs b/src/librustc_infer/infer/nll_relate/mod.rs
index c194e968013..44bacfa80e1 100644
--- a/src/librustc_infer/infer/nll_relate/mod.rs
+++ b/src/librustc_infer/infer/nll_relate/mod.rs
@@ -24,12 +24,12 @@
 use crate::infer::InferCtxt;
 use crate::infer::{ConstVarValue, ConstVariableValue};
 use crate::traits::DomainGoal;
-use rustc::ty::error::TypeError;
-use rustc::ty::fold::{TypeFoldable, TypeVisitor};
-use rustc::ty::relate::{self, Relate, RelateResult, TypeRelation};
-use rustc::ty::subst::GenericArg;
-use rustc::ty::{self, InferConst, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashMap;
+use rustc_middle::ty::error::TypeError;
+use rustc_middle::ty::fold::{TypeFoldable, TypeVisitor};
+use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
+use rustc_middle::ty::subst::GenericArg;
+use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
 use std::fmt::Debug;
 
 #[derive(PartialEq)]
diff --git a/src/librustc_infer/infer/outlives/env.rs b/src/librustc_infer/infer/outlives/env.rs
index 6c1e86bf408..38c3f0ee6ac 100644
--- a/src/librustc_infer/infer/outlives/env.rs
+++ b/src/librustc_infer/infer/outlives/env.rs
@@ -1,9 +1,9 @@
 use crate::infer::{GenericKind, InferCtxt};
 use crate::traits::query::OutlivesBound;
-use rustc::ty;
-use rustc::ty::free_region_map::FreeRegionMap;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
+use rustc_middle::ty;
+use rustc_middle::ty::free_region_map::FreeRegionMap;
 
 use super::explicit_outlives_bounds;
 
diff --git a/src/librustc_infer/infer/outlives/mod.rs b/src/librustc_infer/infer/outlives/mod.rs
index 75cf742de31..ed3d8605869 100644
--- a/src/librustc_infer/infer/outlives/mod.rs
+++ b/src/librustc_infer/infer/outlives/mod.rs
@@ -4,8 +4,8 @@ pub mod env;
 pub mod obligations;
 pub mod verify;
 
-use rustc::traits::query::OutlivesBound;
-use rustc::ty;
+use rustc_middle::traits::query::OutlivesBound;
+use rustc_middle::ty;
 
 pub fn explicit_outlives_bounds<'tcx>(
     param_env: ty::ParamEnv<'tcx>,
diff --git a/src/librustc_infer/infer/outlives/obligations.rs b/src/librustc_infer/infer/outlives/obligations.rs
index e3790b02734..e6feb5e1edc 100644
--- a/src/librustc_infer/infer/outlives/obligations.rs
+++ b/src/librustc_infer/infer/outlives/obligations.rs
@@ -63,9 +63,9 @@ use crate::infer::outlives::env::RegionBoundPairs;
 use crate::infer::outlives::verify::VerifyBoundCx;
 use crate::infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, VerifyBound};
 use crate::traits::ObligationCause;
-use rustc::ty::outlives::Component;
-use rustc::ty::subst::GenericArgKind;
-use rustc::ty::{self, Region, Ty, TyCtxt, TypeFoldable};
+use rustc_middle::ty::outlives::Component;
+use rustc_middle::ty::subst::GenericArgKind;
+use rustc_middle::ty::{self, Region, Ty, TyCtxt, TypeFoldable};
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
diff --git a/src/librustc_infer/infer/outlives/verify.rs b/src/librustc_infer/infer/outlives/verify.rs
index 08f73d2c9d2..1cd6830b6a2 100644
--- a/src/librustc_infer/infer/outlives/verify.rs
+++ b/src/librustc_infer/infer/outlives/verify.rs
@@ -1,10 +1,10 @@
 use crate::infer::outlives::env::RegionBoundPairs;
 use crate::infer::{GenericKind, VerifyBound};
 use crate::traits;
-use rustc::ty::subst::{InternalSubsts, Subst};
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_data_structures::captures::Captures;
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty::subst::{InternalSubsts, Subst};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 
 use smallvec::smallvec;
 
diff --git a/src/librustc_infer/infer/region_constraints/leak_check.rs b/src/librustc_infer/infer/region_constraints/leak_check.rs
index 6ebe3f57597..18e86162eb5 100644
--- a/src/librustc_infer/infer/region_constraints/leak_check.rs
+++ b/src/librustc_infer/infer/region_constraints/leak_check.rs
@@ -1,7 +1,7 @@
 use super::*;
 use crate::infer::{CombinedSnapshot, PlaceholderMap};
-use rustc::ty::error::TypeError;
-use rustc::ty::relate::RelateResult;
+use rustc_middle::ty::error::TypeError;
+use rustc_middle::ty::relate::RelateResult;
 
 impl<'tcx> RegionConstraintCollector<'tcx> {
     /// Searches region constraints created since `snapshot` that
diff --git a/src/librustc_infer/infer/region_constraints/mod.rs b/src/librustc_infer/infer/region_constraints/mod.rs
index 72637f4544a..e10b0938955 100644
--- a/src/librustc_infer/infer/region_constraints/mod.rs
+++ b/src/librustc_infer/infer/region_constraints/mod.rs
@@ -6,15 +6,15 @@ use self::UndoLog::*;
 use super::unify_key;
 use super::{MiscVariable, RegionVariableOrigin, SubregionOrigin};
 
-use rustc::ty::ReStatic;
-use rustc::ty::{self, Ty, TyCtxt};
-use rustc::ty::{ReLateBound, ReVar};
-use rustc::ty::{Region, RegionVid};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::unify as ut;
 use rustc_hir::def_id::DefId;
 use rustc_index::vec::IndexVec;
+use rustc_middle::ty::ReStatic;
+use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{ReLateBound, ReVar};
+use rustc_middle::ty::{Region, RegionVid};
 use rustc_span::Span;
 
 use std::collections::BTreeMap;
@@ -23,7 +23,7 @@ use std::{cmp, fmt, mem};
 
 mod leak_check;
 
-pub use rustc::infer::MemberConstraint;
+pub use rustc_middle::infer::MemberConstraint;
 
 #[derive(Default)]
 pub struct RegionConstraintCollector<'tcx> {
diff --git a/src/librustc_infer/infer/resolve.rs b/src/librustc_infer/infer/resolve.rs
index ce0f2f40894..22b90f24155 100644
--- a/src/librustc_infer/infer/resolve.rs
+++ b/src/librustc_infer/infer/resolve.rs
@@ -1,7 +1,7 @@
 use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use super::{FixupError, FixupResult, InferCtxt, Span};
-use rustc::ty::fold::{TypeFolder, TypeVisitor};
-use rustc::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable};
+use rustc_middle::ty::fold::{TypeFolder, TypeVisitor};
+use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable};
 
 ///////////////////////////////////////////////////////////////////////////
 // OPPORTUNISTIC VAR RESOLVER
diff --git a/src/librustc_infer/infer/sub.rs b/src/librustc_infer/infer/sub.rs
index f6fc38b5358..080af37492d 100644
--- a/src/librustc_infer/infer/sub.rs
+++ b/src/librustc_infer/infer/sub.rs
@@ -2,10 +2,10 @@ use super::combine::{CombineFields, RelationDir};
 use super::SubregionOrigin;
 
 use crate::traits::Obligation;
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::relate::{Cause, Relate, RelateResult, TypeRelation};
-use rustc::ty::TyVar;
-use rustc::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::fold::TypeFoldable;
+use rustc_middle::ty::relate::{Cause, Relate, RelateResult, TypeRelation};
+use rustc_middle::ty::TyVar;
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use std::mem;
 
 /// Ensures `a` is made a subtype of `b`. Returns `a` on success.
diff --git a/src/librustc_infer/infer/type_variable.rs b/src/librustc_infer/infer/type_variable.rs
index 53bc70a5344..8e4199f0c26 100644
--- a/src/librustc_infer/infer/type_variable.rs
+++ b/src/librustc_infer/infer/type_variable.rs
@@ -1,5 +1,5 @@
-use rustc::ty::{self, Ty, TyVid};
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty::{self, Ty, TyVid};
 use rustc_span::symbol::Symbol;
 use rustc_span::Span;
 
diff --git a/src/librustc_infer/lib.rs b/src/librustc_infer/lib.rs
index cb8ae8c592b..5dd5165b688 100644
--- a/src/librustc_infer/lib.rs
+++ b/src/librustc_infer/lib.rs
@@ -30,7 +30,7 @@ extern crate rustc_data_structures;
 #[macro_use]
 extern crate log;
 #[macro_use]
-extern crate rustc;
+extern crate rustc_middle;
 
 pub mod infer;
 pub mod traits;
diff --git a/src/librustc_infer/traits/engine.rs b/src/librustc_infer/traits/engine.rs
index 9ad722342a1..a95257ba682 100644
--- a/src/librustc_infer/traits/engine.rs
+++ b/src/librustc_infer/traits/engine.rs
@@ -1,7 +1,7 @@
 use crate::infer::InferCtxt;
 use crate::traits::Obligation;
-use rustc::ty::{self, ToPredicate, Ty, WithConstness};
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty::{self, ToPredicate, Ty, WithConstness};
 
 use super::FulfillmentError;
 use super::{ObligationCause, PredicateObligation};
diff --git a/src/librustc_infer/traits/error_reporting/mod.rs b/src/librustc_infer/traits/error_reporting/mod.rs
index 47d3cdb7a4e..9206166d0bd 100644
--- a/src/librustc_infer/traits/error_reporting/mod.rs
+++ b/src/librustc_infer/traits/error_reporting/mod.rs
@@ -1,12 +1,12 @@
 use super::ObjectSafetyViolation;
 
 use crate::infer::InferCtxt;
-use rustc::ty::TyCtxt;
 use rustc_ast::ast;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::Span;
 use std::fmt;
 
diff --git a/src/librustc_infer/traits/mod.rs b/src/librustc_infer/traits/mod.rs
index 1c0785497be..758a0b39d43 100644
--- a/src/librustc_infer/traits/mod.rs
+++ b/src/librustc_infer/traits/mod.rs
@@ -6,11 +6,11 @@ mod engine;
 pub mod error_reporting;
 mod project;
 mod structural_impls;
-mod util;
+pub mod util;
 
-use rustc::ty::error::{ExpectedFound, TypeError};
-use rustc::ty::{self, Ty};
 use rustc_hir as hir;
+use rustc_middle::ty::error::{ExpectedFound, TypeError};
+use rustc_middle::ty::{self, Ty};
 use rustc_span::Span;
 
 pub use self::FulfillmentErrorCode::*;
@@ -26,7 +26,7 @@ pub use self::project::{
 };
 crate use self::util::elaborate_predicates;
 
-pub use rustc::traits::*;
+pub use rustc_middle::traits::*;
 
 /// An `Obligation` represents some trait reference (e.g., `int: Eq`) for
 /// which the vtable must be found. The process of finding a vtable is
diff --git a/src/librustc_infer/traits/project.rs b/src/librustc_infer/traits/project.rs
index 06870ccc7dd..48375a9ddf4 100644
--- a/src/librustc_infer/traits/project.rs
+++ b/src/librustc_infer/traits/project.rs
@@ -2,11 +2,11 @@
 
 use super::PredicateObligation;
 
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::{self, Ty};
 use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
+use rustc_middle::ty::fold::TypeFoldable;
+use rustc_middle::ty::{self, Ty};
 
-pub use rustc::traits::Reveal;
+pub use rustc_middle::traits::Reveal;
 
 #[derive(Clone)]
 pub struct MismatchedProjectionTypes<'tcx> {
diff --git a/src/librustc_infer/traits/structural_impls.rs b/src/librustc_infer/traits/structural_impls.rs
index 6630f664f96..595a8cd7683 100644
--- a/src/librustc_infer/traits/structural_impls.rs
+++ b/src/librustc_infer/traits/structural_impls.rs
@@ -1,7 +1,7 @@
 use crate::traits;
 use crate::traits::project::Normalized;
-use rustc::ty;
-use rustc::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
+use rustc_middle::ty;
+use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 
 use std::fmt;
 
diff --git a/src/librustc_infer/traits/util.rs b/src/librustc_infer/traits/util.rs
index 90f3cb1d24c..4fa74f93ddc 100644
--- a/src/librustc_infer/traits/util.rs
+++ b/src/librustc_infer/traits/util.rs
@@ -1,10 +1,13 @@
 use smallvec::smallvec;
 
-use rustc::ty::outlives::Component;
-use rustc::ty::{self, ToPolyTraitRef, TyCtxt};
 use rustc_data_structures::fx::FxHashSet;
+use rustc_middle::ty::outlives::Component;
+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 @@ pub struct Elaborator<'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>>,
@@ -98,6 +116,10 @@ pub fn elaborate_predicates<'tcx>(
 }
 
 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 @@ impl Iterator for Elaborator<'tcx> {
         }
     }
 }
+
+///////////////////////////////////////////////////////////////////////////
+// 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/Cargo.toml b/src/librustc_interface/Cargo.toml
index 2e055ff183f..c9d81e51641 100644
--- a/src/librustc_interface/Cargo.toml
+++ b/src/librustc_interface/Cargo.toml
@@ -21,7 +21,7 @@ rustc_parse = { path = "../librustc_parse" }
 rustc_session = { path = "../librustc_session" }
 rustc_span = { path = "../librustc_span" }
 rustc_serialize = { path = "../libserialize", package = "serialize" }
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc_ast_lowering = { path = "../librustc_ast_lowering" }
 rustc_ast_passes = { path = "../librustc_ast_passes" }
 rustc_incremental = { path = "../librustc_incremental" }
diff --git a/src/librustc_interface/callbacks.rs b/src/librustc_interface/callbacks.rs
index 0345b82d3bb..88c3d0ec56f 100644
--- a/src/librustc_interface/callbacks.rs
+++ b/src/librustc_interface/callbacks.rs
@@ -1,6 +1,6 @@
 //! Throughout the compiler tree, there are several places which want to have
 //! access to state or queries while being inside crates that are dependencies
-//! of librustc. To facilitate this, we have the
+//! of librustc_middle. To facilitate this, we have the
 //! `rustc_data_structures::AtomicRef` type, which allows us to setup a global
 //! static which can then be set in this file at program startup.
 //!
@@ -9,12 +9,12 @@
 //! The functions in this file should fall back to the default set in their
 //! origin crate when the `TyCtxt` is not present in TLS.
 
-use rustc::ty::tls;
 use rustc_errors::{Diagnostic, TRACK_DIAGNOSTICS};
+use rustc_middle::ty::tls;
 use std::fmt;
 
 /// This is a callback from librustc_ast as it cannot access the implicit state
-/// in librustc otherwise.
+/// in librustc_middle otherwise.
 fn span_debug(span: rustc_span::Span, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     tls::with_opt(|tcx| {
         if let Some(tcx) = tcx {
@@ -26,7 +26,7 @@ fn span_debug(span: rustc_span::Span, f: &mut fmt::Formatter<'_>) -> fmt::Result
 }
 
 /// This is a callback from librustc_ast as it cannot access the implicit state
-/// in librustc otherwise. It is used to when diagnostic messages are
+/// in librustc_middle otherwise. It is used to when diagnostic messages are
 /// emitted and stores them in the current query, if there is one.
 fn track_diagnostic(diagnostic: &Diagnostic) {
     tls::with_context_opt(|icx| {
@@ -40,7 +40,7 @@ fn track_diagnostic(diagnostic: &Diagnostic) {
 }
 
 /// This is a callback from librustc_hir as it cannot access the implicit state
-/// in librustc otherwise.
+/// in librustc_middle otherwise.
 fn def_id_debug(def_id: rustc_hir::def_id::DefId, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     write!(f, "DefId({}:{}", def_id.krate, def_id.index.index())?;
     tls::with_opt(|opt_tcx| {
@@ -58,5 +58,5 @@ pub fn setup_callbacks() {
     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::ty::RESOLVE_INSTANCE.swap(&(rustc_ty::instance::resolve_instance as _));
+    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 65a7a48d440..8e929b7daa8 100644
--- a/src/librustc_interface/interface.rs
+++ b/src/librustc_interface/interface.rs
@@ -1,8 +1,6 @@
 pub use crate::passes::BoxedResolver;
 use crate::util;
 
-use rustc::ty;
-use rustc::util::common::ErrorReported;
 use rustc_ast::ast::{self, MetaItemKind};
 use rustc_ast::token;
 use rustc_codegen_ssa::traits::CodegenBackend;
@@ -10,7 +8,9 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 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_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 7cf0b4c44a6..609c80a2b79 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -3,25 +3,24 @@ use crate::proc_macro_decls;
 use crate::util;
 
 use log::{info, log_enabled, warn};
-use rustc::arena::Arena;
-use rustc::dep_graph::DepGraph;
-use rustc::middle;
-use rustc::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn};
-use rustc::ty::steal::Steal;
-use rustc::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt};
-use rustc::util::common::ErrorReported;
 use rustc_ast::mut_visit::MutVisitor;
 use rustc_ast::{self, ast, visit};
 use rustc_codegen_ssa::back::link::emit_metadata;
 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;
 use rustc_hir::Crate;
 use rustc_lint::LintStore;
+use rustc_middle::arena::Arena;
+use rustc_middle::dep_graph::DepGraph;
+use rustc_middle::middle;
+use rustc_middle::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn};
+use rustc_middle::ty::steal::Steal;
+use rustc_middle::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt};
 use rustc_mir as mir;
 use rustc_mir_build as mir_build;
 use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str};
@@ -678,7 +677,7 @@ pub fn default_provide(providers: &mut ty::query::Providers<'_>) {
     providers.analysis = analysis;
     proc_macro_decls::provide(providers);
     plugin::build::provide(providers);
-    rustc::hir::provide(providers);
+    rustc_middle::hir::provide(providers);
     mir::provide(providers);
     mir_build::provide(providers);
     rustc_privacy::provide(providers);
@@ -711,7 +710,7 @@ impl<'tcx> QueryContext<'tcx> {
     }
 
     pub fn print_stats(&mut self) {
-        self.enter(|tcx| ty::query::print_stats(tcx))
+        self.enter(ty::query::print_stats)
     }
 }
 
diff --git a/src/librustc_interface/proc_macro_decls.rs b/src/librustc_interface/proc_macro_decls.rs
index 076a8cef92c..47b53aeba72 100644
--- a/src/librustc_interface/proc_macro_decls.rs
+++ b/src/librustc_interface/proc_macro_decls.rs
@@ -1,9 +1,9 @@
-use rustc::ty::query::Providers;
-use rustc::ty::TyCtxt;
 use rustc_ast::attr;
 use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::sym;
 
 pub fn find(tcx: TyCtxt<'_>) -> Option<DefId> {
diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs
index b0eeb57173f..6a62d754f28 100644
--- a/src/librustc_interface/queries.rs
+++ b/src/librustc_interface/queries.rs
@@ -1,18 +1,18 @@
 use crate::interface::{Compiler, Result};
 use crate::passes::{self, BoxedResolver, QueryContext};
 
-use rustc::arena::Arena;
-use rustc::dep_graph::DepGraph;
-use rustc::ty::steal::Steal;
-use rustc::ty::{GlobalCtxt, ResolverOutputs, TyCtxt};
-use rustc::util::common::ErrorReported;
 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;
 use rustc_lint::LintStore;
+use rustc_middle::arena::Arena;
+use rustc_middle::dep_graph::DepGraph;
+use rustc_middle::ty::steal::Steal;
+use rustc_middle::ty::{GlobalCtxt, ResolverOutputs, TyCtxt};
 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 8a8ba8a96f7..f58c5cc8eeb 100644
--- a/src/librustc_interface/tests.rs
+++ b/src/librustc_interface/tests.rs
@@ -2,9 +2,9 @@ extern crate getopts;
 
 use crate::interface::parse_cfgspecs;
 
-use rustc::middle::cstore;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig};
+use rustc_middle::middle::cstore;
 use rustc_session::config::{build_configuration, build_session_options, to_crate_config};
 use rustc_session::config::{rustc_optgroups, ErrorOutputType, ExternLocation, Options, Passes};
 use rustc_session::config::{ExternEntry, LinkerPluginLto, LtoCli, SwitchWithOptPath};
@@ -562,6 +562,8 @@ fn test_debugging_options_tracking_hash() {
     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
     opts.debugging_opts.dump_mir_graphviz = true;
     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
+    opts.debugging_opts.dump_mir_dataflow = true;
+    assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
 
     // Make sure changing a [TRACKED] option changes the hash
     opts = reference.clone();
diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs
index eff7dacef79..a8cc34e1854 100644
--- a/src/librustc_interface/util.rs
+++ b/src/librustc_interface/util.rs
@@ -1,5 +1,4 @@
 use log::info;
-use rustc::ty;
 use rustc_ast::ast::{AttrVec, BlockCheckMode};
 use rustc_ast::mut_visit::{visit_clobber, MutVisitor, *};
 use rustc_ast::ptr::P;
@@ -14,6 +13,7 @@ use rustc_data_structures::stable_hasher::StableHasher;
 use rustc_data_structures::sync::{Lock, Lrc};
 use rustc_errors::registry::Registry;
 use rustc_metadata::dynamic_lib::DynamicLibrary;
+use rustc_middle::ty;
 use rustc_resolve::{self, Resolver};
 use rustc_session as session;
 use rustc_session::config::{ErrorOutputType, Input, OutputFilenames};
diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs
index d3ac58a49c8..5ccfc1b276b 100644
--- a/src/librustc_lexer/src/lib.rs
+++ b/src/librustc_lexer/src/lib.rs
@@ -17,9 +17,13 @@
 mod cursor;
 pub mod unescape;
 
+#[cfg(test)]
+mod tests;
+
 use self::LiteralKind::*;
 use self::TokenKind::*;
 use crate::cursor::{Cursor, EOF_CHAR};
+use std::convert::TryInto;
 
 /// Parsed token.
 /// It doesn't contain information about data that has been parsed,
@@ -132,9 +136,84 @@ pub enum LiteralKind {
     /// "b"abc"", "b"abc"
     ByteStr { terminated: bool },
     /// "r"abc"", "r#"abc"#", "r####"ab"###"c"####", "r#"a"
-    RawStr { n_hashes: usize, started: bool, terminated: bool },
+    RawStr(UnvalidatedRawStr),
     /// "br"abc"", "br#"abc"#", "br####"ab"###"c"####", "br#"a"
-    RawByteStr { n_hashes: usize, started: bool, terminated: bool },
+    RawByteStr(UnvalidatedRawStr),
+}
+
+/// Represents something that looks like a raw string, but may have some
+/// problems. Use `.validate()` to convert it into something
+/// usable.
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
+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`
+    n_end_hashes: usize,
+    /// The offset starting at `r` or `br` where the user may have intended to end the string.
+    /// Currently, it is the longest sequence of pattern `"#+"`.
+    possible_terminator_offset: Option<usize>,
+}
+
+/// Error produced validating a raw string. Represents cases like:
+/// - `r##~"abcde"##`: `LexRawStrError::InvalidStarter`
+/// - `r###"abcde"##`: `LexRawStrError::NoTerminator { expected: 3, found: 2, possible_terminator_offset: Some(11)`
+/// - Too many `#`s (>65536): `TooManyDelimiters`
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
+pub enum LexRawStrError {
+    /// Non `#` characters exist between `r` and `"` eg. `r#~"..`
+    InvalidStarter,
+    /// The string was never terminated. `possible_terminator_offset` is the number of characters after `r` or `br` where they
+    /// may have intended to terminate it.
+    NoTerminator { expected: usize, found: usize, possible_terminator_offset: Option<usize> },
+    /// More than 65536 `#`s exist.
+    TooManyDelimiters,
+}
+
+/// Raw String that contains a valid prefix (`#+"`) and postfix (`"#+`) where
+/// there are a matching number of `#` characters in both. Note that this will
+/// not consume extra trailing `#` characters: `r###"abcde"####` is lexed as a
+/// `ValidatedRawString { n_hashes: 3 }` followed by a `#` token.
+#[derive(Debug, Eq, PartialEq, Copy, Clone)]
+pub struct ValidatedRawStr {
+    n_hashes: u16,
+}
+
+impl ValidatedRawStr {
+    pub fn num_hashes(&self) -> u16 {
+        self.n_hashes
+    }
+}
+
+impl UnvalidatedRawStr {
+    pub fn validate(self) -> Result<ValidatedRawStr, LexRawStrError> {
+        if !self.valid_start {
+            return Err(LexRawStrError::InvalidStarter);
+        }
+
+        // Only up to 65535 `#`s are allowed in raw strings
+        let n_start_safe: u16 =
+            self.n_start_hashes.try_into().map_err(|_| LexRawStrError::TooManyDelimiters)?;
+
+        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,
+                possible_terminator_offset: self.possible_terminator_offset,
+            })
+        } else {
+            // Since the lexer should never produce a literal with n_end > n_start, if n_start <= n_end,
+            // they must be equal.
+            debug_assert_eq!(self.n_start_hashes, self.n_end_hashes);
+            Ok(ValidatedRawStr { n_hashes: n_start_safe })
+        }
+    }
 }
 
 /// Base of numeric literal encoding according to its prefix.
@@ -209,7 +288,7 @@ pub fn is_whitespace(c: char) -> bool {
         // Dedicated whitespace characters from Unicode
         | '\u{2028}' // LINE SEPARATOR
         | '\u{2029}' // PARAGRAPH SEPARATOR
-            => true,
+        => true,
         _ => false,
     }
 }
@@ -258,12 +337,12 @@ impl Cursor<'_> {
             'r' => match (self.first(), self.second()) {
                 ('#', c1) if is_id_start(c1) => self.raw_ident(),
                 ('#', _) | ('"', _) => {
-                    let (n_hashes, started, terminated) = self.raw_double_quoted_string();
+                    let raw_str_i = self.raw_double_quoted_string(1);
                     let suffix_start = self.len_consumed();
-                    if terminated {
+                    if raw_str_i.n_end_hashes == raw_str_i.n_start_hashes {
                         self.eat_literal_suffix();
                     }
-                    let kind = RawStr { n_hashes, started, terminated };
+                    let kind = RawStr(raw_str_i);
                     Literal { kind, suffix_start }
                 }
                 _ => self.ident(),
@@ -293,12 +372,14 @@ impl Cursor<'_> {
                 }
                 ('r', '"') | ('r', '#') => {
                     self.bump();
-                    let (n_hashes, started, terminated) = self.raw_double_quoted_string();
+                    let raw_str_i = self.raw_double_quoted_string(2);
                     let suffix_start = self.len_consumed();
+                    let terminated = raw_str_i.n_start_hashes == raw_str_i.n_end_hashes;
                     if terminated {
                         self.eat_literal_suffix();
                     }
-                    let kind = RawByteStr { n_hashes, started, terminated };
+
+                    let kind = RawByteStr(raw_str_i);
                     Literal { kind, suffix_start }
                 }
                 _ => self.ident(),
@@ -594,29 +675,43 @@ impl Cursor<'_> {
         false
     }
 
-    /// Eats the double-quoted string and returns a tuple of
-    /// (amount of the '#' symbols, raw string started, raw string terminated)
-    fn raw_double_quoted_string(&mut self) -> (usize, bool, bool) {
+    /// Eats the double-quoted string and returns an `UnvalidatedRawStr`.
+    fn raw_double_quoted_string(&mut self, prefix_len: usize) -> UnvalidatedRawStr {
         debug_assert!(self.prev() == 'r');
-        let mut started: bool = false;
-        let mut finished: bool = false;
+        let mut valid_start: bool = false;
+        let start_pos = self.len_consumed();
+        let (mut possible_terminator_offset, mut max_hashes) = (None, 0);
 
         // Count opening '#' symbols.
-        let n_hashes = self.eat_while(|c| c == '#');
+        let n_start_hashes = self.eat_while(|c| c == '#');
 
         // Check that string is started.
         match self.bump() {
-            Some('"') => started = true,
-            _ => return (n_hashes, started, finished),
+            Some('"') => valid_start = true,
+            _ => {
+                return UnvalidatedRawStr {
+                    valid_start,
+                    valid_end: false,
+                    n_start_hashes,
+                    n_end_hashes: 0,
+                    possible_terminator_offset,
+                };
+            }
         }
 
         // Skip the string contents and on each '#' character met, check if this is
         // a raw string termination.
-        while !finished {
+        loop {
             self.eat_while(|c| c != '"');
 
             if self.is_eof() {
-                return (n_hashes, started, finished);
+                return UnvalidatedRawStr {
+                    valid_start,
+                    valid_end: false,
+                    n_start_hashes,
+                    n_end_hashes: max_hashes,
+                    possible_terminator_offset,
+                };
             }
 
             // Eat closing double quote.
@@ -624,7 +719,7 @@ impl Cursor<'_> {
 
             // Check that amount of closing '#' symbols
             // is equal to the amount of opening ones.
-            let mut hashes_left = n_hashes;
+            let mut hashes_left = n_start_hashes;
             let is_closing_hash = |c| {
                 if c == '#' && hashes_left != 0 {
                     hashes_left -= 1;
@@ -633,10 +728,24 @@ impl Cursor<'_> {
                     false
                 }
             };
-            finished = self.eat_while(is_closing_hash) == n_hashes;
+            let n_end_hashes = self.eat_while(is_closing_hash);
+
+            if n_end_hashes == n_start_hashes {
+                return UnvalidatedRawStr {
+                    valid_start,
+                    valid_end: true,
+                    n_start_hashes,
+                    n_end_hashes,
+                    possible_terminator_offset: None,
+                };
+            } else if n_end_hashes > max_hashes {
+                // Keep track of possible terminators to give a hint about where there might be
+                // a missing terminator
+                possible_terminator_offset =
+                    Some(self.len_consumed() - start_pos - n_end_hashes + prefix_len);
+                max_hashes = n_end_hashes;
+            }
         }
-
-        (n_hashes, started, finished)
     }
 
     fn eat_decimal_digits(&mut self) -> bool {
diff --git a/src/librustc_lexer/src/tests.rs b/src/librustc_lexer/src/tests.rs
new file mode 100644
index 00000000000..06fc159fe25
--- /dev/null
+++ b/src/librustc_lexer/src/tests.rs
@@ -0,0 +1,148 @@
+#[cfg(test)]
+mod tests {
+    use crate::*;
+
+    fn check_raw_str(
+        s: &str,
+        expected: UnvalidatedRawStr,
+        validated: Result<ValidatedRawStr, LexRawStrError>,
+    ) {
+        let s = &format!("r{}", s);
+        let mut cursor = Cursor::new(s);
+        cursor.bump();
+        let tok = cursor.raw_double_quoted_string(0);
+        assert_eq!(tok, expected);
+        assert_eq!(tok.validate(), validated);
+    }
+
+    #[test]
+    fn test_naked_raw_str() {
+        check_raw_str(
+            r#""abc""#,
+            UnvalidatedRawStr {
+                n_start_hashes: 0,
+                n_end_hashes: 0,
+                valid_start: true,
+                valid_end: true,
+                possible_terminator_offset: None,
+            },
+            Ok(ValidatedRawStr { n_hashes: 0 }),
+        );
+    }
+
+    #[test]
+    fn test_raw_no_start() {
+        check_raw_str(
+            r##""abc"#"##,
+            UnvalidatedRawStr {
+                n_start_hashes: 0,
+                n_end_hashes: 0,
+                valid_start: true,
+                valid_end: true,
+                possible_terminator_offset: None,
+            },
+            Ok(ValidatedRawStr { n_hashes: 0 }),
+        );
+    }
+
+    #[test]
+    fn test_too_many_terminators() {
+        // this error is handled in the parser later
+        check_raw_str(
+            r###"#"abc"##"###,
+            UnvalidatedRawStr {
+                n_start_hashes: 1,
+                n_end_hashes: 1,
+                valid_end: true,
+                valid_start: true,
+                possible_terminator_offset: None,
+            },
+            Ok(ValidatedRawStr { n_hashes: 1 }),
+        );
+    }
+
+    #[test]
+    fn test_unterminated() {
+        check_raw_str(
+            r#"#"abc"#,
+            UnvalidatedRawStr {
+                n_start_hashes: 1,
+                n_end_hashes: 0,
+                valid_end: false,
+                valid_start: true,
+                possible_terminator_offset: None,
+            },
+            Err(LexRawStrError::NoTerminator {
+                expected: 1,
+                found: 0,
+                possible_terminator_offset: None,
+            }),
+        );
+        check_raw_str(
+            r###"##"abc"#"###,
+            UnvalidatedRawStr {
+                n_start_hashes: 2,
+                n_end_hashes: 1,
+                valid_start: true,
+                valid_end: false,
+                possible_terminator_offset: Some(7),
+            },
+            Err(LexRawStrError::NoTerminator {
+                expected: 2,
+                found: 1,
+                possible_terminator_offset: Some(7),
+            }),
+        );
+        // We're looking for "# not just any #
+        check_raw_str(
+            r###"##"abc#"###,
+            UnvalidatedRawStr {
+                n_start_hashes: 2,
+                n_end_hashes: 0,
+                valid_start: true,
+                valid_end: false,
+                possible_terminator_offset: None,
+            },
+            Err(LexRawStrError::NoTerminator {
+                expected: 2,
+                found: 0,
+                possible_terminator_offset: None,
+            }),
+        )
+    }
+
+    #[test]
+    fn test_invalid_start() {
+        check_raw_str(
+            r##"#~"abc"#"##,
+            UnvalidatedRawStr {
+                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/Cargo.toml b/src/librustc_lint/Cargo.toml
index 9785af5eab2..44a5ba3de51 100644
--- a/src/librustc_lint/Cargo.toml
+++ b/src/librustc_lint/Cargo.toml
@@ -11,7 +11,7 @@ path = "lib.rs"
 [dependencies]
 log = "0.4"
 unicode-security = "0.0.2"
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc_ast_pretty = { path = "../librustc_ast_pretty" }
 rustc_attr = { path = "../librustc_attr" }
 rustc_errors = { path = "../librustc_errors" }
diff --git a/src/librustc_lint/array_into_iter.rs b/src/librustc_lint/array_into_iter.rs
index a91d735622f..3eb587c016a 100644
--- a/src/librustc_lint/array_into_iter.rs
+++ b/src/librustc_lint/array_into_iter.rs
@@ -1,8 +1,8 @@
 use crate::{LateContext, LateLintPass, LintContext};
-use rustc::ty;
-use rustc::ty::adjustment::{Adjust, Adjustment};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
+use rustc_middle::ty;
+use rustc_middle::ty::adjustment::{Adjust, Adjustment};
 use rustc_session::lint::FutureIncompatibleInfo;
 use rustc_span::symbol::sym;
 
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 906e46edfe7..cff86e8f218 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -1,9 +1,8 @@
 //! Lints in the Rust compiler.
 //!
 //! This contains lints which can feasibly be implemented as their own
-//! AST visitor. Also see `rustc::lint::builtin`, which contains the
-//! definitions of lints that are emitted directly inside the main
-//! compiler.
+//! AST visitor. Also see `rustc_session::lint::builtin`, which contains the
+//! definitions of lints that are emitted directly inside the main compiler.
 //!
 //! To add a new lint to rustc, declare it here using `declare_lint!()`.
 //! Then add code to emit the new lint in the appropriate circumstances.
@@ -11,7 +10,7 @@
 //! new `LintPass`, or using `Session::add_lint` elsewhere in the
 //! compiler. Only do the latter if the check can't be written cleanly as a
 //! `LintPass` (also, note that such lints will need to be defined in
-//! `rustc::lint::builtin`, not here).
+//! `rustc_session::lint::builtin`, not here).
 //!
 //! If you define a new `EarlyLintPass`, you will also need to add it to the
 //! `add_early_builtin!` or `add_early_builtin_with_new!` invocation in
@@ -22,8 +21,6 @@
 //! `late_lint_methods!` invocation in `lib.rs`.
 
 use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
-use rustc::lint::LintDiagnosticBuilder;
-use rustc::ty::{self, layout::VariantIdx, Ty, TyCtxt};
 use rustc_ast::ast::{self, Expr};
 use rustc_ast::attr::{self, HasAttrs};
 use rustc_ast::tokenstream::{TokenStream, TokenTree};
@@ -38,11 +35,14 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{GenericParamKind, PatKind};
 use rustc_hir::{HirIdSet, Node};
+use rustc_middle::lint::LintDiagnosticBuilder;
+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};
@@ -50,7 +50,7 @@ use crate::nonstandard_style::{method_context, MethodLateContext};
 use log::debug;
 use std::fmt::Write;
 
-// hardwired lints from librustc
+// hardwired lints from librustc_middle
 pub use rustc_session::lint::builtin::*;
 
 declare_lint! {
@@ -646,41 +646,35 @@ declare_lint_pass!(
 
 impl EarlyLintPass for AnonymousParameters {
     fn check_trait_item(&mut self, cx: &EarlyContext<'_>, it: &ast::AssocItem) {
-        match it.kind {
-            ast::AssocItemKind::Fn(_, ref sig, _, _) => {
-                for arg in sig.decl.inputs.iter() {
-                    match arg.pat.kind {
-                        ast::PatKind::Ident(_, ident, None) => {
-                            if ident.name == kw::Invalid {
-                                cx.struct_span_lint(ANONYMOUS_PARAMETERS, arg.pat.span, |lint| {
-                                    let ty_snip = cx.sess.source_map().span_to_snippet(arg.ty.span);
-
-                                    let (ty_snip, appl) = if let Ok(ref snip) = ty_snip {
-                                        (snip.as_str(), Applicability::MachineApplicable)
-                                    } else {
-                                        ("<type>", Applicability::HasPlaceholders)
-                                    };
+        if let ast::AssocItemKind::Fn(_, ref sig, _, _) = it.kind {
+            for arg in sig.decl.inputs.iter() {
+                if let ast::PatKind::Ident(_, ident, None) = arg.pat.kind {
+                    if ident.name == kw::Invalid {
+                        cx.struct_span_lint(ANONYMOUS_PARAMETERS, arg.pat.span, |lint| {
+                            let ty_snip = cx.sess.source_map().span_to_snippet(arg.ty.span);
+
+                            let (ty_snip, appl) = if let Ok(ref snip) = ty_snip {
+                                (snip.as_str(), Applicability::MachineApplicable)
+                            } else {
+                                ("<type>", Applicability::HasPlaceholders)
+                            };
 
-                                    lint.build(
-                                        "anonymous parameters are deprecated and will be \
+                            lint.build(
+                                "anonymous parameters are deprecated and will be \
                                      removed in the next edition.",
-                                    )
-                                    .span_suggestion(
-                                        arg.pat.span,
-                                        "try naming the parameter or explicitly \
+                            )
+                            .span_suggestion(
+                                arg.pat.span,
+                                "try naming the parameter or explicitly \
                                             ignoring it",
-                                        format!("_: {}", ty_snip),
-                                        appl,
-                                    )
-                                    .emit();
-                                })
-                            }
-                        }
-                        _ => (),
+                                format!("_: {}", ty_snip),
+                                appl,
+                            )
+                            .emit();
+                        })
                     }
                 }
             }
-            _ => (),
         }
     }
 }
@@ -888,18 +882,14 @@ declare_lint_pass!(MutableTransmutes => [MUTABLE_TRANSMUTES]);
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
     fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) {
         use rustc_target::spec::abi::Abi::RustIntrinsic;
-
-        match get_transmute_from_to(cx, expr).map(|(ty1, ty2)| (&ty1.kind, &ty2.kind)) {
-            Some((&ty::Ref(_, _, from_mt), &ty::Ref(_, _, to_mt))) => {
-                if to_mt == hir::Mutability::Mut && from_mt == hir::Mutability::Not {
-                    let msg = "mutating transmuted &mut T from &T may cause undefined behavior, \
+        if let Some((&ty::Ref(_, _, from_mt), &ty::Ref(_, _, to_mt))) =
+            get_transmute_from_to(cx, expr).map(|(ty1, ty2)| (&ty1.kind, &ty2.kind))
+        {
+            if to_mt == hir::Mutability::Mut && from_mt == hir::Mutability::Not {
+                let msg = "mutating transmuted &mut T from &T may cause undefined behavior, \
                                consider instead using an UnsafeCell";
-                    cx.struct_span_lint(MUTABLE_TRANSMUTES, expr.span, |lint| {
-                        lint.build(msg).emit()
-                    });
-                }
+                cx.struct_span_lint(MUTABLE_TRANSMUTES, expr.span, |lint| lint.build(msg).emit());
             }
-            _ => (),
         }
 
         fn get_transmute_from_to<'a, 'tcx>(
@@ -1207,8 +1197,8 @@ declare_lint_pass!(
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints {
     fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item<'tcx>) {
-        use rustc::ty::fold::TypeFoldable;
-        use rustc::ty::Predicate::*;
+        use rustc_middle::ty::fold::TypeFoldable;
+        use rustc_middle::ty::Predicate::*;
 
         if cx.tcx.features().trivial_bounds {
             let def_id = cx.tcx.hir().local_def_id(item.hir_id);
@@ -1558,7 +1548,7 @@ impl ExplicitOutlivesRequirements {
         inferred_outlives: &[ty::Region<'tcx>],
         infer_static: bool,
     ) -> Vec<(usize, Span)> {
-        use rustc::middle::resolve_lifetime::Region;
+        use rustc_middle::middle::resolve_lifetime::Region;
 
         bounds
             .iter()
@@ -1641,7 +1631,7 @@ impl ExplicitOutlivesRequirements {
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements {
     fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item<'_>) {
-        use rustc::middle::resolve_lifetime::Region;
+        use rustc_middle::middle::resolve_lifetime::Region;
 
         let infer_static = cx.tcx.features().infer_static_outlives_requirements;
         let def_id = cx.tcx.hir().local_def_id(item.hir_id);
@@ -1926,7 +1916,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue {
             ty: Ty<'tcx>,
             init: InitKind,
         ) -> Option<InitError> {
-            use rustc::ty::TyKind::*;
+            use rustc_middle::ty::TyKind::*;
             match ty.kind {
                 // Primitive types that don't like 0 as a value.
                 Ref(..) => Some(("references must be non-null".to_string(), None)),
diff --git a/src/librustc_lint/context.rs b/src/librustc_lint/context.rs
index 257b179d6ba..1747a78d36a 100644
--- a/src/librustc_lint/context.rs
+++ b/src/librustc_lint/context.rs
@@ -18,11 +18,6 @@ use self::TargetLint::*;
 
 use crate::levels::LintLevelsBuilder;
 use crate::passes::{EarlyLintPassObject, LateLintPassObject};
-use rustc::lint::LintDiagnosticBuilder;
-use rustc::middle::privacy::AccessLevels;
-use rustc::middle::stability;
-use rustc::ty::layout::{LayoutError, LayoutOf, TyLayout};
-use rustc::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt};
 use rustc_ast::ast;
 use rustc_ast::util::lev_distance::find_best_match_for_name;
 use rustc_data_structures::fx::FxHashMap;
@@ -31,10 +26,16 @@ use rustc_errors::{struct_span_err, Applicability};
 use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, DefId};
 use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
+use rustc_middle::lint::LintDiagnosticBuilder;
+use rustc_middle::middle::privacy::AccessLevels;
+use rustc_middle::middle::stability;
+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;
 
@@ -787,9 +788,8 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
                 let mut path = print_prefix(self)?;
 
                 // Skip `::{{constructor}}` on tuple/unit structs.
-                match disambiguated_data.data {
-                    DefPathData::Ctor => return Ok(path),
-                    _ => {}
+                if let DefPathData::Ctor = disambiguated_data.data {
+                    return Ok(path);
                 }
 
                 path.push(disambiguated_data.data.as_symbol());
@@ -811,9 +811,9 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
 
 impl<'a, 'tcx> LayoutOf for LateContext<'a, 'tcx> {
     type Ty = Ty<'tcx>;
-    type TyLayout = Result<TyLayout<'tcx>, LayoutError<'tcx>>;
+    type TyAndLayout = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>;
 
-    fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
+    fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout {
         self.tcx.layout_of(self.param_env.and(ty))
     }
 }
diff --git a/src/librustc_lint/early.rs b/src/librustc_lint/early.rs
index 34da29c9747..018e9da243c 100644
--- a/src/librustc_lint/early.rs
+++ b/src/librustc_lint/early.rs
@@ -104,6 +104,11 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
         run_early_pass!(self, check_pat_post, p);
     }
 
+    fn visit_anon_const(&mut self, c: &'a ast::AnonConst) {
+        run_early_pass!(self, check_anon_const, c);
+        ast_visit::walk_anon_const(self, c);
+    }
+
     fn visit_expr(&mut self, e: &'a ast::Expr) {
         self.with_lint_attrs(e.id, &e.attrs, |cx| {
             run_early_pass!(cx, check_expr, e);
diff --git a/src/librustc_lint/internal.rs b/src/librustc_lint/internal.rs
index d8c685f2b22..6de8fb45d22 100644
--- a/src/librustc_lint/internal.rs
+++ b/src/librustc_lint/internal.rs
@@ -175,18 +175,15 @@ fn lint_ty_kind_usage(cx: &LateContext<'_, '_>, segment: &PathSegment<'_>) -> bo
 }
 
 fn is_ty_or_ty_ctxt(cx: &LateContext<'_, '_>, ty: &Ty<'_>) -> Option<String> {
-    match &ty.kind {
-        TyKind::Path(qpath) => {
-            if let QPath::Resolved(_, path) = qpath {
-                let did = path.res.opt_def_id()?;
-                if cx.tcx.is_diagnostic_item(sym::Ty, did) {
-                    return Some(format!("Ty{}", gen_args(path.segments.last().unwrap())));
-                } else if cx.tcx.is_diagnostic_item(sym::TyCtxt, did) {
-                    return Some(format!("TyCtxt{}", gen_args(path.segments.last().unwrap())));
-                }
+    if let TyKind::Path(qpath) = &ty.kind {
+        if let QPath::Resolved(_, path) = qpath {
+            let did = path.res.opt_def_id()?;
+            if cx.tcx.is_diagnostic_item(sym::Ty, did) {
+                return Some(format!("Ty{}", gen_args(path.segments.last().unwrap())));
+            } else if cx.tcx.is_diagnostic_item(sym::TyCtxt, did) {
+                return Some(format!("TyCtxt{}", gen_args(path.segments.last().unwrap())));
             }
         }
-        _ => {}
     }
 
     None
diff --git a/src/librustc_lint/late.rs b/src/librustc_lint/late.rs
index d2cc5510603..1999a8ec5f6 100644
--- a/src/librustc_lint/late.rs
+++ b/src/librustc_lint/late.rs
@@ -15,8 +15,6 @@
 //! for all lint attributes.
 
 use crate::{passes::LateLintPassObject, LateContext, LateLintPass, LintStore};
-use rustc::hir::map::Map;
-use rustc::ty::{self, TyCtxt};
 use rustc_ast::ast;
 use rustc_ast::walk_list;
 use rustc_data_structures::sync::{join, par_iter, ParallelIterator};
@@ -24,6 +22,8 @@ use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::intravisit as hir_visit;
 use rustc_hir::intravisit::Visitor;
+use rustc_middle::hir::map::Map;
+use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::lint::LintPass;
 use rustc_span::Span;
 
diff --git a/src/librustc_lint/levels.rs b/src/librustc_lint/levels.rs
index 2062f9499ae..c78b088fb12 100644
--- a/src/librustc_lint/levels.rs
+++ b/src/librustc_lint/levels.rs
@@ -1,10 +1,5 @@
 use crate::context::{CheckLintNameResult, LintStore};
 use crate::late::unerased_lint_store;
-use rustc::hir::map::Map;
-use rustc::lint::LintDiagnosticBuilder;
-use rustc::lint::{struct_lint_level, LintLevelMap, LintLevelSets, LintSet, LintSource};
-use rustc::ty::query::Providers;
-use rustc::ty::TyCtxt;
 use rustc_ast::ast;
 use rustc_ast::attr;
 use rustc_ast::unwrap_or;
@@ -14,6 +9,11 @@ use rustc_errors::{struct_span_err, Applicability};
 use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_hir::{intravisit, HirId};
+use rustc_middle::hir::map::Map;
+use rustc_middle::lint::LintDiagnosticBuilder;
+use rustc_middle::lint::{struct_lint_level, LintLevelMap, LintLevelSets, LintSet, LintSource};
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::TyCtxt;
 use rustc_session::lint::{builtin, Level, Lint};
 use rustc_session::parse::feature_err;
 use rustc_session::Session;
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 825ac04bc09..af1fad2c660 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -19,7 +19,7 @@
 //! example) requires more effort. See `emit_lint` and `GatherNodeLevels`
 //! in `context.rs`.
 //!
-//! Some code also exists in `rustc_session::lint`, `rustc::lint`.
+//! Some code also exists in `rustc_session::lint`, `rustc_middle::lint`.
 //!
 //! ## Note
 //!
@@ -35,7 +35,7 @@
 #![recursion_limit = "256"]
 
 #[macro_use]
-extern crate rustc;
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_session;
 
@@ -53,11 +53,11 @@ mod redundant_semicolon;
 mod types;
 mod unused;
 
-use rustc::ty::query::Providers;
-use rustc::ty::TyCtxt;
 use rustc_ast::ast;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::TyCtxt;
 use rustc_session::lint::builtin::{
     BARE_TRAIT_OBJECTS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS,
     INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS,
@@ -104,6 +104,7 @@ macro_rules! early_lint_passes {
             $args,
             [
                 UnusedParens: UnusedParens,
+                UnusedBraces: UnusedBraces,
                 UnusedImportBraces: UnusedImportBraces,
                 UnsafeCode: UnsafeCode,
                 AnonymousParameters: AnonymousParameters,
@@ -275,6 +276,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
         UNUSED_FEATURES,
         UNUSED_LABELS,
         UNUSED_PARENS,
+        UNUSED_BRACES,
         REDUNDANT_SEMICOLONS
     );
 
diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs
index afab55358d9..052b461039b 100644
--- a/src/librustc_lint/nonstandard_style.rs
+++ b/src/librustc_lint/nonstandard_style.rs
@@ -1,5 +1,4 @@
 use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
-use rustc::ty;
 use rustc_ast::ast;
 use rustc_attr as attr;
 use rustc_errors::Applicability;
@@ -7,6 +6,7 @@ use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{GenericParamKind, PatKind};
+use rustc_middle::ty;
 use rustc_span::symbol::sym;
 use rustc_span::{symbol::Ident, BytePos, Span};
 use rustc_target::spec::abi::Abi;
diff --git a/src/librustc_lint/passes.rs b/src/librustc_lint/passes.rs
index ace15471445..c9e12afedbb 100644
--- a/src/librustc_lint/passes.rs
+++ b/src/librustc_lint/passes.rs
@@ -170,6 +170,7 @@ macro_rules! early_lint_methods {
             fn check_stmt(a: &ast::Stmt);
             fn check_arm(a: &ast::Arm);
             fn check_pat(a: &ast::Pat);
+            fn check_anon_const(a: &ast::AnonConst);
             fn check_pat_post(a: &ast::Pat);
             fn check_expr(a: &ast::Expr);
             fn check_expr_post(a: &ast::Expr);
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index fcd50001cb3..a6e1ed84c87 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -1,10 +1,6 @@
 #![allow(non_snake_case)]
 
 use crate::{LateContext, LateLintPass, LintContext};
-use rustc::mir::interpret::{sign_extend, truncate};
-use rustc::ty::layout::{self, IntegerExt, LayoutOf, SizeSkeleton, VariantIdx};
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
 use rustc_ast::ast;
 use rustc_attr as attr;
 use rustc_data_structures::fx::FxHashSet;
@@ -13,9 +9,14 @@ use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 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::{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;
@@ -150,7 +151,7 @@ fn report_bin_hex_error(
     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) => {
@@ -919,7 +920,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
     }
 
     fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
-        use crate::rustc::ty::TypeFoldable;
+        use rustc_middle::ty::TypeFoldable;
 
         struct ProhibitOpaqueTypes<'tcx> {
             ty: Option<Ty<'tcx>>,
@@ -1034,8 +1035,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
                 | 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_lint/unused.rs b/src/librustc_lint/unused.rs
index b5826d6a5ef..c74b399555a 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -1,7 +1,7 @@
+use crate::Lint;
 use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
-use rustc::ty::adjustment;
-use rustc::ty::{self, Ty};
 use rustc_ast::ast;
+use rustc_ast::ast::{ExprKind, StmtKind};
 use rustc_ast::attr;
 use rustc_ast::util::parser;
 use rustc_ast_pretty::pprust;
@@ -11,6 +11,8 @@ use rustc_feature::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty::adjustment;
+use rustc_middle::ty::{self, Ty};
 use rustc_session::lint::builtin::UNUSED_ATTRIBUTES;
 use rustc_span::symbol::Symbol;
 use rustc_span::symbol::{kw, sym};
@@ -285,12 +287,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
         let attr_info = attr.ident().and_then(|ident| self.builtin_attributes.get(&ident.name));
 
         if let Some(&&(name, ty, ..)) = attr_info {
-            match ty {
-                AttributeType::Whitelisted => {
-                    debug!("{:?} is Whitelisted", name);
-                    return;
-                }
-                _ => (),
+            if let AttributeType::Whitelisted = ty {
+                debug!("{:?} is Whitelisted", name);
+                return;
             }
         }
 
@@ -318,16 +317,58 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
     }
 }
 
-declare_lint! {
-    pub(super) UNUSED_PARENS,
-    Warn,
-    "`if`, `match`, `while` and `return` do not need parentheses"
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+enum UnusedDelimsCtx {
+    FunctionArg,
+    MethodArg,
+    AssignedValue,
+    IfCond,
+    WhileCond,
+    ForIterExpr,
+    MatchScrutineeExpr,
+    ReturnValue,
+    BlockRetValue,
+    LetScrutineeExpr,
+    ArrayLenExpr,
+    AnonConst,
 }
 
-declare_lint_pass!(UnusedParens => [UNUSED_PARENS]);
+impl From<UnusedDelimsCtx> for &'static str {
+    fn from(ctx: UnusedDelimsCtx) -> &'static str {
+        match ctx {
+            UnusedDelimsCtx::FunctionArg => "function argument",
+            UnusedDelimsCtx::MethodArg => "method argument",
+            UnusedDelimsCtx::AssignedValue => "assigned value",
+            UnusedDelimsCtx::IfCond => "`if` condition",
+            UnusedDelimsCtx::WhileCond => "`while` condition",
+            UnusedDelimsCtx::ForIterExpr => "`for` iterator expression",
+            UnusedDelimsCtx::MatchScrutineeExpr => "`match` scrutinee expression",
+            UnusedDelimsCtx::ReturnValue => "`return` value",
+            UnusedDelimsCtx::BlockRetValue => "block return value",
+            UnusedDelimsCtx::LetScrutineeExpr => "`let` scrutinee expression",
+            UnusedDelimsCtx::ArrayLenExpr | UnusedDelimsCtx::AnonConst => "const expression",
+        }
+    }
+}
 
-impl UnusedParens {
-    fn is_expr_parens_necessary(inner: &ast::Expr, followed_by_block: bool) -> bool {
+/// Used by both `UnusedParens` and `UnusedBraces` to prevent code duplication.
+trait UnusedDelimLint {
+    const DELIM_STR: &'static str;
+
+    // this cannot be a constant is it refers to a static.
+    fn lint(&self) -> &'static Lint;
+
+    fn check_unused_delims_expr(
+        &self,
+        cx: &EarlyContext<'_>,
+        value: &ast::Expr,
+        ctx: UnusedDelimsCtx,
+        followed_by_block: bool,
+        left_pos: Option<BytePos>,
+        right_pos: Option<BytePos>,
+    );
+
+    fn is_expr_delims_necessary(inner: &ast::Expr, followed_by_block: bool) -> bool {
         followed_by_block
             && match inner.kind {
                 ast::ExprKind::Ret(_) | ast::ExprKind::Break(..) => true,
@@ -335,98 +376,41 @@ impl UnusedParens {
             }
     }
 
-    fn check_unused_parens_expr(
+    fn emit_unused_delims_expr(
         &self,
         cx: &EarlyContext<'_>,
         value: &ast::Expr,
-        msg: &str,
-        followed_by_block: bool,
+        ctx: UnusedDelimsCtx,
         left_pos: Option<BytePos>,
         right_pos: Option<BytePos>,
     ) {
-        match value.kind {
-            ast::ExprKind::Paren(ref inner) => {
-                if !Self::is_expr_parens_necessary(inner, followed_by_block)
-                    && value.attrs.is_empty()
-                    && !value.span.from_expansion()
-                {
-                    let expr_text =
-                        if let Ok(snippet) = cx.sess().source_map().span_to_snippet(value.span) {
-                            snippet
-                        } else {
-                            pprust::expr_to_string(value)
-                        };
-                    let keep_space = (
-                        left_pos.map(|s| s >= value.span.lo()).unwrap_or(false),
-                        right_pos.map(|s| s <= value.span.hi()).unwrap_or(false),
-                    );
-                    Self::remove_outer_parens(cx, value.span, &expr_text, msg, keep_space);
-                }
-            }
-            ast::ExprKind::Let(_, ref expr) => {
-                // FIXME(#60336): Properly handle `let true = (false && true)`
-                // actually needing the parenthesis.
-                self.check_unused_parens_expr(
-                    cx,
-                    expr,
-                    "`let` head expression",
-                    followed_by_block,
-                    None,
-                    None,
-                );
-            }
-            _ => {}
-        }
+        let expr_text = if let Ok(snippet) = cx.sess().source_map().span_to_snippet(value.span) {
+            snippet
+        } else {
+            pprust::expr_to_string(value)
+        };
+        let keep_space = (
+            left_pos.map(|s| s >= value.span.lo()).unwrap_or(false),
+            right_pos.map(|s| s <= value.span.hi()).unwrap_or(false),
+        );
+        self.emit_unused_delims(cx, value.span, &expr_text, ctx.into(), keep_space);
     }
 
-    fn check_unused_parens_pat(
+    fn emit_unused_delims(
         &self,
         cx: &EarlyContext<'_>,
-        value: &ast::Pat,
-        avoid_or: bool,
-        avoid_mut: bool,
-    ) {
-        use ast::{BindingMode, Mutability, PatKind};
-
-        if let PatKind::Paren(inner) = &value.kind {
-            match inner.kind {
-                // The lint visitor will visit each subpattern of `p`. We do not want to lint
-                // any range pattern no matter where it occurs in the pattern. For something like
-                // `&(a..=b)`, there is a recursive `check_pat` on `a` and `b`, but we will assume
-                // that if there are unnecessary parens they serve a purpose of readability.
-                PatKind::Range(..) => return,
-                // Avoid `p0 | .. | pn` if we should.
-                PatKind::Or(..) if avoid_or => return,
-                // Avoid `mut x` and `mut x @ p` if we should:
-                PatKind::Ident(BindingMode::ByValue(Mutability::Mut), ..) if avoid_mut => return,
-                // Otherwise proceed with linting.
-                _ => {}
-            }
-
-            let pattern_text =
-                if let Ok(snippet) = cx.sess().source_map().span_to_snippet(value.span) {
-                    snippet
-                } else {
-                    pprust::pat_to_string(value)
-                };
-            Self::remove_outer_parens(cx, value.span, &pattern_text, "pattern", (false, false));
-        }
-    }
-
-    fn remove_outer_parens(
-        cx: &EarlyContext<'_>,
         span: Span,
         pattern: &str,
         msg: &str,
         keep_space: (bool, bool),
     ) {
-        cx.struct_span_lint(UNUSED_PARENS, span, |lint| {
-            let span_msg = format!("unnecessary parentheses around {}", msg);
+        cx.struct_span_lint(self.lint(), span, |lint| {
+            let span_msg = format!("unnecessary {} around {}", Self::DELIM_STR, msg);
             let mut err = lint.build(&span_msg);
             let mut ate_left_paren = false;
             let mut ate_right_paren = false;
             let parens_removed = pattern.trim_matches(|c| match c {
-                '(' => {
+                '(' | '{' => {
                     if ate_left_paren {
                         false
                     } else {
@@ -434,7 +418,7 @@ impl UnusedParens {
                         true
                     }
                 }
-                ')' => {
+                ')' | '}' => {
                     if ate_right_paren {
                         false
                     } else {
@@ -460,61 +444,51 @@ impl UnusedParens {
                 replace
             };
 
-            err.span_suggestion_short(
-                span,
-                "remove these parentheses",
-                replace,
-                Applicability::MachineApplicable,
-            );
+            let suggestion = format!("remove these {}", Self::DELIM_STR);
+
+            err.span_suggestion_short(span, &suggestion, replace, Applicability::MachineApplicable);
             err.emit();
         });
     }
-}
 
-impl EarlyLintPass for UnusedParens {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
         use rustc_ast::ast::ExprKind::*;
-        let (value, msg, followed_by_block, left_pos, right_pos) = match e.kind {
-            Let(ref pat, ..) => {
-                self.check_unused_parens_pat(cx, pat, false, false);
-                return;
-            }
-
+        let (value, ctx, followed_by_block, left_pos, right_pos) = match e.kind {
             If(ref cond, ref block, ..) => {
                 let left = e.span.lo() + rustc_span::BytePos(2);
                 let right = block.span.lo();
-                (cond, "`if` condition", true, Some(left), Some(right))
+                (cond, UnusedDelimsCtx::IfCond, true, Some(left), Some(right))
             }
 
             While(ref cond, ref block, ..) => {
                 let left = e.span.lo() + rustc_span::BytePos(5);
                 let right = block.span.lo();
-                (cond, "`while` condition", true, Some(left), Some(right))
+                (cond, UnusedDelimsCtx::WhileCond, true, Some(left), Some(right))
             }
 
-            ForLoop(ref pat, ref cond, ref block, ..) => {
-                self.check_unused_parens_pat(cx, pat, false, false);
-                (cond, "`for` head expression", true, None, Some(block.span.lo()))
+            ForLoop(_, ref cond, ref block, ..) => {
+                (cond, UnusedDelimsCtx::ForIterExpr, true, None, Some(block.span.lo()))
             }
 
             Match(ref head, _) => {
                 let left = e.span.lo() + rustc_span::BytePos(5);
-                (head, "`match` head expression", true, Some(left), None)
+                (head, UnusedDelimsCtx::MatchScrutineeExpr, true, Some(left), None)
             }
 
             Ret(Some(ref value)) => {
                 let left = e.span.lo() + rustc_span::BytePos(3);
-                (value, "`return` value", false, Some(left), None)
+                (value, UnusedDelimsCtx::ReturnValue, false, Some(left), None)
             }
 
-            Assign(_, ref value, _) => (value, "assigned value", false, None, None),
-            AssignOp(.., ref value) => (value, "assigned value", false, None, None),
+            Assign(_, ref value, _) | AssignOp(.., ref value) => {
+                (value, UnusedDelimsCtx::AssignedValue, false, None, None)
+            }
             // either function/method call, or something this lint doesn't care about
             ref call_or_other => {
-                let (args_to_check, call_kind) = match *call_or_other {
-                    Call(_, ref args) => (&args[..], "function"),
-                    // first "argument" is self (which sometimes needs parens)
-                    MethodCall(_, ref args) => (&args[1..], "method"),
+                let (args_to_check, ctx) = match *call_or_other {
+                    Call(_, ref args) => (&args[..], UnusedDelimsCtx::FunctionArg),
+                    // first "argument" is self (which sometimes needs delims)
+                    MethodCall(_, ref args) => (&args[1..], UnusedDelimsCtx::MethodArg),
                     // actual catch-all arm
                     _ => {
                         return;
@@ -527,14 +501,152 @@ impl EarlyLintPass for UnusedParens {
                 if e.span.ctxt().outer_expn_data().call_site.from_expansion() {
                     return;
                 }
-                let msg = format!("{} argument", call_kind);
                 for arg in args_to_check {
-                    self.check_unused_parens_expr(cx, arg, &msg, false, None, None);
+                    self.check_unused_delims_expr(cx, arg, ctx, false, None, None);
                 }
                 return;
             }
         };
-        self.check_unused_parens_expr(cx, &value, msg, followed_by_block, left_pos, right_pos);
+        self.check_unused_delims_expr(cx, &value, ctx, followed_by_block, left_pos, right_pos);
+    }
+
+    fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
+        match s.kind {
+            StmtKind::Local(ref local) => {
+                if let Some(ref value) = local.init {
+                    self.check_unused_delims_expr(
+                        cx,
+                        &value,
+                        UnusedDelimsCtx::AssignedValue,
+                        false,
+                        None,
+                        None,
+                    );
+                }
+            }
+            StmtKind::Expr(ref expr) => {
+                self.check_unused_delims_expr(
+                    cx,
+                    &expr,
+                    UnusedDelimsCtx::BlockRetValue,
+                    false,
+                    None,
+                    None,
+                );
+            }
+            _ => {}
+        }
+    }
+
+    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
+        use ast::ItemKind::*;
+
+        if let Const(.., Some(expr)) | Static(.., Some(expr)) = &item.kind {
+            self.check_unused_delims_expr(
+                cx,
+                expr,
+                UnusedDelimsCtx::AssignedValue,
+                false,
+                None,
+                None,
+            );
+        }
+    }
+}
+
+declare_lint! {
+    pub(super) UNUSED_PARENS,
+    Warn,
+    "`if`, `match`, `while` and `return` do not need parentheses"
+}
+
+declare_lint_pass!(UnusedParens => [UNUSED_PARENS]);
+
+impl UnusedDelimLint for UnusedParens {
+    const DELIM_STR: &'static str = "parentheses";
+
+    fn lint(&self) -> &'static Lint {
+        UNUSED_PARENS
+    }
+
+    fn check_unused_delims_expr(
+        &self,
+        cx: &EarlyContext<'_>,
+        value: &ast::Expr,
+        ctx: UnusedDelimsCtx,
+        followed_by_block: bool,
+        left_pos: Option<BytePos>,
+        right_pos: Option<BytePos>,
+    ) {
+        match value.kind {
+            ast::ExprKind::Paren(ref inner) => {
+                if !Self::is_expr_delims_necessary(inner, followed_by_block)
+                    && value.attrs.is_empty()
+                    && !value.span.from_expansion()
+                {
+                    self.emit_unused_delims_expr(cx, value, ctx, left_pos, right_pos)
+                }
+            }
+            ast::ExprKind::Let(_, ref expr) => {
+                // FIXME(#60336): Properly handle `let true = (false && true)`
+                // actually needing the parenthesis.
+                self.check_unused_delims_expr(
+                    cx,
+                    expr,
+                    UnusedDelimsCtx::LetScrutineeExpr,
+                    followed_by_block,
+                    None,
+                    None,
+                );
+            }
+            _ => {}
+        }
+    }
+}
+
+impl UnusedParens {
+    fn check_unused_parens_pat(
+        &self,
+        cx: &EarlyContext<'_>,
+        value: &ast::Pat,
+        avoid_or: bool,
+        avoid_mut: bool,
+    ) {
+        use ast::{BindingMode, Mutability, PatKind};
+
+        if let PatKind::Paren(inner) = &value.kind {
+            match inner.kind {
+                // The lint visitor will visit each subpattern of `p`. We do not want to lint
+                // any range pattern no matter where it occurs in the pattern. For something like
+                // `&(a..=b)`, there is a recursive `check_pat` on `a` and `b`, but we will assume
+                // that if there are unnecessary parens they serve a purpose of readability.
+                PatKind::Range(..) => return,
+                // Avoid `p0 | .. | pn` if we should.
+                PatKind::Or(..) if avoid_or => return,
+                // Avoid `mut x` and `mut x @ p` if we should:
+                PatKind::Ident(BindingMode::ByValue(Mutability::Mut), ..) if avoid_mut => return,
+                // Otherwise proceed with linting.
+                _ => {}
+            }
+
+            let pattern_text =
+                if let Ok(snippet) = cx.sess().source_map().span_to_snippet(value.span) {
+                    snippet
+                } else {
+                    pprust::pat_to_string(value)
+                };
+            self.emit_unused_delims(cx, value.span, &pattern_text, "pattern", (false, false));
+        }
+    }
+}
+
+impl EarlyLintPass for UnusedParens {
+    fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
+        if let ExprKind::Let(ref pat, ..) | ExprKind::ForLoop(ref pat, ..) = e.kind {
+            self.check_unused_parens_pat(cx, pat, false, false);
+        }
+
+        <Self as UnusedDelimLint>::check_expr(self, cx, e)
     }
 
     fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) {
@@ -559,22 +671,16 @@ impl EarlyLintPass for UnusedParens {
         }
     }
 
-    fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
-        use ast::StmtKind::*;
-
-        match s.kind {
-            Local(ref local) => {
-                self.check_unused_parens_pat(cx, &local.pat, false, false);
+    fn check_anon_const(&mut self, cx: &EarlyContext<'_>, c: &ast::AnonConst) {
+        self.check_unused_delims_expr(cx, &c.value, UnusedDelimsCtx::AnonConst, false, None, None);
+    }
 
-                if let Some(ref value) = local.init {
-                    self.check_unused_parens_expr(cx, &value, "assigned value", false, None, None);
-                }
-            }
-            Expr(ref expr) => {
-                self.check_unused_parens_expr(cx, &expr, "block return value", false, None, None);
-            }
-            _ => {}
+    fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
+        if let StmtKind::Local(ref local) = s.kind {
+            self.check_unused_parens_pat(cx, &local.pat, false, false);
         }
+
+        <Self as UnusedDelimLint>::check_stmt(self, cx, s)
     }
 
     fn check_param(&mut self, cx: &EarlyContext<'_>, param: &ast::Param) {
@@ -590,6 +696,16 @@ impl EarlyLintPass for UnusedParens {
             match &r.kind {
                 &ast::TyKind::TraitObject(..) => {}
                 &ast::TyKind::ImplTrait(_, ref bounds) if bounds.len() > 1 => {}
+                &ast::TyKind::Array(_, ref len) => {
+                    self.check_unused_delims_expr(
+                        cx,
+                        &len.value,
+                        UnusedDelimsCtx::ArrayLenExpr,
+                        false,
+                        None,
+                        None,
+                    );
+                }
                 _ => {
                     let pattern_text =
                         if let Ok(snippet) = cx.sess().source_map().span_to_snippet(ty.span) {
@@ -598,21 +714,136 @@ impl EarlyLintPass for UnusedParens {
                             pprust::ty_to_string(ty)
                         };
 
-                    Self::remove_outer_parens(cx, ty.span, &pattern_text, "type", (false, false));
+                    self.emit_unused_delims(cx, ty.span, &pattern_text, "type", (false, false));
                 }
             }
         }
     }
 
     fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
-        use ast::ItemKind::*;
+        <Self as UnusedDelimLint>::check_item(self, cx, item)
+    }
+}
 
-        if let Const(.., Some(expr)) | Static(.., Some(expr)) = &item.kind {
-            self.check_unused_parens_expr(cx, expr, "assigned value", false, None, None);
+declare_lint! {
+    pub(super) UNUSED_BRACES,
+    Warn,
+    "unnecessary braces around an expression"
+}
+
+declare_lint_pass!(UnusedBraces => [UNUSED_BRACES]);
+
+impl UnusedDelimLint for UnusedBraces {
+    const DELIM_STR: &'static str = "braces";
+
+    fn lint(&self) -> &'static Lint {
+        UNUSED_BRACES
+    }
+
+    fn check_unused_delims_expr(
+        &self,
+        cx: &EarlyContext<'_>,
+        value: &ast::Expr,
+        ctx: UnusedDelimsCtx,
+        followed_by_block: bool,
+        left_pos: Option<BytePos>,
+        right_pos: Option<BytePos>,
+    ) {
+        match value.kind {
+            ast::ExprKind::Block(ref inner, None)
+                if inner.rules == ast::BlockCheckMode::Default =>
+            {
+                // emit a warning under the following conditions:
+                //
+                // - the block does not have a label
+                // - the block is not `unsafe`
+                // - the block contains exactly one expression (do not lint `{ expr; }`)
+                // - `followed_by_block` is true and the internal expr may contain a `{`
+                // - the block is not multiline (do not lint multiline match arms)
+                //      ```
+                //      match expr {
+                //          Pattern => {
+                //              somewhat_long_expression
+                //          }
+                //          // ...
+                //      }
+                //      ```
+                // - the block has no attribute and was not created inside a macro
+                // - if the block is an `anon_const`, the inner expr must be a literal
+                //      (do not lint `struct A<const N: usize>; let _: A<{ 2 + 3 }>;`)
+                //
+                // FIXME(const_generics): handle paths when #67075 is fixed.
+                if let [stmt] = inner.stmts.as_slice() {
+                    if let ast::StmtKind::Expr(ref expr) = stmt.kind {
+                        if !Self::is_expr_delims_necessary(expr, followed_by_block)
+                            && (ctx != UnusedDelimsCtx::AnonConst
+                                || matches!(expr.kind, ast::ExprKind::Lit(_)))
+                            // array length expressions are checked during `check_anon_const` and `check_ty`,
+                            // once as `ArrayLenExpr` and once as `AnonConst`.
+                            //
+                            // As we do not want to lint this twice, we do not emit an error for
+                            // `ArrayLenExpr` if `AnonConst` would do the same.
+                            && (ctx != UnusedDelimsCtx::ArrayLenExpr
+                                || !matches!(expr.kind, ast::ExprKind::Lit(_)))
+                            && !cx.sess().source_map().is_multiline(value.span)
+                            && value.attrs.is_empty()
+                            && !value.span.from_expansion()
+                        {
+                            self.emit_unused_delims_expr(cx, value, ctx, left_pos, right_pos)
+                        }
+                    }
+                }
+            }
+            ast::ExprKind::Let(_, ref expr) => {
+                // FIXME(#60336): Properly handle `let true = (false && true)`
+                // actually needing the parenthesis.
+                self.check_unused_delims_expr(
+                    cx,
+                    expr,
+                    UnusedDelimsCtx::LetScrutineeExpr,
+                    followed_by_block,
+                    None,
+                    None,
+                );
+            }
+            _ => {}
         }
     }
 }
 
+impl EarlyLintPass for UnusedBraces {
+    fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
+        <Self as UnusedDelimLint>::check_expr(self, cx, e)
+    }
+
+    fn check_anon_const(&mut self, cx: &EarlyContext<'_>, c: &ast::AnonConst) {
+        self.check_unused_delims_expr(cx, &c.value, UnusedDelimsCtx::AnonConst, false, None, None);
+    }
+
+    fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
+        <Self as UnusedDelimLint>::check_stmt(self, cx, s)
+    }
+
+    fn check_ty(&mut self, cx: &EarlyContext<'_>, ty: &ast::Ty) {
+        if let &ast::TyKind::Paren(ref r) = &ty.kind {
+            if let ast::TyKind::Array(_, ref len) = r.kind {
+                self.check_unused_delims_expr(
+                    cx,
+                    &len.value,
+                    UnusedDelimsCtx::ArrayLenExpr,
+                    false,
+                    None,
+                    None,
+                );
+            }
+        }
+    }
+
+    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
+        <Self as UnusedDelimLint>::check_item(self, cx, item)
+    }
+}
+
 declare_lint! {
     UNUSED_IMPORT_BRACES,
     Allow,
diff --git a/src/librustc_macros/src/hash_stable.rs b/src/librustc_macros/src/hash_stable.rs
index dc6ae961e5a..c955c137782 100644
--- a/src/librustc_macros/src/hash_stable.rs
+++ b/src/librustc_macros/src/hash_stable.rs
@@ -115,13 +115,13 @@ pub fn hash_stable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::To
     s.bound_impl(
         quote!(
             ::rustc_data_structures::stable_hasher::HashStable<
-                ::rustc::ich::StableHashingContext<'__ctx>,
+                ::rustc_middle::ich::StableHashingContext<'__ctx>,
             >
         ),
         quote! {
             fn hash_stable(
                 &self,
-                __hcx: &mut ::rustc::ich::StableHashingContext<'__ctx>,
+                __hcx: &mut ::rustc_middle::ich::StableHashingContext<'__ctx>,
                 __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                 #discriminant
                 match *self { #body }
diff --git a/src/librustc_macros/src/lift.rs b/src/librustc_macros/src/lift.rs
index a246b34b2c2..4bf4ce00a4d 100644
--- a/src/librustc_macros/src/lift.rs
+++ b/src/librustc_macros/src/lift.rs
@@ -39,11 +39,11 @@ pub fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStre
 
     s.add_impl_generic(newtcx);
     s.bound_impl(
-        quote!(::rustc::ty::Lift<'__lifted>),
+        quote!(::rustc_middle::ty::Lift<'__lifted>),
         quote! {
             type Lifted = #lifted;
 
-            fn lift_to_tcx(&self, __tcx: ::rustc::ty::TyCtxt<'__lifted>) -> Option<#lifted> {
+            fn lift_to_tcx(&self, __tcx: ::rustc_middle::ty::TyCtxt<'__lifted>) -> Option<#lifted> {
                 Some(match *self { #body })
             }
         },
diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs
index 26c3bce4a9a..7ed77304a90 100644
--- a/src/librustc_macros/src/query.rs
+++ b/src/librustc_macros/src/query.rs
@@ -356,9 +356,11 @@ fn add_query_description_impl(
                 quote! { #t }
             })
             .unwrap_or(quote! { _ });
+        // expr is a `Block`, meaning that `{ #expr }` gets expanded
+        // to `{ { stmts... } }`, which triggers the `unused_braces` lint.
         quote! {
             #[inline]
-            #[allow(unused_variables)]
+            #[allow(unused_variables, unused_braces)]
             fn cache_on_disk(
                 #tcx: TyCtxt<'tcx>,
                 #key: Self::Key,
@@ -429,7 +431,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
                 });
 
                 try_load_from_on_disk_cache_stream.extend(quote! {
-                    ::rustc::dep_graph::DepKind::#name => {
+                    ::rustc_middle::dep_graph::DepKind::#name => {
                         if <#arg as DepNodeParams<TyCtxt<'_>>>::CAN_RECONSTRUCT_QUERY_KEY {
                             debug_assert!($tcx.dep_graph
                                             .node_color($dep_node)
@@ -486,7 +488,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
 
             // Add a match arm to force the query given the dep node
             dep_node_force_stream.extend(quote! {
-                ::rustc::dep_graph::DepKind::#name => {
+                ::rustc_middle::dep_graph::DepKind::#name => {
                     if <#arg as DepNodeParams<TyCtxt<'_>>>::CAN_RECONSTRUCT_QUERY_KEY {
                         if let Some(key) = <#arg as DepNodeParams<TyCtxt<'_>>>::recover($tcx, $dep_node) {
                             force_query::<crate::ty::query::queries::#name<'_>, _>(
@@ -510,7 +512,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
     }
 
     dep_node_force_stream.extend(quote! {
-        ::rustc::dep_graph::DepKind::Null => {
+        ::rustc_middle::dep_graph::DepKind::Null => {
             bug!("Cannot force dep node: {:?}", $dep_node)
         }
     });
diff --git a/src/librustc_macros/src/type_foldable.rs b/src/librustc_macros/src/type_foldable.rs
index 687401e3344..6931e6552ad 100644
--- a/src/librustc_macros/src/type_foldable.rs
+++ b/src/librustc_macros/src/type_foldable.rs
@@ -11,25 +11,25 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::
         vi.construct(|_, index| {
             let bind = &bindings[index];
             quote! {
-                ::rustc::ty::fold::TypeFoldable::fold_with(#bind, __folder)
+                ::rustc_middle::ty::fold::TypeFoldable::fold_with(#bind, __folder)
             }
         })
     });
     let body_visit = s.fold(false, |acc, bind| {
-        quote! { #acc || ::rustc::ty::fold::TypeFoldable::visit_with(#bind, __folder) }
+        quote! { #acc || ::rustc_middle::ty::fold::TypeFoldable::visit_with(#bind, __folder) }
     });
 
     s.bound_impl(
-        quote!(::rustc::ty::fold::TypeFoldable<'tcx>),
+        quote!(::rustc_middle::ty::fold::TypeFoldable<'tcx>),
         quote! {
-            fn super_fold_with<__F: ::rustc::ty::fold::TypeFolder<'tcx>>(
+            fn super_fold_with<__F: ::rustc_middle::ty::fold::TypeFolder<'tcx>>(
                 &self,
                 __folder: &mut __F
             ) -> Self {
                 match *self { #body_fold }
             }
 
-            fn super_visit_with<__F: ::rustc::ty::fold::TypeVisitor<'tcx>>(
+            fn super_visit_with<__F: ::rustc_middle::ty::fold::TypeVisitor<'tcx>>(
                 &self,
                 __folder: &mut __F
             ) -> bool {
diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml
index ea439b1f41d..a88ccd52e91 100644
--- a/src/librustc_metadata/Cargo.toml
+++ b/src/librustc_metadata/Cargo.toml
@@ -14,7 +14,7 @@ flate2 = "1.0"
 log = "0.4"
 memmap = "0.7"
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc_attr = { path = "../librustc_attr" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors" }
diff --git a/src/librustc_metadata/build.rs b/src/librustc_metadata/build.rs
index d230ba91039..7d5c58ecea2 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/creader.rs b/src/librustc_metadata/creader.rs
index a807fa6b8d4..3e5d7b8efd5 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -3,9 +3,6 @@
 use crate::locator::{CrateLocator, CratePaths};
 use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob};
 
-use rustc::middle::cstore::DepKind;
-use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource, MetadataLoaderDyn};
-use rustc::ty::TyCtxt;
 use rustc_ast::expand::allocator::{global_allocator_spans, AllocatorKind};
 use rustc_ast::{ast, attr};
 use rustc_data_structures::svh::Svh;
@@ -15,6 +12,11 @@ use rustc_expand::base::SyntaxExtension;
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_hir::definitions::Definitions;
 use rustc_index::vec::IndexVec;
+use rustc_middle::middle::cstore::DepKind;
+use rustc_middle::middle::cstore::{
+    CrateSource, ExternCrate, ExternCrateSource, MetadataLoaderDyn,
+};
+use rustc_middle::ty::TyCtxt;
 use rustc_session::config;
 use rustc_session::output::validate_crate_name;
 use rustc_session::search_paths::PathKind;
diff --git a/src/librustc_metadata/dependency_format.rs b/src/librustc_metadata/dependency_format.rs
index 4cfaf03b7a5..91654067f08 100644
--- a/src/librustc_metadata/dependency_format.rs
+++ b/src/librustc_metadata/dependency_format.rs
@@ -53,12 +53,12 @@
 
 use crate::creader::CStore;
 
-use rustc::middle::cstore::LinkagePreference::{self, RequireDynamic, RequireStatic};
-use rustc::middle::cstore::{self, DepKind};
-use rustc::middle::dependency_format::{Dependencies, DependencyList, Linkage};
-use rustc::ty::TyCtxt;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::CrateNum;
+use rustc_middle::middle::cstore::LinkagePreference::{self, RequireDynamic, RequireStatic};
+use rustc_middle::middle::cstore::{self, DepKind};
+use rustc_middle::middle::dependency_format::{Dependencies, DependencyList, Linkage};
+use rustc_middle::ty::TyCtxt;
 use rustc_session::config;
 use rustc_target::spec::PanicStrategy;
 
diff --git a/src/librustc_metadata/foreign_modules.rs b/src/librustc_metadata/foreign_modules.rs
index 60b8239a821..b312aa37d46 100644
--- a/src/librustc_metadata/foreign_modules.rs
+++ b/src/librustc_metadata/foreign_modules.rs
@@ -1,7 +1,7 @@
-use rustc::middle::cstore::ForeignModule;
-use rustc::ty::TyCtxt;
 use rustc_hir as hir;
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
+use rustc_middle::middle::cstore::ForeignModule;
+use rustc_middle::ty::TyCtxt;
 
 crate fn collect(tcx: TyCtxt<'_>) -> Vec<ForeignModule> {
     let mut collector = Collector { tcx, modules: Vec::new() };
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index 2993aed2f8a..22a2bf28041 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -14,7 +14,7 @@ extern crate libc;
 extern crate proc_macro;
 
 #[macro_use]
-extern crate rustc;
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_data_structures;
 
diff --git a/src/librustc_metadata/link_args.rs b/src/librustc_metadata/link_args.rs
index 56b26efe5bf..2dd4a9c9dbc 100644
--- a/src/librustc_metadata/link_args.rs
+++ b/src/librustc_metadata/link_args.rs
@@ -1,6 +1,6 @@
-use rustc::ty::TyCtxt;
 use rustc_hir as hir;
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::sym;
 use rustc_target::spec::abi::Abi;
 
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index c1a95c094b1..d56c8490ef5 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -215,11 +215,11 @@
 use crate::creader::Library;
 use crate::rmeta::{rustc_version, MetadataBlob, METADATA_HEADER};
 
-use rustc::middle::cstore::{CrateSource, MetadataLoader};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::MetadataRef;
 use rustc_errors::{struct_span_err, DiagnosticBuilder};
+use rustc_middle::middle::cstore::{CrateSource, MetadataLoader};
 use rustc_session::filesearch::{FileDoesntMatch, FileMatches, FileSearch};
 use rustc_session::search_paths::PathKind;
 use rustc_session::{config, CrateDisambiguator, Session};
diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs
index 19d2d620f58..4b92a2205c2 100644
--- a/src/librustc_metadata/native_libs.rs
+++ b/src/librustc_metadata/native_libs.rs
@@ -1,10 +1,10 @@
-use rustc::middle::cstore::{self, NativeLibrary};
-use rustc::ty::TyCtxt;
 use rustc_attr as attr;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
+use rustc_middle::middle::cstore::{self, NativeLibrary};
+use rustc_middle::ty::TyCtxt;
 use rustc_session::parse::feature_err;
 use rustc_session::Session;
 use rustc_span::source_map::Span;
@@ -162,8 +162,13 @@ impl Collector<'tcx> {
             }
         }
         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 4520df58899..c59b155d5db 100644
--- a/src/librustc_metadata/rmeta/decoder.rs
+++ b/src/librustc_metadata/rmeta/decoder.rs
@@ -4,17 +4,6 @@ use crate::creader::CrateMetadataRef;
 use crate::rmeta::table::{FixedSizeEncoding, Table};
 use crate::rmeta::*;
 
-use rustc::dep_graph::{self, DepNode, DepNodeExt, DepNodeIndex};
-use rustc::hir::exports::Export;
-use rustc::middle::cstore::{CrateSource, ExternCrate};
-use rustc::middle::cstore::{ForeignModule, LinkagePreference, NativeLibrary};
-use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
-use rustc::middle::lang_items;
-use rustc::mir::interpret::{AllocDecodingSession, AllocDecodingState};
-use rustc::mir::{self, interpret, BodyAndCache, Promoted};
-use rustc::ty::codec::TyDecoder;
-use rustc::ty::{self, Ty, TyCtxt};
-use rustc::util::common::record_time;
 use rustc_ast::ast::{self, Ident};
 use rustc_attr as attr;
 use rustc_data_structures::captures::Captures;
@@ -29,10 +18,21 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
 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::mir::interpret::{AllocDecodingSession, AllocDecodingState};
+use rustc_middle::mir::{self, interpret, BodyAndCache, Promoted};
+use rustc_middle::ty::codec::TyDecoder;
+use rustc_middle::ty::{self, Ty, TyCtxt};
+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,6 +41,7 @@ use proc_macro::bridge::client::ProcMacro;
 use std::io;
 use std::mem;
 use std::num::NonZeroUsize;
+use std::path::Path;
 use std::u32;
 
 pub use cstore_impl::{provide, provide_extern};
@@ -427,7 +428,7 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
         // 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 +458,7 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
             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 +634,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
     }
 
     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 +666,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
                 .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 +689,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
     }
 
     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 +782,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             ctor_did,
             data.discr,
             self.root
-                .per_def
+                .tables
                 .children
                 .get(self, index)
                 .unwrap_or(Lazy::empty())
@@ -812,7 +813,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
 
         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 +832,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         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 +841,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         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 +853,31 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         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 +887,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
     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 +915,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
     }
 
     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 +985,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
 
         // 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 +1005,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
                     EntryKind::ForeignMod => {
                         let child_children = self
                             .root
-                            .per_def
+                            .tables
                             .children
                             .get(self, child_index)
                             .unwrap_or(Lazy::empty());
@@ -1016,7 +1017,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
                                     vis: self.get_visibility(child_index),
                                     span: self
                                         .root
-                                        .per_def
+                                        .tables
                                         .span
                                         .get(self, child_index)
                                         .unwrap()
@@ -1096,13 +1097,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
     }
 
     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 +1122,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
     ) -> 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 +1173,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
     }
 
     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 +1210,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
 
         Lrc::from(
             self.root
-                .per_def
+                .tables
                 .attributes
                 .get(self, item_id)
                 .unwrap_or(Lazy::empty())
@@ -1220,7 +1221,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
 
     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 +1237,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
     ) -> &'tcx [DefId] {
         tcx.arena.alloc_from_iter(
             self.root
-                .per_def
+                .tables
                 .inherent_impls
                 .get(self, id)
                 .unwrap_or(Lazy::empty())
@@ -1416,7 +1417,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
     }
 
     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 +1461,45 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
     ///
     /// 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 +1508,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
                     // 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 +1521,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
                         ..
                     } = 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 +1548,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
                         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/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
index 7a1ac9e0a60..c99b1dc3606 100644
--- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
+++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
@@ -4,13 +4,6 @@ use crate::link_args;
 use crate::native_libs;
 use crate::rmeta::{self, encoder};
 
-use rustc::hir::exports::Export;
-use rustc::middle::cstore::{CrateSource, CrateStore, EncodedMetadata, NativeLibraryKind};
-use rustc::middle::exported_symbols::ExportedSymbol;
-use rustc::middle::stability::DeprecationEntry;
-use rustc::ty::query::Providers;
-use rustc::ty::query::QueryConfig;
-use rustc::ty::{self, TyCtxt};
 use rustc_ast::ast;
 use rustc_ast::attr;
 use rustc_ast::expand::allocator::AllocatorKind;
@@ -19,6 +12,13 @@ use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::definitions::DefPathTable;
 use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
+use rustc_middle::hir::exports::Export;
+use rustc_middle::middle::cstore::{CrateSource, CrateStore, EncodedMetadata, NativeLibraryKind};
+use rustc_middle::middle::exported_symbols::ExportedSymbol;
+use rustc_middle::middle::stability::DeprecationEntry;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::query::QueryConfig;
+use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::{CrateDisambiguator, Session};
 use rustc_span::source_map::{self, Span, Spanned};
 use rustc_span::symbol::Symbol;
diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs
index 3686b2f2048..f2e9f4d7e0b 100644
--- a/src/librustc_metadata/rmeta/encoder.rs
+++ b/src/librustc_metadata/rmeta/encoder.rs
@@ -2,16 +2,6 @@ use crate::rmeta::table::FixedSizeEncoding;
 use crate::rmeta::*;
 
 use log::{debug, trace};
-use rustc::hir::map::Map;
-use rustc::middle::cstore::{EncodedMetadata, ForeignModule, LinkagePreference, NativeLibrary};
-use rustc::middle::dependency_format::Linkage;
-use rustc::middle::exported_symbols::{metadata_symbol_name, ExportedSymbol, SymbolExportLevel};
-use rustc::middle::lang_items;
-use rustc::mir::{self, interpret};
-use rustc::traits::specialization_graph;
-use rustc::ty::codec::{self as ty_codec, TyEncoder};
-use rustc::ty::layout::VariantIdx;
-use rustc::ty::{self, SymbolName, Ty, TyCtxt};
 use rustc_ast::ast::{self, Ident};
 use rustc_ast::attr;
 use rustc_data_structures::fingerprint::Fingerprint;
@@ -25,13 +15,27 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX,
 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;
+use rustc_middle::middle::cstore::{
+    EncodedMetadata, ForeignModule, LinkagePreference, NativeLibrary,
+};
+use rustc_middle::middle::dependency_format::Linkage;
+use rustc_middle::middle::exported_symbols::{
+    metadata_symbol_name, ExportedSymbol, SymbolExportLevel,
+};
+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::{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;
@@ -41,7 +45,7 @@ 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>,
@@ -493,8 +497,8 @@ impl<'tcx> EncodeContext<'tcx> {
         };
 
         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();
@@ -556,7 +560,7 @@ impl<'tcx> EncodeContext<'tcx> {
             impls,
             exported_symbols,
             interpret_alloc_index,
-            per_def,
+            tables,
         });
 
         let total_bytes = self.position();
@@ -581,7 +585,7 @@ impl<'tcx> EncodeContext<'tcx> {
             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);
         }
@@ -593,12 +597,12 @@ impl<'tcx> EncodeContext<'tcx> {
 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) {
@@ -617,12 +621,12 @@ impl EncodeContext<'tcx> {
         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
         }));
@@ -633,7 +637,7 @@ impl EncodeContext<'tcx> {
         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);
@@ -668,14 +672,14 @@ impl EncodeContext<'tcx> {
             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);
@@ -703,11 +707,11 @@ impl EncodeContext<'tcx> {
             },
         };
 
-        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);
@@ -725,10 +729,10 @@ impl EncodeContext<'tcx> {
         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);
@@ -767,14 +771,14 @@ impl EncodeContext<'tcx> {
             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);
@@ -786,12 +790,12 @@ impl EncodeContext<'tcx> {
 
     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));
     }
 
@@ -799,13 +803,13 @@ impl EncodeContext<'tcx> {
         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) {
@@ -822,7 +826,7 @@ impl EncodeContext<'tcx> {
             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<'_>),
@@ -863,9 +867,9 @@ impl EncodeContext<'tcx> {
             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);
@@ -882,7 +886,7 @@ impl EncodeContext<'tcx> {
             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);
@@ -915,7 +919,7 @@ impl EncodeContext<'tcx> {
             }
         };
 
-        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);
@@ -947,16 +951,16 @@ impl EncodeContext<'tcx> {
             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);
@@ -1001,14 +1005,14 @@ impl EncodeContext<'tcx> {
     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));
         }
     }
 
@@ -1017,7 +1021,7 @@ impl EncodeContext<'tcx> {
         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
             }));
@@ -1027,21 +1031,21 @@ impl EncodeContext<'tcx> {
     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);
         }
     }
 
@@ -1062,7 +1066,7 @@ impl EncodeContext<'tcx> {
 
         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) => {
@@ -1168,26 +1172,26 @@ impl EncodeContext<'tcx> {
             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
@@ -1196,7 +1200,7 @@ impl EncodeContext<'tcx> {
             }
             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
@@ -1221,11 +1225,11 @@ impl EncodeContext<'tcx> {
             _ => {}
         }
         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);
@@ -1284,19 +1288,19 @@ impl EncodeContext<'tcx> {
     /// 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);
         }
@@ -1310,7 +1314,7 @@ impl EncodeContext<'tcx> {
         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)
@@ -1320,12 +1324,12 @@ impl EncodeContext<'tcx> {
 
             _ => 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);
@@ -1339,9 +1343,9 @@ impl EncodeContext<'tcx> {
         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);
@@ -1512,7 +1516,7 @@ impl EncodeContext<'tcx> {
 
         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,
@@ -1529,17 +1533,17 @@ impl EncodeContext<'tcx> {
             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);
@@ -1619,17 +1623,14 @@ impl EncodeContext<'tcx> {
     }
 
     fn encode_info_for_expr(&mut self, expr: &hir::Expr<'_>) {
-        match expr.kind {
-            hir::ExprKind::Closure(..) => {
-                let def_id = self.tcx.hir().local_def_id(expr.hir_id);
-                self.encode_info_for_closure(def_id);
-            }
-            _ => {}
+        if let hir::ExprKind::Closure(..) = expr.kind {
+            let def_id = self.tcx.hir().local_def_id(expr.hir_id);
+            self.encode_info_for_closure(def_id);
         }
     }
 
     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
@@ -1845,7 +1846,7 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata {
     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 57415c0a607..71872d53a56 100644
--- a/src/librustc_metadata/rmeta/mod.rs
+++ b/src/librustc_metadata/rmeta/mod.rs
@@ -1,12 +1,6 @@
 use decoder::Metadata;
 use table::{Table, TableBuilder};
 
-use rustc::hir::exports::Export;
-use rustc::middle::cstore::{DepKind, ForeignModule, LinkagePreference, NativeLibrary};
-use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
-use rustc::middle::lang_items;
-use rustc::mir;
-use rustc::ty::{self, ReprOptions, Ty};
 use rustc_ast::ast::{self, MacroDef};
 use rustc_attr as attr;
 use rustc_data_structures::svh::Svh;
@@ -14,7 +8,13 @@ use rustc_data_structures::sync::MetadataRef;
 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::mir;
+use rustc_middle::ty::{self, ReprOptions, Ty};
 use rustc_serialize::opaque::Encoder;
 use rustc_session::config::SymbolManglingVersion;
 use rustc_session::CrateDisambiguator;
@@ -197,7 +197,7 @@ crate struct CrateRoot<'tcx> {
     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 @@ crate struct TraitImpls {
     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 @@ macro_rules! define_per_def_tables {
     }
 }
 
-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/Cargo.toml b/src/librustc_middle/Cargo.toml
index 1dd742c3549..dd322b9da95 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc_middle/Cargo.toml
@@ -1,11 +1,11 @@
 [package]
 authors = ["The Rust Project Developers"]
-name = "rustc"
+name = "rustc_middle"
 version = "0.0.0"
 edition = "2018"
 
 [lib]
-name = "rustc"
+name = "rustc_middle"
 path = "lib.rs"
 doctest = false
 
diff --git a/src/librustc/README.md b/src/librustc_middle/README.md
index de58f546cd3..de58f546cd3 100644
--- a/src/librustc/README.md
+++ b/src/librustc_middle/README.md
diff --git a/src/librustc_middle/arena.rs b/src/librustc_middle/arena.rs
new file mode 100644
index 00000000000..e3dec59478c
--- /dev/null
+++ b/src/librustc_middle/arena.rs
@@ -0,0 +1,132 @@
+/// This declares a list of types which can be allocated by `Arena`.
+///
+/// The `few` modifier will cause allocation to use the shared arena and recording the destructor.
+/// This is faster and more memory efficient if there's only a few allocations of the type.
+/// Leaving `few` out will cause the type to get its own dedicated `TypedArena` which is
+/// faster and more memory efficient if there is lots of allocations.
+///
+/// Specifying the `decode` modifier will add decode impls for &T and &[T] where T is the type
+/// listed. These impls will appear in the implement_ty_decoder! macro.
+#[macro_export]
+macro_rules! arena_types {
+    ($macro:path, $args:tt, $tcx:lifetime) => (
+        $macro!($args, [
+            [] layouts: rustc_target::abi::Layout,
+            [] generics: rustc_middle::ty::Generics,
+            [] trait_def: rustc_middle::ty::TraitDef,
+            [] adt_def: rustc_middle::ty::AdtDef,
+            [] steal_mir: rustc_middle::ty::steal::Steal<rustc_middle::mir::BodyAndCache<$tcx>>,
+            [] mir: rustc_middle::mir::BodyAndCache<$tcx>,
+            [] steal_promoted: rustc_middle::ty::steal::Steal<
+                rustc_index::vec::IndexVec<
+                    rustc_middle::mir::Promoted,
+                    rustc_middle::mir::BodyAndCache<$tcx>
+                >
+            >,
+            [] promoted: rustc_index::vec::IndexVec<
+                rustc_middle::mir::Promoted,
+                rustc_middle::mir::BodyAndCache<$tcx>
+            >,
+            [decode] tables: rustc_middle::ty::TypeckTables<$tcx>,
+            [decode] borrowck_result: rustc_middle::mir::BorrowCheckResult<$tcx>,
+            [] const_allocs: rustc_middle::mir::interpret::Allocation,
+            [] vtable_method: Option<(
+                rustc_hir::def_id::DefId,
+                rustc_middle::ty::subst::SubstsRef<$tcx>
+            )>,
+            [few, decode] mir_keys: rustc_hir::def_id::DefIdSet,
+            [decode] specialization_graph: rustc_middle::traits::specialization_graph::Graph,
+            [] region_scope_tree: rustc_middle::middle::region::ScopeTree,
+            [] item_local_set: rustc_hir::ItemLocalSet,
+            [decode] mir_const_qualif: rustc_index::bit_set::BitSet<rustc_middle::mir::Local>,
+            [] trait_impls_of: rustc_middle::ty::trait_def::TraitImpls,
+            [] associated_items: rustc_middle::ty::AssociatedItems,
+            [] dropck_outlives:
+                rustc_middle::infer::canonical::Canonical<'tcx,
+                    rustc_middle::infer::canonical::QueryResponse<'tcx,
+                        rustc_middle::traits::query::DropckOutlivesResult<'tcx>
+                    >
+                >,
+            [] normalize_projection_ty:
+                rustc_middle::infer::canonical::Canonical<'tcx,
+                    rustc_middle::infer::canonical::QueryResponse<'tcx,
+                        rustc_middle::traits::query::NormalizationResult<'tcx>
+                    >
+                >,
+            [] implied_outlives_bounds:
+                rustc_middle::infer::canonical::Canonical<'tcx,
+                    rustc_middle::infer::canonical::QueryResponse<'tcx,
+                        Vec<rustc_middle::traits::query::OutlivesBound<'tcx>>
+                    >
+                >,
+            [] type_op_subtype:
+                rustc_middle::infer::canonical::Canonical<'tcx,
+                    rustc_middle::infer::canonical::QueryResponse<'tcx, ()>
+                >,
+            [] type_op_normalize_poly_fn_sig:
+                rustc_middle::infer::canonical::Canonical<'tcx,
+                    rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::PolyFnSig<'tcx>>
+                >,
+            [] type_op_normalize_fn_sig:
+                rustc_middle::infer::canonical::Canonical<'tcx,
+                    rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::FnSig<'tcx>>
+                >,
+            [] type_op_normalize_predicate:
+                rustc_middle::infer::canonical::Canonical<'tcx,
+                    rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Predicate<'tcx>>
+                >,
+            [] type_op_normalize_ty:
+                rustc_middle::infer::canonical::Canonical<'tcx,
+                    rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Ty<'tcx>>
+                >,
+            [few] crate_inherent_impls: rustc_middle::ty::CrateInherentImpls,
+            [few] upstream_monomorphizations:
+                rustc_hir::def_id::DefIdMap<
+                    rustc_data_structures::fx::FxHashMap<
+                        rustc_middle::ty::subst::SubstsRef<'tcx>,
+                        rustc_hir::def_id::CrateNum
+                    >
+                >,
+            [few] diagnostic_items: rustc_data_structures::fx::FxHashMap<
+                rustc_span::symbol::Symbol,
+                rustc_hir::def_id::DefId,
+            >,
+            [few] resolve_lifetimes: rustc_middle::middle::resolve_lifetime::ResolveLifetimes,
+            [few] lint_levels: rustc_middle::lint::LintLevelMap,
+            [few] stability_index: rustc_middle::middle::stability::Index<'tcx>,
+            [few] features: rustc_feature::Features,
+            [few] all_traits: Vec<rustc_hir::def_id::DefId>,
+            [few] privacy_access_levels: rustc_middle::middle::privacy::AccessLevels,
+            [few] target_features_whitelist: rustc_data_structures::fx::FxHashMap<
+                String,
+                Option<rustc_span::symbol::Symbol>
+            >,
+            [few] wasm_import_module_map: rustc_data_structures::fx::FxHashMap<
+                rustc_hir::def_id::DefId,
+                String
+            >,
+            [few] get_lib_features: rustc_middle::middle::lib_features::LibFeatures,
+            [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>,
+            [few] reachable_non_generics: rustc_hir::def_id::DefIdMap<
+                rustc_middle::middle::exported_symbols::SymbolExportLevel
+            >,
+            [few] crate_variances: rustc_middle::ty::CrateVariancesMap<'tcx>,
+            [few] inferred_outlives_crate: rustc_middle::ty::CratePredicatesMap<'tcx>,
+            [] upvars: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>,
+
+            // Interned types
+            [] tys: rustc_middle::ty::TyS<$tcx>,
+
+            // HIR query types
+            [few] indexed_hir: rustc_middle::hir::map::IndexedHir<$tcx>,
+            [few] hir_definitions: rustc_hir::definitions::Definitions,
+            [] hir_owner: rustc_middle::hir::Owner<$tcx>,
+            [] hir_owner_nodes: rustc_middle::hir::OwnerNodes<$tcx>,
+        ], $tcx);
+    )
+}
+
+arena_types!(arena::declare_arena, [], 'tcx);
diff --git a/src/librustc/benches/lib.rs b/src/librustc_middle/benches/lib.rs
index 237751bcbd7..237751bcbd7 100644
--- a/src/librustc/benches/lib.rs
+++ b/src/librustc_middle/benches/lib.rs
diff --git a/src/librustc/build.rs b/src/librustc_middle/build.rs
index af7723aea34..af7723aea34 100644
--- a/src/librustc/build.rs
+++ b/src/librustc_middle/build.rs
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc_middle/dep_graph/dep_node.rs
index f4a4aab844c..f4a4aab844c 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc_middle/dep_graph/dep_node.rs
diff --git a/src/librustc/dep_graph/mod.rs b/src/librustc_middle/dep_graph/mod.rs
index f56df19bfb0..f56df19bfb0 100644
--- a/src/librustc/dep_graph/mod.rs
+++ b/src/librustc_middle/dep_graph/mod.rs
diff --git a/src/librustc/hir/exports.rs b/src/librustc_middle/hir/exports.rs
index 4c144a54d63..4c144a54d63 100644
--- a/src/librustc/hir/exports.rs
+++ b/src/librustc_middle/hir/exports.rs
diff --git a/src/librustc/hir/map/blocks.rs b/src/librustc_middle/hir/map/blocks.rs
index 7024e86f95d..7024e86f95d 100644
--- a/src/librustc/hir/map/blocks.rs
+++ b/src/librustc_middle/hir/map/blocks.rs
diff --git a/src/librustc/hir/map/collector.rs b/src/librustc_middle/hir/map/collector.rs
index 70ea856498d..70ea856498d 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc_middle/hir/map/collector.rs
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc_middle/hir/map/mod.rs
index e8ce13e06e9..e8ce13e06e9 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc_middle/hir/map/mod.rs
diff --git a/src/librustc/hir/mod.rs b/src/librustc_middle/hir/mod.rs
index ce8e1f48daa..ce8e1f48daa 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc_middle/hir/mod.rs
diff --git a/src/librustc/ich/hcx.rs b/src/librustc_middle/ich/hcx.rs
index d58aa383667..d58aa383667 100644
--- a/src/librustc/ich/hcx.rs
+++ b/src/librustc_middle/ich/hcx.rs
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc_middle/ich/impls_hir.rs
index f668cc99754..f668cc99754 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc_middle/ich/impls_hir.rs
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc_middle/ich/impls_syntax.rs
index c5a4b53b10d..c5a4b53b10d 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc_middle/ich/impls_syntax.rs
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc_middle/ich/impls_ty.rs
index 41cc8cbaebb..226277e440a 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc_middle/ich/impls_ty.rs
@@ -1,5 +1,5 @@
 //! This module contains `HashStable` implementations for various data types
-//! from rustc::ty in no particular order.
+//! from `rustc_middle::ty` in no particular order.
 
 use crate::ich::{NodeIdHashingMode, StableHashingContext};
 use crate::middle::region;
diff --git a/src/librustc/ich/mod.rs b/src/librustc_middle/ich/mod.rs
index 516e3ed979c..c8fb2bf39cc 100644
--- a/src/librustc/ich/mod.rs
+++ b/src/librustc_middle/ich/mod.rs
@@ -4,7 +4,6 @@ pub use self::hcx::{
     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/infer/canonical.rs b/src/librustc_middle/infer/canonical.rs
index 5f7e8c84965..5f7e8c84965 100644
--- a/src/librustc/infer/canonical.rs
+++ b/src/librustc_middle/infer/canonical.rs
diff --git a/src/librustc/infer/mod.rs b/src/librustc_middle/infer/mod.rs
index 497d3811f28..497d3811f28 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc_middle/infer/mod.rs
diff --git a/src/librustc/infer/unify_key.rs b/src/librustc_middle/infer/unify_key.rs
index e205453a48c..e205453a48c 100644
--- a/src/librustc/infer/unify_key.rs
+++ b/src/librustc_middle/infer/unify_key.rs
diff --git a/src/librustc/lib.rs b/src/librustc_middle/lib.rs
index 6f18560a02d..4ed03fd21ad 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc_middle/lib.rs
@@ -92,5 +92,5 @@ pub mod util {
     pub mod common;
 }
 
-// Allows macros to refer to this crate as `::rustc`
-extern crate self as rustc;
+// Allows macros to refer to this crate as `::rustc_middle`
+extern crate self as rustc_middle;
diff --git a/src/librustc/lint.rs b/src/librustc_middle/lint.rs
index 53061436de0..53061436de0 100644
--- a/src/librustc/lint.rs
+++ b/src/librustc_middle/lint.rs
diff --git a/src/librustc/macros.rs b/src/librustc_middle/macros.rs
index 88ddd96eec8..88ddd96eec8 100644
--- a/src/librustc/macros.rs
+++ b/src/librustc_middle/macros.rs
diff --git a/src/librustc/middle/codegen_fn_attrs.rs b/src/librustc_middle/middle/codegen_fn_attrs.rs
index 61b25cc4864..61b25cc4864 100644
--- a/src/librustc/middle/codegen_fn_attrs.rs
+++ b/src/librustc_middle/middle/codegen_fn_attrs.rs
diff --git a/src/librustc/middle/cstore.rs b/src/librustc_middle/middle/cstore.rs
index 012390e8f74..012390e8f74 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc_middle/middle/cstore.rs
diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc_middle/middle/dependency_format.rs
index ee5f822d313..ee5f822d313 100644
--- a/src/librustc/middle/dependency_format.rs
+++ b/src/librustc_middle/middle/dependency_format.rs
diff --git a/src/librustc/middle/exported_symbols.rs b/src/librustc_middle/middle/exported_symbols.rs
index 1f4318fa537..1f4318fa537 100644
--- a/src/librustc/middle/exported_symbols.rs
+++ b/src/librustc_middle/middle/exported_symbols.rs
diff --git a/src/librustc/middle/free_region.rs b/src/librustc_middle/middle/free_region.rs
index 62ccd946744..62ccd946744 100644
--- a/src/librustc/middle/free_region.rs
+++ b/src/librustc_middle/middle/free_region.rs
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc_middle/middle/lang_items.rs
index 36560371587..0f98c338c16 100644
--- a/src/librustc/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/limits.rs b/src/librustc_middle/middle/limits.rs
index 6de53c703e1..c43c22cd61b 100644
--- a/src/librustc/middle/limits.rs
+++ b/src/librustc_middle/middle/limits.rs
@@ -5,7 +5,7 @@
 //! this via an attribute on the crate like `#![recursion_limit="22"]`. This pass
 //! just peeks and looks for that attribute.
 
-use rustc::bug;
+use crate::bug;
 use rustc_ast::ast;
 use rustc_data_structures::sync::Once;
 use rustc_session::Session;
diff --git a/src/librustc/middle/mod.rs b/src/librustc_middle/middle/mod.rs
index 464488964af..464488964af 100644
--- a/src/librustc/middle/mod.rs
+++ b/src/librustc_middle/middle/mod.rs
diff --git a/src/librustc/middle/privacy.rs b/src/librustc_middle/middle/privacy.rs
index 4756e83b5e9..4756e83b5e9 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc_middle/middle/privacy.rs
diff --git a/src/librustc/middle/region.rs b/src/librustc_middle/middle/region.rs
index 73251ee2680..dd9ab102129 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc_middle/middle/region.rs
@@ -293,7 +293,7 @@ pub struct ScopeTree {
     ///
     /// Then:
     ///     1. From the ordering guarantee of HIR visitors (see
-    ///     `rustc::hir::intravisit`), `D` does not dominate `U`.
+    ///     `rustc_hir::intravisit`), `D` does not dominate `U`.
     ///     2. Therefore, `D` is *potentially* storage-dead at `U` (because
     ///     we might visit `U` without ever getting to `D`).
     ///     3. However, we guarantee that at each HIR point, each
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc_middle/middle/resolve_lifetime.rs
index c21ba1b3bd2..c21ba1b3bd2 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc_middle/middle/resolve_lifetime.rs
diff --git a/src/librustc/middle/stability.rs b/src/librustc_middle/middle/stability.rs
index 46525bdedad..46525bdedad 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc_middle/middle/stability.rs
diff --git a/src/librustc/mir/cache.rs b/src/librustc_middle/mir/cache.rs
index 00ecc7a7a0a..00ecc7a7a0a 100644
--- a/src/librustc/mir/cache.rs
+++ b/src/librustc_middle/mir/cache.rs
diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc_middle/mir/interpret/allocation.rs
index ada02ceb5cb..8b9f0977485 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc_middle/mir/interpret/allocation.rs
@@ -7,14 +7,12 @@ use std::ops::{Deref, DerefMut, Range};
 
 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)]
@@ -379,12 +377,9 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
             // *Now*, we better make sure that the inside is free of relocations too.
             self.check_relocations(cx, ptr, size)?;
         } else {
-            match self.relocations.get(&ptr.offset) {
-                Some(&(tag, alloc_id)) => {
-                    let ptr = Pointer::new_with_tag(alloc_id, Size::from_bytes(bits), tag);
-                    return Ok(ScalarMaybeUndef::Scalar(ptr.into()));
-                }
-                None => {}
+            if let Some(&(tag, alloc_id)) = self.relocations.get(&ptr.offset) {
+                let ptr = Pointer::new_with_tag(alloc_id, Size::from_bytes(bits), tag);
+                return Ok(ScalarMaybeUndef::Scalar(ptr.into()));
             }
         }
         // We don't. Just return the bits.
@@ -437,11 +432,8 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
         write_target_uint(endian, dst, bytes).unwrap();
 
         // See if we have to also write a relocation.
-        match val {
-            Scalar::Ptr(val) => {
-                self.relocations.insert(ptr.offset, (val.tag, val.alloc_id));
-            }
-            _ => {}
+        if let Scalar::Ptr(val) = val {
+            self.relocations.insert(ptr.offset, (val.tag, val.alloc_id));
         }
 
         Ok(())
diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc_middle/mir/interpret/error.rs
index c46ab89d004..7844fb10840 100644
--- a/src/librustc/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_hir::definitions::DefPathData;
 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)]
@@ -53,9 +54,8 @@ pub struct ConstEvalErr<'tcx> {
 
 #[derive(Debug)]
 pub struct FrameInfo<'tcx> {
-    /// This span is in the caller.
-    pub call_site: Span,
     pub instance: ty::Instance<'tcx>,
+    pub span: Span,
     pub lint_root: Option<hir::HirId>,
 }
 
@@ -65,12 +65,12 @@ impl<'tcx> fmt::Display for FrameInfo<'tcx> {
             if tcx.def_key(self.instance.def_id()).disambiguated_data.data
                 == DefPathData::ClosureExpr
             {
-                write!(f, "inside call to closure")?;
+                write!(f, "inside closure")?;
             } else {
-                write!(f, "inside call to `{}`", self.instance)?;
+                write!(f, "inside `{}`", self.instance)?;
             }
-            if !self.call_site.is_dummy() {
-                let lo = tcx.sess.source_map().lookup_char_pos(self.call_site.lo());
+            if !self.span.is_dummy() {
+                let lo = tcx.sess.source_map().lookup_char_pos(self.span.lo());
                 write!(f, " at {}:{}:{}", lo.file.name, lo.line, lo.col.to_usize() + 1)?;
             }
             Ok(())
@@ -168,13 +168,10 @@ impl<'tcx> ConstEvalErr<'tcx> {
             if let Some(span_msg) = span_msg {
                 err.span_label(self.span, span_msg);
             }
-            // Add spans for the stacktrace.
-            // Skip the last, which is just the environment of the constant.  The stacktrace
-            // is sometimes empty because we create "fake" eval contexts in CTFE to do work
-            // on constant values.
-            if !self.stacktrace.is_empty() {
-                for frame_info in &self.stacktrace[..self.stacktrace.len() - 1] {
-                    err.span_label(frame_info.call_site, frame_info.to_string());
+            // Add spans for the stacktrace. Don't print a single-line backtrace though.
+            if self.stacktrace.len() > 1 {
+                for frame_info in &self.stacktrace {
+                    err.span_label(frame_info.span, frame_info.to_string());
                 }
             }
             // Let the caller finish the job.
diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc_middle/mir/interpret/mod.rs
index 10c3a06da08..96bf694d8fa 100644
--- a/src/librustc/mir/interpret/mod.rs
+++ b/src/librustc_middle/mir/interpret/mod.rs
@@ -109,10 +109,10 @@ use rustc_data_structures::tiny_list::TinyList;
 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 @@ impl<'tcx> AllocMap<'tcx> {
 
 #[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/mir/interpret/pointer.rs b/src/librustc_middle/mir/interpret/pointer.rs
index d22207bd816..7549d902dfb 100644
--- a/src/librustc/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 @@ impl Display for CheckInAllocMsg {
 // Pointer arithmetic
 ////////////////////////////////////////////////////////////////////////////////
 
-pub trait PointerArithmetic: layout::HasDataLayout {
+pub trait PointerArithmetic: HasDataLayout {
     // These are not supposed to be overridden.
 
     #[inline(always)]
@@ -100,7 +99,7 @@ pub trait PointerArithmetic: layout::HasDataLayout {
     }
 }
 
-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/mir/interpret/queries.rs b/src/librustc_middle/mir/interpret/queries.rs
index 46bf1d96957..46bf1d96957 100644
--- a/src/librustc/mir/interpret/queries.rs
+++ b/src/librustc_middle/mir/interpret/queries.rs
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc_middle/mir/interpret/value.rs
index bf4ee848823..f3c1c87dad4 100644
--- a/src/librustc/mir/interpret/value.rs
+++ b/src/librustc_middle/mir/interpret/value.rs
@@ -6,12 +6,9 @@ use rustc_apfloat::{
     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/mir/mod.rs b/src/librustc_middle/mir/mod.rs
index 9ba9d816d0f..36e10f8759d 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc_middle/mir/mod.rs
@@ -6,7 +6,6 @@ use crate::mir::interpret::{GlobalAlloc, Scalar};
 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 as hir;
 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;
@@ -2030,9 +2030,9 @@ impl<'tcx> Operand<'tcx> {
 
     /// Returns the `Place` that is the target of this `Operand`, or `None` if this `Operand` is a
     /// constant.
-    pub fn place(&self) -> Option<&Place<'tcx>> {
+    pub fn place(&self) -> Option<Place<'tcx>> {
         match self {
-            Operand::Copy(place) | Operand::Move(place) => Some(place),
+            Operand::Copy(place) | Operand::Move(place) => Some(*place),
             Operand::Constant(_) => None,
         }
     }
diff --git a/src/librustc/mir/mono.rs b/src/librustc_middle/mir/mono.rs
index 0b64cb479d5..0b64cb479d5 100644
--- a/src/librustc/mir/mono.rs
+++ b/src/librustc_middle/mir/mono.rs
diff --git a/src/librustc/mir/query.rs b/src/librustc_middle/mir/query.rs
index 8c81f5227d2..8c81f5227d2 100644
--- a/src/librustc/mir/query.rs
+++ b/src/librustc_middle/mir/query.rs
diff --git a/src/librustc/mir/tcx.rs b/src/librustc_middle/mir/tcx.rs
index feb66319267..06b27c5e8b3 100644
--- a/src/librustc/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/mir/traversal.rs b/src/librustc_middle/mir/traversal.rs
index ed8129b1e09..ed8129b1e09 100644
--- a/src/librustc/mir/traversal.rs
+++ b/src/librustc_middle/mir/traversal.rs
diff --git a/src/librustc/mir/type_foldable.rs b/src/librustc_middle/mir/type_foldable.rs
index 9520f081b6b..9520f081b6b 100644
--- a/src/librustc/mir/type_foldable.rs
+++ b/src/librustc_middle/mir/type_foldable.rs
diff --git a/src/librustc/mir/visit.rs b/src/librustc_middle/mir/visit.rs
index c1b27b40f7d..400d15cdc14 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc_middle/mir/visit.rs
@@ -65,12 +65,12 @@ use rustc_span::Span;
 // variant argument) that does not require visiting, as in
 // `is_cleanup` above.
 
-macro_rules! body_cache_type {
-    (mut $a:lifetime, $tcx:lifetime) => {
+macro_rules! body_type {
+    (mut $tcx:lifetime) => {
         &mut BodyAndCache<$tcx>
     };
-    ($a:lifetime, $tcx:lifetime) => {
-        ReadOnlyBodyAndCache<$a, $tcx>
+    ($tcx:lifetime) => {
+        &Body<$tcx>
     };
 }
 
@@ -82,7 +82,7 @@ macro_rules! make_mir_visitor {
 
             fn visit_body(
                 &mut self,
-                body: body_cache_type!($($mutability)? '_, 'tcx)
+                body: body_type!($($mutability)? 'tcx)
             ) {
                 self.super_body(body);
             }
@@ -254,7 +254,7 @@ macro_rules! make_mir_visitor {
 
             fn super_body(
                 &mut self,
-                $($mutability)? body: body_cache_type!($($mutability)? '_, 'tcx)
+                $($mutability)? body: body_type!($($mutability)? 'tcx)
             ) {
                 let span = body.span;
                 if let Some(yield_ty) = &$($mutability)? body.yield_ty {
@@ -819,7 +819,7 @@ macro_rules! make_mir_visitor {
 
             fn visit_location(
                 &mut self,
-                body: body_cache_type!($($mutability)? '_, 'tcx),
+                body: body_type!($($mutability)? 'tcx),
                 location: Location
             ) {
                 let basic_block = & $($mutability)? body[location.block];
diff --git a/src/librustc/query/mod.rs b/src/librustc_middle/query/mod.rs
index c1ece627509..2ffbbfb1762 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc_middle/query/mod.rs
@@ -738,7 +738,7 @@ rustc_queries! {
 
         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 }
         }
     }
diff --git a/src/librustc/tests.rs b/src/librustc_middle/tests.rs
index cf3ea2ffa93..757e0bd3bfb 100644
--- a/src/librustc/tests.rs
+++ b/src/librustc_middle/tests.rs
@@ -1,6 +1,6 @@
 use super::*;
 
-// FIXME(#27438): right now the unit tests of librustc don't refer to any actual
+// FIXME(#27438): right now the unit tests of librustc_middle don't refer to any actual
 //                functions generated in librustc_data_structures (all
 //                references are through generic functions), but statics are
 //                referenced from time to time. Due to this bug we won't
diff --git a/src/librustc/traits/mod.rs b/src/librustc_middle/traits/mod.rs
index c129b574fd3..c129b574fd3 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc_middle/traits/mod.rs
diff --git a/src/librustc/traits/query.rs b/src/librustc_middle/traits/query.rs
index 67f4b15f919..67f4b15f919 100644
--- a/src/librustc/traits/query.rs
+++ b/src/librustc_middle/traits/query.rs
diff --git a/src/librustc/traits/select.rs b/src/librustc_middle/traits/select.rs
index d316d7659e2..d316d7659e2 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc_middle/traits/select.rs
diff --git a/src/librustc/traits/specialization_graph.rs b/src/librustc_middle/traits/specialization_graph.rs
index 1847326a742..a2793f98050 100644
--- a/src/librustc/traits/specialization_graph.rs
+++ b/src/librustc_middle/traits/specialization_graph.rs
@@ -154,14 +154,44 @@ impl Iterator for Ancestors<'_> {
     }
 }
 
-pub struct NodeItem<T> {
-    pub node: Node,
-    pub item: T,
+/// Information about the most specialized definition of an associated item.
+pub struct LeafDef {
+    /// The associated item described by this `LeafDef`.
+    pub item: ty::AssocItem,
+
+    /// The node in the specialization graph containing the definition of `item`.
+    pub defining_node: Node,
+
+    /// The "top-most" (ie. least specialized) specialization graph node that finalized the
+    /// definition of `item`.
+    ///
+    /// Example:
+    ///
+    /// ```
+    /// trait Tr {
+    ///     fn assoc(&self);
+    /// }
+    ///
+    /// impl<T> Tr for T {
+    ///     default fn assoc(&self) {}
+    /// }
+    ///
+    /// impl Tr for u8 {}
+    /// ```
+    ///
+    /// If we start the leaf definition search at `impl Tr for u8`, that impl will be the
+    /// `finalizing_node`, while `defining_node` will be the generic impl.
+    ///
+    /// If the leaf definition search is started at the generic impl, `finalizing_node` will be
+    /// `None`, since the most specialized impl we found still allows overriding the method
+    /// (doesn't finalize it).
+    pub finalizing_node: Option<Node>,
 }
 
-impl<T> NodeItem<T> {
-    pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> NodeItem<U> {
-        NodeItem { node: self.node, item: f(self.item) }
+impl LeafDef {
+    /// Returns whether this definition is known to not be further specializable.
+    pub fn is_final(&self) -> bool {
+        self.finalizing_node.is_some()
     }
 }
 
@@ -173,18 +203,36 @@ impl<'tcx> Ancestors<'tcx> {
         tcx: TyCtxt<'tcx>,
         trait_item_name: Ident,
         trait_item_kind: ty::AssocKind,
-    ) -> Option<NodeItem<ty::AssocItem>> {
+    ) -> Option<LeafDef> {
         let trait_def_id = self.trait_def_id;
+        let mut finalizing_node = None;
+
         self.find_map(|node| {
-            node.item(tcx, trait_item_name, trait_item_kind, trait_def_id)
-                .map(|item| NodeItem { node, item })
+            if let Some(item) = node.item(tcx, trait_item_name, trait_item_kind, trait_def_id) {
+                if finalizing_node.is_none() {
+                    let is_specializable = item.defaultness.is_default()
+                        || tcx.impl_defaultness(node.def_id()).is_default();
+
+                    if !is_specializable {
+                        finalizing_node = Some(node);
+                    }
+                }
+
+                Some(LeafDef { item, defining_node: node, finalizing_node })
+            } else {
+                // Item not mentioned. This "finalizes" any defaulted item provided by an ancestor.
+                finalizing_node = Some(node);
+                None
+            }
         })
     }
 }
 
 /// Walk up the specialization ancestors of a given impl, starting with that
-/// impl itself. Returns `None` if an error was reported while building the
-/// specialization graph.
+/// impl itself.
+///
+/// Returns `Err` if an error was reported while building the specialization
+/// graph.
 pub fn ancestors(
     tcx: TyCtxt<'tcx>,
     trait_def_id: DefId,
diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc_middle/traits/structural_impls.rs
index b1fb02a67b3..b1fb02a67b3 100644
--- a/src/librustc/traits/structural_impls.rs
+++ b/src/librustc_middle/traits/structural_impls.rs
diff --git a/src/librustc/ty/_match.rs b/src/librustc_middle/ty/_match.rs
index 35f8eb20475..35f8eb20475 100644
--- a/src/librustc/ty/_match.rs
+++ b/src/librustc_middle/ty/_match.rs
diff --git a/src/librustc/ty/adjustment.rs b/src/librustc_middle/ty/adjustment.rs
index 851bffc2065..851bffc2065 100644
--- a/src/librustc/ty/adjustment.rs
+++ b/src/librustc_middle/ty/adjustment.rs
diff --git a/src/librustc/ty/binding.rs b/src/librustc_middle/ty/binding.rs
index 5ee88115090..5ee88115090 100644
--- a/src/librustc/ty/binding.rs
+++ b/src/librustc_middle/ty/binding.rs
diff --git a/src/librustc/ty/cast.rs b/src/librustc_middle/ty/cast.rs
index 31c106cb230..31c106cb230 100644
--- a/src/librustc/ty/cast.rs
+++ b/src/librustc_middle/ty/cast.rs
diff --git a/src/librustc/ty/codec.rs b/src/librustc_middle/ty/codec.rs
index cbbc937ed7d..cbbc937ed7d 100644
--- a/src/librustc/ty/codec.rs
+++ b/src/librustc_middle/ty/codec.rs
diff --git a/src/librustc/ty/context.rs b/src/librustc_middle/ty/context.rs
index 0ab91d7e112..95d0c758d08 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc_middle/ty/context.rs
@@ -6,12 +6,11 @@ use crate::dep_graph::{self, DepConstructor};
 use crate::hir::exports::Export;
 use crate::ich::{NodeIdHashingMode, StableHashingContext};
 use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
+use crate::lint::LintDiagnosticBuilder;
 use crate::lint::{struct_lint_level, LintSource};
 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};
@@ -20,7 +19,6 @@ use crate::mir::{
 };
 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};
@@ -37,8 +35,6 @@ use crate::ty::{ConstVid, FloatVar, FloatVid, IntVar, IntVid, TyVar, TyVid};
 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::lint::LintDiagnosticBuilder;
 use rustc_ast::ast;
 use rustc_ast::expand::allocator::AllocatorKind;
 use rustc_ast::node_id::NodeMap;
@@ -50,10 +46,13 @@ use rustc_data_structures::stable_hasher::{
     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_session::Session;
 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 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     /// 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/ty/diagnostics.rs b/src/librustc_middle/ty/diagnostics.rs
index d1eb21e25ff..d1eb21e25ff 100644
--- a/src/librustc/ty/diagnostics.rs
+++ b/src/librustc_middle/ty/diagnostics.rs
diff --git a/src/librustc/ty/erase_regions.rs b/src/librustc_middle/ty/erase_regions.rs
index 4bf08096ede..4bf08096ede 100644
--- a/src/librustc/ty/erase_regions.rs
+++ b/src/librustc_middle/ty/erase_regions.rs
diff --git a/src/librustc/ty/error.rs b/src/librustc_middle/ty/error.rs
index d0bc0d5fabf..d0bc0d5fabf 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc_middle/ty/error.rs
diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc_middle/ty/fast_reject.rs
index 2a937d6581d..2a937d6581d 100644
--- a/src/librustc/ty/fast_reject.rs
+++ b/src/librustc_middle/ty/fast_reject.rs
diff --git a/src/librustc/ty/flags.rs b/src/librustc_middle/ty/flags.rs
index 5243e1fbf57..99a6511b297 100644
--- a/src/librustc/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 @@ impl FlagComputation {
 
             &ty::Param(_) => {
                 self.add_flags(TypeFlags::HAS_TY_PARAM);
+                self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
             }
 
             &ty::Generator(_, ref substs, _) => {
@@ -99,14 +100,17 @@ impl FlagComputation {
 
             &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 @@ impl FlagComputation {
             }
             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 @@ impl FlagComputation {
         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/ty/fold.rs b/src/librustc_middle/ty/fold.rs
index 3f4f2407f1e..a3d611a1325 100644
--- a/src/librustc/ty/fold.rs
+++ b/src/librustc_middle/ty/fold.rs
@@ -142,6 +142,13 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
         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/ty/free_region_map.rs b/src/librustc_middle/ty/free_region_map.rs
index 2ab12a4acbf..2ab12a4acbf 100644
--- a/src/librustc/ty/free_region_map.rs
+++ b/src/librustc_middle/ty/free_region_map.rs
diff --git a/src/librustc/ty/inhabitedness/def_id_forest.rs b/src/librustc_middle/ty/inhabitedness/def_id_forest.rs
index 14ead77653c..14ead77653c 100644
--- a/src/librustc/ty/inhabitedness/def_id_forest.rs
+++ b/src/librustc_middle/ty/inhabitedness/def_id_forest.rs
diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc_middle/ty/inhabitedness/mod.rs
index b166c4dea0c..b166c4dea0c 100644
--- a/src/librustc/ty/inhabitedness/mod.rs
+++ b/src/librustc_middle/ty/inhabitedness/mod.rs
diff --git a/src/librustc/ty/instance.rs b/src/librustc_middle/ty/instance.rs
index fcfee0fea85..5d47a6e13f4 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc_middle/ty/instance.rs
@@ -1,10 +1,10 @@
 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;
diff --git a/src/librustc/ty/layout.rs b/src/librustc_middle/ty/layout.rs
index ad4352c0105..520793c69fd 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc_middle/ty/layout.rs
@@ -1,4 +1,5 @@
 use crate::ich::StableHashingContext;
+use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use crate::mir::{GeneratorLayout, GeneratorSavedLocal};
 use crate::ty::subst::Subst;
 use crate::ty::{self, subst::SubstsRef, ReprOptions, Ty, TyCtxt, TypeFoldable};
@@ -14,8 +15,8 @@ use rustc_span::DUMMY_SP;
 use rustc_target::abi::call::{
     ArgAbi, ArgAttribute, ArgAttributes, Conv, FnAbi, PassMode, Reg, RegKind,
 };
-pub use rustc_target::abi::*;
-use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec};
+use rustc_target::abi::*;
+use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec, PanicStrategy};
 
 use std::cmp;
 use std::fmt;
@@ -229,7 +230,7 @@ enum StructKind {
 // Invert a bijective mapping, i.e. `invert(map)[y] = x` if `map[x] = y`.
 // This is used to go between `memory_index` (source field order to memory order)
 // and `inverse_memory_index` (memory order to source field order).
-// See also `FieldPlacement::Arbitrary::memory_index` for more details.
+// See also `FieldsShape::Arbitrary::memory_index` for more details.
 // FIXME(eddyb) build a better abstraction for permutations, if possible.
 fn invert_mapping(map: &[u32]) -> Vec<u32> {
     let mut inverse = vec![0; map.len()];
@@ -256,7 +257,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
 
         Layout {
             variants: Variants::Single { index: VariantIdx::new(0) },
-            fields: FieldPlacement::Arbitrary {
+            fields: FieldsShape::Arbitrary {
                 offsets: vec![Size::ZERO, b_offset],
                 memory_index: vec![0, 1],
             },
@@ -270,7 +271,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
     fn univariant_uninterned(
         &self,
         ty: Ty<'tcx>,
-        fields: &[TyLayout<'_>],
+        fields: &[TyAndLayout<'_>],
         repr: &ReprOptions,
         kind: StructKind,
     ) -> Result<Layout, LayoutError<'tcx>> {
@@ -293,7 +294,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
             let end =
                 if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() };
             let optimizing = &mut inverse_memory_index[..end];
-            let field_align = |f: &TyLayout<'_>| {
+            let field_align = |f: &TyAndLayout<'_>| {
                 if let Some(pack) = pack { f.align.abi.min(pack) } else { f.align.abi }
             };
             match kind {
@@ -422,11 +423,15 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                     (
                         Some((
                             i,
-                            &TyLayout { layout: &Layout { abi: Abi::Scalar(ref a), .. }, .. },
+                            &TyAndLayout {
+                                layout: &Layout { abi: Abi::Scalar(ref a), .. }, ..
+                            },
                         )),
                         Some((
                             j,
-                            &TyLayout { layout: &Layout { abi: Abi::Scalar(ref b), .. }, .. },
+                            &TyAndLayout {
+                                layout: &Layout { abi: Abi::Scalar(ref b), .. }, ..
+                            },
                         )),
                         None,
                     ) => {
@@ -438,7 +443,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                         };
                         let pair = self.scalar_pair(a.clone(), b.clone());
                         let pair_offsets = match pair.fields {
-                            FieldPlacement::Arbitrary { ref offsets, ref memory_index } => {
+                            FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
                                 assert_eq!(memory_index, &[0, 1]);
                                 offsets
                             }
@@ -466,7 +471,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
 
         Ok(Layout {
             variants: Variants::Single { index: VariantIdx::new(0) },
-            fields: FieldPlacement::Arbitrary { offsets, memory_index },
+            fields: FieldsShape::Arbitrary { offsets, memory_index },
             abi,
             largest_niche,
             align,
@@ -485,7 +490,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         };
         let scalar = |value: Primitive| tcx.intern_layout(Layout::scalar(self, scalar_unit(value)));
 
-        let univariant = |fields: &[TyLayout<'_>], repr: &ReprOptions, kind| {
+        let univariant = |fields: &[TyAndLayout<'_>], repr: &ReprOptions, kind| {
             Ok(tcx.intern_layout(self.univariant_uninterned(ty, fields, repr, kind)?))
         };
         debug_assert!(!ty.has_infer_types_or_consts());
@@ -515,7 +520,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
             // The never type.
             ty::Never => tcx.intern_layout(Layout {
                 variants: Variants::Single { index: VariantIdx::new(0) },
-                fields: FieldPlacement::Union(0),
+                fields: FieldsShape::Union(0),
                 abi: Abi::Uninhabited,
                 largest_niche: None,
                 align: dl.i8_align,
@@ -576,7 +581,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
 
                 tcx.intern_layout(Layout {
                     variants: Variants::Single { index: VariantIdx::new(0) },
-                    fields: FieldPlacement::Array { stride: element.size, count },
+                    fields: FieldsShape::Array { stride: element.size, count },
                     abi,
                     largest_niche,
                     align: element.align,
@@ -587,7 +592,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                 let element = self.layout_of(element)?;
                 tcx.intern_layout(Layout {
                     variants: Variants::Single { index: VariantIdx::new(0) },
-                    fields: FieldPlacement::Array { stride: element.size, count: 0 },
+                    fields: FieldsShape::Array { stride: element.size, count: 0 },
                     abi: Abi::Aggregate { sized: false },
                     largest_niche: None,
                     align: element.align,
@@ -596,7 +601,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
             }
             ty::Str => tcx.intern_layout(Layout {
                 variants: Variants::Single { index: VariantIdx::new(0) },
-                fields: FieldPlacement::Array { stride: Size::from_bytes(1), count: 0 },
+                fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 },
                 abi: Abi::Aggregate { sized: false },
                 largest_niche: None,
                 align: dl.i8_align,
@@ -665,7 +670,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
 
                 tcx.intern_layout(Layout {
                     variants: Variants::Single { index: VariantIdx::new(0) },
-                    fields: FieldPlacement::Array { stride: element.size, count },
+                    fields: FieldsShape::Array { stride: element.size, count },
                     abi: Abi::Vector { element: scalar, count },
                     largest_niche: element.largest_niche.clone(),
                     size,
@@ -741,7 +746,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
 
                     return Ok(tcx.intern_layout(Layout {
                         variants: Variants::Single { index },
-                        fields: FieldPlacement::Union(variants[index].len()),
+                        fields: FieldsShape::Union(variants[index].len()),
                         abi,
                         largest_niche: None,
                         align,
@@ -754,7 +759,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                 // but *not* an encoding of the discriminant (e.g., a tag value).
                 // See issue #49298 for more details on the need to leave space
                 // for non-ZST uninhabited data (mostly partial initialization).
-                let absent = |fields: &[TyLayout<'_>]| {
+                let absent = |fields: &[TyAndLayout<'_>]| {
                     let uninhabited = fields.iter().any(|f| f.abi.is_uninhabited());
                     let is_zst = fields.iter().all(|f| f.is_zst());
                     uninhabited && is_zst
@@ -975,7 +980,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                                     discr_index: 0,
                                     variants: st,
                                 },
-                                fields: FieldPlacement::Arbitrary {
+                                fields: FieldsShape::Arbitrary {
                                     offsets: vec![offset],
                                     memory_index: vec![0],
                                 },
@@ -1116,7 +1121,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                     let new_ity_size = ity.size();
                     for variant in &mut layout_variants {
                         match variant.fields {
-                            FieldPlacement::Arbitrary { ref mut offsets, .. } => {
+                            FieldsShape::Arbitrary { ref mut offsets, .. } => {
                                 for i in offsets {
                                     if *i <= old_ity_size {
                                         assert_eq!(*i, old_ity_size);
@@ -1146,7 +1151,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                     let mut common_prim = None;
                     for (field_layouts, layout_variant) in variants.iter().zip(&layout_variants) {
                         let offsets = match layout_variant.fields {
-                            FieldPlacement::Arbitrary { ref offsets, .. } => offsets,
+                            FieldsShape::Arbitrary { ref offsets, .. } => offsets,
                             _ => bug!(),
                         };
                         let mut fields =
@@ -1182,7 +1187,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                     if let Some((prim, offset)) = common_prim {
                         let pair = self.scalar_pair(tag.clone(), scalar_unit(prim));
                         let pair_offsets = match pair.fields {
-                            FieldPlacement::Arbitrary { ref offsets, ref memory_index } => {
+                            FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
                                 assert_eq!(memory_index, &[0, 1]);
                                 offsets
                             }
@@ -1213,7 +1218,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                         discr_index: 0,
                         variants: layout_variants,
                     },
-                    fields: FieldPlacement::Arbitrary {
+                    fields: FieldsShape::Arbitrary {
                         offsets: vec![Size::ZERO],
                         memory_index: vec![0],
                     },
@@ -1352,11 +1357,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         {
             let mut used_variants = BitSet::new_empty(info.variant_fields.len());
             for assignment in &assignments {
-                match assignment {
-                    Assigned(idx) => {
-                        used_variants.insert(*idx);
-                    }
-                    _ => {}
+                if let Assigned(idx) = assignment {
+                    used_variants.insert(*idx);
                 }
             }
             if used_variants.count() < 2 {
@@ -1404,7 +1406,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         let discr_int_ty = discr_int.to_ty(tcx, false);
         let discr = Scalar { value: Primitive::Int(discr_int, false), valid_range: 0..=max_discr };
         let discr_layout = self.tcx.intern_layout(Layout::scalar(self, discr.clone()));
-        let discr_layout = TyLayout { ty: discr_int_ty, layout: discr_layout };
+        let discr_layout = TyAndLayout { ty: discr_int_ty, layout: discr_layout };
 
         let promoted_layouts = ineligible_locals
             .iter()
@@ -1433,7 +1435,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         // GeneratorLayout.
         debug!("prefix = {:#?}", prefix);
         let (outer_fields, promoted_offsets, promoted_memory_index) = match prefix.fields {
-            FieldPlacement::Arbitrary { mut offsets, memory_index } => {
+            FieldsShape::Arbitrary { mut offsets, memory_index } => {
                 let mut inverse_memory_index = invert_mapping(&memory_index);
 
                 // "a" (`0..b_start`) and "b" (`b_start..`) correspond to
@@ -1456,7 +1458,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                 let memory_index_b = invert_mapping(&inverse_memory_index_b);
 
                 let outer_fields =
-                    FieldPlacement::Arbitrary { offsets: offsets_a, memory_index: memory_index_a };
+                    FieldsShape::Arbitrary { offsets: offsets_a, memory_index: memory_index_a };
                 (outer_fields, offsets_b, memory_index_b)
             }
             _ => bug!(),
@@ -1490,7 +1492,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                 variant.variants = Variants::Single { index };
 
                 let (offsets, memory_index) = match variant.fields {
-                    FieldPlacement::Arbitrary { offsets, memory_index } => (offsets, memory_index),
+                    FieldsShape::Arbitrary { offsets, memory_index } => (offsets, memory_index),
                     _ => bug!(),
                 };
 
@@ -1533,7 +1535,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                 combined_inverse_memory_index.retain(|&i| i != INVALID_FIELD_IDX);
                 let combined_memory_index = invert_mapping(&combined_inverse_memory_index);
 
-                variant.fields = FieldPlacement::Arbitrary {
+                variant.fields = FieldsShape::Arbitrary {
                     offsets: combined_offsets,
                     memory_index: combined_memory_index,
                 };
@@ -1573,7 +1575,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
     /// This is invoked by the `layout_raw` query to record the final
     /// layout of each type.
     #[inline(always)]
-    fn record_layout_for_printing(&self, layout: TyLayout<'tcx>) {
+    fn record_layout_for_printing(&self, layout: TyAndLayout<'tcx>) {
         // If we are running with `-Zprint-type-sizes`, maybe record layouts
         // for dumping later.
         if self.tcx.sess.opts.debugging_opts.print_type_sizes {
@@ -1581,7 +1583,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         }
     }
 
-    fn record_layout_for_printing_outlined(&self, layout: TyLayout<'tcx>) {
+    fn record_layout_for_printing_outlined(&self, layout: TyAndLayout<'tcx>) {
         // Ignore layouts that are done with non-empty environments or
         // non-monomorphic layouts, as the user only wants to see the stuff
         // resulting from the final codegen session.
@@ -1624,7 +1626,9 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         let adt_kind = adt_def.adt_kind();
         let adt_packed = adt_def.repr.pack.is_some();
 
-        let build_variant_info = |n: Option<Ident>, flds: &[ast::Name], layout: TyLayout<'tcx>| {
+        let build_variant_info = |n: Option<Ident>,
+                                  flds: &[ast::Name],
+                                  layout: TyAndLayout<'tcx>| {
             let mut min_size = Size::ZERO;
             let field_info: Vec<_> = flds
                 .iter()
@@ -1891,19 +1895,19 @@ impl<'tcx, T: HasTyCtxt<'tcx>> HasTyCtxt<'tcx> for LayoutCx<'tcx, T> {
     }
 }
 
-pub type TyLayout<'tcx> = ::rustc_target::abi::TyLayout<'tcx, Ty<'tcx>>;
+pub type TyAndLayout<'tcx> = ::rustc_target::abi::TyAndLayout<'tcx, Ty<'tcx>>;
 
 impl<'tcx> LayoutOf for LayoutCx<'tcx, TyCtxt<'tcx>> {
     type Ty = Ty<'tcx>;
-    type TyLayout = Result<TyLayout<'tcx>, LayoutError<'tcx>>;
+    type TyAndLayout = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>;
 
     /// Computes the layout of a type. Note that this implicitly
     /// executes in "reveal all" mode.
-    fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
+    fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout {
         let param_env = self.param_env.with_reveal_all();
         let ty = self.tcx.normalize_erasing_regions(param_env, ty);
         let layout = self.tcx.layout_raw(param_env.and(ty))?;
-        let layout = TyLayout { ty, layout };
+        let layout = TyAndLayout { ty, layout };
 
         // N.B., this recording is normally disabled; when enabled, it
         // can however trigger recursive invocations of `layout_of`.
@@ -1919,15 +1923,15 @@ impl<'tcx> LayoutOf for LayoutCx<'tcx, TyCtxt<'tcx>> {
 
 impl LayoutOf for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> {
     type Ty = Ty<'tcx>;
-    type TyLayout = Result<TyLayout<'tcx>, LayoutError<'tcx>>;
+    type TyAndLayout = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>;
 
     /// Computes the layout of a type. Note that this implicitly
     /// executes in "reveal all" mode.
-    fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
+    fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout {
         let param_env = self.param_env.with_reveal_all();
         let ty = self.tcx.normalize_erasing_regions(param_env, ty);
         let layout = self.tcx.layout_raw(param_env.and(ty))?;
-        let layout = TyLayout { ty, layout };
+        let layout = TyAndLayout { ty, layout };
 
         // N.B., this recording is normally disabled; when enabled, it
         // can however trigger recursive invocations of `layout_of`.
@@ -1950,7 +1954,7 @@ impl TyCtxt<'tcx> {
     pub fn layout_of(
         self,
         param_env_and_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
-    ) -> Result<TyLayout<'tcx>, LayoutError<'tcx>> {
+    ) -> Result<TyAndLayout<'tcx>, LayoutError<'tcx>> {
         let cx = LayoutCx { tcx: self, param_env: param_env_and_ty.param_env };
         cx.layout_of(param_env_and_ty.value)
     }
@@ -1963,26 +1967,30 @@ impl ty::query::TyCtxtAt<'tcx> {
     pub fn layout_of(
         self,
         param_env_and_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
-    ) -> Result<TyLayout<'tcx>, LayoutError<'tcx>> {
+    ) -> Result<TyAndLayout<'tcx>, LayoutError<'tcx>> {
         let cx = LayoutCx { tcx: self.at(self.span), param_env: param_env_and_ty.param_env };
         cx.layout_of(param_env_and_ty.value)
     }
 }
 
-impl<'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx>
+impl<'tcx, C> TyAndLayoutMethods<'tcx, C> for Ty<'tcx>
 where
-    C: LayoutOf<Ty = Ty<'tcx>, TyLayout: MaybeResult<TyLayout<'tcx>>>
+    C: LayoutOf<Ty = Ty<'tcx>, TyAndLayout: MaybeResult<TyAndLayout<'tcx>>>
         + HasTyCtxt<'tcx>
         + HasParamEnv<'tcx>,
 {
-    fn for_variant(this: TyLayout<'tcx>, cx: &C, variant_index: VariantIdx) -> TyLayout<'tcx> {
+    fn for_variant(
+        this: TyAndLayout<'tcx>,
+        cx: &C,
+        variant_index: VariantIdx,
+    ) -> TyAndLayout<'tcx> {
         let layout = match this.variants {
             Variants::Single { index }
                 // If all variants but one are uninhabited, the variant layout is the enum layout.
                 if index == variant_index &&
                 // Don't confuse variants of uninhabited enums with the enum itself.
                 // For more details see https://github.com/rust-lang/rust/issues/69763.
-                this.fields != FieldPlacement::Union(0) =>
+                this.fields != FieldsShape::Union(0) =>
             {
                 this.layout
             }
@@ -2000,7 +2008,7 @@ where
                 let tcx = cx.tcx();
                 tcx.intern_layout(Layout {
                     variants: Variants::Single { index: variant_index },
-                    fields: FieldPlacement::Union(fields),
+                    fields: FieldsShape::Union(fields),
                     abi: Abi::Uninhabited,
                     largest_niche: None,
                     align: tcx.data_layout.i8_align,
@@ -2013,14 +2021,14 @@ where
 
         assert_eq!(layout.variants, Variants::Single { index: variant_index });
 
-        TyLayout { ty: this.ty, layout }
+        TyAndLayout { ty: this.ty, layout }
     }
 
-    fn field(this: TyLayout<'tcx>, cx: &C, i: usize) -> C::TyLayout {
+    fn field(this: TyAndLayout<'tcx>, cx: &C, i: usize) -> C::TyAndLayout {
         let tcx = cx.tcx();
-        let discr_layout = |discr: &Scalar| -> C::TyLayout {
+        let discr_layout = |discr: &Scalar| -> C::TyAndLayout {
             let layout = Layout::scalar(cx, discr.clone());
-            MaybeResult::from(Ok(TyLayout {
+            MaybeResult::from(Ok(TyAndLayout {
                 layout: tcx.intern_layout(layout),
                 ty: discr.value.to_ty(tcx),
             }))
@@ -2037,7 +2045,7 @@ where
             | ty::FnDef(..)
             | ty::GeneratorWitness(..)
             | ty::Foreign(..)
-            | ty::Dynamic(..) => bug!("TyLayout::field_type({:?}): not applicable", this),
+            | ty::Dynamic(..) => bug!("TyAndLayout::field_type({:?}): not applicable", this),
 
             // Potentially-fat pointers.
             ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
@@ -2046,7 +2054,7 @@ where
                 // Reuse the fat `*T` type as its own thin pointer data field.
                 // This provides information about, e.g., DST struct pointees
                 // (which may have no non-DST form), and will work as long
-                // as the `Abi` or `FieldPlacement` is checked by users.
+                // as the `Abi` or `FieldsShape` is checked by users.
                 if i == 0 {
                     let nil = tcx.mk_unit();
                     let ptr_ty = if this.ty.is_unsafe_ptr() {
@@ -2080,7 +2088,7 @@ where
                         ])
                         */
                     }
-                    _ => bug!("TyLayout::field_type({:?}): not applicable", this),
+                    _ => bug!("TyAndLayout::field_type({:?}): not applicable", this),
                 }
             }
 
@@ -2132,11 +2140,11 @@ where
             | ty::Opaque(..)
             | ty::Param(_)
             | ty::Infer(_)
-            | ty::Error => bug!("TyLayout::field_type: unexpected type `{}`", this.ty),
+            | ty::Error => bug!("TyAndLayout::field_type: unexpected type `{}`", this.ty),
         })
     }
 
-    fn pointee_info_at(this: TyLayout<'tcx>, cx: &C, offset: Size) -> Option<PointeeInfo> {
+    fn pointee_info_at(this: TyAndLayout<'tcx>, cx: &C, offset: Size) -> Option<PointeeInfo> {
         match this.ty.kind {
             ty::RawPtr(mt) if offset.bytes() == 0 => {
                 cx.layout_of(mt.ty).to_result().ok().map(|layout| PointeeInfo {
@@ -2211,7 +2219,7 @@ where
 
                 if let Some(variant) = data_variant {
                     // We're not interested in any unions.
-                    if let FieldPlacement::Union(_) = variant.fields {
+                    if let FieldsShape::Union(_) = variant.fields {
                         data_variant = None;
                     }
                 }
@@ -2337,7 +2345,7 @@ impl<'tcx> ty::Instance<'tcx> {
 
 pub trait FnAbiExt<'tcx, C>
 where
-    C: LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
+    C: LayoutOf<Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>>
         + HasDataLayout
         + HasTargetSpec
         + HasTyCtxt<'tcx>
@@ -2361,21 +2369,70 @@ where
         sig: ty::PolyFnSig<'tcx>,
         extra_args: &[Ty<'tcx>],
         caller_location: Option<Ty<'tcx>>,
+        codegen_fn_attr_flags: CodegenFnAttrFlags,
         mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgAbi<'tcx, Ty<'tcx>>,
     ) -> Self;
     fn adjust_for_abi(&mut self, cx: &C, abi: SpecAbi);
 }
 
+fn fn_can_unwind(
+    panic_strategy: PanicStrategy,
+    codegen_fn_attr_flags: CodegenFnAttrFlags,
+    call_conv: Conv,
+) -> bool {
+    if panic_strategy != PanicStrategy::Unwind {
+        // In panic=abort mode we assume nothing can unwind anywhere, so
+        // optimize based on this!
+        false
+    } else if codegen_fn_attr_flags.contains(CodegenFnAttrFlags::UNWIND) {
+        // If a specific #[unwind] attribute is present, use that.
+        true
+    } else if codegen_fn_attr_flags.contains(CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) {
+        // Special attribute for allocator functions, which can't unwind.
+        false
+    } else {
+        if call_conv == Conv::Rust {
+            // Any Rust method (or `extern "Rust" fn` or `extern
+            // "rust-call" fn`) is explicitly allowed to unwind
+            // (unless it has no-unwind attribute, handled above).
+            true
+        } else {
+            // Anything else is either:
+            //
+            //  1. A foreign item using a non-Rust ABI (like `extern "C" { fn foo(); }`), or
+            //
+            //  2. A Rust item using a non-Rust ABI (like `extern "C" fn foo() { ... }`).
+            //
+            // Foreign items (case 1) are assumed to not unwind; it is
+            // UB otherwise. (At least for now; see also
+            // rust-lang/rust#63909 and Rust RFC 2753.)
+            //
+            // Items defined in Rust with non-Rust ABIs (case 2) are also
+            // not supposed to unwind. Whether this should be enforced
+            // (versus stating it is UB) and *how* it would be enforced
+            // is currently under discussion; see rust-lang/rust#58794.
+            //
+            // In either case, we mark item as explicitly nounwind.
+            false
+        }
+    }
+}
+
 impl<'tcx, C> FnAbiExt<'tcx, C> for call::FnAbi<'tcx, Ty<'tcx>>
 where
-    C: LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
+    C: LayoutOf<Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>>
         + HasDataLayout
         + HasTargetSpec
         + HasTyCtxt<'tcx>
         + HasParamEnv<'tcx>,
 {
     fn of_fn_ptr(cx: &C, sig: ty::PolyFnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
-        call::FnAbi::new_internal(cx, sig, extra_args, None, |ty, _| ArgAbi::new(cx.layout_of(ty)))
+        // Assume that fn pointers may always unwind
+        let codegen_fn_attr_flags = CodegenFnAttrFlags::UNWIND;
+
+        call::FnAbi::new_internal(cx, sig, extra_args, None, codegen_fn_attr_flags, |ty, _| {
+            ArgAbi::new(cx.layout_of(ty))
+        })
     }
 
     fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
@@ -2387,7 +2444,9 @@ where
             None
         };
 
-        call::FnAbi::new_internal(cx, sig, extra_args, caller_location, |ty, arg_idx| {
+        let attrs = cx.tcx().codegen_fn_attrs(instance.def_id()).flags;
+
+        call::FnAbi::new_internal(cx, sig, extra_args, caller_location, attrs, |ty, arg_idx| {
             let mut layout = cx.layout_of(ty);
             // Don't pass the vtable, it's not an argument of the virtual fn.
             // Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait`
@@ -2443,6 +2502,7 @@ where
         sig: ty::PolyFnSig<'tcx>,
         extra_args: &[Ty<'tcx>],
         caller_location: Option<Ty<'tcx>>,
+        codegen_fn_attr_flags: CodegenFnAttrFlags,
         mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgAbi<'tcx, Ty<'tcx>>,
     ) -> Self {
         debug!("FnAbi::new_internal({:?}, {:?})", sig, extra_args);
@@ -2518,7 +2578,7 @@ where
         // Handle safe Rust thin and fat pointers.
         let adjust_for_rust_scalar = |attrs: &mut ArgAttributes,
                                       scalar: &Scalar,
-                                      layout: TyLayout<'tcx>,
+                                      layout: TyAndLayout<'tcx>,
                                       offset: Size,
                                       is_return: bool| {
             // Booleans are always an i1 that needs to be zero-extended.
@@ -2632,6 +2692,7 @@ where
             c_variadic: sig.c_variadic,
             fixed_count: inputs.len(),
             conv,
+            can_unwind: fn_can_unwind(cx.tcx().sess.panic_strategy(), codegen_fn_attr_flags, conv),
         };
         fn_abi.adjust_for_abi(cx, sig.abi);
         fn_abi
diff --git a/src/librustc/ty/mod.rs b/src/librustc_middle/ty/mod.rs
index 43982439d47..901365ef691 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc_middle/ty/mod.rs
@@ -11,14 +11,12 @@ use crate::hir::exports::ExportMap;
 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_data_structures::sync::{self, par_iter, Lrc, ParallelIterator};
 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_session::DataTypeKind;
 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};
@@ -524,101 +523,106 @@ bitflags! {
         // 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;
     }
 }
 
@@ -2078,7 +2082,7 @@ pub struct AdtDef {
     /// 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/ty/normalize_erasing_regions.rs b/src/librustc_middle/ty/normalize_erasing_regions.rs
index 2f0a57c59eb..2f0a57c59eb 100644
--- a/src/librustc/ty/normalize_erasing_regions.rs
+++ b/src/librustc_middle/ty/normalize_erasing_regions.rs
diff --git a/src/librustc/ty/outlives.rs b/src/librustc_middle/ty/outlives.rs
index 9dd96f2f2b5..9dd96f2f2b5 100644
--- a/src/librustc/ty/outlives.rs
+++ b/src/librustc_middle/ty/outlives.rs
diff --git a/src/librustc/ty/print/mod.rs b/src/librustc_middle/ty/print/mod.rs
index a932f334dde..a932f334dde 100644
--- a/src/librustc/ty/print/mod.rs
+++ b/src/librustc_middle/ty/print/mod.rs
diff --git a/src/librustc/ty/print/obsolete.rs b/src/librustc_middle/ty/print/obsolete.rs
index 7605d44c7f3..757a8bd23f6 100644
--- a/src/librustc/ty/print/obsolete.rs
+++ b/src/librustc_middle/ty/print/obsolete.rs
@@ -5,9 +5,9 @@
 //! Note: A lot of this could looks very similar to what's already in `ty::print`.
 //! FIXME(eddyb) implement a custom `PrettyPrinter` for this.
 
-use rustc::bug;
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::{self, Const, Instance, Ty, TyCtxt};
+use crate::bug;
+use crate::ty::subst::SubstsRef;
+use crate::ty::{self, Const, Instance, Ty, TyCtxt};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use std::fmt::Write;
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs
index b1626d95eb3..a8b7b6a4b97 100644
--- a/src/librustc/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::{DefKind, Namespace};
 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;
@@ -318,18 +319,15 @@ pub trait PrettyPrinter<'tcx>:
         debug!("try_print_visible_def_path: cur_def_key={:?}", cur_def_key);
 
         // For a constructor, we want the name of its parent rather than <unnamed>.
-        match cur_def_key.disambiguated_data.data {
-            DefPathData::Ctor => {
-                let parent = DefId {
-                    krate: def_id.krate,
-                    index: cur_def_key
-                        .parent
-                        .expect("`DefPathData::Ctor` / `VariantData` missing a parent"),
-                };
+        if let DefPathData::Ctor = cur_def_key.disambiguated_data.data {
+            let parent = DefId {
+                krate: def_id.krate,
+                index: cur_def_key
+                    .parent
+                    .expect("`DefPathData::Ctor` / `VariantData` missing a parent"),
+            };
 
-                cur_def_key = self.tcx().def_key(parent);
-            }
-            _ => {}
+            cur_def_key = self.tcx().def_key(parent);
         }
 
         let visible_parent = match visible_parent_map.get(&def_id).cloned() {
@@ -561,7 +559,7 @@ pub trait PrettyPrinter<'tcx>:
                 // We use verbose printing in 'NO_QUERIES' mode, to
                 // avoid needing to call `predicates_of`. This should
                 // only affect certain debug messages (e.g. messages printed
-                // from `rustc::ty` during the computation of `tcx.predicates_of`),
+                // from `rustc_middle::ty` during the computation of `tcx.predicates_of`),
                 // and should have no effect on any compiler output.
                 if self.tcx().sess.verbose() || NO_QUERIES.with(|q| q.get()) {
                     p!(write("Opaque({:?}, {:?})", def_id, substs));
@@ -1420,9 +1418,8 @@ impl<F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
         self = print_prefix(self)?;
 
         // Skip `::{{constructor}}` on tuple/unit structs.
-        match disambiguated_data.data {
-            DefPathData::Ctor => return Ok(self),
-            _ => {}
+        if let DefPathData::Ctor = disambiguated_data.data {
+            return Ok(self);
         }
 
         // FIXME(eddyb) `name` should never be empty, but it
@@ -1784,11 +1781,8 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
         struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet<Symbol>);
         impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> {
             fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
-                match *r {
-                    ty::ReLateBound(_, ty::BrNamed(_, name)) => {
-                        self.0.insert(name);
-                    }
-                    _ => {}
+                if let ty::ReLateBound(_, ty::BrNamed(_, name)) = *r {
+                    self.0.insert(name);
                 }
                 r.super_visit_with(self)
             }
diff --git a/src/librustc/ty/query/README.md b/src/librustc_middle/ty/query/README.md
index 8ec07b9fdeb..8ec07b9fdeb 100644
--- a/src/librustc/ty/query/README.md
+++ b/src/librustc_middle/ty/query/README.md
diff --git a/src/librustc/ty/query/job.rs b/src/librustc_middle/ty/query/job.rs
index 5f7a9e81158..5f7a9e81158 100644
--- a/src/librustc/ty/query/job.rs
+++ b/src/librustc_middle/ty/query/job.rs
diff --git a/src/librustc/ty/query/keys.rs b/src/librustc_middle/ty/query/keys.rs
index a261e484a85..a261e484a85 100644
--- a/src/librustc/ty/query/keys.rs
+++ b/src/librustc_middle/ty/query/keys.rs
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc_middle/ty/query/mod.rs
index 744237520fb..9986eb88dc3 100644
--- a/src/librustc/ty/query/mod.rs
+++ b/src/librustc_middle/ty/query/mod.rs
@@ -7,7 +7,6 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
 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::steal::Steal;
 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/ty/query/on_disk_cache.rs b/src/librustc_middle/ty/query/on_disk_cache.rs
index 8aecc0e698a..8aecc0e698a 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc_middle/ty/query/on_disk_cache.rs
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc_middle/ty/query/plumbing.rs
index 1bb392f436f..1bb392f436f 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc_middle/ty/query/plumbing.rs
diff --git a/src/librustc/ty/query/profiling_support.rs b/src/librustc_middle/ty/query/profiling_support.rs
index e0d3e764dad..e0d3e764dad 100644
--- a/src/librustc/ty/query/profiling_support.rs
+++ b/src/librustc_middle/ty/query/profiling_support.rs
diff --git a/src/librustc/ty/query/stats.rs b/src/librustc_middle/ty/query/stats.rs
index b496bf839ab..b496bf839ab 100644
--- a/src/librustc/ty/query/stats.rs
+++ b/src/librustc_middle/ty/query/stats.rs
diff --git a/src/librustc/ty/query/values.rs b/src/librustc_middle/ty/query/values.rs
index b01d15c29b2..b01d15c29b2 100644
--- a/src/librustc/ty/query/values.rs
+++ b/src/librustc_middle/ty/query/values.rs
diff --git a/src/librustc/ty/relate.rs b/src/librustc_middle/ty/relate.rs
index 5ff77d073d3..5ff77d073d3 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc_middle/ty/relate.rs
diff --git a/src/librustc/ty/steal.rs b/src/librustc_middle/ty/steal.rs
index 224e76845d7..224e76845d7 100644
--- a/src/librustc/ty/steal.rs
+++ b/src/librustc_middle/ty/steal.rs
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc_middle/ty/structural_impls.rs
index 429791d09a4..0ac4466d34f 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc_middle/ty/structural_impls.rs
@@ -254,7 +254,7 @@ CloneTypeFoldableAndLiftImpls! {
     (),
     bool,
     usize,
-    crate::ty::layout::VariantIdx,
+    ::rustc_target::abi::VariantIdx,
     u64,
     String,
     crate::middle::region::Scope,
diff --git a/src/librustc/ty/sty.rs b/src/librustc_middle/ty/sty.rs
index d440e84e15c..ef815aaab75 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc_middle/ty/sty.rs
@@ -10,7 +10,6 @@ use crate::middle::region;
 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_hir::def_id::{DefId, LocalDefId};
 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;
@@ -1238,7 +1238,7 @@ pub type Region<'tcx> = &'tcx RegionKind;
 ///
 /// The scope regions are related to one another based on the AST
 /// structure. (See `RegionRelations` type, and particularly the
-/// `rustc::middle::region::ScopeTree`.)
+/// `rustc_middle::middle::region::ScopeTree`.)
 ///
 /// Note that inference variables and bound regions are not included
 /// in this diagram. In the case of inference variables, they should
@@ -1623,16 +1623,19 @@ impl RegionKind {
                 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 @@ impl<'tcx> ConstKind<'tcx> {
     }
 
     #[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/ty/subst.rs b/src/librustc_middle/ty/subst.rs
index 0f4485a7050..0f4485a7050 100644
--- a/src/librustc/ty/subst.rs
+++ b/src/librustc_middle/ty/subst.rs
diff --git a/src/librustc/ty/trait_def.rs b/src/librustc_middle/ty/trait_def.rs
index ed9054fcffd..ed9054fcffd 100644
--- a/src/librustc/ty/trait_def.rs
+++ b/src/librustc_middle/ty/trait_def.rs
diff --git a/src/librustc/ty/util.rs b/src/librustc_middle/ty/util.rs
index dab367a6639..86575b01333 100644
--- a/src/librustc/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/ty/walk.rs b/src/librustc_middle/ty/walk.rs
index da08fbcf144..da08fbcf144 100644
--- a/src/librustc/ty/walk.rs
+++ b/src/librustc_middle/ty/walk.rs
diff --git a/src/librustc/util/bug.rs b/src/librustc_middle/util/bug.rs
index 54cd8a29f94..54cd8a29f94 100644
--- a/src/librustc/util/bug.rs
+++ b/src/librustc_middle/util/bug.rs
diff --git a/src/librustc/util/common.rs b/src/librustc_middle/util/common.rs
index 19b43bfd162..1e09702bf27 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc_middle/util/common.rs
@@ -8,8 +8,6 @@ use std::time::{Duration, Instant};
 #[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/util/common/tests.rs b/src/librustc_middle/util/common/tests.rs
index 9a9fb203c62..9a9fb203c62 100644
--- a/src/librustc/util/common/tests.rs
+++ b/src/librustc_middle/util/common/tests.rs
diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml
index 256a80076b9..f9b195e92eb 100644
--- a/src/librustc_mir/Cargo.toml
+++ b/src/librustc_mir/Cargo.toml
@@ -16,7 +16,7 @@ itertools = "0.8"
 log = "0.4"
 log_settings = "0.1.1"
 polonius-engine = "0.12.0"
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc_ast_pretty = { path = "../librustc_ast_pretty" }
 rustc_attr = { path = "../librustc_attr" }
 rustc_data_structures = { path = "../librustc_data_structures" }
diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs
index 9f4f0ce5620..7242bbcd2eb 100644
--- a/src/librustc_mir/borrow_check/borrow_set.rs
+++ b/src/librustc_mir/borrow_check/borrow_set.rs
@@ -3,13 +3,13 @@ use crate::borrow_check::path_utils::allow_two_phase_borrow;
 use crate::borrow_check::place_ext::PlaceExt;
 use crate::dataflow::indexes::BorrowIndex;
 use crate::dataflow::move_paths::MoveData;
-use rustc::mir::traversal;
-use rustc::mir::visit::{MutatingUseContext, NonUseContext, PlaceContext, Visitor};
-use rustc::mir::{self, Body, Local, Location, ReadOnlyBodyAndCache};
-use rustc::ty::{RegionVid, TyCtxt};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_index::bit_set::BitSet;
 use rustc_index::vec::IndexVec;
+use rustc_middle::mir::traversal;
+use rustc_middle::mir::visit::{MutatingUseContext, NonUseContext, PlaceContext, Visitor};
+use rustc_middle::mir::{self, Body, Local, Location, ReadOnlyBodyAndCache};
+use rustc_middle::ty::{RegionVid, TyCtxt};
 use std::fmt;
 use std::ops::Index;
 
@@ -107,7 +107,7 @@ impl LocalsStateAtExit {
             LocalsStateAtExit::AllAreInvalidated
         } else {
             let mut has_storage_dead = HasStorageDead(BitSet::new_empty(body.local_decls.len()));
-            has_storage_dead.visit_body(body);
+            has_storage_dead.visit_body(&body);
             let mut has_storage_dead_or_moved = has_storage_dead.0;
             for move_out in &move_data.moves {
                 if let Some(index) = move_data.base_local(move_out.path) {
@@ -206,7 +206,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> {
             let idx = self.idx_vec.push(borrow);
             self.location_map.insert(location, idx);
 
-            self.insert_as_pending_if_two_phase(location, &assigned_place, kind, idx);
+            self.insert_as_pending_if_two_phase(location, assigned_place, kind, idx);
 
             self.local_map.entry(borrowed_place.local).or_default().insert(idx);
         }
diff --git a/src/librustc_mir/borrow_check/constraint_generation.rs b/src/librustc_mir/borrow_check/constraint_generation.rs
index 46cfe0897a9..e0420d974fb 100644
--- a/src/librustc_mir/borrow_check/constraint_generation.rs
+++ b/src/librustc_mir/borrow_check/constraint_generation.rs
@@ -1,13 +1,13 @@
-use rustc::mir::visit::TyContext;
-use rustc::mir::visit::Visitor;
-use rustc::mir::{
+use rustc_infer::infer::InferCtxt;
+use rustc_middle::mir::visit::TyContext;
+use rustc_middle::mir::visit::Visitor;
+use rustc_middle::mir::{
     BasicBlock, BasicBlockData, Body, Local, Location, Place, PlaceRef, ProjectionElem, Rvalue,
     SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, UserTypeProjection,
 };
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::{self, RegionVid, Ty};
-use rustc_infer::infer::InferCtxt;
+use rustc_middle::ty::fold::TypeFoldable;
+use rustc_middle::ty::subst::SubstsRef;
+use rustc_middle::ty::{self, RegionVid, Ty};
 
 use crate::borrow_check::{
     borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, nll::ToRegionVid,
@@ -114,7 +114,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> {
     fn visit_assign(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
         // When we see `X = ...`, then kill borrows of
         // `(*X).foo` and so forth.
-        self.record_killed_borrows_for_place(place, location);
+        self.record_killed_borrows_for_place(*place, location);
 
         self.super_assign(place, rvalue, location);
     }
@@ -139,7 +139,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> {
 
         // A `Call` terminator's return value can be a local which has borrows,
         // so we need to record those as `killed` as well.
-        if let TerminatorKind::Call { ref destination, .. } = terminator.kind {
+        if let TerminatorKind::Call { destination, .. } = terminator.kind {
             if let Some((place, _)) = destination {
                 self.record_killed_borrows_for_place(place, location);
             }
@@ -177,7 +177,7 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> {
 
     /// When recording facts for Polonius, records the borrows on the specified place
     /// as `killed`. For example, when assigning to a local, or on a call's return destination.
-    fn record_killed_borrows_for_place(&mut self, place: &Place<'tcx>, location: Location) {
+    fn record_killed_borrows_for_place(&mut self, place: Place<'tcx>, location: Location) {
         if let Some(all_facts) = self.all_facts {
             let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation");
 
@@ -217,7 +217,7 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> {
                             let places_conflict = places_conflict::places_conflict(
                                 self.infcx.tcx,
                                 self.body,
-                                &self.borrow_set.borrows[borrow_index].borrowed_place,
+                                self.borrow_set.borrows[borrow_index].borrowed_place,
                                 place,
                                 places_conflict::PlaceConflictBias::NoOverlap,
                             );
diff --git a/src/librustc_mir/borrow_check/constraints/graph.rs b/src/librustc_mir/borrow_check/constraints/graph.rs
index c60a11e348d..f3f6b8c10da 100644
--- a/src/librustc_mir/borrow_check/constraints/graph.rs
+++ b/src/librustc_mir/borrow_check/constraints/graph.rs
@@ -1,7 +1,7 @@
-use rustc::mir::ConstraintCategory;
-use rustc::ty::RegionVid;
 use rustc_data_structures::graph;
 use rustc_index::vec::IndexVec;
+use rustc_middle::mir::ConstraintCategory;
+use rustc_middle::ty::RegionVid;
 use rustc_span::DUMMY_SP;
 
 use crate::borrow_check::{
diff --git a/src/librustc_mir/borrow_check/constraints/mod.rs b/src/librustc_mir/borrow_check/constraints/mod.rs
index ef70b127ac5..3772b7d8f98 100644
--- a/src/librustc_mir/borrow_check/constraints/mod.rs
+++ b/src/librustc_mir/borrow_check/constraints/mod.rs
@@ -1,7 +1,7 @@
-use rustc::mir::ConstraintCategory;
-use rustc::ty::RegionVid;
 use rustc_data_structures::graph::scc::Sccs;
 use rustc_index::vec::IndexVec;
+use rustc_middle::mir::ConstraintCategory;
+use rustc_middle::ty::RegionVid;
 use std::fmt;
 use std::ops::Index;
 
diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
index 8f18fb4a30e..9df57605631 100644
--- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
@@ -1,15 +1,15 @@
-use rustc::mir::{
-    self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory,
-    FakeReadCause, Local, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
-    ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm,
-};
-use rustc::ty::{self, Ty};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{AsyncGeneratorKind, GeneratorKind};
 use rustc_index::vec::Idx;
+use rustc_middle::mir::{
+    self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory,
+    FakeReadCause, Local, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
+    ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm,
+};
+use rustc_middle::ty::{self, Ty};
 use rustc_span::source_map::DesugaringKind;
 use rustc_span::Span;
 use rustc_trait_selection::traits::error_reporting::suggest_constraining_type_param;
@@ -222,8 +222,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                             &mut err,
                             &param.name.as_str(),
                             "Copy",
-                            tcx.sess.source_map(),
-                            span,
                             None,
                         );
                     }
@@ -249,7 +247,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     pub(in crate::borrow_check) fn report_move_out_while_borrowed(
         &mut self,
         location: Location,
-        (place, span): (&Place<'tcx>, Span),
+        (place, span): (Place<'tcx>, Span),
         borrow: &BorrowData<'tcx>,
     ) {
         debug!(
@@ -293,7 +291,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     pub(in crate::borrow_check) fn report_use_while_mutably_borrowed(
         &mut self,
         location: Location,
-        (place, _span): (&Place<'tcx>, Span),
+        (place, _span): (Place<'tcx>, Span),
         borrow: &BorrowData<'tcx>,
     ) -> DiagnosticBuilder<'cx> {
         let borrow_spans = self.retrieve_borrow_spans(borrow);
@@ -332,7 +330,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     pub(in crate::borrow_check) fn report_conflicting_borrow(
         &mut self,
         location: Location,
-        (place, span): (&Place<'tcx>, Span),
+        (place, span): (Place<'tcx>, Span),
         gen_borrow_kind: BorrowKind,
         issued_borrow: &BorrowData<'tcx>,
     ) -> DiagnosticBuilder<'cx> {
@@ -349,7 +347,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         };
 
         let (desc_place, msg_place, msg_borrow, union_type_name) =
-            self.describe_place_for_conflicting_borrow(place, &issued_borrow.borrowed_place);
+            self.describe_place_for_conflicting_borrow(place, issued_borrow.borrowed_place);
 
         let explanation = self.explain_why_borrow_contains_point(location, issued_borrow, None);
         let second_borrow_desc = if explanation.is_explained() { "second " } else { "" };
@@ -398,8 +396,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 );
                 self.suggest_split_at_mut_if_applicable(
                     &mut err,
-                    &place,
-                    &issued_borrow.borrowed_place,
+                    place,
+                    issued_borrow.borrowed_place,
                 );
                 err
             }
@@ -412,7 +410,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             (BorrowKind::Mut { .. }, BorrowKind::Shallow)
             | (BorrowKind::Unique, BorrowKind::Shallow) => {
                 if let Some(immutable_section_description) =
-                    self.classify_immutable_section(&issued_borrow.assigned_place)
+                    self.classify_immutable_section(issued_borrow.assigned_place)
                 {
                     let mut err = self.cannot_mutate_in_immutable_section(
                         span,
@@ -548,17 +546,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     fn suggest_split_at_mut_if_applicable(
         &self,
         err: &mut DiagnosticBuilder<'_>,
-        place: &Place<'tcx>,
-        borrowed_place: &Place<'tcx>,
+        place: Place<'tcx>,
+        borrowed_place: Place<'tcx>,
     ) {
-        match (&place.projection[..], &borrowed_place.projection[..]) {
-            ([ProjectionElem::Index(_)], [ProjectionElem::Index(_)]) => {
-                err.help(
-                    "consider using `.split_at_mut(position)` or similar method to obtain \
+        if let ([ProjectionElem::Index(_)], [ProjectionElem::Index(_)]) =
+            (&place.projection[..], &borrowed_place.projection[..])
+        {
+            err.help(
+                "consider using `.split_at_mut(position)` or similar method to obtain \
                      two mutable non-overlapping sub-slices",
-                );
-            }
-            _ => {}
+            );
         }
     }
 
@@ -587,8 +584,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     /// >  mutable (via `a.u.s.b`) [E0502]
     pub(in crate::borrow_check) fn describe_place_for_conflicting_borrow(
         &self,
-        first_borrowed_place: &Place<'tcx>,
-        second_borrowed_place: &Place<'tcx>,
+        first_borrowed_place: Place<'tcx>,
+        second_borrowed_place: Place<'tcx>,
     ) -> (String, String, String, String) {
         // Define a small closure that we can use to check if the type of a place
         // is a union.
@@ -618,13 +615,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     cursor = proj_base;
 
                     match elem {
-                        ProjectionElem::Field(field, _)
-                            if union_ty(*local, proj_base).is_some() =>
-                        {
-                            return Some((
-                                PlaceRef { local: *local, projection: proj_base },
-                                field,
-                            ));
+                        ProjectionElem::Field(field, _) if union_ty(local, proj_base).is_some() => {
+                            return Some((PlaceRef { local, projection: proj_base }, field));
                         }
                         _ => {}
                     }
@@ -634,7 +626,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             .and_then(|(target_base, target_field)| {
                 // With the place of a union and a field access into it, we traverse the second
                 // borrowed place and look for a access to a different field of the same union.
-                let Place { local, ref projection } = *second_borrowed_place;
+                let Place { local, ref projection } = second_borrowed_place;
 
                 let mut cursor = &projection[..];
                 while let [proj_base @ .., elem] = cursor {
@@ -685,7 +677,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         &mut self,
         location: Location,
         borrow: &BorrowData<'tcx>,
-        place_span: (&Place<'tcx>, Span),
+        place_span: (Place<'tcx>, Span),
         kind: Option<WriteKind>,
     ) {
         debug!(
@@ -970,7 +962,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         &mut self,
         location: Location,
         borrow: &BorrowData<'tcx>,
-        (place, drop_span): (&Place<'tcx>, Span),
+        (place, drop_span): (Place<'tcx>, Span),
         kind: Option<WriteKind>,
         dropped_ty: Ty<'tcx>,
     ) {
@@ -1382,7 +1374,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     pub(in crate::borrow_check) fn report_illegal_mutation_of_borrowed(
         &mut self,
         location: Location,
-        (place, span): (&Place<'tcx>, Span),
+        (place, span): (Place<'tcx>, Span),
         loan: &BorrowData<'tcx>,
     ) {
         let loan_spans = self.retrieve_borrow_spans(loan);
@@ -1390,7 +1382,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
         let descr_place = self.describe_any_place(place.as_ref());
         if loan.kind == BorrowKind::Shallow {
-            if let Some(section) = self.classify_immutable_section(&loan.assigned_place) {
+            if let Some(section) = self.classify_immutable_section(loan.assigned_place) {
                 let mut err = self.cannot_mutate_in_immutable_section(
                     span,
                     loan_span,
@@ -1435,9 +1427,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     pub(in crate::borrow_check) fn report_illegal_reassignment(
         &mut self,
         _location: Location,
-        (place, span): (&Place<'tcx>, Span),
+        (place, span): (Place<'tcx>, Span),
         assigned_span: Span,
-        err_place: &Place<'tcx>,
+        err_place: Place<'tcx>,
     ) {
         let (from_arg, local_decl, local_name) = match err_place.as_local() {
             Some(local) => (
@@ -1542,17 +1534,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     }
 
     /// Describe the reason for the fake borrow that was assigned to `place`.
-    fn classify_immutable_section(&self, place: &Place<'tcx>) -> Option<&'static str> {
-        use rustc::mir::visit::Visitor;
-        struct FakeReadCauseFinder<'a, 'tcx> {
-            place: &'a Place<'tcx>,
+    fn classify_immutable_section(&self, place: Place<'tcx>) -> Option<&'static str> {
+        use rustc_middle::mir::visit::Visitor;
+        struct FakeReadCauseFinder<'tcx> {
+            place: Place<'tcx>,
             cause: Option<FakeReadCause>,
         }
-        impl<'tcx> Visitor<'tcx> for FakeReadCauseFinder<'_, 'tcx> {
+        impl<'tcx> Visitor<'tcx> for FakeReadCauseFinder<'tcx> {
             fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) {
                 match statement {
-                    Statement { kind: StatementKind::FakeRead(cause, box ref place), .. }
-                        if *place == *self.place =>
+                    Statement { kind: StatementKind::FakeRead(cause, box place), .. }
+                        if *place == self.place =>
                     {
                         self.cause = Some(*cause);
                     }
@@ -1561,7 +1553,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             }
         }
         let mut visitor = FakeReadCauseFinder { place, cause: None };
-        visitor.visit_body(self.body);
+        visitor.visit_body(&self.body);
         match visitor.cause {
             Some(FakeReadCause::ForMatchGuard) => Some("match guard"),
             Some(FakeReadCause::ForIndex) => Some("indexing expression"),
@@ -1823,7 +1815,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 for (index, argument) in sig.inputs().skip_binder().iter().enumerate() {
                     if let ty::Ref(argument_region, _, _) = argument.kind {
                         if argument_region == return_region {
-                            // Need to use the `rustc::ty` types to compare against the
+                            // Need to use the `rustc_middle::ty` types to compare against the
                             // `return_region`. Then use the `rustc_hir` type to get only
                             // the lifetime span.
                             if let hir::TyKind::Rptr(lifetime, _) = &fn_decl.inputs[index].kind {
diff --git a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs
index 6475677988f..7340e88f19b 100644
--- a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs
@@ -2,16 +2,16 @@
 
 use std::collections::VecDeque;
 
-use rustc::mir::{
-    Body, CastKind, ConstraintCategory, FakeReadCause, Local, Location, Operand, Place, Rvalue,
-    Statement, StatementKind, TerminatorKind,
-};
-use rustc::ty::adjustment::PointerCast;
-use rustc::ty::{self, RegionVid, TyCtxt};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{Applicability, DiagnosticBuilder};
 use rustc_index::vec::IndexVec;
 use rustc_infer::infer::NLLRegionVariableOrigin;
+use rustc_middle::mir::{
+    Body, CastKind, ConstraintCategory, FakeReadCause, Local, Location, Operand, Place, Rvalue,
+    Statement, StatementKind, TerminatorKind,
+};
+use rustc_middle::ty::adjustment::PointerCast;
+use rustc_middle::ty::{self, RegionVid, TyCtxt};
 use rustc_span::symbol::Symbol;
 use rustc_span::Span;
 
@@ -227,29 +227,26 @@ impl BorrowExplanation {
         span: Span,
         region_name: &RegionName,
     ) {
-        match category {
-            ConstraintCategory::OpaqueType => {
-                if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(span) {
-                    let suggestable_name = if region_name.was_named() {
-                        region_name.to_string()
-                    } else {
-                        "'_".to_string()
-                    };
+        if let ConstraintCategory::OpaqueType = category {
+            if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(span) {
+                let suggestable_name = if region_name.was_named() {
+                    region_name.to_string()
+                } else {
+                    "'_".to_string()
+                };
 
-                    err.span_suggestion(
-                        span,
-                        &format!(
-                            "you can add a bound to the {}to make it last less than \
+                err.span_suggestion(
+                    span,
+                    &format!(
+                        "you can add a bound to the {}to make it last less than \
                              `'static` and match `{}`",
-                            category.description(),
-                            region_name,
-                        ),
-                        format!("{} + {}", snippet, suggestable_name),
-                        Applicability::Unspecified,
-                    );
-                }
+                        category.description(),
+                        region_name,
+                    ),
+                    format!("{} + {}", snippet, suggestable_name),
+                    Applicability::Unspecified,
+                );
             }
-            _ => {}
         }
     }
 }
@@ -289,7 +286,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         &self,
         location: Location,
         borrow: &BorrowData<'tcx>,
-        kind_place: Option<(WriteKind, &Place<'tcx>)>,
+        kind_place: Option<(WriteKind, Place<'tcx>)>,
     ) -> BorrowExplanation {
         debug!(
             "explain_why_borrow_contains_point(location={:?}, borrow={:?}, kind_place={:?})",
diff --git a/src/librustc_mir/borrow_check/diagnostics/find_use.rs b/src/librustc_mir/borrow_check/diagnostics/find_use.rs
index ca4141d5fa5..6c6bde8ae2c 100644
--- a/src/librustc_mir/borrow_check/diagnostics/find_use.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/find_use.rs
@@ -6,10 +6,10 @@ use crate::borrow_check::{
     region_infer::{Cause, RegionInferenceContext},
 };
 use crate::util::liveness::{self, DefUse};
-use rustc::mir::visit::{MirVisitable, PlaceContext, Visitor};
-use rustc::mir::{Body, Local, Location};
-use rustc::ty::{RegionVid, TyCtxt};
 use rustc_data_structures::fx::FxHashSet;
+use rustc_middle::mir::visit::{MirVisitable, PlaceContext, Visitor};
+use rustc_middle::mir::{Body, Local, Location};
+use rustc_middle::ty::{RegionVid, TyCtxt};
 
 crate fn find<'tcx>(
     body: &Body<'tcx>,
diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs
index 605093d8aca..619ae0ff8fa 100644
--- a/src/librustc_mir/borrow_check/diagnostics/mod.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs
@@ -1,18 +1,18 @@
 //! Borrow checker diagnostics.
 
-use rustc::mir::{
-    AggregateKind, Constant, Field, Local, LocalInfo, LocalKind, Location, Operand, Place,
-    PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
-};
-use rustc::ty::layout::VariantIdx;
-use rustc::ty::print::Print;
-use rustc::ty::{self, DefIdTree, Ty, TyCtxt};
 use rustc_errors::DiagnosticBuilder;
 use rustc_hir as hir;
 use rustc_hir::def::Namespace;
 use rustc_hir::def_id::DefId;
 use rustc_hir::GeneratorKind;
+use rustc_middle::mir::{
+    AggregateKind, Constant, Field, Local, LocalInfo, LocalKind, Location, Operand, Place,
+    PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
+};
+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/diagnostics/move_errors.rs b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs
index 2cdc1ced0bb..d32533b6ce9 100644
--- a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs
@@ -1,6 +1,6 @@
-use rustc::mir::*;
-use rustc::ty;
 use rustc_errors::{Applicability, DiagnosticBuilder};
+use rustc_middle::mir::*;
+use rustc_middle::ty;
 use rustc_span::source_map::DesugaringKind;
 use rustc_span::{Span, Symbol};
 
@@ -105,7 +105,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                         // whether or not the right-hand side is a place expression
                         if let LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
                             VarBindingForm {
-                                opt_match_place: Some((ref opt_match_place, match_span)),
+                                opt_match_place: Some((opt_match_place, match_span)),
                                 binding_mode: _,
                                 opt_ty_info: _,
                                 pat_span: _,
@@ -117,7 +117,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                                 grouped_errors,
                                 kind,
                                 original_path,
-                                move_from,
+                                *move_from,
                                 local,
                                 opt_match_place,
                                 match_span,
@@ -143,16 +143,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         grouped_errors: &mut Vec<GroupedMoveError<'tcx>>,
         kind: IllegalMoveOriginKind<'tcx>,
         original_path: Place<'tcx>,
-        move_from: &Place<'tcx>,
+        move_from: Place<'tcx>,
         bind_to: Local,
-        match_place: &Option<Place<'tcx>>,
+        match_place: Option<Place<'tcx>>,
         match_span: Span,
         statement_span: Span,
     ) {
         debug!("append_binding_error(match_place={:?}, match_span={:?})", match_place, match_span);
 
         let from_simple_let = match_place.is_none();
-        let match_place = match_place.as_ref().unwrap_or(move_from);
+        let match_place = match_place.unwrap_or(move_from);
 
         match self.move_data.rev_lookup.find(match_place.as_ref()) {
             // Error with the match place
@@ -178,7 +178,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 };
                 grouped_errors.push(GroupedMoveError::MovesFromPlace {
                     span,
-                    move_from: *match_place,
+                    move_from,
                     original_path,
                     kind,
                     binds_to,
@@ -223,14 +223,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             let (span, use_spans, original_path, kind): (
                 Span,
                 Option<UseSpans>,
-                &Place<'tcx>,
+                Place<'tcx>,
                 &IllegalMoveOriginKind<'_>,
             ) = match error {
-                GroupedMoveError::MovesFromPlace { span, ref original_path, ref kind, .. }
-                | GroupedMoveError::MovesFromValue { span, ref original_path, ref kind, .. } => {
+                GroupedMoveError::MovesFromPlace { span, original_path, ref kind, .. }
+                | GroupedMoveError::MovesFromValue { span, original_path, ref kind, .. } => {
                     (span, None, original_path, kind)
                 }
-                GroupedMoveError::OtherIllegalMove { use_spans, ref original_path, ref kind } => {
+                GroupedMoveError::OtherIllegalMove { use_spans, original_path, ref kind } => {
                     (use_spans.args_or_use(), Some(use_spans), original_path, kind)
                 }
             };
@@ -247,7 +247,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                     IllegalMoveOriginKind::BorrowedContent { target_place } => self
                         .report_cannot_move_from_borrowed_content(
                             original_path,
-                            target_place,
+                            *target_place,
                             span,
                             use_spans,
                         ),
@@ -268,7 +268,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
     fn report_cannot_move_from_static(
         &mut self,
-        place: &Place<'tcx>,
+        place: Place<'tcx>,
         span: Span,
     ) -> DiagnosticBuilder<'a> {
         let description = if place.projection.len() == 1 {
@@ -288,8 +288,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
     fn report_cannot_move_from_borrowed_content(
         &mut self,
-        move_place: &Place<'tcx>,
-        deref_target_place: &Place<'tcx>,
+        move_place: Place<'tcx>,
+        deref_target_place: Place<'tcx>,
         span: Span,
         use_spans: Option<UseSpans>,
     ) -> DiagnosticBuilder<'a> {
diff --git a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs
index f224041270d..35edd3d803d 100644
--- a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs
@@ -1,9 +1,9 @@
-use rustc::mir::{self, ClearCrossCrate, Local, LocalInfo, Location};
-use rustc::mir::{Mutability, Place, PlaceRef, ProjectionElem};
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_hir as hir;
 use rustc_hir::Node;
 use rustc_index::vec::Idx;
+use rustc_middle::mir::{self, ClearCrossCrate, Local, LocalInfo, Location};
+use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::source_map::DesugaringKind;
 use rustc_span::symbol::kw;
 use rustc_span::Span;
@@ -22,7 +22,7 @@ pub(crate) enum AccessKind {
 impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
     pub(crate) fn report_mutability_error(
         &mut self,
-        access_place: &Place<'tcx>,
+        access_place: Place<'tcx>,
         span: Span,
         the_place_err: PlaceRef<'tcx>,
         error_access: AccessKind,
@@ -497,62 +497,60 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         let mut look_at_return = true;
         // If we can detect the expression to be an `fn` call where the closure was an argument,
         // we point at the `fn` definition argument...
-        match node {
-            hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Call(func, args), .. }) => {
-                let arg_pos = args
-                    .iter()
-                    .enumerate()
-                    .filter(|(_, arg)| arg.span == self.body.span)
-                    .map(|(pos, _)| pos)
-                    .next();
-                let def_id = hir.local_def_id(item_id);
-                let tables = self.infcx.tcx.typeck_tables_of(def_id);
-                if let Some(ty::FnDef(def_id, _)) =
-                    tables.node_type_opt(func.hir_id).as_ref().map(|ty| &ty.kind)
-                {
-                    let arg = match hir.get_if_local(*def_id) {
-                        Some(hir::Node::Item(hir::Item {
-                            ident,
-                            kind: hir::ItemKind::Fn(sig, ..),
-                            ..
-                        }))
-                        | Some(hir::Node::TraitItem(hir::TraitItem {
-                            ident,
-                            kind: hir::TraitItemKind::Fn(sig, _),
-                            ..
-                        }))
-                        | Some(hir::Node::ImplItem(hir::ImplItem {
-                            ident,
-                            kind: hir::ImplItemKind::Fn(sig, _),
-                            ..
-                        })) => Some(
-                            arg_pos
-                                .and_then(|pos| {
-                                    sig.decl.inputs.get(
-                                        pos + if sig.decl.implicit_self.has_implicit_self() {
-                                            1
-                                        } else {
-                                            0
-                                        },
-                                    )
-                                })
-                                .map(|arg| arg.span)
-                                .unwrap_or(ident.span),
-                        ),
-                        _ => None,
-                    };
-                    if let Some(span) = arg {
-                        err.span_label(span, "change this to accept `FnMut` instead of `Fn`");
-                        err.span_label(func.span, "expects `Fn` instead of `FnMut`");
-                        if self.infcx.tcx.sess.source_map().is_multiline(self.body.span) {
-                            err.span_label(self.body.span, "in this closure");
-                        }
-                        look_at_return = false;
+        if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Call(func, args), .. }) = node {
+            let arg_pos = args
+                .iter()
+                .enumerate()
+                .filter(|(_, arg)| arg.span == self.body.span)
+                .map(|(pos, _)| pos)
+                .next();
+            let def_id = hir.local_def_id(item_id);
+            let tables = self.infcx.tcx.typeck_tables_of(def_id);
+            if let Some(ty::FnDef(def_id, _)) =
+                tables.node_type_opt(func.hir_id).as_ref().map(|ty| &ty.kind)
+            {
+                let arg = match hir.get_if_local(*def_id) {
+                    Some(hir::Node::Item(hir::Item {
+                        ident,
+                        kind: hir::ItemKind::Fn(sig, ..),
+                        ..
+                    }))
+                    | Some(hir::Node::TraitItem(hir::TraitItem {
+                        ident,
+                        kind: hir::TraitItemKind::Fn(sig, _),
+                        ..
+                    }))
+                    | Some(hir::Node::ImplItem(hir::ImplItem {
+                        ident,
+                        kind: hir::ImplItemKind::Fn(sig, _),
+                        ..
+                    })) => Some(
+                        arg_pos
+                            .and_then(|pos| {
+                                sig.decl.inputs.get(
+                                    pos + if sig.decl.implicit_self.has_implicit_self() {
+                                        1
+                                    } else {
+                                        0
+                                    },
+                                )
+                            })
+                            .map(|arg| arg.span)
+                            .unwrap_or(ident.span),
+                    ),
+                    _ => None,
+                };
+                if let Some(span) = arg {
+                    err.span_label(span, "change this to accept `FnMut` instead of `Fn`");
+                    err.span_label(func.span, "expects `Fn` instead of `FnMut`");
+                    if self.infcx.tcx.sess.source_map().is_multiline(self.body.span) {
+                        err.span_label(self.body.span, "in this closure");
                     }
+                    look_at_return = false;
                 }
             }
-            _ => {}
         }
+
         if look_at_return && hir.get_return_block(closure_id).is_some() {
             // ...otherwise we are probably in the tail expression of the function, point at the
             // return type.
diff --git a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs b/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs
index ee9489078bd..dd970d800fb 100644
--- a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs
@@ -4,9 +4,9 @@
 use std::collections::BTreeMap;
 
 use log::debug;
-use rustc::ty::RegionVid;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::DiagnosticBuilder;
+use rustc_middle::ty::RegionVid;
 
 use smallvec::SmallVec;
 
diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs
index 93800d2a2b3..98c0542f9c0 100644
--- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs
@@ -1,12 +1,12 @@
 //! Error reporting machinery for lifetime errors.
 
-use rustc::mir::ConstraintCategory;
-use rustc::ty::{self, RegionVid, Ty};
 use rustc_errors::{Applicability, DiagnosticBuilder};
 use rustc_infer::infer::{
     error_reporting::nice_region_error::NiceRegionError,
     error_reporting::unexpected_hidden_region_diagnostic, NLLRegionVariableOrigin,
 };
+use rustc_middle::mir::ConstraintCategory;
+use rustc_middle::ty::{self, RegionVid, Ty};
 use rustc_span::symbol::kw;
 use rustc_span::Span;
 
diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/src/librustc_mir/borrow_check/diagnostics/region_name.rs
index 6756f476f61..a085c2f7f69 100644
--- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/region_name.rs
@@ -1,11 +1,11 @@
 use std::fmt::{self, Display};
 
-use rustc::ty::print::RegionHighlightMode;
-use rustc::ty::subst::{GenericArgKind, SubstsRef};
-use rustc::ty::{self, RegionVid, Ty};
 use rustc_errors::DiagnosticBuilder;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
+use rustc_middle::ty::print::RegionHighlightMode;
+use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
+use rustc_middle::ty::{self, RegionVid, Ty};
 use rustc_span::symbol::kw;
 use rustc_span::{symbol::Symbol, Span, DUMMY_SP};
 
diff --git a/src/librustc_mir/borrow_check/diagnostics/var_name.rs b/src/librustc_mir/borrow_check/diagnostics/var_name.rs
index c4933bedc22..a850b85e9bb 100644
--- a/src/librustc_mir/borrow_check/diagnostics/var_name.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/var_name.rs
@@ -1,8 +1,8 @@
 use crate::borrow_check::Upvar;
 use crate::borrow_check::{nll::ToRegionVid, region_infer::RegionInferenceContext};
-use rustc::mir::{Body, Local};
-use rustc::ty::{RegionVid, TyCtxt};
 use rustc_index::vec::{Idx, IndexVec};
+use rustc_middle::mir::{Body, Local};
+use rustc_middle::ty::{RegionVid, TyCtxt};
 use rustc_span::source_map::Span;
 use rustc_span::symbol::Symbol;
 
diff --git a/src/librustc_mir/borrow_check/facts.rs b/src/librustc_mir/borrow_check/facts.rs
index cd8139b17b4..6d6b94ecf64 100644
--- a/src/librustc_mir/borrow_check/facts.rs
+++ b/src/librustc_mir/borrow_check/facts.rs
@@ -2,9 +2,9 @@ use crate::borrow_check::location::{LocationIndex, LocationTable};
 use crate::dataflow::indexes::{BorrowIndex, MovePathIndex};
 use polonius_engine::AllFacts as PoloniusFacts;
 use polonius_engine::Atom;
-use rustc::mir::Local;
-use rustc::ty::{RegionVid, TyCtxt};
 use rustc_index::vec::Idx;
+use rustc_middle::mir::Local;
+use rustc_middle::ty::{RegionVid, TyCtxt};
 use std::error::Error;
 use std::fmt::Debug;
 use std::fs::{self, File};
diff --git a/src/librustc_mir/borrow_check/invalidation.rs b/src/librustc_mir/borrow_check/invalidation.rs
index 3d1768cf0e5..318751113b2 100644
--- a/src/librustc_mir/borrow_check/invalidation.rs
+++ b/src/librustc_mir/borrow_check/invalidation.rs
@@ -1,10 +1,10 @@
-use rustc::mir::visit::Visitor;
-use rustc::mir::TerminatorKind;
-use rustc::mir::{BasicBlock, Body, Location, Place, ReadOnlyBodyAndCache, Rvalue};
-use rustc::mir::{BorrowKind, Mutability, Operand};
-use rustc::mir::{Statement, StatementKind};
-use rustc::ty::TyCtxt;
 use rustc_data_structures::graph::dominators::Dominators;
+use rustc_middle::mir::visit::Visitor;
+use rustc_middle::mir::TerminatorKind;
+use rustc_middle::mir::{BasicBlock, Body, Location, Place, ReadOnlyBodyAndCache, Rvalue};
+use rustc_middle::mir::{BorrowKind, Mutability, Operand};
+use rustc_middle::mir::{Statement, StatementKind};
+use rustc_middle::ty::TyCtxt;
 
 use crate::dataflow::indexes::BorrowIndex;
 
@@ -37,7 +37,7 @@ pub(super) fn generate_invalidates<'tcx>(
             body: &body,
             dominators,
         };
-        ig.visit_body(body);
+        ig.visit_body(&body);
     }
 }
 
@@ -56,33 +56,33 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
     fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
         self.check_activations(location);
 
-        match statement.kind {
-            StatementKind::Assign(box (ref lhs, ref rhs)) => {
+        match &statement.kind {
+            StatementKind::Assign(box (lhs, rhs)) => {
                 self.consume_rvalue(location, rhs);
 
-                self.mutate_place(location, lhs, Shallow(None), JustWrite);
+                self.mutate_place(location, *lhs, Shallow(None), JustWrite);
             }
             StatementKind::FakeRead(_, _) => {
                 // Only relevant for initialized/liveness/safety checks.
             }
-            StatementKind::SetDiscriminant { ref place, variant_index: _ } => {
-                self.mutate_place(location, place, Shallow(None), JustWrite);
+            StatementKind::SetDiscriminant { place, variant_index: _ } => {
+                self.mutate_place(location, **place, Shallow(None), JustWrite);
             }
-            StatementKind::LlvmInlineAsm(ref asm) => {
+            StatementKind::LlvmInlineAsm(asm) => {
                 for (o, output) in asm.asm.outputs.iter().zip(asm.outputs.iter()) {
                     if o.is_indirect {
                         // FIXME(eddyb) indirect inline asm outputs should
                         // be encoded through MIR place derefs instead.
                         self.access_place(
                             location,
-                            output,
+                            *output,
                             (Deep, Read(ReadKind::Copy)),
                             LocalMutationIsAllowed::No,
                         );
                     } else {
                         self.mutate_place(
                             location,
-                            output,
+                            *output,
                             if o.is_rw { Deep } else { Shallow(None) },
                             if o.is_rw { WriteAndRead } else { JustWrite },
                         );
@@ -102,7 +102,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
             StatementKind::StorageDead(local) => {
                 self.access_place(
                     location,
-                    &Place::from(local),
+                    Place::from(*local),
                     (Shallow(None), Write(WriteKind::StorageDeadOrDrop)),
                     LocalMutationIsAllowed::Yes,
                 );
@@ -119,27 +119,27 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
             TerminatorKind::SwitchInt { ref discr, switch_ty: _, values: _, targets: _ } => {
                 self.consume_operand(location, discr);
             }
-            TerminatorKind::Drop { location: ref drop_place, target: _, unwind: _ } => {
+            TerminatorKind::Drop { location: drop_place, target: _, unwind: _ } => {
                 self.access_place(
                     location,
-                    drop_place,
+                    *drop_place,
                     (AccessDepth::Drop, Write(WriteKind::StorageDeadOrDrop)),
                     LocalMutationIsAllowed::Yes,
                 );
             }
             TerminatorKind::DropAndReplace {
-                location: ref drop_place,
+                location: drop_place,
                 value: ref new_value,
                 target: _,
                 unwind: _,
             } => {
-                self.mutate_place(location, drop_place, Deep, JustWrite);
+                self.mutate_place(location, *drop_place, Deep, JustWrite);
                 self.consume_operand(location, new_value);
             }
             TerminatorKind::Call {
                 ref func,
                 ref args,
-                ref destination,
+                destination,
                 cleanup: _,
                 from_hir_call: _,
             } => {
@@ -147,13 +147,13 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
                 for arg in args {
                     self.consume_operand(location, arg);
                 }
-                if let Some((ref dest, _ /*bb*/)) = *destination {
-                    self.mutate_place(location, dest, Deep, JustWrite);
+                if let Some((dest, _ /*bb*/)) = destination {
+                    self.mutate_place(location, *dest, Deep, JustWrite);
                 }
             }
             TerminatorKind::Assert { ref cond, expected: _, ref msg, target: _, cleanup: _ } => {
                 self.consume_operand(location, cond);
-                use rustc::mir::AssertKind;
+                use rustc_middle::mir::AssertKind;
                 if let AssertKind::BoundsCheck { ref len, ref index } = *msg {
                     self.consume_operand(location, len);
                     self.consume_operand(location, index);
@@ -166,19 +166,19 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
                 let borrow_set = self.borrow_set.clone();
                 let resume = self.location_table.start_index(resume.start_location());
                 for i in borrow_set.borrows.indices() {
-                    if borrow_of_local_data(&borrow_set.borrows[i].borrowed_place) {
+                    if borrow_of_local_data(borrow_set.borrows[i].borrowed_place) {
                         self.all_facts.invalidates.push((resume, i));
                     }
                 }
 
-                self.mutate_place(location, resume_arg, Deep, JustWrite);
+                self.mutate_place(location, *resume_arg, Deep, JustWrite);
             }
             TerminatorKind::Resume | TerminatorKind::Return | TerminatorKind::GeneratorDrop => {
                 // Invalidate all borrows of local places
                 let borrow_set = self.borrow_set.clone();
                 let start = self.location_table.start_index(location);
                 for i in borrow_set.borrows.indices() {
-                    if borrow_of_local_data(&borrow_set.borrows[i].borrowed_place) {
+                    if borrow_of_local_data(borrow_set.borrows[i].borrowed_place) {
                         self.all_facts.invalidates.push((start, i));
                     }
                 }
@@ -201,7 +201,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
     fn mutate_place(
         &mut self,
         location: Location,
-        place: &Place<'tcx>,
+        place: Place<'tcx>,
         kind: AccessDepth,
         _mode: MutateMode,
     ) {
@@ -216,7 +216,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
     /// Simulates consumption of an operand.
     fn consume_operand(&mut self, location: Location, operand: &Operand<'tcx>) {
         match *operand {
-            Operand::Copy(ref place) => {
+            Operand::Copy(place) => {
                 self.access_place(
                     location,
                     place,
@@ -224,7 +224,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
                     LocalMutationIsAllowed::No,
                 );
             }
-            Operand::Move(ref place) => {
+            Operand::Move(place) => {
                 self.access_place(
                     location,
                     place,
@@ -239,7 +239,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
     // Simulates consumption of an rvalue
     fn consume_rvalue(&mut self, location: Location, rvalue: &Rvalue<'tcx>) {
         match *rvalue {
-            Rvalue::Ref(_ /*rgn*/, bk, ref place) => {
+            Rvalue::Ref(_ /*rgn*/, bk, place) => {
                 let access_kind = match bk {
                     BorrowKind::Shallow => {
                         (Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk)))
@@ -258,7 +258,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
                 self.access_place(location, place, access_kind, LocalMutationIsAllowed::No);
             }
 
-            Rvalue::AddressOf(mutability, ref place) => {
+            Rvalue::AddressOf(mutability, place) => {
                 let access_kind = match mutability {
                     Mutability::Mut => (
                         Deep,
@@ -279,7 +279,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
                 self.consume_operand(location, operand)
             }
 
-            Rvalue::Len(ref place) | Rvalue::Discriminant(ref place) => {
+            Rvalue::Len(place) | Rvalue::Discriminant(place) => {
                 let af = match *rvalue {
                     Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
                     Rvalue::Discriminant(..) => None,
@@ -313,7 +313,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
     fn access_place(
         &mut self,
         location: Location,
-        place: &Place<'tcx>,
+        place: Place<'tcx>,
         kind: (AccessDepth, ReadOrWrite),
         _is_local_mutation_allowed: LocalMutationIsAllowed,
     ) {
@@ -325,7 +325,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
     fn check_access_for_conflict(
         &mut self,
         location: Location,
-        place: &Place<'tcx>,
+        place: Place<'tcx>,
         sd: AccessDepth,
         rw: ReadOrWrite,
     ) {
@@ -413,7 +413,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
 
             self.access_place(
                 location,
-                &borrow.borrowed_place,
+                borrow.borrowed_place,
                 (Deep, Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index)),
                 LocalMutationIsAllowed::No,
             );
diff --git a/src/librustc_mir/borrow_check/location.rs b/src/librustc_mir/borrow_check/location.rs
index 7bc746b181d..375ff72679f 100644
--- a/src/librustc_mir/borrow_check/location.rs
+++ b/src/librustc_mir/borrow_check/location.rs
@@ -1,5 +1,5 @@
-use rustc::mir::{BasicBlock, Body, Location};
 use rustc_index::vec::{Idx, IndexVec};
+use rustc_middle::mir::{BasicBlock, Body, Location};
 
 /// Maps between a MIR Location, which identifies a particular
 /// statement within a basic block, to a "rich location", which
diff --git a/src/librustc_mir/borrow_check/member_constraints.rs b/src/librustc_mir/borrow_check/member_constraints.rs
index 4323e2db844..d4baa5d809a 100644
--- a/src/librustc_mir/borrow_check/member_constraints.rs
+++ b/src/librustc_mir/borrow_check/member_constraints.rs
@@ -1,8 +1,8 @@
-use crate::rustc::ty::{self, Ty};
-use rustc::infer::MemberConstraint;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::DefId;
 use rustc_index::vec::IndexVec;
+use rustc_middle::infer::MemberConstraint;
+use rustc_middle::ty::{self, Ty};
 use rustc_span::Span;
 use std::hash::Hash;
 use std::ops::Index;
@@ -71,7 +71,7 @@ impl<'tcx> MemberConstraintSet<'tcx, ty::RegionVid> {
     /// Pushes a member constraint into the set.
     ///
     /// The input member constraint `m_c` is in the form produced by
-    /// the the `rustc::infer` code.
+    /// the the `rustc_middle::infer` code.
     ///
     /// The `to_region_vid` callback fn is used to convert the regions
     /// within into `RegionVid` format -- it typically consults the
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index e3dc9e0f105..52847af214f 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -1,14 +1,5 @@
 //! This query borrow-checks the MIR to (further) ensure it is not broken.
 
-use rustc::mir::{
-    read_only, traversal, Body, BodyAndCache, ClearCrossCrate, Local, Location, Mutability,
-    Operand, Place, PlaceElem, PlaceRef, ReadOnlyBodyAndCache,
-};
-use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
-use rustc::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
-use rustc::mir::{Terminator, TerminatorKind};
-use rustc::ty::query::Providers;
-use rustc::ty::{self, RegionVid, TyCtxt};
 use rustc_ast::ast::Name;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::graph::dominators::Dominators;
@@ -18,6 +9,15 @@ use rustc_hir::{def_id::DefId, HirId, Node};
 use rustc_index::bit_set::BitSet;
 use rustc_index::vec::IndexVec;
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
+use rustc_middle::mir::{
+    read_only, traversal, Body, BodyAndCache, ClearCrossCrate, Local, Location, Mutability,
+    Operand, Place, PlaceElem, PlaceRef, ReadOnlyBodyAndCache,
+};
+use rustc_middle::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
+use rustc_middle::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
+use rustc_middle::mir::{Terminator, TerminatorKind};
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::{self, RegionVid, TyCtxt};
 use rustc_session::lint::builtin::{MUTABLE_BORROW_RESERVATION_CONFLICT, UNUSED_MUT};
 use rustc_span::{Span, DUMMY_SP};
 
@@ -299,8 +299,8 @@ fn do_mir_borrowck<'a, 'tcx>(
     }
 
     dataflow::visit_results(
-        &*body,
-        traversal::reverse_postorder(&*body).map(|(bb, _)| bb),
+        &body,
+        traversal::reverse_postorder(&body).map(|(bb, _)| bb),
         &results,
         &mut mbcx,
     );
@@ -308,8 +308,7 @@ fn do_mir_borrowck<'a, 'tcx>(
     // Convert any reservation warnings into lints.
     let reservation_warnings = mem::take(&mut mbcx.reservation_warnings);
     for (_, (place, span, location, bk, borrow)) in reservation_warnings {
-        let mut initial_diag =
-            mbcx.report_conflicting_borrow(location, (&place, span), bk, &borrow);
+        let mut initial_diag = mbcx.report_conflicting_borrow(location, (place, span), bk, &borrow);
 
         let scope = mbcx.body.source_info(location).scope;
         let lint_root = match &mbcx.body.source_scopes[scope].local_data {
@@ -523,11 +522,11 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
 
         self.check_activations(location, span, flow_state);
 
-        match stmt.kind {
-            StatementKind::Assign(box (ref lhs, ref rhs)) => {
+        match &stmt.kind {
+            StatementKind::Assign(box (lhs, ref rhs)) => {
                 self.consume_rvalue(location, (rhs, span), flow_state);
 
-                self.mutate_place(location, (lhs, span), Shallow(None), JustWrite, flow_state);
+                self.mutate_place(location, (*lhs, span), Shallow(None), JustWrite, flow_state);
             }
             StatementKind::FakeRead(_, box ref place) => {
                 // Read for match doesn't access any memory and is used to
@@ -547,8 +546,8 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
                     flow_state,
                 );
             }
-            StatementKind::SetDiscriminant { ref place, variant_index: _ } => {
-                self.mutate_place(location, (place, span), Shallow(None), JustWrite, flow_state);
+            StatementKind::SetDiscriminant { place, variant_index: _ } => {
+                self.mutate_place(location, (**place, span), Shallow(None), JustWrite, flow_state);
             }
             StatementKind::LlvmInlineAsm(ref asm) => {
                 for (o, output) in asm.asm.outputs.iter().zip(asm.outputs.iter()) {
@@ -557,7 +556,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
                         // be encoded through MIR place derefs instead.
                         self.access_place(
                             location,
-                            (output, o.span),
+                            (*output, o.span),
                             (Deep, Read(ReadKind::Copy)),
                             LocalMutationIsAllowed::No,
                             flow_state,
@@ -571,7 +570,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
                     } else {
                         self.mutate_place(
                             location,
-                            (output, o.span),
+                            (*output, o.span),
                             if o.is_rw { Deep } else { Shallow(None) },
                             if o.is_rw { WriteAndRead } else { JustWrite },
                             flow_state,
@@ -592,7 +591,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
             StatementKind::StorageDead(local) => {
                 self.access_place(
                     location,
-                    (&Place::from(local), span),
+                    (Place::from(*local), span),
                     (Shallow(None), Write(WriteKind::StorageDeadOrDrop)),
                     LocalMutationIsAllowed::Yes,
                     flow_state,
@@ -638,14 +637,14 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
 
                 self.access_place(
                     loc,
-                    (drop_place, span),
+                    (*drop_place, span),
                     (AccessDepth::Drop, Write(WriteKind::StorageDeadOrDrop)),
                     LocalMutationIsAllowed::Yes,
                     flow_state,
                 );
             }
             TerminatorKind::DropAndReplace {
-                location: ref drop_place,
+                location: drop_place,
                 value: ref new_value,
                 target: _,
                 unwind: _,
@@ -664,20 +663,20 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
                 for arg in args {
                     self.consume_operand(loc, (arg, span), flow_state);
                 }
-                if let Some((ref dest, _ /*bb*/)) = *destination {
+                if let Some((dest, _ /*bb*/)) = *destination {
                     self.mutate_place(loc, (dest, span), Deep, JustWrite, flow_state);
                 }
             }
             TerminatorKind::Assert { ref cond, expected: _, ref msg, target: _, cleanup: _ } => {
                 self.consume_operand(loc, (cond, span), flow_state);
-                use rustc::mir::AssertKind;
+                use rustc_middle::mir::AssertKind;
                 if let AssertKind::BoundsCheck { ref len, ref index } = *msg {
                     self.consume_operand(loc, (len, span), flow_state);
                     self.consume_operand(loc, (index, span), flow_state);
                 }
             }
 
-            TerminatorKind::Yield { ref value, resume: _, ref resume_arg, drop: _ } => {
+            TerminatorKind::Yield { ref value, resume: _, resume_arg, drop: _ } => {
                 self.consume_operand(loc, (value, span), flow_state);
                 self.mutate_place(loc, (resume_arg, span), Deep, JustWrite, flow_state);
             }
@@ -884,7 +883,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     fn access_place(
         &mut self,
         location: Location,
-        place_span: (&Place<'tcx>, Span),
+        place_span: (Place<'tcx>, Span),
         kind: (AccessDepth, ReadOrWrite),
         is_local_mutation_allowed: LocalMutationIsAllowed,
         flow_state: &Flows<'cx, 'tcx>,
@@ -905,7 +904,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         // Check is_empty() first because it's the common case, and doing that
         // way we avoid the clone() call.
         if !self.access_place_error_reported.is_empty()
-            && self.access_place_error_reported.contains(&(*place_span.0, place_span.1))
+            && self.access_place_error_reported.contains(&(place_span.0, place_span.1))
         {
             debug!(
                 "access_place: suppressing error place_span=`{:?}` kind=`{:?}`",
@@ -933,14 +932,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         if conflict_error || mutability_error {
             debug!("access_place: logging error place_span=`{:?}` kind=`{:?}`", place_span, kind);
 
-            self.access_place_error_reported.insert((*place_span.0, place_span.1));
+            self.access_place_error_reported.insert((place_span.0, place_span.1));
         }
     }
 
     fn check_access_for_conflict(
         &mut self,
         location: Location,
-        place_span: (&Place<'tcx>, Span),
+        place_span: (Place<'tcx>, Span),
         sd: AccessDepth,
         rw: ReadOrWrite,
         flow_state: &Flows<'cx, 'tcx>,
@@ -1043,7 +1042,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     // these sepately so that we only emit a warning if borrow
                     // checking was otherwise successful.
                     this.reservation_warnings
-                        .insert(bi, (*place_span.0, place_span.1, location, bk, borrow.clone()));
+                        .insert(bi, (place_span.0, place_span.1, location, bk, borrow.clone()));
 
                     // Don't suppress actual errors.
                     Control::Continue
@@ -1100,7 +1099,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     fn mutate_place(
         &mut self,
         location: Location,
-        place_span: (&'cx Place<'tcx>, Span),
+        place_span: (Place<'tcx>, Span),
         kind: AccessDepth,
         mode: MutateMode,
         flow_state: &Flows<'cx, 'tcx>,
@@ -1150,7 +1149,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         flow_state: &Flows<'cx, 'tcx>,
     ) {
         match *rvalue {
-            Rvalue::Ref(_ /*rgn*/, bk, ref place) => {
+            Rvalue::Ref(_ /*rgn*/, bk, place) => {
                 let access_kind = match bk {
                     BorrowKind::Shallow => {
                         (Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk)))
@@ -1188,7 +1187,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 );
             }
 
-            Rvalue::AddressOf(mutability, ref place) => {
+            Rvalue::AddressOf(mutability, place) => {
                 let access_kind = match mutability {
                     Mutability::Mut => (
                         Deep,
@@ -1222,7 +1221,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 self.consume_operand(location, (operand, span), flow_state)
             }
 
-            Rvalue::Len(ref place) | Rvalue::Discriminant(ref place) => {
+            Rvalue::Len(place) | Rvalue::Discriminant(place) => {
                 let af = match *rvalue {
                     Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
                     Rvalue::Discriminant(..) => None,
@@ -1283,7 +1282,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     }
 
     fn propagate_closure_used_mut_upvar(&mut self, operand: &Operand<'tcx>) {
-        let propagate_closure_used_mut_place = |this: &mut Self, place: &Place<'tcx>| {
+        let propagate_closure_used_mut_place = |this: &mut Self, place: Place<'tcx>| {
             if !place.projection.is_empty() {
                 if let Some(field) = this.is_upvar_field_projection(place.as_ref()) {
                     this.used_mut_upvars.push(field);
@@ -1297,7 +1296,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         // captures of a closure are copied/moved directly
         // when generating MIR.
         match *operand {
-            Operand::Move(ref place) | Operand::Copy(ref place) => {
+            Operand::Move(place) | Operand::Copy(place) => {
                 match place.as_local() {
                     Some(local) if !self.body.local_decls[local].is_user_variable() => {
                         if self.body.local_decls[local].ty.is_mutable_ptr() {
@@ -1336,8 +1335,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         let stmt = &bbd.statements[loc.statement_index];
                         debug!("temporary assigned in: stmt={:?}", stmt);
 
-                        if let StatementKind::Assign(box (_, Rvalue::Ref(_, _, ref source))) =
-                            stmt.kind
+                        if let StatementKind::Assign(box (_, Rvalue::Ref(_, _, source))) = stmt.kind
                         {
                             propagate_closure_used_mut_place(self, source);
                         } else {
@@ -1361,7 +1359,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         flow_state: &Flows<'cx, 'tcx>,
     ) {
         match *operand {
-            Operand::Copy(ref place) => {
+            Operand::Copy(place) => {
                 // copy of place: check if this is "copy of frozen path"
                 // (FIXME: see check_loans.rs)
                 self.access_place(
@@ -1380,7 +1378,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     flow_state,
                 );
             }
-            Operand::Move(ref place) => {
+            Operand::Move(place) => {
                 // move of place: check if this is move of already borrowed path
                 self.access_place(
                     location,
@@ -1411,7 +1409,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         span: Span,
     ) {
         debug!("check_for_invalidation_at_exit({:?})", borrow);
-        let place = &borrow.borrowed_place;
+        let place = borrow.borrowed_place;
         let mut root_place = PlaceRef { local: place.local, projection: &[] };
 
         // FIXME(nll-rfc#40): do more precise destructor tracking here. For now
@@ -1465,7 +1463,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     fn check_for_local_borrow(&mut self, borrow: &BorrowData<'tcx>, yield_span: Span) {
         debug!("check_for_local_borrow({:?})", borrow);
 
-        if borrow_of_local_data(&borrow.borrowed_place) {
+        if borrow_of_local_data(borrow.borrowed_place) {
             let err = self.cannot_borrow_across_generator_yield(
                 self.retrieve_borrow_spans(borrow).var_or_use(),
                 yield_span,
@@ -1491,7 +1489,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
             self.access_place(
                 location,
-                (&borrow.borrowed_place, span),
+                (borrow.borrowed_place, span),
                 (Deep, Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index)),
                 LocalMutationIsAllowed::No,
                 flow_state,
@@ -1506,7 +1504,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         &mut self,
         location: Location,
         local: Local,
-        place_span: (&Place<'tcx>, Span),
+        place_span: (Place<'tcx>, Span),
         flow_state: &Flows<'cx, 'tcx>,
     ) {
         debug!("check_if_reassignment_to_immutable_state({:?})", local);
@@ -1730,7 +1728,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     fn check_if_assigned_path_is_moved(
         &mut self,
         location: Location,
-        (place, span): (&'cx Place<'tcx>, Span),
+        (place, span): (Place<'tcx>, Span),
         flow_state: &Flows<'cx, 'tcx>,
     ) {
         debug!("check_if_assigned_path_is_moved place: {:?}", place);
@@ -1903,7 +1901,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     /// Returns `true` if an error is reported.
     fn check_access_permissions(
         &mut self,
-        (place, span): (&Place<'tcx>, Span),
+        (place, span): (Place<'tcx>, Span),
         kind: ReadOrWrite,
         is_local_mutation_allowed: LocalMutationIsAllowed,
         flow_state: &Flows<'cx, 'tcx>,
diff --git a/src/librustc_mir/borrow_check/nll.rs b/src/librustc_mir/borrow_check/nll.rs
index 8e929a4fa22..678ab3ed323 100644
--- a/src/librustc_mir/borrow_check/nll.rs
+++ b/src/librustc_mir/borrow_check/nll.rs
@@ -1,15 +1,15 @@
 //! The entry point of the NLL borrow checker.
 
-use rustc::mir::{
-    BasicBlock, Body, BodyAndCache, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind,
-    Location, Promoted, ReadOnlyBodyAndCache,
-};
-use rustc::ty::{self, RegionKind, RegionVid};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::Diagnostic;
 use rustc_hir::def_id::DefId;
 use rustc_index::vec::IndexVec;
 use rustc_infer::infer::InferCtxt;
+use rustc_middle::mir::{
+    BasicBlock, Body, BodyAndCache, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind,
+    Location, Promoted, ReadOnlyBodyAndCache,
+};
+use rustc_middle::ty::{self, RegionKind, RegionVid};
 use rustc_span::symbol::sym;
 use std::env;
 use std::fmt::Debug;
@@ -317,7 +317,7 @@ pub(super) fn dump_mir_results<'a, 'tcx>(
     regioncx: &RegionInferenceContext<'_>,
     closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
 ) {
-    if !mir_util::dump_enabled(infcx.tcx, "nll", source) {
+    if !mir_util::dump_enabled(infcx.tcx, "nll", source.def_id()) {
         return;
     }
 
diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/src/librustc_mir/borrow_check/path_utils.rs
index deec6f386ff..f5238e7b7be 100644
--- a/src/librustc_mir/borrow_check/path_utils.rs
+++ b/src/librustc_mir/borrow_check/path_utils.rs
@@ -2,10 +2,10 @@ use crate::borrow_check::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation}
 use crate::borrow_check::places_conflict;
 use crate::borrow_check::AccessDepth;
 use crate::dataflow::indexes::BorrowIndex;
-use rustc::mir::BorrowKind;
-use rustc::mir::{BasicBlock, Body, Location, Place};
-use rustc::ty::TyCtxt;
 use rustc_data_structures::graph::dominators::Dominators;
+use rustc_middle::mir::BorrowKind;
+use rustc_middle::mir::{BasicBlock, Body, Location, Place};
+use rustc_middle::ty::TyCtxt;
 
 /// Returns `true` if the borrow represented by `kind` is
 /// allowed to be split into separate Reservation and
@@ -27,7 +27,7 @@ pub(super) fn each_borrow_involving_path<'tcx, F, I, S>(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
     _location: Location,
-    access_place: (AccessDepth, &Place<'tcx>),
+    access_place: (AccessDepth, Place<'tcx>),
     borrow_set: &BorrowSet<'tcx>,
     candidates: I,
     mut op: F,
@@ -48,7 +48,7 @@ pub(super) fn each_borrow_involving_path<'tcx, F, I, S>(
         if places_conflict::borrow_conflicts_with_place(
             tcx,
             body,
-            &borrowed.borrowed_place,
+            borrowed.borrowed_place,
             borrowed.kind,
             place.as_ref(),
             access,
@@ -130,7 +130,7 @@ pub(super) fn is_active<'tcx>(
 
 /// Determines if a given borrow is borrowing local data
 /// This is called for all Yield expressions on movable generators
-pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool {
+pub(super) fn borrow_of_local_data(place: Place<'_>) -> bool {
     // Reborrow of already borrowed data is ignored
     // Any errors will be caught on the initial borrow
     !place.is_indirect()
diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs
index 01c44d0d905..e53f50326d3 100644
--- a/src/librustc_mir/borrow_check/place_ext.rs
+++ b/src/librustc_mir/borrow_check/place_ext.rs
@@ -1,8 +1,8 @@
 use crate::borrow_check::borrow_set::LocalsStateAtExit;
-use rustc::mir::ProjectionElem;
-use rustc::mir::{Body, Mutability, Place};
-use rustc::ty::{self, TyCtxt};
 use rustc_hir as hir;
+use rustc_middle::mir::ProjectionElem;
+use rustc_middle::mir::{Body, Mutability, Place};
+use rustc_middle::ty::{self, TyCtxt};
 
 /// Extension methods for the `Place` type.
 crate trait PlaceExt<'tcx> {
diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs
index 767ffa50fed..d48df6a9109 100644
--- a/src/librustc_mir/borrow_check/places_conflict.rs
+++ b/src/librustc_mir/borrow_check/places_conflict.rs
@@ -1,9 +1,9 @@
 use crate::borrow_check::ArtificialField;
 use crate::borrow_check::Overlap;
 use crate::borrow_check::{AccessDepth, Deep, Shallow};
-use rustc::mir::{Body, BorrowKind, Local, Place, PlaceElem, PlaceRef, ProjectionElem};
-use rustc::ty::{self, TyCtxt};
 use rustc_hir as hir;
+use rustc_middle::mir::{Body, BorrowKind, Local, Place, PlaceElem, PlaceRef, ProjectionElem};
+use rustc_middle::ty::{self, TyCtxt};
 use std::cmp::max;
 
 /// When checking if a place conflicts with another place, this enum is used to influence decisions
@@ -24,8 +24,8 @@ crate enum PlaceConflictBias {
 crate fn places_conflict<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
-    borrow_place: &Place<'tcx>,
-    access_place: &Place<'tcx>,
+    borrow_place: Place<'tcx>,
+    access_place: Place<'tcx>,
     bias: PlaceConflictBias,
 ) -> bool {
     borrow_conflicts_with_place(
@@ -46,7 +46,7 @@ crate fn places_conflict<'tcx>(
 pub(super) fn borrow_conflicts_with_place<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
-    borrow_place: &Place<'tcx>,
+    borrow_place: Place<'tcx>,
     borrow_kind: BorrowKind,
     access_place: PlaceRef<'tcx>,
     access: AccessDepth,
@@ -71,7 +71,7 @@ pub(super) fn borrow_conflicts_with_place<'tcx>(
 fn place_components_conflict<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
-    borrow_place: &Place<'tcx>,
+    borrow_place: Place<'tcx>,
     borrow_kind: BorrowKind,
     access_place: PlaceRef<'tcx>,
     access: AccessDepth,
diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs
index c64e8c363af..e3d0cdbd188 100644
--- a/src/librustc_mir/borrow_check/prefixes.rs
+++ b/src/librustc_mir/borrow_check/prefixes.rs
@@ -9,9 +9,9 @@
 
 use super::MirBorrowckCtxt;
 
-use rustc::mir::{Place, PlaceRef, ProjectionElem, ReadOnlyBodyAndCache};
-use rustc::ty::{self, TyCtxt};
 use rustc_hir as hir;
+use rustc_middle::mir::{Place, PlaceRef, ProjectionElem, ReadOnlyBodyAndCache};
+use rustc_middle::ty::{self, TyCtxt};
 
 pub trait IsPrefixOf<'tcx> {
     fn is_prefix_of(&self, other: PlaceRef<'tcx>) -> bool;
diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs
index c8b0e59ebb1..303f43b0ee2 100644
--- a/src/librustc_mir/borrow_check/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/region_infer/mod.rs
@@ -1,11 +1,6 @@
 use std::collections::VecDeque;
 use std::rc::Rc;
 
-use rustc::mir::{
-    Body, ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements,
-    ConstraintCategory, Local, Location,
-};
-use rustc::ty::{self, subst::SubstsRef, RegionVid, Ty, TyCtxt, TypeFoldable};
 use rustc_data_structures::binary_search_util;
 use rustc_data_structures::frozen::Frozen;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -16,6 +11,11 @@ use rustc_index::vec::IndexVec;
 use rustc_infer::infer::canonical::QueryOutlivesConstraint;
 use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound};
 use rustc_infer::infer::{InferCtxt, NLLRegionVariableOrigin, RegionVariableOrigin};
+use rustc_middle::mir::{
+    Body, ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements,
+    ConstraintCategory, Local, Location,
+};
+use rustc_middle::ty::{self, subst::SubstsRef, RegionVid, Ty, TyCtxt, TypeFoldable};
 use rustc_span::Span;
 
 use crate::borrow_check::{
@@ -202,7 +202,7 @@ pub(crate) enum Cause {
 ///
 /// For more information about this translation, see
 /// `InferCtxt::process_registered_region_obligations` and
-/// `InferCtxt::type_must_outlive` in `rustc::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/region_infer/opaque_types.rs b/src/librustc_mir/borrow_check/region_infer/opaque_types.rs
index 49b49437328..7e352bfba77 100644
--- a/src/librustc_mir/borrow_check/region_infer/opaque_types.rs
+++ b/src/librustc_mir/borrow_check/region_infer/opaque_types.rs
@@ -1,7 +1,7 @@
-use rustc::ty::{self, TyCtxt, TypeFoldable};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::InferCtxt;
+use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
 use rustc_span::Span;
 use rustc_trait_selection::opaque_types::InferCtxtExt;
 
diff --git a/src/librustc_mir/borrow_check/region_infer/reverse_sccs.rs b/src/librustc_mir/borrow_check/region_infer/reverse_sccs.rs
index ff19ac5f21a..5d345a6e63d 100644
--- a/src/librustc_mir/borrow_check/region_infer/reverse_sccs.rs
+++ b/src/librustc_mir/borrow_check/region_infer/reverse_sccs.rs
@@ -1,10 +1,10 @@
 use crate::borrow_check::constraints::ConstraintSccIndex;
 use crate::borrow_check::RegionInferenceContext;
 use itertools::Itertools;
-use rustc::ty::RegionVid;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::graph::vec_graph::VecGraph;
 use rustc_data_structures::graph::WithSuccessors;
+use rustc_middle::ty::RegionVid;
 use std::ops::Range;
 use std::rc::Rc;
 
diff --git a/src/librustc_mir/borrow_check/region_infer/values.rs b/src/librustc_mir/borrow_check/region_infer/values.rs
index 675463cb1c1..5310fd4abaf 100644
--- a/src/librustc_mir/borrow_check/region_infer/values.rs
+++ b/src/librustc_mir/borrow_check/region_infer/values.rs
@@ -1,9 +1,9 @@
-use rustc::mir::{BasicBlock, Body, Location, ReadOnlyBodyAndCache};
-use rustc::ty::{self, RegionVid};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_index::bit_set::{HybridBitSet, SparseBitMatrix};
 use rustc_index::vec::Idx;
 use rustc_index::vec::IndexVec;
+use rustc_middle::mir::{BasicBlock, Body, Location, ReadOnlyBodyAndCache};
+use rustc_middle::ty::{self, RegionVid};
 use std::fmt::Debug;
 use std::rc::Rc;
 
diff --git a/src/librustc_mir/borrow_check/renumber.rs b/src/librustc_mir/borrow_check/renumber.rs
index a63d18c27f1..a1d7bc1462f 100644
--- a/src/librustc_mir/borrow_check/renumber.rs
+++ b/src/librustc_mir/borrow_check/renumber.rs
@@ -1,9 +1,9 @@
-use rustc::mir::visit::{MutVisitor, TyContext};
-use rustc::mir::{BodyAndCache, Location, PlaceElem, Promoted};
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc_index::vec::IndexVec;
 use rustc_infer::infer::{InferCtxt, NLLRegionVariableOrigin};
+use rustc_middle::mir::visit::{MutVisitor, TyContext};
+use rustc_middle::mir::{BodyAndCache, Location, PlaceElem, Promoted};
+use rustc_middle::ty::subst::SubstsRef;
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
 
 /// Replaces all free regions appearing in the MIR with fresh
 /// inference variables, returning the number of variables created.
diff --git a/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs b/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs
index 576759c2a35..8e4f44e8195 100644
--- a/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs
+++ b/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs
@@ -1,12 +1,12 @@
-use rustc::mir::ConstraintCategory;
-use rustc::ty::subst::GenericArgKind;
-use rustc::ty::{self, TyCtxt};
 use rustc_infer::infer::canonical::QueryOutlivesConstraint;
 use rustc_infer::infer::canonical::QueryRegionConstraints;
 use rustc_infer::infer::outlives::env::RegionBoundPairs;
 use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
 use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
 use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
+use rustc_middle::mir::ConstraintCategory;
+use rustc_middle::ty::subst::GenericArgKind;
+use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::DUMMY_SP;
 
 use crate::borrow_check::{
diff --git a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs
index 86951f93f0e..0583295bfca 100644
--- a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs
+++ b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs
@@ -1,13 +1,13 @@
-use rustc::mir::ConstraintCategory;
-use rustc::traits::query::OutlivesBound;
-use rustc::ty::free_region_map::FreeRegionRelations;
-use rustc::ty::{self, RegionVid, Ty, TyCtxt};
 use rustc_data_structures::frozen::Frozen;
 use rustc_data_structures::transitive_relation::TransitiveRelation;
 use rustc_infer::infer::canonical::QueryRegionConstraints;
 use rustc_infer::infer::outlives;
 use rustc_infer::infer::region_constraints::GenericKind;
 use rustc_infer::infer::InferCtxt;
+use rustc_middle::mir::ConstraintCategory;
+use rustc_middle::traits::query::OutlivesBound;
+use rustc_middle::ty::free_region_map::FreeRegionRelations;
+use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
 use rustc_span::DUMMY_SP;
 use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
 use std::rc::Rc;
diff --git a/src/librustc_mir/borrow_check/type_check/input_output.rs b/src/librustc_mir/borrow_check/type_check/input_output.rs
index f2194c77c89..83ee46acdc4 100644
--- a/src/librustc_mir/borrow_check/type_check/input_output.rs
+++ b/src/librustc_mir/borrow_check/type_check/input_output.rs
@@ -7,9 +7,9 @@
 //! `RETURN_PLACE` the MIR arguments) are always fully normalized (and
 //! contain revealed `impl Trait` values).
 
-use rustc::mir::*;
-use rustc::ty::Ty;
 use rustc_infer::infer::LateBoundRegionConversionTime;
+use rustc_middle::mir::*;
+use rustc_middle::ty::Ty;
 
 use rustc_index::vec::Idx;
 use rustc_span::Span;
diff --git a/src/librustc_mir/borrow_check/type_check/liveness/local_use_map.rs b/src/librustc_mir/borrow_check/type_check/liveness/local_use_map.rs
index 8155aa0ee00..88e2109b1b2 100644
--- a/src/librustc_mir/borrow_check/type_check/liveness/local_use_map.rs
+++ b/src/librustc_mir/borrow_check/type_check/liveness/local_use_map.rs
@@ -1,7 +1,7 @@
-use rustc::mir::visit::{PlaceContext, Visitor};
-use rustc::mir::{Local, Location, ReadOnlyBodyAndCache};
 use rustc_data_structures::vec_linked_list as vll;
 use rustc_index::vec::IndexVec;
+use rustc_middle::mir::visit::{PlaceContext, Visitor};
+use rustc_middle::mir::{Local, Location, ReadOnlyBodyAndCache};
 
 use crate::util::liveness::{categorize, DefUse};
 
@@ -81,7 +81,7 @@ impl LocalUseMap {
         live_locals.iter().for_each(|&local| locals_with_use_data[local] = true);
 
         LocalUseMapBuild { local_use_map: &mut local_use_map, elements, locals_with_use_data }
-            .visit_body(body);
+            .visit_body(&body);
 
         local_use_map
     }
diff --git a/src/librustc_mir/borrow_check/type_check/liveness/mod.rs b/src/librustc_mir/borrow_check/type_check/liveness/mod.rs
index a55529ed0ef..13bdaa357ce 100644
--- a/src/librustc_mir/borrow_check/type_check/liveness/mod.rs
+++ b/src/librustc_mir/borrow_check/type_check/liveness/mod.rs
@@ -1,6 +1,6 @@
-use rustc::mir::{Body, Local, ReadOnlyBodyAndCache};
-use rustc::ty::{RegionVid, TyCtxt};
 use rustc_data_structures::fx::FxHashSet;
+use rustc_middle::mir::{Body, Local, ReadOnlyBodyAndCache};
+use rustc_middle::ty::{RegionVid, TyCtxt};
 use std::rc::Rc;
 
 use crate::dataflow::move_paths::MoveData;
diff --git a/src/librustc_mir/borrow_check/type_check/liveness/polonius.rs b/src/librustc_mir/borrow_check/type_check/liveness/polonius.rs
index 407e0628b6e..26d75f08ae4 100644
--- a/src/librustc_mir/borrow_check/type_check/liveness/polonius.rs
+++ b/src/librustc_mir/borrow_check/type_check/liveness/polonius.rs
@@ -2,9 +2,9 @@ use crate::borrow_check::location::{LocationIndex, LocationTable};
 use crate::dataflow::indexes::MovePathIndex;
 use crate::dataflow::move_paths::{LookupResult, MoveData};
 use crate::util::liveness::{categorize, DefUse};
-use rustc::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
-use rustc::mir::{Local, Location, Place, ReadOnlyBodyAndCache};
-use rustc::ty::subst::GenericArg;
+use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
+use rustc_middle::mir::{Local, Location, Place, ReadOnlyBodyAndCache};
+use rustc_middle::ty::subst::GenericArg;
 
 use super::TypeChecker;
 
@@ -43,7 +43,7 @@ impl UseFactsExtractor<'_> {
 
     fn insert_path_access(&mut self, path: MovePathIndex, location: Location) {
         debug!("UseFactsExtractor::insert_path_access({:?}, {:?})", path, location);
-        self.path_accessed_at_base.push((path, self.location_table.start_index(location)));
+        self.path_accessed_at_base.push((path, self.location_to_index(location)));
     }
 
     fn place_to_mpi(&self, place: &Place<'_>) -> Option<MovePathIndex> {
@@ -101,7 +101,7 @@ pub(super) fn populate_access_facts(
             location_table,
             move_data,
         };
-        extractor.visit_body(body);
+        extractor.visit_body(&body);
 
         facts.var_dropped_at.extend(
             dropped_at.iter().map(|&(local, location)| (local, location_table.mid_index(location))),
diff --git a/src/librustc_mir/borrow_check/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/type_check/liveness/trace.rs
index 75b269c79b9..fe5c020c8bb 100644
--- a/src/librustc_mir/borrow_check/type_check/liveness/trace.rs
+++ b/src/librustc_mir/borrow_check/type_check/liveness/trace.rs
@@ -1,8 +1,8 @@
-use rustc::mir::{BasicBlock, ConstraintCategory, Local, Location, ReadOnlyBodyAndCache};
-use rustc::ty::{Ty, TypeFoldable};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_index::bit_set::HybridBitSet;
 use rustc_infer::infer::canonical::QueryRegionConstraints;
+use rustc_middle::mir::{BasicBlock, ConstraintCategory, Local, Location, ReadOnlyBodyAndCache};
+use rustc_middle::ty::{Ty, TypeFoldable};
 use rustc_trait_selection::traits::query::dropck_outlives::DropckOutlivesResult;
 use rustc_trait_selection::traits::query::type_op::outlives::DropckOutlives;
 use rustc_trait_selection::traits::query::type_op::TypeOp;
diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs
index 54ca0c6a260..a118fe2db71 100644
--- a/src/librustc_mir/borrow_check/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/type_check/mod.rs
@@ -5,19 +5,6 @@ use std::{fmt, iter, mem};
 
 use either::Either;
 
-use rustc::mir::tcx::PlaceTy;
-use rustc::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
-use rustc::mir::AssertKind;
-use rustc::mir::*;
-use rustc::ty::adjustment::PointerCast;
-use rustc::ty::cast::CastTy;
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::layout::VariantIdx;
-use rustc::ty::subst::{GenericArgKind, Subst, SubstsRef, UserSubsts};
-use rustc::ty::{
-    self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, RegionVid, ToPolyTraitRef, Ty,
-    TyCtxt, UserType, UserTypeAnnotationIndex,
-};
 use rustc_data_structures::frozen::Frozen;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::struct_span_err;
@@ -30,7 +17,20 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
 use rustc_infer::infer::{
     InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin,
 };
+use rustc_middle::mir::tcx::PlaceTy;
+use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
+use rustc_middle::mir::AssertKind;
+use rustc_middle::mir::*;
+use rustc_middle::ty::adjustment::PointerCast;
+use rustc_middle::ty::cast::CastTy;
+use rustc_middle::ty::fold::TypeFoldable;
+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 _;
@@ -210,7 +210,7 @@ fn type_check_internal<'a, 'tcx, R>(
     );
     let errors_reported = {
         let mut verifier = TypeVerifier::new(&mut checker, *body, promoted);
-        verifier.visit_body(body);
+        verifier.visit_body(&body);
         verifier.errors_reported
     };
 
@@ -435,7 +435,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
         }
     }
 
-    fn visit_body(&mut self, body: ReadOnlyBodyAndCache<'_, 'tcx>) {
+    fn visit_body(&mut self, body: &Body<'tcx>) {
         self.sanitize_type(&"return type", body.return_ty());
         for local_decl in &body.local_decls {
             self.sanitize_type(local_decl, local_decl.ty);
@@ -563,7 +563,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
 
         swap_constraints(self);
 
-        self.visit_body(promoted_body);
+        self.visit_body(&promoted_body);
 
         if !self.errors_reported {
             // if verifier failed, don't do further checks to avoid ICEs
@@ -1053,7 +1053,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
     /// regions which are extracted and stored as having occurred at
     /// `locations`.
     ///
-    /// **Any `rustc::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/type_check/relate_tys.rs b/src/librustc_mir/borrow_check/type_check/relate_tys.rs
index ebaafd40262..b9a76057d51 100644
--- a/src/librustc_mir/borrow_check/type_check/relate_tys.rs
+++ b/src/librustc_mir/borrow_check/type_check/relate_tys.rs
@@ -1,8 +1,8 @@
-use rustc::mir::ConstraintCategory;
-use rustc::ty::relate::TypeRelation;
-use rustc::ty::{self, Ty};
 use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate};
 use rustc_infer::infer::{InferCtxt, NLLRegionVariableOrigin};
+use rustc_middle::mir::ConstraintCategory;
+use rustc_middle::ty::relate::TypeRelation;
+use rustc_middle::ty::{self, Ty};
 use rustc_trait_selection::traits::query::Fallible;
 use rustc_trait_selection::traits::DomainGoal;
 
diff --git a/src/librustc_mir/borrow_check/universal_regions.rs b/src/librustc_mir/borrow_check/universal_regions.rs
index 825931cf892..4d67d7204ca 100644
--- a/src/librustc_mir/borrow_check/universal_regions.rs
+++ b/src/librustc_mir/borrow_check/universal_regions.rs
@@ -13,17 +13,17 @@
 //! just returns them for other code to use.
 
 use either::Either;
-use rustc::middle::lang_items;
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::subst::{InternalSubsts, Subst, SubstsRef};
-use rustc::ty::{self, RegionVid, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashMap;
 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::ty::fold::TypeFoldable;
+use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
+use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
 use std::iter;
 
 use crate::borrow_check::nll::ToRegionVid;
diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/src/librustc_mir/borrow_check/used_muts.rs
index 5e4eebb771f..2da72f3bcc5 100644
--- a/src/librustc_mir/borrow_check/used_muts.rs
+++ b/src/librustc_mir/borrow_check/used_muts.rs
@@ -1,5 +1,5 @@
-use rustc::mir::visit::{PlaceContext, Visitor};
-use rustc::mir::{Local, Location, Place, Statement, StatementKind, TerminatorKind};
+use rustc_middle::mir::visit::{PlaceContext, Visitor};
+use rustc_middle::mir::{Local, Location, Place, Statement, StatementKind, TerminatorKind};
 
 use rustc_data_structures::fx::FxHashSet;
 
@@ -32,7 +32,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 never_initialized_mut_locals: &mut never_initialized_mut_locals,
                 mbcx: self,
             };
-            visitor.visit_body(visitor.mbcx.body);
+            visitor.visit_body(&visitor.mbcx.body);
         }
 
         // Take the union of the existed `used_mut` set with those variables we've found were
@@ -51,7 +51,7 @@ struct GatherUsedMutsVisitor<'visit, 'cx, 'tcx> {
 }
 
 impl GatherUsedMutsVisitor<'_, '_, '_> {
-    fn remove_never_initialized_mut_locals(&mut self, into: &Place<'_>) {
+    fn remove_never_initialized_mut_locals(&mut self, into: Place<'_>) {
         // Remove any locals that we found were initialized from the
         // `never_initialized_mut_locals` set. At the end, the only remaining locals will
         // be those that were never initialized - we will consider those as being used as
@@ -66,26 +66,23 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc
         debug!("visit_terminator_kind: kind={:?}", kind);
         match &kind {
             TerminatorKind::Call { destination: Some((into, _)), .. } => {
-                self.remove_never_initialized_mut_locals(&into);
+                self.remove_never_initialized_mut_locals(*into);
             }
             TerminatorKind::DropAndReplace { location, .. } => {
-                self.remove_never_initialized_mut_locals(&location);
+                self.remove_never_initialized_mut_locals(*location);
             }
             _ => {}
         }
     }
 
     fn visit_statement(&mut self, statement: &Statement<'tcx>, _location: Location) {
-        match &statement.kind {
-            StatementKind::Assign(box (into, _)) => {
-                debug!(
-                    "visit_statement: statement={:?} local={:?} \
+        if let StatementKind::Assign(box (into, _)) = &statement.kind {
+            debug!(
+                "visit_statement: statement={:?} local={:?} \
                     never_initialized_mut_locals={:?}",
-                    statement, into.local, self.never_initialized_mut_locals
-                );
-                self.remove_never_initialized_mut_locals(into);
-            }
-            _ => {}
+                statement, into.local, self.never_initialized_mut_locals
+            );
+            self.remove_never_initialized_mut_locals(*into);
         }
     }
 
diff --git a/src/librustc_mir/const_eval/error.rs b/src/librustc_mir/const_eval/error.rs
index aa30f43df93..f7e28cf8d8c 100644
--- a/src/librustc_mir/const_eval/error.rs
+++ b/src/librustc_mir/const_eval/error.rs
@@ -1,7 +1,7 @@
 use std::error::Error;
 use std::fmt;
 
-use rustc::mir::AssertKind;
+use rustc_middle::mir::AssertKind;
 use rustc_span::Symbol;
 
 use super::InterpCx;
@@ -18,7 +18,7 @@ pub enum ConstEvalErrKind {
 }
 
 // The errors become `MachineStop` with plain strings when being raised.
-// `ConstEvalErr` (in `librustc/mir/interpret/error.rs`) knows to
+// `ConstEvalErr` (in `librustc_middle/mir/interpret/error.rs`) knows to
 // handle these.
 impl<'tcx> Into<InterpErrorInfo<'tcx>> for ConstEvalErrKind {
     fn into(self) -> InterpErrorInfo<'tcx> {
@@ -55,6 +55,6 @@ pub fn error_to_const_error<'mir, 'tcx, M: Machine<'mir, 'tcx>>(
     mut error: InterpErrorInfo<'tcx>,
 ) -> ConstEvalErr<'tcx> {
     error.print_backtrace();
-    let stacktrace = ecx.generate_stacktrace(None);
+    let stacktrace = ecx.generate_stacktrace();
     ConstEvalErr { error: error.kind, stacktrace, span: ecx.tcx.span }
 }
diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs
index ffbff00cf37..97cdb32e2cd 100644
--- a/src/librustc_mir/const_eval/eval_queries.rs
+++ b/src/librustc_mir/const_eval/eval_queries.rs
@@ -5,12 +5,13 @@ use crate::interpret::{
     InterpCx, InterpResult, MPlaceTy, MemoryKind, OpTy, RawConst, RefTracking, Scalar,
     ScalarMaybeUndef, StackPopCleanup,
 };
-use rustc::mir;
-use rustc::mir::interpret::{ConstEvalErr, ErrorHandled};
-use rustc::traits::Reveal;
-use rustc::ty::{self, layout, layout::LayoutOf, subst::Subst, TyCtxt};
 use rustc_hir::def::DefKind;
+use rustc_middle::mir;
+use rustc_middle::mir::interpret::{ConstEvalErr, ErrorHandled};
+use rustc_middle::traits::Reveal;
+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 {
@@ -46,7 +47,6 @@ fn eval_body_using_ecx<'mir, 'tcx>(
 
     ecx.push_stack_frame(
         cid.instance,
-        body.span,
         body,
         Some(ret.into()),
         StackPopCleanup::None { cleanup: false },
@@ -106,8 +106,8 @@ pub(super) fn op_to_const<'tcx>(
     // 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,
@@ -173,7 +173,7 @@ fn validate_and_turn_into_const<'tcx>(
     tcx: TyCtxt<'tcx>,
     constant: RawConst<'tcx>,
     key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
-) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
+) -> ::rustc_middle::mir::interpret::ConstEvalResult<'tcx> {
     let cid = key.value;
     let def_id = cid.instance.def.def_id();
     let is_static = tcx.is_static(def_id);
@@ -223,7 +223,7 @@ fn validate_and_turn_into_const<'tcx>(
 pub fn const_eval_validated_provider<'tcx>(
     tcx: TyCtxt<'tcx>,
     key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
-) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
+) -> ::rustc_middle::mir::interpret::ConstEvalResult<'tcx> {
     // see comment in const_eval_raw_provider for what we're doing here
     if key.param_env.reveal == Reveal::All {
         let mut key = key;
@@ -257,7 +257,7 @@ pub fn const_eval_validated_provider<'tcx>(
 pub fn const_eval_raw_provider<'tcx>(
     tcx: TyCtxt<'tcx>,
     key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
-) -> ::rustc::mir::interpret::ConstEvalRawResult<'tcx> {
+) -> ::rustc_middle::mir::interpret::ConstEvalRawResult<'tcx> {
     // Because the constant is computed twice (once per value of `Reveal`), we are at risk of
     // reporting the same error twice here. To resolve this, we check whether we can evaluate the
     // constant in the more restrictive `Reveal::UserFacing`, which most likely already was
@@ -307,7 +307,7 @@ pub fn const_eval_raw_provider<'tcx>(
     );
 
     let res = ecx.load_mir(cid.instance.def, cid.promoted);
-    res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, *body))
+    res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, &body))
         .and_then(|place| {
             Ok(RawConst { alloc_id: place.ptr.assert_ptr().alloc_id, ty: place.layout.ty })
         })
diff --git a/src/librustc_mir/const_eval/fn_queries.rs b/src/librustc_mir/const_eval/fn_queries.rs
index 470e4e7ed25..8ae4f9f4a0d 100644
--- a/src/librustc_mir/const_eval/fn_queries.rs
+++ b/src/librustc_mir/const_eval/fn_queries.rs
@@ -1,9 +1,9 @@
-use rustc::hir::map::blocks::FnLikeNode;
-use rustc::ty::query::Providers;
-use rustc::ty::TyCtxt;
 use rustc_attr as attr;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_middle::hir::map::blocks::FnLikeNode;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::Symbol;
 use rustc_target::spec::abi::Abi;
 
diff --git a/src/librustc_mir/const_eval/machine.rs b/src/librustc_mir/const_eval/machine.rs
index 0970e097919..e9263471478 100644
--- a/src/librustc_mir/const_eval/machine.rs
+++ b/src/librustc_mir/const_eval/machine.rs
@@ -1,16 +1,16 @@
-use rustc::mir;
-use rustc::ty::layout::HasTyCtxt;
-use rustc::ty::{self, Ty};
+use rustc_middle::mir;
+use rustc_middle::ty::layout::HasTyCtxt;
+use rustc_middle::ty::{self, Ty};
 use std::borrow::{Borrow, Cow};
 use std::collections::hash_map::Entry;
 use std::hash::Hash;
 
 use rustc_data_structures::fx::FxHashMap;
 
-use rustc::mir::AssertMessage;
 use rustc_ast::ast::Mutability;
+use rustc_hir::def_id::DefId;
+use rustc_middle::mir::AssertMessage;
 use rustc_span::symbol::Symbol;
-use rustc_span::{def_id::DefId, Span};
 
 use crate::interpret::{
     self, AllocId, Allocation, GlobalId, ImmTy, InterpCx, InterpResult, Memory, MemoryKind, OpTy,
@@ -64,7 +64,6 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter> {
     /// If this returns successfully (`Ok`), the function should just be evaluated normally.
     fn hook_panic_fn(
         &mut self,
-        span: Span,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx>],
     ) -> InterpResult<'tcx> {
@@ -77,7 +76,7 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter> {
 
             let msg_place = self.deref_operand(args[0])?;
             let msg = Symbol::intern(self.read_str(msg_place)?);
-            let span = self.find_closest_untracked_caller_location().unwrap_or(span);
+            let span = self.find_closest_untracked_caller_location();
             let (file, line, col) = self.location_triple_for_span(span);
             Err(ConstEvalErrKind::Panic { msg, file, line, col }.into())
         } else {
@@ -191,7 +190,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
 
     fn find_mir_or_eval_fn(
         ecx: &mut InterpCx<'mir, 'tcx, Self>,
-        span: Span,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx>],
         ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
@@ -213,7 +211,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
             } else {
                 // Some functions we support even if they are non-const -- but avoid testing
                 // that for const fn!
-                ecx.hook_panic_fn(span, instance, args)?;
+                ecx.hook_panic_fn(instance, args)?;
                 // We certainly do *not* want to actually call the fn
                 // though, so be sure we return here.
                 throw_unsup_format!("calling non-const function `{}`", instance)
@@ -248,13 +246,12 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
 
     fn call_intrinsic(
         ecx: &mut InterpCx<'mir, 'tcx, Self>,
-        span: Span,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx>],
         ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
         _unwind: Option<mir::BasicBlock>,
     ) -> InterpResult<'tcx> {
-        if ecx.emulate_intrinsic(span, instance, args, ret)? {
+        if ecx.emulate_intrinsic(instance, args, ret)? {
             return Ok(());
         }
         // An intrinsic that we do not support
@@ -267,7 +264,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
         msg: &AssertMessage<'tcx>,
         _unwind: Option<mir::BasicBlock>,
     ) -> InterpResult<'tcx> {
-        use rustc::mir::AssertKind::*;
+        use rustc_middle::mir::AssertKind::*;
         // Convert `AssertKind<Operand>` to `AssertKind<u64>`.
         let err = match msg {
             BoundsCheck { ref len, ref index } => {
diff --git a/src/librustc_mir/const_eval/mod.rs b/src/librustc_mir/const_eval/mod.rs
index 6e7e6f9d345..e1146ef30d1 100644
--- a/src/librustc_mir/const_eval/mod.rs
+++ b/src/librustc_mir/const_eval/mod.rs
@@ -2,10 +2,10 @@
 
 use std::convert::TryFrom;
 
-use rustc::mir;
-use rustc::ty::layout::VariantIdx;
-use rustc::ty::{self, TyCtxt};
+use rustc_middle::mir;
+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/drop_flag_effects.rs b/src/librustc_mir/dataflow/drop_flag_effects.rs
index 720b17e7ff8..91b342ae5c3 100644
--- a/src/librustc_mir/dataflow/drop_flag_effects.rs
+++ b/src/librustc_mir/dataflow/drop_flag_effects.rs
@@ -1,6 +1,6 @@
 use crate::util::elaborate_drops::DropFlagState;
-use rustc::mir::{self, Body, Location};
-use rustc::ty::{self, TyCtxt};
+use rustc_middle::mir::{self, Body, Location};
+use rustc_middle::ty::{self, TyCtxt};
 
 use super::indexes::MovePathIndex;
 use super::move_paths::{InitKind, LookupResult, MoveData};
@@ -49,7 +49,7 @@ where
 fn place_contents_drop_state_cannot_differ<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
-    place: &mir::Place<'tcx>,
+    place: mir::Place<'tcx>,
 ) -> bool {
     let ty = place.ty(body, tcx).ty;
     match ty.kind {
@@ -110,7 +110,7 @@ pub(crate) fn on_all_children_bits<'tcx, F>(
         move_data: &MoveData<'tcx>,
         path: MovePathIndex,
     ) -> bool {
-        place_contents_drop_state_cannot_differ(tcx, body, &move_data.move_paths[path].place)
+        place_contents_drop_state_cannot_differ(tcx, body, move_data.move_paths[path].place)
     }
 
     fn on_all_children_bits<'tcx, F>(
diff --git a/src/librustc_mir/dataflow/framework/cursor.rs b/src/librustc_mir/dataflow/framework/cursor.rs
index 170157aca5d..39676d03740 100644
--- a/src/librustc_mir/dataflow/framework/cursor.rs
+++ b/src/librustc_mir/dataflow/framework/cursor.rs
@@ -2,8 +2,8 @@
 
 use std::borrow::Borrow;
 
-use rustc::mir::{self, BasicBlock, Location, TerminatorKind};
 use rustc_index::bit_set::BitSet;
+use rustc_middle::mir::{self, BasicBlock, Location, TerminatorKind};
 
 use super::{Analysis, Results};
 
@@ -135,14 +135,14 @@ where
                     target.block,
                     func,
                     args,
-                    return_place,
+                    *return_place,
                 );
             }
             TerminatorKind::Yield { resume, resume_arg, .. } => {
                 self.results.borrow().analysis.apply_yield_resume_effect(
                     &mut self.state,
                     *resume,
-                    resume_arg,
+                    *resume_arg,
                 );
             }
             _ => {}
diff --git a/src/librustc_mir/dataflow/framework/engine.rs b/src/librustc_mir/dataflow/framework/engine.rs
index d32072125b3..2a9d2d99c8a 100644
--- a/src/librustc_mir/dataflow/framework/engine.rs
+++ b/src/librustc_mir/dataflow/framework/engine.rs
@@ -4,17 +4,18 @@ use std::ffi::OsString;
 use std::fs;
 use std::path::PathBuf;
 
-use rustc::mir::{self, traversal, BasicBlock, Location};
-use rustc::ty::{self, TyCtxt};
 use rustc_ast::ast;
 use rustc_data_structures::work_queue::WorkQueue;
 use rustc_hir::def_id::DefId;
 use rustc_index::bit_set::BitSet;
 use rustc_index::vec::IndexVec;
+use rustc_middle::mir::{self, traversal, BasicBlock, Location};
+use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::symbol::{sym, Symbol};
 
 use super::graphviz;
 use super::{Analysis, GenKillAnalysis, GenKillSet, Results};
+use crate::util::pretty::dump_enabled;
 
 /// A solver for dataflow problems.
 pub struct Engine<'a, 'tcx, A>
@@ -228,7 +229,7 @@ where
                     self.propagate_bits_into_entry_set_for(in_out, drop, dirty_list);
                 }
 
-                self.analysis.apply_yield_resume_effect(in_out, target, &resume_arg);
+                self.analysis.apply_yield_resume_effect(in_out, target, resume_arg);
                 self.propagate_bits_into_entry_set_for(in_out, target, dirty_list);
             }
 
@@ -272,7 +273,7 @@ where
                     }
                 }
 
-                if let Some((ref dest_place, dest_bb)) = *destination {
+                if let Some((dest_place, dest_bb)) = *destination {
                     // N.B.: This must be done *last*, otherwise the unwind path will see the call
                     // return effect.
                     self.analysis.apply_call_return_effect(in_out, bb, func, args, dest_place);
@@ -314,7 +315,7 @@ where
         in_out: &mut BitSet<A::Idx>,
         bb: BasicBlock,
         enum_def: &'tcx ty::AdtDef,
-        enum_place: &mir::Place<'tcx>,
+        enum_place: mir::Place<'tcx>,
         dirty_list: &mut WorkQueue<BasicBlock>,
         values: &[u128],
         targets: &[BasicBlock],
@@ -361,14 +362,14 @@ fn switch_on_enum_discriminant(
     tcx: TyCtxt<'tcx>,
     body: &'mir mir::Body<'tcx>,
     block: &'mir mir::BasicBlockData<'tcx>,
-    switch_on: &mir::Place<'tcx>,
-) -> Option<(&'mir mir::Place<'tcx>, &'tcx ty::AdtDef)> {
+    switch_on: mir::Place<'tcx>,
+) -> Option<(mir::Place<'tcx>, &'tcx ty::AdtDef)> {
     match block.statements.last().map(|stmt| &stmt.kind) {
         Some(mir::StatementKind::Assign(box (lhs, mir::Rvalue::Discriminant(discriminated))))
-            if lhs == switch_on =>
+            if *lhs == switch_on =>
         {
             match &discriminated.ty(body, tcx).ty.kind {
-                ty::Adt(def, _) => Some((discriminated, def)),
+                ty::Adt(def, _) => Some((*discriminated, def)),
 
                 // `Rvalue::Discriminant` is also used to get the active yield point for a
                 // generator, but we do not need edge-specific effects in that case. This may
@@ -400,12 +401,25 @@ where
     let attrs = match RustcMirAttrs::parse(tcx, def_id) {
         Ok(attrs) => attrs,
 
-        // Invalid `rustc_mir` attrs will be reported using `span_err`.
+        // Invalid `rustc_mir` attrs are reported in `RustcMirAttrs::parse`
         Err(()) => return Ok(()),
     };
 
     let path = match attrs.output_path(A::NAME) {
         Some(path) => path,
+
+        None if tcx.sess.opts.debugging_opts.dump_mir_dataflow
+            && dump_enabled(tcx, A::NAME, def_id) =>
+        {
+            let mut path = PathBuf::from(&tcx.sess.opts.debugging_opts.dump_mir_dir);
+
+            let item_name = ty::print::with_forced_impl_filename_line(|| {
+                tcx.def_path(def_id).to_filename_friendly_no_crate()
+            });
+            path.push(format!("rustc.{}.{}.dot", item_name, A::NAME));
+            path
+        }
+
         None => return Ok(()),
     };
 
@@ -430,7 +444,12 @@ where
 
     let graphviz = graphviz::Formatter::new(body, def_id, results, &mut *formatter);
     dot::render_opts(&graphviz, &mut buf, &[dot::RenderOption::Monospace])?;
+
+    if let Some(parent) = path.parent() {
+        fs::create_dir_all(parent)?;
+    }
     fs::write(&path, buf)?;
+
     Ok(())
 }
 
diff --git a/src/librustc_mir/dataflow/framework/graphviz.rs b/src/librustc_mir/dataflow/framework/graphviz.rs
index c15f2a726ee..bdd41121359 100644
--- a/src/librustc_mir/dataflow/framework/graphviz.rs
+++ b/src/librustc_mir/dataflow/framework/graphviz.rs
@@ -3,10 +3,10 @@
 use std::cell::RefCell;
 use std::{io, ops, str};
 
-use rustc::mir::{self, BasicBlock, Body, Location};
 use rustc_hir::def_id::DefId;
 use rustc_index::bit_set::{BitSet, HybridBitSet};
 use rustc_index::vec::{Idx, IndexVec};
+use rustc_middle::mir::{self, BasicBlock, Body, Location};
 
 use super::{Analysis, GenKillSet, Results, ResultsRefCursor};
 use crate::util::graphviz_safe_def_name;
@@ -229,26 +229,22 @@ where
         }
 
         // Write any changes caused by terminator-specific effects
-        match terminator.kind {
-            mir::TerminatorKind::Call { destination: Some(_), .. } => {
-                let num_state_columns = self.num_state_columns();
-                self.write_row(w, "", "(on successful return)", |this, w, fmt| {
-                    write!(
-                        w,
-                        r#"<td balign="left" colspan="{colspan}" {fmt} align="left">"#,
-                        colspan = num_state_columns,
-                        fmt = fmt,
-                    )?;
-
-                    let state_on_unwind = this.results.get().clone();
-                    this.results.seek_after_assume_success(terminator_loc);
-                    write_diff(w, this.results.analysis(), &state_on_unwind, this.results.get())?;
-
-                    write!(w, "</td>")
-                })?;
-            }
-
-            _ => {}
+        if let mir::TerminatorKind::Call { destination: Some(_), .. } = terminator.kind {
+            let num_state_columns = self.num_state_columns();
+            self.write_row(w, "", "(on successful return)", |this, w, fmt| {
+                write!(
+                    w,
+                    r#"<td balign="left" colspan="{colspan}" {fmt} align="left">"#,
+                    colspan = num_state_columns,
+                    fmt = fmt,
+                )?;
+
+                let state_on_unwind = this.results.get().clone();
+                this.results.seek_after_assume_success(terminator_loc);
+                write_diff(w, this.results.analysis(), &state_on_unwind, this.results.get())?;
+
+                write!(w, "</td>")
+            })?;
         };
 
         write!(w, "</table>")
diff --git a/src/librustc_mir/dataflow/framework/mod.rs b/src/librustc_mir/dataflow/framework/mod.rs
index 8556be7e740..06da8799dd4 100644
--- a/src/librustc_mir/dataflow/framework/mod.rs
+++ b/src/librustc_mir/dataflow/framework/mod.rs
@@ -32,12 +32,12 @@
 
 use std::io;
 
-use rustc::mir::{self, BasicBlock, Location};
-use rustc::ty::layout::VariantIdx;
-use rustc::ty::{self, TyCtxt};
 use rustc_hir::def_id::DefId;
 use rustc_index::bit_set::{BitSet, HybridBitSet};
 use rustc_index::vec::{Idx, IndexVec};
+use rustc_middle::mir::{self, BasicBlock, Location};
+use rustc_middle::ty::{self, TyCtxt};
+use rustc_target::abi::VariantIdx;
 
 mod cursor;
 mod engine;
@@ -225,7 +225,7 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> {
         block: BasicBlock,
         func: &mir::Operand<'tcx>,
         args: &[mir::Operand<'tcx>],
-        return_place: &mir::Place<'tcx>,
+        return_place: mir::Place<'tcx>,
     );
 
     /// Updates the current dataflow state with the effect of resuming from a `Yield` terminator.
@@ -238,7 +238,7 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> {
         &self,
         _state: &mut BitSet<Self::Idx>,
         _resume_block: BasicBlock,
-        _resume_place: &mir::Place<'tcx>,
+        _resume_place: mir::Place<'tcx>,
     ) {
     }
 
@@ -251,7 +251,7 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> {
         &self,
         _state: &mut BitSet<Self::Idx>,
         _block: BasicBlock,
-        _enum_place: &mir::Place<'tcx>,
+        _enum_place: mir::Place<'tcx>,
         _adt: &ty::AdtDef,
         _variant: VariantIdx,
     ) {
@@ -332,7 +332,7 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> {
         block: BasicBlock,
         func: &mir::Operand<'tcx>,
         args: &[mir::Operand<'tcx>],
-        return_place: &mir::Place<'tcx>,
+        return_place: mir::Place<'tcx>,
     );
 
     /// See `Analysis::apply_yield_resume_effect`.
@@ -340,7 +340,7 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> {
         &self,
         _trans: &mut BitSet<Self::Idx>,
         _resume_block: BasicBlock,
-        _resume_place: &mir::Place<'tcx>,
+        _resume_place: mir::Place<'tcx>,
     ) {
     }
 
@@ -349,7 +349,7 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> {
         &self,
         _state: &mut impl GenKill<Self::Idx>,
         _block: BasicBlock,
-        _enum_place: &mir::Place<'tcx>,
+        _enum_place: mir::Place<'tcx>,
         _adt: &ty::AdtDef,
         _variant: VariantIdx,
     ) {
@@ -402,7 +402,7 @@ where
         block: BasicBlock,
         func: &mir::Operand<'tcx>,
         args: &[mir::Operand<'tcx>],
-        return_place: &mir::Place<'tcx>,
+        return_place: mir::Place<'tcx>,
     ) {
         self.call_return_effect(state, block, func, args, return_place);
     }
@@ -411,7 +411,7 @@ where
         &self,
         state: &mut BitSet<Self::Idx>,
         resume_block: BasicBlock,
-        resume_place: &mir::Place<'tcx>,
+        resume_place: mir::Place<'tcx>,
     ) {
         self.yield_resume_effect(state, resume_block, resume_place);
     }
@@ -420,7 +420,7 @@ where
         &self,
         state: &mut BitSet<Self::Idx>,
         block: BasicBlock,
-        enum_place: &mir::Place<'tcx>,
+        enum_place: mir::Place<'tcx>,
         adt: &ty::AdtDef,
         variant: VariantIdx,
     ) {
diff --git a/src/librustc_mir/dataflow/framework/tests.rs b/src/librustc_mir/dataflow/framework/tests.rs
index 8f07a10e1b0..8c65b7452d1 100644
--- a/src/librustc_mir/dataflow/framework/tests.rs
+++ b/src/librustc_mir/dataflow/framework/tests.rs
@@ -1,9 +1,9 @@
 //! A test for the logic that updates the state in a `ResultsCursor` during seek.
 
-use rustc::mir::{self, BasicBlock, Location};
-use rustc::ty;
 use rustc_index::bit_set::BitSet;
 use rustc_index::vec::IndexVec;
+use rustc_middle::mir::{self, BasicBlock, Location};
+use rustc_middle::ty;
 use rustc_span::DUMMY_SP;
 
 use super::*;
@@ -223,7 +223,7 @@ impl Analysis<'tcx> for MockAnalysis<'tcx> {
         block: BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        _return_place: &mir::Place<'tcx>,
+        _return_place: mir::Place<'tcx>,
     ) {
         let location = self.body.terminator_loc(block);
         let idx = self.effect_at_target(SeekTarget::AfterAssumeCallReturns(location)).unwrap();
diff --git a/src/librustc_mir/dataflow/framework/visitor.rs b/src/librustc_mir/dataflow/framework/visitor.rs
index 6e1513bcd1d..9561b68398d 100644
--- a/src/librustc_mir/dataflow/framework/visitor.rs
+++ b/src/librustc_mir/dataflow/framework/visitor.rs
@@ -1,5 +1,5 @@
-use rustc::mir::{self, BasicBlock, Location};
 use rustc_index::bit_set::BitSet;
+use rustc_middle::mir::{self, BasicBlock, Location};
 
 use super::{Analysis, Results};
 use crate::dataflow::impls::{borrows::Borrows, EverInitializedPlaces, MaybeUninitializedPlaces};
diff --git a/src/librustc_mir/dataflow/graphviz.rs b/src/librustc_mir/dataflow/graphviz.rs
deleted file mode 100644
index a9ef7ef6c52..00000000000
--- a/src/librustc_mir/dataflow/graphviz.rs
+++ /dev/null
@@ -1,277 +0,0 @@
-//! Hook into libgraphviz for rendering dataflow graphs for MIR.
-
-use rustc::mir::{BasicBlock, Body};
-use rustc_hir::def_id::DefId;
-
-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/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs
index 955021d83aa..6972a81cf1b 100644
--- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs
+++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs
@@ -1,9 +1,9 @@
 pub use super::*;
 
 use crate::dataflow::{AnalysisDomain, GenKill, GenKillAnalysis};
-use rustc::mir::visit::Visitor;
-use rustc::mir::*;
-use rustc::ty::{ParamEnv, TyCtxt};
+use rustc_middle::mir::visit::Visitor;
+use rustc_middle::mir::*;
+use rustc_middle::ty::{ParamEnv, TyCtxt};
 use rustc_span::DUMMY_SP;
 
 pub type MaybeMutBorrowedLocals<'mir, 'tcx> = MaybeBorrowedLocals<MutBorrow<'mir, 'tcx>>;
@@ -123,7 +123,7 @@ where
         _block: mir::BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        _dest_place: &mir::Place<'tcx>,
+        _dest_place: mir::Place<'tcx>,
     ) {
     }
 }
@@ -160,13 +160,13 @@ where
 
         match rvalue {
             mir::Rvalue::AddressOf(mt, borrowed_place) => {
-                if !borrowed_place.is_indirect() && self.kind.in_address_of(*mt, borrowed_place) {
+                if !borrowed_place.is_indirect() && self.kind.in_address_of(*mt, *borrowed_place) {
                     self.trans.gen(borrowed_place.local);
                 }
             }
 
             mir::Rvalue::Ref(_, kind, borrowed_place) => {
-                if !borrowed_place.is_indirect() && self.kind.in_ref(*kind, borrowed_place) {
+                if !borrowed_place.is_indirect() && self.kind.in_ref(*kind, *borrowed_place) {
                     self.trans.gen(borrowed_place.local);
                 }
             }
@@ -230,7 +230,7 @@ impl MutBorrow<'mir, 'tcx> {
     /// below. See [rust-lang/unsafe-code-guidelines#134].
     ///
     /// [rust-lang/unsafe-code-guidelines#134]: https://github.com/rust-lang/unsafe-code-guidelines/issues/134
-    fn shared_borrow_allows_mutation(&self, place: &Place<'tcx>) -> bool {
+    fn shared_borrow_allows_mutation(&self, place: Place<'tcx>) -> bool {
         !place.ty(self.body, self.tcx).ty.is_freeze(self.tcx, self.param_env, DUMMY_SP)
     }
 }
@@ -238,17 +238,17 @@ impl MutBorrow<'mir, 'tcx> {
 pub trait BorrowAnalysisKind<'tcx> {
     const ANALYSIS_NAME: &'static str;
 
-    fn in_address_of(&self, mt: Mutability, place: &Place<'tcx>) -> bool;
-    fn in_ref(&self, kind: mir::BorrowKind, place: &Place<'tcx>) -> bool;
+    fn in_address_of(&self, mt: Mutability, place: Place<'tcx>) -> bool;
+    fn in_ref(&self, kind: mir::BorrowKind, place: Place<'tcx>) -> bool;
 }
 
 impl BorrowAnalysisKind<'tcx> for AnyBorrow {
     const ANALYSIS_NAME: &'static str = "maybe_borrowed_locals";
 
-    fn in_ref(&self, _: mir::BorrowKind, _: &Place<'_>) -> bool {
+    fn in_ref(&self, _: mir::BorrowKind, _: Place<'_>) -> bool {
         true
     }
-    fn in_address_of(&self, _: Mutability, _: &Place<'_>) -> bool {
+    fn in_address_of(&self, _: Mutability, _: Place<'_>) -> bool {
         true
     }
 }
@@ -256,7 +256,7 @@ impl BorrowAnalysisKind<'tcx> for AnyBorrow {
 impl BorrowAnalysisKind<'tcx> for MutBorrow<'mir, 'tcx> {
     const ANALYSIS_NAME: &'static str = "maybe_mut_borrowed_locals";
 
-    fn in_ref(&self, kind: mir::BorrowKind, place: &Place<'tcx>) -> bool {
+    fn in_ref(&self, kind: mir::BorrowKind, place: Place<'tcx>) -> bool {
         match kind {
             mir::BorrowKind::Mut { .. } => true,
             mir::BorrowKind::Shared | mir::BorrowKind::Shallow | mir::BorrowKind::Unique => {
@@ -265,7 +265,7 @@ impl BorrowAnalysisKind<'tcx> for MutBorrow<'mir, 'tcx> {
         }
     }
 
-    fn in_address_of(&self, mt: Mutability, place: &Place<'tcx>) -> bool {
+    fn in_address_of(&self, mt: Mutability, place: Place<'tcx>) -> bool {
         match mt {
             Mutability::Mut => true,
             Mutability::Not => self.shared_borrow_allows_mutation(place),
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs
index d25d3a9bfc1..0de8f45720e 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -1,6 +1,6 @@
-use rustc::mir::{self, Body, Location, Place};
-use rustc::ty::RegionVid;
-use rustc::ty::TyCtxt;
+use rustc_middle::mir::{self, Body, Location, Place};
+use rustc_middle::ty::RegionVid;
+use rustc_middle::ty::TyCtxt;
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_index::bit_set::BitSet;
@@ -187,7 +187,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
     }
 
     /// Kill any borrows that conflict with `place`.
-    fn kill_borrows_on_place(&self, trans: &mut impl GenKill<BorrowIndex>, place: &Place<'tcx>) {
+    fn kill_borrows_on_place(&self, trans: &mut impl GenKill<BorrowIndex>, place: Place<'tcx>) {
         debug!("kill_borrows_on_place: place={:?}", place);
 
         let other_borrows_of_local = self
@@ -216,7 +216,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
             places_conflict(
                 self.tcx,
                 self.body,
-                &self.borrow_set.borrows[i].borrowed_place,
+                self.borrow_set.borrows[i].borrowed_place,
                 place,
                 PlaceConflictBias::NoOverlap,
             )
@@ -262,8 +262,8 @@ impl<'tcx> dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
         location: Location,
     ) {
         match stmt.kind {
-            mir::StatementKind::Assign(box (ref lhs, ref rhs)) => {
-                if let mir::Rvalue::Ref(_, _, ref place) = *rhs {
+            mir::StatementKind::Assign(box (lhs, ref rhs)) => {
+                if let mir::Rvalue::Ref(_, _, place) = *rhs {
                     if place.ignore_borrow(
                         self.tcx,
                         self.body,
@@ -286,13 +286,13 @@ impl<'tcx> dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
             mir::StatementKind::StorageDead(local) => {
                 // Make sure there are no remaining borrows for locals that
                 // are gone out of scope.
-                self.kill_borrows_on_place(trans, &Place::from(local));
+                self.kill_borrows_on_place(trans, Place::from(local));
             }
 
             mir::StatementKind::LlvmInlineAsm(ref asm) => {
                 for (output, kind) in asm.outputs.iter().zip(&asm.asm.outputs) {
                     if !kind.is_indirect && !kind.is_rw {
-                        self.kill_borrows_on_place(trans, output);
+                        self.kill_borrows_on_place(trans, *output);
                     }
                 }
             }
@@ -329,7 +329,7 @@ impl<'tcx> dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
         _block: mir::BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        _dest_place: &mir::Place<'tcx>,
+        _dest_place: mir::Place<'tcx>,
     ) {
     }
 }
diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs
index 180094e412b..b5f1a2d4eb9 100644
--- a/src/librustc_mir/dataflow/impls/mod.rs
+++ b/src/librustc_mir/dataflow/impls/mod.rs
@@ -2,11 +2,11 @@
 //! bitvectors attached to each basic block, represented via a
 //! zero-sized structure.
 
-use rustc::mir::{self, Body, Location};
-use rustc::ty::layout::VariantIdx;
-use rustc::ty::{self, TyCtxt};
 use rustc_index::bit_set::BitSet;
 use rustc_index::vec::Idx;
+use rustc_middle::mir::{self, Body, Location};
+use rustc_middle::ty::{self, TyCtxt};
+use rustc_target::abi::VariantIdx;
 
 use super::MoveDataParamEnv;
 
@@ -323,7 +323,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
         _block: mir::BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        dest_place: &mir::Place<'tcx>,
+        dest_place: mir::Place<'tcx>,
     ) {
         // when a call returns successfully, that means we need to set
         // the bits for that dest_place to 1 (initialized).
@@ -342,7 +342,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
         &self,
         trans: &mut impl GenKill<Self::Idx>,
         _block: mir::BasicBlock,
-        enum_place: &mir::Place<'tcx>,
+        enum_place: mir::Place<'tcx>,
         _adt: &ty::AdtDef,
         variant: VariantIdx,
     ) {
@@ -425,7 +425,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
         _block: mir::BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        dest_place: &mir::Place<'tcx>,
+        dest_place: mir::Place<'tcx>,
     ) {
         // when a call returns successfully, that means we need to set
         // the bits for that dest_place to 0 (initialized).
@@ -494,7 +494,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> {
         _block: mir::BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        dest_place: &mir::Place<'tcx>,
+        dest_place: mir::Place<'tcx>,
     ) {
         // when a call returns successfully, that means we need to set
         // the bits for that dest_place to 1 (initialized).
@@ -544,18 +544,15 @@ impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
         );
         trans.gen_all(init_loc_map[location].iter().copied());
 
-        match stmt.kind {
-            mir::StatementKind::StorageDead(local) => {
-                // End inits for StorageDead, so that an immutable variable can
-                // be reinitialized on the next iteration of the loop.
-                let move_path_index = rev_lookup.find_local(local);
-                debug!(
-                    "stmt {:?} at loc {:?} clears the ever initialized status of {:?}",
-                    stmt, location, &init_path_map[move_path_index]
-                );
-                trans.kill_all(init_path_map[move_path_index].iter().copied());
-            }
-            _ => {}
+        if let mir::StatementKind::StorageDead(local) = stmt.kind {
+            // End inits for StorageDead, so that an immutable variable can
+            // be reinitialized on the next iteration of the loop.
+            let move_path_index = rev_lookup.find_local(local);
+            debug!(
+                "stmt {:?} at loc {:?} clears the ever initialized status of {:?}",
+                stmt, location, &init_path_map[move_path_index]
+            );
+            trans.kill_all(init_path_map[move_path_index].iter().copied());
         }
     }
 
@@ -588,7 +585,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
         block: mir::BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        _dest_place: &mir::Place<'tcx>,
+        _dest_place: mir::Place<'tcx>,
     ) {
         let move_data = self.move_data();
         let init_loc_map = &move_data.init_loc_map;
diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/src/librustc_mir/dataflow/impls/storage_liveness.rs
index 67d024e62d9..3dfcfe16fb5 100644
--- a/src/librustc_mir/dataflow/impls/storage_liveness.rs
+++ b/src/librustc_mir/dataflow/impls/storage_liveness.rs
@@ -2,8 +2,8 @@ pub use super::*;
 
 use crate::dataflow::BottomValue;
 use crate::dataflow::{self, GenKill, Results, ResultsRefCursor};
-use rustc::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
-use rustc::mir::*;
+use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
+use rustc_middle::mir::*;
 use std::cell::RefCell;
 
 #[derive(Copy, Clone)]
@@ -56,7 +56,7 @@ impl dataflow::GenKillAnalysis<'tcx> for MaybeStorageLive {
         _block: BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        _return_place: &mir::Place<'tcx>,
+        _return_place: mir::Place<'tcx>,
     ) {
         // Nothing to do when a call returns successfully
     }
@@ -83,7 +83,7 @@ impl<'mir, 'tcx> MaybeRequiresStorage<'mir, 'tcx> {
     ) -> Self {
         MaybeRequiresStorage {
             body,
-            borrowed_locals: RefCell::new(ResultsRefCursor::new(*body, borrowed_locals)),
+            borrowed_locals: RefCell::new(ResultsRefCursor::new(&body, borrowed_locals)),
         }
     }
 }
@@ -231,7 +231,7 @@ impl<'mir, 'tcx> dataflow::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir,
         _block: BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        return_place: &mir::Place<'tcx>,
+        return_place: mir::Place<'tcx>,
     ) {
         trans.gen(return_place.local);
     }
@@ -240,7 +240,7 @@ impl<'mir, 'tcx> dataflow::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir,
         &self,
         trans: &mut BitSet<Self::Idx>,
         _resume_block: BasicBlock,
-        resume_place: &mir::Place<'tcx>,
+        resume_place: mir::Place<'tcx>,
     ) {
         trans.gen(resume_place.local);
     }
@@ -250,7 +250,7 @@ impl<'mir, 'tcx> MaybeRequiresStorage<'mir, 'tcx> {
     /// Kill locals that are fully moved and have not been borrowed.
     fn check_for_move(&self, trans: &mut impl GenKill<Local>, loc: Location) {
         let mut visitor = MoveVisitor { trans, borrowed_locals: &self.borrowed_locals };
-        visitor.visit_location(self.body, loc);
+        visitor.visit_location(&self.body, loc);
     }
 }
 
diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs
index 96e5b6936a1..d244587fcc8 100644
--- a/src/librustc_mir/dataflow/mod.rs
+++ b/src/librustc_mir/dataflow/mod.rs
@@ -1,5 +1,5 @@
-use rustc::ty;
 use rustc_ast::ast::{self, MetaItem};
+use rustc_middle::ty;
 use rustc_span::symbol::{sym, Symbol};
 
 pub(crate) use self::drop_flag_effects::*;
diff --git a/src/librustc_mir/dataflow/move_paths/abs_domain.rs b/src/librustc_mir/dataflow/move_paths/abs_domain.rs
index 0ecf22ae233..28936274baa 100644
--- a/src/librustc_mir/dataflow/move_paths/abs_domain.rs
+++ b/src/librustc_mir/dataflow/move_paths/abs_domain.rs
@@ -11,8 +11,8 @@
 //! `a[x]` would still overlap them both. But that is not this
 //! representation does today.)
 
-use rustc::mir::{Local, Operand, PlaceElem, ProjectionElem};
-use rustc::ty::Ty;
+use rustc_middle::mir::{Local, Operand, PlaceElem, ProjectionElem};
+use rustc_middle::ty::Ty;
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub struct AbstractOperand;
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs
index 8061765f66d..fabe575c289 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/src/librustc_mir/dataflow/move_paths/builder.rs
@@ -1,7 +1,7 @@
-use rustc::mir::tcx::RvalueInitializationState;
-use rustc::mir::*;
-use rustc::ty::{self, TyCtxt};
 use rustc_index::vec::IndexVec;
+use rustc_middle::mir::tcx::RvalueInitializationState;
+use rustc_middle::mir::*;
+use rustc_middle::ty::{self, TyCtxt};
 use smallvec::{smallvec, SmallVec};
 
 use std::convert::TryInto;
@@ -94,7 +94,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
     /// problematic for borrowck.
     ///
     /// Maybe we should have separate "borrowck" and "moveck" modes.
-    fn move_path_for(&mut self, place: &Place<'tcx>) -> Result<MovePathIndex, MoveError<'tcx>> {
+    fn move_path_for(&mut self, place: Place<'tcx>) -> Result<MovePathIndex, MoveError<'tcx>> {
         debug!("lookup({:?})", place);
         let mut base = self.builder.data.rev_lookup.locals[place.local];
 
@@ -144,15 +144,16 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                         },
                     ));
                 }
-                ty::Array(..) => match elem {
-                    ProjectionElem::Index(..) => {
+
+                ty::Array(..) => {
+                    if let ProjectionElem::Index(..) = elem {
                         return Err(MoveError::cannot_move_out_of(
                             self.loc,
                             InteriorOfSliceOrArray { ty: place_ty, is_index: true },
                         ));
                     }
-                    _ => {}
-                },
+                }
+
                 _ => {}
             };
 
@@ -194,7 +195,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
         })
     }
 
-    fn create_move_path(&mut self, place: &Place<'tcx>) {
+    fn create_move_path(&mut self, place: Place<'tcx>) {
         // This is an non-moving access (such as an overwrite or
         // drop), so this not being a valid move path is OK.
         let _ = self.move_path_for(place);
@@ -278,22 +279,22 @@ struct Gatherer<'b, 'a, 'tcx> {
 
 impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
     fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
-        match stmt.kind {
-            StatementKind::Assign(box (ref place, ref rval)) => {
-                self.create_move_path(place);
+        match &stmt.kind {
+            StatementKind::Assign(box (place, rval)) => {
+                self.create_move_path(*place);
                 if let RvalueInitializationState::Shallow = rval.initialization_state() {
                     // Box starts out uninitialized - need to create a separate
                     // move-path for the interior so it will be separate from
                     // the exterior.
-                    self.create_move_path(&self.builder.tcx.mk_place_deref(place.clone()));
+                    self.create_move_path(self.builder.tcx.mk_place_deref(place.clone()));
                     self.gather_init(place.as_ref(), InitKind::Shallow);
                 } else {
                     self.gather_init(place.as_ref(), InitKind::Deep);
                 }
                 self.gather_rvalue(rval);
             }
-            StatementKind::FakeRead(_, ref place) => {
-                self.create_move_path(place);
+            StatementKind::FakeRead(_, place) => {
+                self.create_move_path(**place);
             }
             StatementKind::LlvmInlineAsm(ref asm) => {
                 for (output, kind) in asm.outputs.iter().zip(&asm.asm.outputs) {
@@ -307,7 +308,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             }
             StatementKind::StorageLive(_) => {}
             StatementKind::StorageDead(local) => {
-                self.gather_move(&Place::from(local));
+                self.gather_move(Place::from(*local));
             }
             StatementKind::SetDiscriminant { .. } => {
                 span_bug!(
@@ -368,7 +369,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             | TerminatorKind::Unreachable => {}
 
             TerminatorKind::Return => {
-                self.gather_move(&Place::return_place());
+                self.gather_move(Place::return_place());
             }
 
             TerminatorKind::Assert { ref cond, .. } => {
@@ -379,16 +380,16 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                 self.gather_operand(discr);
             }
 
-            TerminatorKind::Yield { ref value, resume_arg: ref place, .. } => {
+            TerminatorKind::Yield { ref value, resume_arg: place, .. } => {
                 self.gather_operand(value);
                 self.create_move_path(place);
                 self.gather_init(place.as_ref(), InitKind::Deep);
             }
 
-            TerminatorKind::Drop { ref location, target: _, unwind: _ } => {
+            TerminatorKind::Drop { location, target: _, unwind: _ } => {
                 self.gather_move(location);
             }
-            TerminatorKind::DropAndReplace { ref location, ref value, .. } => {
+            TerminatorKind::DropAndReplace { location, ref value, .. } => {
                 self.create_move_path(location);
                 self.gather_operand(value);
                 self.gather_init(location.as_ref(), InitKind::Deep);
@@ -404,7 +405,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                 for arg in args {
                     self.gather_operand(arg);
                 }
-                if let Some((ref destination, _bb)) = *destination {
+                if let Some((destination, _bb)) = *destination {
                     self.create_move_path(destination);
                     self.gather_init(destination.as_ref(), InitKind::NonPanicPathOnly);
                 }
@@ -415,14 +416,14 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
     fn gather_operand(&mut self, operand: &Operand<'tcx>) {
         match *operand {
             Operand::Constant(..) | Operand::Copy(..) => {} // not-a-move
-            Operand::Move(ref place) => {
+            Operand::Move(place) => {
                 // a move
                 self.gather_move(place);
             }
         }
     }
 
-    fn gather_move(&mut self, place: &Place<'tcx>) {
+    fn gather_move(&mut self, place: Place<'tcx>) {
         debug!("gather_move({:?}, {:?})", self.loc, place);
 
         if let [ref base @ .., ProjectionElem::Subslice { from, to, from_end: false }] =
@@ -433,7 +434,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             // are disjoint, which is expected by drop elaboration.
             let base_place =
                 Place { local: place.local, projection: self.builder.tcx.intern_place_elems(base) };
-            let base_path = match self.move_path_for(&base_place) {
+            let base_path = match self.move_path_for(base_place) {
                 Ok(path) => path,
                 Err(MoveError::UnionMove { path }) => {
                     self.record_move(place, path);
@@ -466,13 +467,13 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             match self.move_path_for(place) {
                 Ok(path) | Err(MoveError::UnionMove { path }) => self.record_move(place, path),
                 Err(error @ MoveError::IllegalMove { .. }) => {
-                    self.builder.errors.push((*place, error));
+                    self.builder.errors.push((place, error));
                 }
             };
         }
     }
 
-    fn record_move(&mut self, place: &Place<'tcx>, path: MovePathIndex) {
+    fn record_move(&mut self, place: Place<'tcx>, path: MovePathIndex) {
         let move_out = self.builder.data.moves.push(MoveOut { path, source: self.loc });
         debug!(
             "gather_move({:?}, {:?}): adding move {:?} of {:?}",
diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs
index 593952bfa7c..d66d2625d78 100644
--- a/src/librustc_mir/dataflow/move_paths/mod.rs
+++ b/src/librustc_mir/dataflow/move_paths/mod.rs
@@ -1,8 +1,8 @@
 use core::slice::Iter;
-use rustc::mir::*;
-use rustc::ty::{ParamEnv, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_index::vec::{Enumerated, IndexVec};
+use rustc_middle::mir::*;
+use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
 use rustc_span::Span;
 use smallvec::SmallVec;
 
diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs
index 6fe97bcb118..67696aa2da8 100644
--- a/src/librustc_mir/interpret/cast.rs
+++ b/src/librustc_mir/interpret/cast.rs
@@ -1,18 +1,16 @@
 use std::convert::TryFrom;
 
-use rustc::ty::adjustment::PointerCast;
-use rustc::ty::layout::{self, Size, TyLayout};
-use rustc::ty::{self, Ty, TypeAndMut, TypeFoldable};
-use rustc_ast::ast::FloatTy;
-use rustc_span::symbol::sym;
-use rustc_target::abi::LayoutOf;
-
-use rustc::mir::interpret::{InterpResult, PointerArithmetic, Scalar};
-use rustc::mir::CastKind;
+use super::{FnVal, ImmTy, Immediate, InterpCx, Machine, OpTy, PlaceTy};
 use rustc_apfloat::ieee::{Double, Single};
 use rustc_apfloat::{Float, FloatConvert};
-
-use super::{FnVal, ImmTy, Immediate, InterpCx, Machine, OpTy, PlaceTy};
+use rustc_ast::ast::FloatTy;
+use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar};
+use rustc_middle::mir::CastKind;
+use rustc_middle::ty::adjustment::PointerCast;
+use rustc_middle::ty::layout::TyAndLayout;
+use rustc_middle::ty::{self, Ty, TypeAndMut, TypeFoldable};
+use rustc_span::symbol::sym;
+use rustc_target::abi::{LayoutOf, Size, Variants};
 
 impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     pub fn cast(
@@ -21,7 +19,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         kind: CastKind,
         dest: PlaceTy<'tcx, M::PointerTag>,
     ) -> InterpResult<'tcx> {
-        use rustc::mir::CastKind::*;
+        use rustc_middle::mir::CastKind::*;
         match kind {
             Pointer(PointerCast::Unsize) => {
                 self.unsize_into(src, dest)?;
@@ -102,9 +100,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     fn cast_immediate(
         &self,
         src: ImmTy<'tcx, M::PointerTag>,
-        dest_layout: TyLayout<'tcx>,
+        dest_layout: TyAndLayout<'tcx>,
     ) -> InterpResult<'tcx, Immediate<M::PointerTag>> {
-        use rustc::ty::TyKind::*;
+        use rustc_middle::ty::TyKind::*;
         trace!("Casting {:?}: {:?} to {:?}", *src, src.layout.ty, dest_layout.ty);
 
         match src.layout.ty.kind {
@@ -134,7 +132,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
         // 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)?;
@@ -143,7 +141,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                         .into());
                 }
             }
-            layout::Variants::Multiple { .. } => {}
+            Variants::Multiple { .. } => {}
         }
 
         // Handle casting the metadata away from a fat pointer.
@@ -183,14 +181,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     fn cast_from_int_like(
         &self,
         v: u128, // raw bits
-        src_layout: TyLayout<'tcx>,
-        dest_layout: TyLayout<'tcx>,
+        src_layout: TyAndLayout<'tcx>,
+        dest_layout: TyAndLayout<'tcx>,
     ) -> InterpResult<'tcx, Scalar<M::PointerTag>> {
         // Let's make sure v is sign-extended *if* it has a signed type.
         let signed = src_layout.abi.is_signed();
         let v = if signed { self.sign_extend(v, src_layout) } else { v };
         trace!("cast_from_int: {}, {}, {}", v, src_layout.ty, dest_layout.ty);
-        use rustc::ty::TyKind::*;
+        use rustc_middle::ty::TyKind::*;
         match dest_layout.ty.kind {
             Int(_) | Uint(_) | RawPtr(_) => {
                 let v = self.truncate(v, dest_layout);
@@ -224,7 +222,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     where
         F: Float + Into<Scalar<M::PointerTag>> + FloatConvert<Single> + FloatConvert<Double>,
     {
-        use rustc::ty::TyKind::*;
+        use rustc_middle::ty::TyKind::*;
         match dest_ty.kind {
             // float -> uint
             Uint(t) => {
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index c2baabf4233..10d3101ebb8 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -2,22 +2,23 @@ use std::cell::Cell;
 use std::fmt::Write;
 use std::mem;
 
-use rustc::ich::StableHashingContext;
-use rustc::mir;
-use rustc::mir::interpret::{
-    sign_extend, truncate, AllocId, FrameInfo, GlobalId, InterpResult, Pointer, Scalar,
-};
-use rustc::ty::layout::{self, Align, HasDataLayout, LayoutOf, Size, TyLayout};
-use rustc::ty::query::TyCtxtAt;
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_index::vec::IndexVec;
 use rustc_macros::HashStable;
-use rustc_span::source_map::{self, Span, DUMMY_SP};
+use rustc_middle::ich::StableHashingContext;
+use rustc_middle::mir;
+use rustc_middle::mir::interpret::{
+    sign_extend, truncate, AllocId, FrameInfo, GlobalId, InterpResult, Pointer, Scalar,
+};
+use rustc_middle::ty::layout::{self, TyAndLayout};
+use rustc_middle::ty::query::TyCtxtAt;
+use rustc_middle::ty::subst::SubstsRef;
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
+use rustc_span::source_map::DUMMY_SP;
+use rustc_target::abi::{Abi, Align, HasDataLayout, LayoutOf, Size, TargetDataLayout};
 
 use super::{
     Immediate, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, OpTy, Operand, Place, PlaceTy,
@@ -57,9 +58,6 @@ pub struct Frame<'mir, 'tcx, Tag = (), Extra = ()> {
     /// The def_id and substs of the current function.
     pub instance: ty::Instance<'tcx>,
 
-    /// The span of the call site.
-    pub span: source_map::Span,
-
     /// Extra data for the machine.
     pub extra: Extra,
 
@@ -114,7 +112,7 @@ pub struct LocalState<'tcx, Tag = (), Id = AllocId> {
     pub value: LocalValue<Tag, Id>,
     /// Don't modify if `Some`, this is only used to prevent computing the layout twice
     #[stable_hasher(ignore)]
-    pub layout: Cell<Option<TyLayout<'tcx>>>,
+    pub layout: Cell<Option<TyAndLayout<'tcx>>>,
 }
 
 /// Current value of a local variable
@@ -176,7 +174,7 @@ impl<'mir, 'tcx, Tag, Extra> Frame<'mir, 'tcx, Tag, Extra> {
 
 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
     }
 }
@@ -202,16 +200,63 @@ where
 
 impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for InterpCx<'mir, 'tcx, M> {
     type Ty = Ty<'tcx>;
-    type TyLayout = InterpResult<'tcx, TyLayout<'tcx>>;
+    type TyAndLayout = InterpResult<'tcx, TyAndLayout<'tcx>>;
 
     #[inline]
-    fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
+    fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout {
         self.tcx
             .layout_of(self.param_env.and(ty))
             .map_err(|layout| err_inval!(Layout(layout)).into())
     }
 }
 
+/// 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>(
+    src: TyAndLayout<'tcx>,
+    dest: TyAndLayout<'tcx>,
+) -> bool {
+    if src.ty == dest.ty {
+        // Equal types, all is good.
+        return true;
+    }
+    // Type-changing assignments can happen for (at least) two reasons:
+    // - `&mut T` -> `&T` gets optimized from a reborrow to a mere assignment.
+    // - Subtyping is used. While all normal lifetimes are erased, higher-ranked lifetime
+    //   bounds are still around and can lead to type differences.
+    // There is no good way to check the latter, so we compare layouts instead -- but only
+    // for values with `Scalar`/`ScalarPair` abi.
+    // FIXME: Do something more accurate, type-based.
+    match &src.abi {
+        Abi::Scalar(..) | Abi::ScalarPair(..) => src.layout == dest.layout,
+        _ => false,
+    }
+}
+
+/// 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>(
+    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(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>,
@@ -284,13 +329,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     }
 
     #[inline(always)]
-    pub fn sign_extend(&self, value: u128, ty: TyLayout<'_>) -> u128 {
+    pub fn sign_extend(&self, value: u128, ty: TyAndLayout<'_>) -> u128 {
         assert!(ty.abi.is_signed());
         sign_extend(value, ty.size)
     }
 
     #[inline(always)]
-    pub fn truncate(&self, value: u128, ty: TyLayout<'_>) -> u128 {
+    pub fn truncate(&self, value: u128, ty: TyAndLayout<'_>) -> u128 {
         truncate(value, ty.size)
     }
 
@@ -373,13 +418,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         &self,
         frame: &Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>,
         local: mir::Local,
-        layout: Option<TyLayout<'tcx>>,
-    ) -> InterpResult<'tcx, TyLayout<'tcx>> {
+        layout: Option<TyAndLayout<'tcx>>,
+    ) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
         // `const_prop` runs into this with an invalid (empty) frame, so we
         // 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(layout, || {
                     let local_ty = frame.body.local_decls[local].ty;
                     let local_ty =
                         self.subst_from_frame_and_normalize_erasing_regions(frame, local_ty);
@@ -401,7 +446,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     pub(super) fn size_and_align_of(
         &self,
         metadata: MemPlaceMeta<M::PointerTag>,
-        layout: TyLayout<'tcx>,
+        layout: TyAndLayout<'tcx>,
     ) -> InterpResult<'tcx, Option<(Size, Align)>> {
         if !layout.is_unsized() {
             return Ok(Some((layout.size, layout.align.abi)));
@@ -502,7 +547,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     pub fn push_stack_frame(
         &mut self,
         instance: ty::Instance<'tcx>,
-        span: Span,
         body: &'mir mir::Body<'tcx>,
         return_place: Option<PlaceTy<'tcx, M::PointerTag>>,
         return_to_block: StackPopCleanup,
@@ -522,7 +566,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             // empty local array, we fill it in below, after we are inside the stack frame and
             // all methods actually know about the frame
             locals: IndexVec::new(),
-            span,
             instance,
             stmt: 0,
             extra,
@@ -541,10 +584,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 // statics and constants don't have `Storage*` statements, no need to look for them
                 Some(DefKind::Static) | Some(DefKind::Const) | Some(DefKind::AssocConst) => {}
                 _ => {
-                    trace!("push_stack_frame: {:?}: num_bbs: {}", span, body.basic_blocks().len());
                     for block in body.basic_blocks() {
                         for stmt in block.statements.iter() {
-                            use rustc::mir::StatementKind::{StorageDead, StorageLive};
+                            use rustc_middle::mir::StatementKind::{StorageDead, StorageLive};
                             match stmt.kind {
                                 StorageLive(local) | StorageDead(local) => {
                                     locals[local].value = LocalValue::Dead;
@@ -859,33 +901,21 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         }
     }
 
-    pub fn generate_stacktrace(&self, explicit_span: Option<Span>) -> Vec<FrameInfo<'tcx>> {
-        let mut last_span = None;
+    pub fn generate_stacktrace(&self) -> Vec<FrameInfo<'tcx>> {
         let mut frames = Vec::new();
         for frame in self.stack().iter().rev() {
-            // make sure we don't emit frames that are duplicates of the previous
-            if explicit_span == Some(frame.span) {
-                last_span = Some(frame.span);
-                continue;
-            }
-            if let Some(last) = last_span {
-                if last == frame.span {
-                    continue;
-                }
-            } else {
-                last_span = Some(frame.span);
-            }
-
-            let lint_root = frame.current_source_info().and_then(|source_info| {
+            let source_info = frame.current_source_info();
+            let lint_root = source_info.and_then(|source_info| {
                 match &frame.body.source_scopes[source_info.scope].local_data {
                     mir::ClearCrossCrate::Set(data) => Some(data.lint_root),
                     mir::ClearCrossCrate::Clear => None,
                 }
             });
+            let span = source_info.map_or(DUMMY_SP, |source_info| source_info.span);
 
-            frames.push(FrameInfo { call_site: frame.span, instance: frame.instance, lint_root });
+            frames.push(FrameInfo { span, instance: frame.instance, lint_root });
         }
-        trace!("generate stacktrace: {:#?}, {:?}", frames, explicit_span);
+        trace!("generate stacktrace: {:#?}", frames);
         frames
     }
 }
@@ -899,7 +929,6 @@ where
     fn hash_stable(&self, hcx: &mut StableHashingContext<'ctx>, hasher: &mut StableHasher) {
         self.body.hash_stable(hcx, hasher);
         self.instance.hash_stable(hcx, hasher);
-        self.span.hash_stable(hcx, hasher);
         self.return_to_block.hash_stable(hcx, hasher);
         self.return_place.as_ref().map(|r| &**r).hash_stable(hcx, hasher);
         self.locals.hash_stable(hcx, hasher);
diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index b9ed69842f1..af415b3837f 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -4,10 +4,10 @@
 //! memory, we need to extract all memory allocations to the global memory pool so they stay around.
 
 use super::validity::RefTracking;
-use rustc::mir::interpret::{ErrorHandled, InterpResult};
-use rustc::ty::{self, Ty};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
+use rustc_middle::mir::interpret::{ErrorHandled, InterpResult};
+use rustc_middle::ty::{self, Ty};
 
 use rustc_ast::ast::Mutability;
 
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index 46f8e98ef34..d976df82577 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -4,18 +4,17 @@
 
 use std::convert::TryFrom;
 
-use rustc::mir::{
+use rustc_hir::def_id::DefId;
+use rustc_middle::mir::{
     self,
     interpret::{ConstValue, GlobalId, InterpResult, Scalar},
     BinOp,
 };
-use rustc::ty;
-use rustc::ty::layout::{LayoutOf, Primitive, Size};
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::TyCtxt;
-use rustc_hir::def_id::DefId;
+use rustc_middle::ty;
+use rustc_middle::ty::subst::SubstsRef;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::{sym, Symbol};
-use rustc_span::Span;
+use rustc_target::abi::{Abi, LayoutOf as _, Primitive, Size};
 
 use super::{ImmTy, InterpCx, Machine, OpTy, PlaceTy};
 
@@ -78,7 +77,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     /// Returns `true` if emulation happened.
     pub fn emulate_intrinsic(
         &mut self,
-        span: Span,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx, M::PointerTag>],
         ret: Option<(PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
@@ -98,10 +96,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         };
 
         // Keep the patterns in this match ordered the same as the list in
-        // `src/librustc/ty/constness.rs`
+        // `src/librustc_middle/ty/constness.rs`
         match intrinsic_name {
             sym::caller_location => {
-                let span = self.find_closest_untracked_caller_location().unwrap_or(span);
+                let span = self.find_closest_untracked_caller_location();
                 let location = self.alloc_caller_location_for_span(span);
                 self.write_scalar(location.ptr, dest)?;
             }
@@ -118,7 +116,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     sym::needs_drop => self.tcx.types.bool,
                     sym::type_id => self.tcx.types.u64,
                     sym::type_name => self.tcx.mk_static_str(),
-                    _ => span_bug!(span, "Already checked for nullary intrinsics"),
+                    _ => bug!("already checked for nullary intrinsics"),
                 };
                 let val = self.const_eval(gid, ty)?;
                 self.copy_op(val, dest)?;
@@ -136,7 +134,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 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 01f9cdea0f0..754f45d9ec0 100644
--- a/src/librustc_mir/interpret/intrinsics/caller_location.rs
+++ b/src/librustc_mir/interpret/intrinsics/caller_location.rs
@@ -1,7 +1,7 @@
 use std::convert::TryFrom;
 
-use rustc::middle::lang_items::PanicLocationLangItem;
-use rustc::ty::subst::Subst;
+use rustc_hir::lang_items::PanicLocationLangItem;
+use rustc_middle::ty::subst::Subst;
 use rustc_span::{Span, Symbol};
 use rustc_target::abi::LayoutOf;
 
@@ -12,18 +12,21 @@ use crate::interpret::{
 
 impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     /// Walks up the callstack from the intrinsic's callsite, searching for the first callsite in a
-    /// frame which is not `#[track_caller]`. If the first frame found lacks `#[track_caller]`, then
-    /// `None` is returned and the callsite of the function invocation itself should be used.
-    crate fn find_closest_untracked_caller_location(&self) -> Option<Span> {
-        let mut caller_span = None;
-        for next_caller in self.stack.iter().rev() {
-            if !next_caller.instance.def.requires_caller_location(*self.tcx) {
-                return caller_span;
-            }
-            caller_span = Some(next_caller.span);
-        }
-
-        caller_span
+    /// frame which is not `#[track_caller]`.
+    crate fn find_closest_untracked_caller_location(&self) -> Span {
+        self.stack
+            .iter()
+            .rev()
+            // Find first non-`#[track_caller]` frame.
+            .find(|frame| !frame.instance.def.requires_caller_location(*self.tcx))
+            // Assert that there is always such a frame.
+            .unwrap()
+            .current_source_info()
+            // Assert that the frame we look at is actually executing code currently
+            // (`current_source_info` is None when we are unwinding and the frame does
+            // not require cleanup).
+            .unwrap()
+            .span
     }
 
     /// Allocate a `const core::panic::Location` with the provided filename and line/column numbers.
diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs
index 0d9582c7323..b81a454cac4 100644
--- a/src/librustc_mir/interpret/intrinsics/type_name.rs
+++ b/src/librustc_mir/interpret/intrinsics/type_name.rs
@@ -1,12 +1,12 @@
-use rustc::mir::interpret::Allocation;
-use rustc::ty::{
+use rustc_hir::def_id::CrateNum;
+use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
+use rustc_middle::mir::interpret::Allocation;
+use rustc_middle::ty::{
     self,
     print::{PrettyPrinter, Print, Printer},
     subst::{GenericArg, GenericArgKind},
     Ty, TyCtxt,
 };
-use rustc_hir::def_id::CrateNum;
-use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
 use std::fmt::Write;
 
 struct AbsolutePathPrinter<'tcx> {
@@ -129,9 +129,8 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
         self = print_prefix(self)?;
 
         // Skip `::{{constructor}}` on tuple/unit structs.
-        match disambiguated_data.data {
-            DefPathData::Ctor => return Ok(self),
-            _ => {}
+        if disambiguated_data.data == DefPathData::Ctor {
+            return Ok(self);
         }
 
         self.path.push_str("::");
diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs
index 74933bed8f8..48082a1e346 100644
--- a/src/librustc_mir/interpret/machine.rs
+++ b/src/librustc_mir/interpret/machine.rs
@@ -5,9 +5,9 @@
 use std::borrow::{Borrow, Cow};
 use std::hash::Hash;
 
-use rustc::mir;
-use rustc::ty::{self, Ty};
-use rustc_span::{def_id::DefId, Span};
+use rustc_middle::mir;
+use rustc_middle::ty::{self, Ty};
+use rustc_span::def_id::DefId;
 
 use super::{
     AllocId, Allocation, AllocationExtra, Frame, ImmTy, InterpCx, InterpResult, Memory, MemoryKind,
@@ -135,7 +135,6 @@ pub trait Machine<'mir, 'tcx>: Sized {
     /// was used.
     fn find_mir_or_eval_fn(
         ecx: &mut InterpCx<'mir, 'tcx, Self>,
-        span: Span,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx, Self::PointerTag>],
         ret: Option<(PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
@@ -156,7 +155,6 @@ pub trait Machine<'mir, 'tcx>: Sized {
     /// responsibility to advance the instruction pointer as appropriate.
     fn call_intrinsic(
         ecx: &mut InterpCx<'mir, 'tcx, Self>,
-        span: Span,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx, Self::PointerTag>],
         ret: Option<(PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 4b68d74feb1..04a927c69a6 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -11,11 +11,10 @@ use std::collections::VecDeque;
 use std::convert::TryFrom;
 use std::ptr;
 
-use rustc::ty::layout::{Align, HasDataLayout, Size, TargetDataLayout};
-use rustc::ty::{self, query::TyCtxtAt, Instance, ParamEnv};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-
 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 3063a99886b..fb59a177b97 100644
--- a/src/librustc_mir/interpret/mod.rs
+++ b/src/librustc_mir/interpret/mod.rs
@@ -15,22 +15,16 @@ mod traits;
 mod validity;
 mod visitor;
 
-pub use rustc::mir::interpret::*; // have all the `interpret` symbols in one place: here
+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::visitor::{MutValueVisitor, ValueVisitor};
-
+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::intern::{intern_const_alloc_recursive, InternKind};
+pub use self::visitor::{MutValueVisitor, ValueVisitor};
 
 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 1ffe6a87302..12595e4e4d9 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};
-pub use rustc::mir::interpret::ScalarMaybeUndef;
-use rustc::mir::interpret::{
-    sign_extend, truncate, AllocId, ConstValue, GlobalId, InterpResult, Pointer, Scalar,
-};
-use rustc::ty::layout::{
-    self, HasDataLayout, IntegerExt, LayoutOf, PrimitiveExt, Size, TyLayout, VariantIdx,
-};
-use rustc::ty::print::{FmtPrinter, PrettyPrinter, Printer};
-use rustc::ty::Ty;
-use rustc::{mir, ty};
 use rustc_hir::def::Namespace;
 use rustc_macros::HashStable;
-use std::fmt::Write;
+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 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.
 ///
@@ -88,7 +88,7 @@ impl<'tcx, Tag> Immediate<Tag> {
 #[derive(Copy, Clone, Debug)]
 pub struct ImmTy<'tcx, Tag = ()> {
     pub(crate) imm: Immediate<Tag>,
-    pub layout: TyLayout<'tcx>,
+    pub layout: TyAndLayout<'tcx>,
 }
 
 impl<Tag: Copy> std::fmt::Display for ImmTy<'tcx, Tag> {
@@ -152,7 +152,7 @@ pub enum Operand<Tag = (), Id = AllocId> {
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 pub struct OpTy<'tcx, Tag = ()> {
     op: Operand<Tag>, // Keep this private; it helps enforce invariants.
-    pub layout: TyLayout<'tcx>,
+    pub layout: TyAndLayout<'tcx>,
 }
 
 impl<'tcx, Tag> ::std::ops::Deref for OpTy<'tcx, Tag> {
@@ -179,53 +179,30 @@ impl<'tcx, Tag> From<ImmTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
 
 impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> {
     #[inline]
-    pub fn from_scalar(val: Scalar<Tag>, layout: TyLayout<'tcx>) -> Self {
+    pub fn from_scalar(val: Scalar<Tag>, layout: TyAndLayout<'tcx>) -> Self {
         ImmTy { imm: val.into(), layout }
     }
 
     #[inline]
-    pub fn try_from_uint(i: impl Into<u128>, layout: TyLayout<'tcx>) -> Option<Self> {
+    pub fn try_from_uint(i: impl Into<u128>, layout: TyAndLayout<'tcx>) -> Option<Self> {
         Some(Self::from_scalar(Scalar::try_from_uint(i, layout.size)?, layout))
     }
     #[inline]
-    pub fn from_uint(i: impl Into<u128>, layout: TyLayout<'tcx>) -> Self {
+    pub fn from_uint(i: impl Into<u128>, layout: TyAndLayout<'tcx>) -> Self {
         Self::from_scalar(Scalar::from_uint(i, layout.size), layout)
     }
 
     #[inline]
-    pub fn try_from_int(i: impl Into<i128>, layout: TyLayout<'tcx>) -> Option<Self> {
+    pub fn try_from_int(i: impl Into<i128>, layout: TyAndLayout<'tcx>) -> Option<Self> {
         Some(Self::from_scalar(Scalar::try_from_int(i, layout.size)?, layout))
     }
 
     #[inline]
-    pub fn from_int(i: impl Into<i128>, layout: TyLayout<'tcx>) -> Self {
+    pub fn from_int(i: impl Into<i128>, layout: TyAndLayout<'tcx>) -> Self {
         Self::from_scalar(Scalar::from_int(i, layout.size), layout)
     }
 }
 
-// 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<TyLayout<'tcx>>,
-    compute: impl FnOnce() -> InterpResult<'tcx, TyLayout<'tcx>>,
-) -> InterpResult<'tcx, TyLayout<'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 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         };
 
         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 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 )?;
                 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.
@@ -415,7 +392,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         base: OpTy<'tcx, M::PointerTag>,
         proj_elem: &mir::PlaceElem<'tcx>,
     ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
-        use rustc::mir::ProjectionElem::*;
+        use rustc_middle::mir::ProjectionElem::*;
         Ok(match *proj_elem {
             Field(field, _) => self.operand_field(base, field.index())?,
             Downcast(_, variant) => self.operand_downcast(base, variant)?,
@@ -434,7 +411,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         &self,
         frame: &super::Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>,
         local: mir::Local,
-        layout: Option<TyLayout<'tcx>>,
+        layout: Option<TyAndLayout<'tcx>>,
     ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
         assert_ne!(local, mir::RETURN_PLACE);
         let layout = self.layout_of_local(frame, local, layout)?;
@@ -464,8 +441,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     // avoid allocations.
     pub fn eval_place_to_op(
         &self,
-        place: &mir::Place<'tcx>,
-        layout: Option<TyLayout<'tcx>>,
+        place: mir::Place<'tcx>,
+        layout: Option<TyAndLayout<'tcx>>,
     ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
         let base_op = match place.local {
             mir::RETURN_PLACE => throw_ub!(ReadFromReturnPlace),
@@ -493,12 +470,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     pub fn eval_operand(
         &self,
         mir_op: &mir::Operand<'tcx>,
-        layout: Option<TyLayout<'tcx>>,
+        layout: Option<TyAndLayout<'tcx>>,
     ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
-        use rustc::mir::Operand::*;
+        use rustc_middle::mir::Operand::*;
         let op = match *mir_op {
             // FIXME: do some more logic on `move` to invalidate the old location
-            Copy(ref place) | Move(ref place) => self.eval_place_to_op(place, layout)?,
+            Copy(place) | Move(place) => self.eval_place_to_op(place, layout)?,
 
             Constant(ref constant) => {
                 let val =
@@ -525,7 +502,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     crate fn eval_const_to_op(
         &self,
         val: &ty::Const<'tcx>,
-        layout: Option<TyLayout<'tcx>>,
+        layout: Option<TyAndLayout<'tcx>>,
     ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
         let tag_scalar = |scalar| match scalar {
             Scalar::Ptr(ptr) => Scalar::Ptr(self.tag_global_base_pointer(ptr)),
@@ -587,7 +564,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         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 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     .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 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         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 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                         .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 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 .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 cb0aaa4d40d..0aa7e98f3ed 100644
--- a/src/librustc_mir/interpret/operator.rs
+++ b/src/librustc_mir/interpret/operator.rs
@@ -1,14 +1,11 @@
 use std::convert::TryFrom;
 
-use rustc::mir;
-use rustc::mir::interpret::{InterpResult, Scalar};
-use rustc::ty::{
-    self,
-    layout::{LayoutOf, TyLayout},
-    Ty,
-};
 use rustc_apfloat::Float;
 use rustc_ast::ast::FloatTy;
+use rustc_middle::mir;
+use rustc_middle::mir::interpret::{InterpResult, Scalar};
+use rustc_middle::ty::{self, layout::TyAndLayout, Ty};
+use rustc_target::abi::LayoutOf;
 
 use super::{ImmTy, Immediate, InterpCx, Machine, PlaceTy};
 
@@ -55,7 +52,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         l: char,
         r: char,
     ) -> (Scalar<M::PointerTag>, bool, Ty<'tcx>) {
-        use rustc::mir::BinOp::*;
+        use rustc_middle::mir::BinOp::*;
 
         let res = match bin_op {
             Eq => l == r,
@@ -75,7 +72,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         l: bool,
         r: bool,
     ) -> (Scalar<M::PointerTag>, bool, Ty<'tcx>) {
-        use rustc::mir::BinOp::*;
+        use rustc_middle::mir::BinOp::*;
 
         let res = match bin_op {
             Eq => l == r,
@@ -99,7 +96,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         l: F,
         r: F,
     ) -> (Scalar<M::PointerTag>, bool, Ty<'tcx>) {
-        use rustc::mir::BinOp::*;
+        use rustc_middle::mir::BinOp::*;
 
         let (val, ty) = match bin_op {
             Eq => (Scalar::from_bool(l == r), self.tcx.types.bool),
@@ -123,11 +120,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         bin_op: mir::BinOp,
         // passing in raw bits
         l: u128,
-        left_layout: TyLayout<'tcx>,
+        left_layout: TyAndLayout<'tcx>,
         r: u128,
-        right_layout: TyLayout<'tcx>,
+        right_layout: TyAndLayout<'tcx>,
     ) -> InterpResult<'tcx, (Scalar<M::PointerTag>, bool, Ty<'tcx>)> {
-        use rustc::mir::BinOp::*;
+        use rustc_middle::mir::BinOp::*;
 
         // Shift ops can have an RHS with a different numeric type.
         if bin_op == Shl || bin_op == Shr {
@@ -198,13 +195,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 // We need a special check for overflowing remainder:
                 // "int_min % -1" overflows and returns 0, but after casting things to a larger int
                 // type it does *not* overflow nor give an unrepresentable result!
-                match bin_op {
-                    Rem => {
-                        if r == -1 && l == (1 << (size.bits() - 1)) {
-                            return Ok((Scalar::from_int(0, size), true, left_layout.ty));
-                        }
+                if bin_op == Rem {
+                    if r == -1 && l == (1 << (size.bits() - 1)) {
+                        return Ok((Scalar::from_int(0, size), true, left_layout.ty));
                     }
-                    _ => {}
                 }
                 let l = self.sign_extend(l, left_layout) as i128;
 
@@ -362,7 +356,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         un_op: mir::UnOp,
         val: ImmTy<'tcx, M::PointerTag>,
     ) -> InterpResult<'tcx, (Scalar<M::PointerTag>, bool, Ty<'tcx>)> {
-        use rustc::mir::UnOp::*;
+        use rustc_middle::mir::UnOp::*;
 
         let layout = val.layout;
         let val = val.to_scalar()?;
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 915cffa3321..ec299cdd213 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -5,18 +5,17 @@
 use std::convert::TryFrom;
 use std::hash::Hash;
 
-use rustc::mir;
-use rustc::mir::interpret::truncate;
-use rustc::ty::layout::{
-    self, Align, HasDataLayout, LayoutOf, PrimitiveExt, Size, TyLayout, VariantIdx,
-};
-use rustc::ty::{self, Ty};
 use rustc_macros::HashStable;
+use rustc_middle::mir;
+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)]
@@ -86,7 +85,7 @@ pub enum Place<Tag = (), Id = AllocId> {
 #[derive(Copy, Clone, Debug)]
 pub struct PlaceTy<'tcx, Tag = ()> {
     place: Place<Tag>, // Keep this private; it helps enforce invariants.
-    pub layout: TyLayout<'tcx>,
+    pub layout: TyAndLayout<'tcx>,
 }
 
 impl<'tcx, Tag> ::std::ops::Deref for PlaceTy<'tcx, Tag> {
@@ -101,7 +100,7 @@ impl<'tcx, Tag> ::std::ops::Deref for PlaceTy<'tcx, Tag> {
 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
 pub struct MPlaceTy<'tcx, Tag = ()> {
     mplace: MemPlace<Tag>,
-    pub layout: TyLayout<'tcx>,
+    pub layout: TyAndLayout<'tcx>,
 }
 
 impl<'tcx, Tag> ::std::ops::Deref for MPlaceTy<'tcx, Tag> {
@@ -178,7 +177,7 @@ impl<Tag> MemPlace<Tag> {
 impl<'tcx, Tag> MPlaceTy<'tcx, Tag> {
     /// Produces a MemPlace that works for ZST but nothing else
     #[inline]
-    pub fn dangling(layout: TyLayout<'tcx>, cx: &impl HasDataLayout) -> Self {
+    pub fn dangling(layout: TyAndLayout<'tcx>, cx: &impl HasDataLayout) -> Self {
         let align = layout.align.abi;
         let ptr = Scalar::from_machine_usize(align.bytes(), cx);
         // `Poison` this to make sure that the pointer value `ptr` is never observable by the program.
@@ -196,14 +195,14 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> {
         self,
         offset: Size,
         meta: MemPlaceMeta<Tag>,
-        layout: TyLayout<'tcx>,
+        layout: TyAndLayout<'tcx>,
         cx: &impl HasDataLayout,
     ) -> InterpResult<'tcx, Self> {
         Ok(MPlaceTy { mplace: self.mplace.offset(offset, meta, cx)?, layout })
     }
 
     #[inline]
-    fn from_aligned_ptr(ptr: Pointer<Tag>, layout: TyLayout<'tcx>) -> Self {
+    fn from_aligned_ptr(ptr: Pointer<Tag>, layout: TyAndLayout<'tcx>) -> Self {
         MPlaceTy { mplace: MemPlace::from_ptr(ptr, layout.align.abi), layout }
     }
 
@@ -219,7 +218,7 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> {
             // Go through the layout.  There are lots of types that support a length,
             // e.g., SIMD types.
             match self.layout.fields {
-                layout::FieldPlacement::Array { count, .. } => Ok(count),
+                FieldsShape::Array { count, .. } => Ok(count),
                 _ => bug!("len not supported on sized type {:?}", self.layout.ty),
             }
         }
@@ -437,7 +436,7 @@ where
     ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
         // Not using the layout method because we want to compute on u64
         match base.layout.fields {
-            layout::FieldPlacement::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 @@ where
     {
         let len = base.len(self)?; // also asserts that we have a type where this makes sense
         let stride = match base.layout.fields {
-            layout::FieldPlacement::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 @@ where
         // 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::FieldPlacement::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),
         };
 
@@ -529,7 +528,7 @@ where
         base: MPlaceTy<'tcx, M::PointerTag>,
         proj_elem: &mir::PlaceElem<'tcx>,
     ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
-        use rustc::mir::ProjectionElem::*;
+        use rustc_middle::mir::ProjectionElem::*;
         Ok(match *proj_elem {
             Field(field, _) => self.mplace_field(base, field.index())?,
             Downcast(_, variant) => self.mplace_downcast(base, variant)?,
@@ -617,7 +616,7 @@ where
         base: PlaceTy<'tcx, M::PointerTag>,
         proj_elem: &mir::ProjectionElem<mir::Local, Ty<'tcx>>,
     ) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
-        use rustc::mir::ProjectionElem::*;
+        use rustc_middle::mir::ProjectionElem::*;
         Ok(match *proj_elem {
             Field(field, _) => self.place_field(base, field.index())?,
             Downcast(_, variant) => self.place_downcast(base, variant)?,
@@ -635,7 +634,7 @@ where
     /// place; for reading, a more efficient alternative is `eval_place_for_read`.
     pub fn eval_place(
         &mut self,
-        place: &mir::Place<'tcx>,
+        place: mir::Place<'tcx>,
     ) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
         let mut place_ty = match place.local {
             mir::RETURN_PLACE => {
@@ -802,7 +801,7 @@ where
         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 @@ where
                 // 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 @@ where
         // 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(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 @@ where
         src: OpTy<'tcx, M::PointerTag>,
         dest: PlaceTy<'tcx, M::PointerTag>,
     ) -> InterpResult<'tcx> {
-        if src.layout.layout == dest.layout.layout {
+        if mir_assign_valid_types(src.layout, dest.layout) {
             // Fast path: Just use normal `copy_op`
             return self.copy_op(src, dest);
         }
@@ -1030,7 +1029,7 @@ where
 
     pub fn allocate(
         &mut self,
-        layout: TyLayout<'tcx>,
+        layout: TyAndLayout<'tcx>,
         kind: MemoryKind<M::MemoryKind>,
     ) -> MPlaceTy<'tcx, M::PointerTag> {
         let ptr = self.memory.allocate(layout.size, layout.align.abi, kind);
@@ -1067,17 +1066,17 @@ where
         }
 
         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,
                 ..
             } => {
                 // No need to validate that the discriminant here because the
-                // `TyLayout::for_variant()` call earlier already checks the variant is valid.
+                // `TyAndLayout::for_variant()` call earlier already checks the variant is valid.
 
                 let discr_val =
                     dest.layout.ty.discriminant_for_variant(*self.tcx, variant_index).unwrap().val;
@@ -1091,15 +1090,15 @@ where
                 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,
                 ..
             } => {
                 // No need to validate that the discriminant here because the
-                // `TyLayout::for_variant()` call earlier already checks the variant is valid.
+                // `TyAndLayout::for_variant()` call earlier already checks the variant is valid.
 
                 if variant_index != dataful_variant {
                     let variants_start = niche_variants.start().as_u32();
diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs
index 764edea2fc5..407849c2ce2 100644
--- a/src/librustc_mir/interpret/step.rs
+++ b/src/librustc_mir/interpret/step.rs
@@ -2,9 +2,9 @@
 //!
 //! The main entry point is the `step` method.
 
-use rustc::mir;
-use rustc::mir::interpret::{InterpResult, Scalar};
-use rustc::ty::layout::LayoutOf;
+use rustc_middle::mir;
+use rustc_middle::mir::interpret::{InterpResult, Scalar};
+use rustc_target::abi::LayoutOf;
 
 use super::{InterpCx, Machine};
 
@@ -12,7 +12,7 @@ use super::{InterpCx, Machine};
 /// same type as the result.
 #[inline]
 fn binop_left_homogeneous(op: mir::BinOp) -> bool {
-    use rustc::mir::BinOp::*;
+    use rustc_middle::mir::BinOp::*;
     match op {
         Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Offset | Shl | Shr => true,
         Eq | Ne | Lt | Le | Gt | Ge => false,
@@ -22,7 +22,7 @@ fn binop_left_homogeneous(op: mir::BinOp) -> bool {
 /// same type as the LHS.
 #[inline]
 fn binop_right_homogeneous(op: mir::BinOp) -> bool {
-    use rustc::mir::BinOp::*;
+    use rustc_middle::mir::BinOp::*;
     match op {
         Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Eq | Ne | Lt | Le | Gt | Ge => true,
         Offset | Shl | Shr => false,
@@ -79,7 +79,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> InterpResult<'tcx> {
         info!("{:?}", stmt);
 
-        use rustc::mir::StatementKind::*;
+        use rustc_middle::mir::StatementKind::*;
 
         // Some statements (e.g., box) push new stack frames.
         // We have to record the stack frame number *before* executing the statement.
@@ -87,23 +87,23 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         self.tcx.span = stmt.source_info.span;
         self.memory.tcx.span = stmt.source_info.span;
 
-        match stmt.kind {
-            Assign(box (ref place, ref rvalue)) => self.eval_rvalue_into_place(rvalue, place)?,
+        match &stmt.kind {
+            Assign(box (place, rvalue)) => self.eval_rvalue_into_place(rvalue, *place)?,
 
-            SetDiscriminant { ref place, variant_index } => {
-                let dest = self.eval_place(place)?;
-                self.write_discriminant_index(variant_index, dest)?;
+            SetDiscriminant { place, variant_index } => {
+                let dest = self.eval_place(**place)?;
+                self.write_discriminant_index(*variant_index, dest)?;
             }
 
             // Mark locals as alive
             StorageLive(local) => {
-                let old_val = self.storage_live(local)?;
+                let old_val = self.storage_live(*local)?;
                 self.deallocate_local(old_val)?;
             }
 
             // Mark locals as dead
             StorageDead(local) => {
-                let old_val = self.storage_dead(local);
+                let old_val = self.storage_dead(*local);
                 self.deallocate_local(old_val)?;
             }
 
@@ -112,9 +112,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             FakeRead(..) => {}
 
             // Stacked Borrows.
-            Retag(kind, ref place) => {
-                let dest = self.eval_place(place)?;
-                M::retag(self, kind, dest)?;
+            Retag(kind, place) => {
+                let dest = self.eval_place(**place)?;
+                M::retag(self, *kind, dest)?;
             }
 
             // Statements we do not track.
@@ -138,11 +138,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     pub fn eval_rvalue_into_place(
         &mut self,
         rvalue: &mir::Rvalue<'tcx>,
-        place: &mir::Place<'tcx>,
+        place: mir::Place<'tcx>,
     ) -> InterpResult<'tcx> {
         let dest = self.eval_place(place)?;
 
-        use rustc::mir::Rvalue::*;
+        use rustc_middle::mir::Rvalue::*;
         match *rvalue {
             Use(ref operand) => {
                 // Avoid recomputing the layout
@@ -224,7 +224,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 }
             }
 
-            Len(ref place) => {
+            Len(place) => {
                 // FIXME(CTFE): don't allow computing the length of arrays in const eval
                 let src = self.eval_place(place)?;
                 let mplace = self.force_allocation(src)?;
@@ -232,7 +232,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 self.write_scalar(Scalar::from_machine_usize(len, self), dest)?;
             }
 
-            AddressOf(_, ref place) | Ref(_, _, ref place) => {
+            AddressOf(_, place) | Ref(_, _, place) => {
                 let src = self.eval_place(place)?;
                 let place = self.force_allocation(src)?;
                 if place.layout.size.bytes() > 0 {
@@ -261,7 +261,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 self.cast(src, kind, dest)?;
             }
 
-            Discriminant(ref place) => {
+            Discriminant(place) => {
                 let op = self.eval_place_to_op(place, None)?;
                 let discr_val = self.read_discriminant(op)?.0;
                 let size = dest.layout.size;
diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs
index 5ce5ba31a09..8ad743d2b8b 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/src/librustc_mir/interpret/terminator.rs
@@ -1,10 +1,10 @@
 use std::borrow::Cow;
 use std::convert::TryFrom;
 
-use rustc::ty::layout::{self, LayoutOf, TyLayout};
-use rustc::ty::Instance;
-use rustc::{mir, ty};
-use rustc_span::source_map::Span;
+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::{
@@ -16,7 +16,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         &mut self,
         terminator: &mir::Terminator<'tcx>,
     ) -> InterpResult<'tcx> {
-        use rustc::mir::TerminatorKind::*;
+        use rustc_middle::mir::TerminatorKind::*;
         match terminator.kind {
             Return => {
                 self.frame().return_place.map(|r| self.dump_place(*r));
@@ -30,7 +30,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 trace!("SwitchInt({:?})", *discr);
 
                 // Branch to the `otherwise` case by default, if no match is found.
-                assert!(targets.len() > 0);
+                assert!(!targets.is_empty());
                 let mut target_block = targets[targets.len() - 1];
 
                 for (index, &const_int) in values.iter().enumerate() {
@@ -51,7 +51,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 self.go_to_block(target_block);
             }
 
-            Call { ref func, ref args, ref destination, ref cleanup, .. } => {
+            Call { ref func, ref args, destination, ref cleanup, .. } => {
                 let func = self.eval_operand(func, None)?;
                 let (fn_val, abi) = match func.layout.ty.kind {
                     ty::FnPtr(sig) => {
@@ -68,27 +68,20 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 };
                 let args = self.eval_operands(args)?;
                 let ret = match destination {
-                    Some((dest, ret)) => Some((self.eval_place(dest)?, *ret)),
+                    Some((dest, ret)) => Some((self.eval_place(dest)?, ret)),
                     None => None,
                 };
-                self.eval_fn_call(
-                    fn_val,
-                    terminator.source_info.span,
-                    abi,
-                    &args[..],
-                    ret,
-                    *cleanup,
-                )?;
+                self.eval_fn_call(fn_val, abi, &args[..], ret, *cleanup)?;
             }
 
-            Drop { ref location, target, unwind } => {
+            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);
 
                 let instance = Instance::resolve_drop_in_place(*self.tcx, ty);
-                self.drop_in_place(place, instance, terminator.source_info.span, target, unwind)?;
+                self.drop_in_place(place, instance, target, unwind)?;
             }
 
             Assert { ref cond, expected, ref msg, target, cleanup } => {
@@ -134,8 +127,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
     fn check_argument_compat(
         rust_abi: bool,
-        caller: TyLayout<'tcx>,
-        callee: TyLayout<'tcx>,
+        caller: TyAndLayout<'tcx>,
+        callee: TyAndLayout<'tcx>,
     ) -> bool {
         if caller.ty == callee.ty {
             // No question
@@ -150,12 +143,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             // 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,
@@ -196,7 +189,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     fn eval_fn_call(
         &mut self,
         fn_val: FnVal<'tcx, M::ExtraFnVal>,
-        span: Span,
         caller_abi: Abi,
         args: &[OpTy<'tcx, M::PointerTag>],
         ret: Option<(PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
@@ -242,7 +234,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         match instance.def {
             ty::InstanceDef::Intrinsic(..) => {
                 assert!(caller_abi == Abi::RustIntrinsic || caller_abi == Abi::PlatformIntrinsic);
-                M::call_intrinsic(self, span, instance, args, ret, unwind)
+                M::call_intrinsic(self, instance, args, ret, unwind)
             }
             ty::InstanceDef::VtableShim(..)
             | ty::InstanceDef::ReifyShim(..)
@@ -252,14 +244,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             | ty::InstanceDef::CloneShim(..)
             | ty::InstanceDef::Item(_) => {
                 // We need MIR for this fn
-                let body = match M::find_mir_or_eval_fn(self, span, instance, args, ret, unwind)? {
+                let body = match M::find_mir_or_eval_fn(self, instance, args, ret, unwind)? {
                     Some(body) => body,
                     None => return Ok(()),
                 };
 
                 self.push_stack_frame(
                     instance,
-                    span,
                     body,
                     ret.map(|p| p.0),
                     StackPopCleanup::Goto { ret: ret.map(|p| p.1), unwind },
@@ -328,7 +319,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     // `pass_argument` would be the loop body. It takes care to
                     // not advance `caller_iter` for ZSTs.
                     for local in body.args_iter() {
-                        let dest = self.eval_place(&mir::Place::from(local))?;
+                        let dest = self.eval_place(mir::Place::from(local))?;
                         if Some(local) == body.spread_arg {
                             // Must be a tuple
                             for i in 0..dest.layout.fields.count() {
@@ -346,7 +337,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     }
                     // Don't forget to check the return type!
                     if let Some((caller_ret, _)) = ret {
-                        let callee_ret = self.eval_place(&mir::Place::return_place())?;
+                        let callee_ret = self.eval_place(mir::Place::return_place())?;
                         if !Self::check_argument_compat(
                             rust_abi,
                             caller_ret.layout,
@@ -407,7 +398,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     OpTy::from(ImmTy { layout: this_receiver_ptr, imm: receiver_place.ptr.into() });
                 trace!("Patched self operand to {:#?}", args[0]);
                 // recurse with concrete function
-                self.eval_fn_call(drop_fn, span, caller_abi, &args, ret, unwind)
+                self.eval_fn_call(drop_fn, caller_abi, &args, ret, unwind)
             }
         }
     }
@@ -416,7 +407,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         &mut self,
         place: PlaceTy<'tcx, M::PointerTag>,
         instance: ty::Instance<'tcx>,
-        span: Span,
         target: mir::BasicBlock,
         unwind: Option<mir::BasicBlock>,
     ) -> InterpResult<'tcx> {
@@ -444,7 +434,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
         self.eval_fn_call(
             FnVal::Instance(instance),
-            span,
             Abi::Rust,
             &[arg.into()],
             Some((dest.into(), target)),
diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs
index 1e63766b85d..fb9401c7d8f 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::mir::interpret::{InterpResult, Pointer, PointerArithmetic, Scalar};
-use rustc::ty::layout::{Align, HasDataLayout, LayoutOf, Size};
-use rustc::ty::{self, Instance, Ty, TypeFoldable};
+use rustc_middle::mir::interpret::{InterpResult, Pointer, PointerArithmetic, Scalar};
+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 a355a227480..701e394415b 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -8,11 +8,12 @@ use std::convert::TryFrom;
 use std::fmt::Write;
 use std::ops::RangeInclusive;
 
-use rustc::ty;
-use rustc::ty::layout::{self, LayoutOf, TyLayout, VariantIdx};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
+use rustc_middle::ty;
+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;
 
@@ -177,10 +178,10 @@ struct ValidityVisitor<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> {
 }
 
 impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M> {
-    fn aggregate_field_path_elem(&mut self, layout: TyLayout<'tcx>, field: usize) -> PathElem {
+    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 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
                     };
                 }
             }
-            layout::Variants::Single { .. } => {}
+            Variants::Single { .. } => {}
         }
 
         // Now we know we are projecting to a field, so figure out which one.
@@ -226,11 +227,11 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
             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"),
                 }
             }
 
@@ -266,7 +267,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
     fn check_wide_ptr_meta(
         &mut self,
         meta: MemPlaceMeta<M::PointerTag>,
-        pointee: TyLayout<'tcx>,
+        pointee: TyAndLayout<'tcx>,
     ) -> InterpResult<'tcx> {
         let tail = self.ecx.tcx.struct_tail_erasing_lifetimes(pointee.ty, self.ecx.param_env);
         match tail.kind {
@@ -539,7 +540,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
     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 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
         // 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 e8a76264064..e03984f4d0b 100644
--- a/src/librustc_mir/interpret/visitor.rs
+++ b/src/librustc_mir/interpret/visitor.rs
@@ -1,9 +1,10 @@
 //! Visitor for a run-time value with a given layout: Traverse enums, structs and other compound
 //! types until we arrive at the leaves, with custom handling for primitive types.
 
-use rustc::mir::interpret::InterpResult;
-use rustc::ty;
-use rustc::ty::layout::{self, TyLayout, VariantIdx};
+use rustc_middle::mir::interpret::InterpResult;
+use rustc_middle::ty;
+use rustc_middle::ty::layout::TyAndLayout;
+use rustc_target::abi::{FieldsShape, VariantIdx, Variants};
 
 use super::{InterpCx, MPlaceTy, Machine, OpTy};
 
@@ -12,7 +13,7 @@ use super::{InterpCx, MPlaceTy, Machine, OpTy};
 // that's just more convenient to work with (avoids repeating all the `Machine` bounds).
 pub trait Value<'mir, 'tcx, M: Machine<'mir, 'tcx>>: Copy {
     /// Gets this value's layout.
-    fn layout(&self) -> TyLayout<'tcx>;
+    fn layout(&self) -> TyAndLayout<'tcx>;
 
     /// Makes this into an `OpTy`.
     fn to_op(self, ecx: &InterpCx<'mir, 'tcx, M>) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>>;
@@ -36,7 +37,7 @@ pub trait Value<'mir, 'tcx, M: Machine<'mir, 'tcx>>: Copy {
 // Places in general are not due to `place_field` having to do `force_allocation`.
 impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M> for OpTy<'tcx, M::PointerTag> {
     #[inline(always)]
-    fn layout(&self) -> TyLayout<'tcx> {
+    fn layout(&self) -> TyAndLayout<'tcx> {
         self.layout
     }
 
@@ -74,7 +75,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M> for OpTy<'tcx, M::
 
 impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M> for MPlaceTy<'tcx, M::PointerTag> {
     #[inline(always)]
-    fn layout(&self) -> TyLayout<'tcx> {
+    fn layout(&self) -> TyAndLayout<'tcx> {
         self.layout
     }
 
@@ -207,10 +208,10 @@ macro_rules! make_value_visitor {
 
                 // Visit the fields of this value.
                 match v.layout().fields {
-                    layout::FieldPlacement::Union(fields) => {
+                    FieldsShape::Union(fields) => {
                         self.visit_union(v, fields)?;
                     },
-                    layout::FieldPlacement::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 @@ macro_rules! make_value_visitor {
                             .collect();
                         self.visit_aggregate(v, fields.into_iter())?;
                     },
-                    layout::FieldPlacement::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 @@ macro_rules! make_value_visitor {
                 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 @@ macro_rules! make_value_visitor {
                         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/lib.rs b/src/librustc_mir/lib.rs
index 85e44adc30b..e07b8535b90 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -30,7 +30,7 @@ Rust MIR: a lowered representation of Rust.
 #[macro_use]
 extern crate log;
 #[macro_use]
-extern crate rustc;
+extern crate rustc_middle;
 
 mod borrow_check;
 pub mod const_eval;
@@ -41,7 +41,7 @@ mod shim;
 pub mod transform;
 pub mod util;
 
-use rustc::ty::query::Providers;
+use rustc_middle::ty::query::Providers;
 
 pub fn provide(providers: &mut Providers<'_>) {
     borrow_check::provide(providers);
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index cbd19f080eb..1032ff413af 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -176,23 +176,23 @@
 
 use crate::monomorphize;
 
-use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags;
-use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
-use rustc::mir::interpret::{AllocId, ConstValue};
-use rustc::mir::interpret::{ErrorHandled, GlobalAlloc, Scalar};
-use rustc::mir::mono::{InstantiationMode, MonoItem};
-use rustc::mir::visit::Visitor as MirVisitor;
-use rustc::mir::{self, Local, Location};
-use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast};
-use rustc::ty::print::obsolete::DefPathBasedNames;
-use rustc::ty::subst::InternalSubsts;
-use rustc::ty::{self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::{par_iter, MTLock, MTRef, ParallelIterator};
 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::mir::interpret::{AllocId, ConstValue};
+use rustc_middle::mir::interpret::{ErrorHandled, GlobalAlloc, Scalar};
+use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
+use rustc_middle::mir::visit::Visitor as MirVisitor;
+use rustc_middle::mir::{self, Local, Location};
+use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCast};
+use rustc_middle::ty::print::obsolete::DefPathBasedNames;
+use rustc_middle::ty::subst::InternalSubsts;
+use rustc_middle::ty::{self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable};
 use rustc_session::config::EntryFnType;
 use smallvec::SmallVec;
 use std::iter;
@@ -988,12 +988,9 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> {
     }
 
     fn visit_impl_item(&mut self, ii: &'v hir::ImplItem<'v>) {
-        match ii.kind {
-            hir::ImplItemKind::Fn(hir::FnSig { .. }, _) => {
-                let def_id = self.tcx.hir().local_def_id(ii.hir_id);
-                self.push_if_root(def_id);
-            }
-            _ => { /* nothing to do here */ }
+        if let hir::ImplItemKind::Fn(hir::FnSig { .. }, _) = ii.kind {
+            let def_id = self.tcx.hir().local_def_id(ii.hir_id);
+            self.push_if_root(def_id);
         }
     }
 }
@@ -1162,7 +1159,7 @@ fn collect_neighbours<'tcx>(
     debug!("collect_neighbours: {:?}", instance.def_id());
     let body = tcx.instance_mir(instance.def);
 
-    MirNeighborCollector { tcx, body: &body, output, instance }.visit_body(body);
+    MirNeighborCollector { tcx, body: &body, output, instance }.visit_body(&body);
 }
 
 fn def_id_to_string(tcx: TyCtxt<'_>, def_id: DefId) -> String {
diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs
index 7177bf726d4..bbb8e063a45 100644
--- a/src/librustc_mir/monomorphize/mod.rs
+++ b/src/librustc_mir/monomorphize/mod.rs
@@ -1,6 +1,6 @@
-use rustc::traits;
-use rustc::ty::adjustment::CustomCoerceUnsized;
-use rustc::ty::{self, Ty, TyCtxt};
+use rustc_middle::traits;
+use rustc_middle::ty::adjustment::CustomCoerceUnsized;
+use rustc_middle::ty::{self, Ty, TyCtxt};
 
 pub mod collector;
 pub mod partitioning;
diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs
index 9b81d69ce69..9068c0541a4 100644
--- a/src/librustc_mir/monomorphize/partitioning.rs
+++ b/src/librustc_mir/monomorphize/partitioning.rs
@@ -96,30 +96,22 @@ use std::cmp;
 use std::collections::hash_map::Entry;
 use std::sync::Arc;
 
-use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags;
-use rustc::middle::exported_symbols::SymbolExportLevel;
-use rustc::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, Linkage, Visibility};
-use rustc::mir::mono::{InstantiationMode, MonoItem};
-use rustc::ty::print::characteristic_def_id_of_type;
-use rustc::ty::query::Providers;
-use rustc::ty::{self, DefIdTree, InstanceDef, TyCtxt};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{CrateNum, DefId, DefIdSet, CRATE_DEF_INDEX, LOCAL_CRATE};
-use rustc_span::symbol::Symbol;
+use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
+use rustc_middle::middle::exported_symbols::SymbolExportLevel;
+use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, Linkage, Visibility};
+use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
+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, 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 @@ fn fallback_cgu_name(name_builder: &mut CodegenUnitNameBuilder<'_>) -> Symbol {
 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 @@ where
 
     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 @@ fn merge_codegen_units<'tcx>(
     // 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 @@ fn merge_codegen_units<'tcx>(
         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 @@ fn collect_and_partition_mono_items(
     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 eeb9d5f5a1f..67de81ed77b 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -1,10 +1,10 @@
-use rustc::mir::*;
-use rustc::ty::layout::VariantIdx;
-use rustc::ty::query::Providers;
-use rustc::ty::subst::{InternalSubsts, Subst};
-use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_middle::mir::*;
+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};
 
@@ -230,7 +230,7 @@ fn build_drop_shim<'tcx>(
             elaborate_drops::elaborate_drop(
                 &mut elaborator,
                 source_info,
-                &dropee,
+                dropee,
                 (),
                 return_block,
                 elaborate_drops::Unwind::To(resume_block),
diff --git a/src/librustc_mir/transform/add_call_guards.rs b/src/librustc_mir/transform/add_call_guards.rs
index c979b569ec5..6deb5d6485a 100644
--- a/src/librustc_mir/transform/add_call_guards.rs
+++ b/src/librustc_mir/transform/add_call_guards.rs
@@ -1,7 +1,7 @@
 use crate::transform::{MirPass, MirSource};
-use rustc::mir::*;
-use rustc::ty::TyCtxt;
 use rustc_index::vec::{Idx, IndexVec};
+use rustc_middle::mir::*;
+use rustc_middle::ty::TyCtxt;
 
 #[derive(PartialEq)]
 pub enum AddCallGuards {
diff --git a/src/librustc_mir/transform/add_moves_for_packed_drops.rs b/src/librustc_mir/transform/add_moves_for_packed_drops.rs
index 38db9e51959..7c46855dfd6 100644
--- a/src/librustc_mir/transform/add_moves_for_packed_drops.rs
+++ b/src/librustc_mir/transform/add_moves_for_packed_drops.rs
@@ -1,6 +1,6 @@
-use rustc::mir::*;
-use rustc::ty::TyCtxt;
 use rustc_hir::def_id::DefId;
+use rustc_middle::mir::*;
+use rustc_middle::ty::TyCtxt;
 
 use crate::transform::{MirPass, MirSource};
 use crate::util;
@@ -68,7 +68,7 @@ fn add_moves_for_packed_drops_patch<'tcx>(
         let terminator = data.terminator();
 
         match terminator.kind {
-            TerminatorKind::Drop { ref location, .. }
+            TerminatorKind::Drop { location, .. }
                 if util::is_disaligned(tcx, body, param_env, location) =>
             {
                 add_move_for_packed_drop(tcx, body, &mut patch, terminator, loc, data.is_cleanup);
diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs
index aa9cad7ffc1..5c016b0c515 100644
--- a/src/librustc_mir/transform/add_retag.rs
+++ b/src/librustc_mir/transform/add_retag.rs
@@ -5,8 +5,8 @@
 //! normal MIR semantics.
 
 use crate::transform::{MirPass, MirSource};
-use rustc::mir::*;
-use rustc::ty::{self, Ty, TyCtxt};
+use rustc_middle::mir::*;
+use rustc_middle::ty::{self, Ty, TyCtxt};
 
 pub struct AddRetag;
 
diff --git a/src/librustc_mir/transform/check_consts/mod.rs b/src/librustc_mir/transform/check_consts/mod.rs
index b7383663932..bce3a506b1d 100644
--- a/src/librustc_mir/transform/check_consts/mod.rs
+++ b/src/librustc_mir/transform/check_consts/mod.rs
@@ -4,10 +4,10 @@
 //! has interior mutability or needs to be dropped, as well as the visitor that emits errors when
 //! it finds operations that are invalid in a certain context.
 
-use rustc::mir;
-use rustc::ty::{self, TyCtxt};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_middle::mir;
+use rustc_middle::ty::{self, TyCtxt};
 
 use std::fmt;
 
diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/src/librustc_mir/transform/check_consts/qualifs.rs
index 9359ec16533..f38b9d8ef85 100644
--- a/src/librustc_mir/transform/check_consts/qualifs.rs
+++ b/src/librustc_mir/transform/check_consts/qualifs.rs
@@ -2,8 +2,8 @@
 //!
 //! See the `Qualif` trait for more info.
 
-use rustc::mir::*;
-use rustc::ty::{self, AdtDef, Ty};
+use rustc_middle::mir::*;
+use rustc_middle::ty::{self, AdtDef, Ty};
 use rustc_span::DUMMY_SP;
 
 use super::Item as ConstCx;
diff --git a/src/librustc_mir/transform/check_consts/resolver.rs b/src/librustc_mir/transform/check_consts/resolver.rs
index 5f761ce3448..b95a3939389 100644
--- a/src/librustc_mir/transform/check_consts/resolver.rs
+++ b/src/librustc_mir/transform/check_consts/resolver.rs
@@ -2,9 +2,9 @@
 //!
 //! This contains the dataflow analysis used to track `Qualif`s on complex control-flow graphs.
 
-use rustc::mir::visit::Visitor;
-use rustc::mir::{self, BasicBlock, Local, Location};
 use rustc_index::bit_set::BitSet;
+use rustc_middle::mir::visit::Visitor;
+use rustc_middle::mir::{self, BasicBlock, Local, Location};
 
 use std::marker::PhantomData;
 
@@ -68,7 +68,7 @@ where
         _block: BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        return_place: &mir::Place<'tcx>,
+        return_place: mir::Place<'tcx>,
     ) {
         // We cannot reason about another function's internals, so use conservative type-based
         // qualification for the result of a function call.
@@ -76,7 +76,7 @@ where
         let qualif = Q::in_any_value_of_ty(self.item, return_ty);
 
         if !return_place.is_indirect() {
-            self.assign_qualif_direct(return_place, qualif);
+            self.assign_qualif_direct(&return_place, qualif);
         }
     }
 }
@@ -214,7 +214,7 @@ where
         block: BasicBlock,
         func: &mir::Operand<'tcx>,
         args: &[mir::Operand<'tcx>],
-        return_place: &mir::Place<'tcx>,
+        return_place: mir::Place<'tcx>,
     ) {
         self.transfer_function(state).apply_call_return_effect(block, func, args, return_place)
     }
diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs
index c315a8a65df..e4a0b9cdb48 100644
--- a/src/librustc_mir/transform/check_consts/validation.rs
+++ b/src/librustc_mir/transform/check_consts/validation.rs
@@ -1,14 +1,14 @@
 //! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations.
 
-use rustc::middle::lang_items;
-use rustc::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
-use rustc::mir::*;
-use rustc::ty::cast::CastTy;
-use rustc::ty::{self, Instance, InstanceDef, TyCtxt};
 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::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
+use rustc_middle::mir::*;
+use rustc_middle::ty::cast::CastTy;
+use rustc_middle::ty::{self, Instance, InstanceDef, TyCtxt};
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
@@ -183,7 +183,7 @@ impl Validator<'a, 'mir, 'tcx> {
             self.check_op_spanned(ops::Loop, body.span);
         }
 
-        self.visit_body(body);
+        self.visit_body(&body);
 
         // Ensure that the end result is `Sync` in a non-thread local `static`.
         let should_check_for_sync =
@@ -260,7 +260,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
 
         // Special-case reborrows to be more like a copy of a reference.
         match *rvalue {
-            Rvalue::Ref(_, kind, ref place) => {
+            Rvalue::Ref(_, kind, place) => {
                 if let Some(reborrowed_proj) = place_as_reborrow(self.tcx, *self.body, place) {
                     let ctx = match kind {
                         BorrowKind::Shared => {
@@ -281,7 +281,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
                     return;
                 }
             }
-            Rvalue::AddressOf(mutbl, ref place) => {
+            Rvalue::AddressOf(mutbl, place) => {
                 if let Some(reborrowed_proj) = place_as_reborrow(self.tcx, *self.body, place) {
                     let ctx = match mutbl {
                         Mutability::Not => {
@@ -645,7 +645,7 @@ fn check_return_ty_is_sync(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, hir_id: HirId)
 fn place_as_reborrow(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
-    place: &'a Place<'tcx>,
+    place: Place<'tcx>,
 ) -> Option<&'a [PlaceElem<'tcx>]> {
     place.projection.split_last().and_then(|(outermost, inner)| {
         if outermost != &ProjectionElem::Deref {
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index d241cc5d8a3..3ce9b875e16 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -1,14 +1,14 @@
-use rustc::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
-use rustc::mir::*;
-use rustc::ty::cast::CastTy;
-use rustc::ty::query::Providers;
-use rustc::ty::{self, TyCtxt};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit;
 use rustc_hir::Node;
+use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
+use rustc_middle::mir::*;
+use rustc_middle::ty::cast::CastTy;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::lint::builtin::{SAFE_PACKED_BORROWS, UNUSED_UNSAFE};
 use rustc_span::symbol::{sym, Symbol};
 
@@ -184,14 +184,14 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
         // because either of these would allow modifying the layout constrained field and
         // insert values that violate the layout constraints.
         if context.is_mutating_use() || context.is_borrow() {
-            self.check_mut_borrowing_layout_constrained_field(place, context.is_mutating_use());
+            self.check_mut_borrowing_layout_constrained_field(*place, context.is_mutating_use());
         }
 
         for (i, elem) in place.projection.iter().enumerate() {
             let proj_base = &place.projection[..i];
 
             if context.is_borrow() {
-                if util::is_disaligned(self.tcx, self.body, self.param_env, place) {
+                if util::is_disaligned(self.tcx, self.body, self.param_env, *place) {
                     let source_info = self.source_info;
                     let lint_root = self.body.source_scopes[source_info.scope]
                         .local_data
@@ -382,7 +382,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
     }
     fn check_mut_borrowing_layout_constrained_field(
         &mut self,
-        place: &Place<'tcx>,
+        place: Place<'tcx>,
         is_mut_use: bool,
     ) {
         let mut cursor = place.projection.as_ref();
@@ -396,42 +396,40 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
                 ProjectionElem::Field(..) => {
                     let ty =
                         Place::ty_from(place.local, proj_base, &self.body.local_decls, self.tcx).ty;
-                    match ty.kind {
-                        ty::Adt(def, _) => match self.tcx.layout_scalar_valid_range(def.did) {
-                            (Bound::Unbounded, Bound::Unbounded) => {}
-                            _ => {
-                                let (description, details) = if is_mut_use {
-                                    (
-                                        "mutation of layout constrained field",
-                                        "mutating layout constrained fields cannot statically be \
+                    if let ty::Adt(def, _) = ty.kind {
+                        if self.tcx.layout_scalar_valid_range(def.did)
+                            != (Bound::Unbounded, Bound::Unbounded)
+                        {
+                            let (description, details) = if is_mut_use {
+                                (
+                                    "mutation of layout constrained field",
+                                    "mutating layout constrained fields cannot statically be \
                                         checked for valid values",
-                                    )
+                                )
 
-                                // Check `is_freeze` as late as possible to avoid cycle errors
-                                // with opaque types.
-                                } else if !place.ty(self.body, self.tcx).ty.is_freeze(
-                                    self.tcx,
-                                    self.param_env,
-                                    self.source_info.span,
-                                ) {
-                                    (
-                                        "borrow of layout constrained field with interior \
+                            // Check `is_freeze` as late as possible to avoid cycle errors
+                            // with opaque types.
+                            } else if !place.ty(self.body, self.tcx).ty.is_freeze(
+                                self.tcx,
+                                self.param_env,
+                                self.source_info.span,
+                            ) {
+                                (
+                                    "borrow of layout constrained field with interior \
                                         mutability",
-                                        "references to fields of layout constrained fields \
+                                    "references to fields of layout constrained fields \
                                         lose the constraints. Coupled with interior mutability, \
                                         the field can be changed to invalid values",
-                                    )
-                                } else {
-                                    continue;
-                                };
-                                self.require_unsafe(
-                                    description,
-                                    details,
-                                    UnsafetyViolationKind::GeneralAndConstFn,
-                                );
-                            }
-                        },
-                        _ => {}
+                                )
+                            } else {
+                                continue;
+                            };
+                            self.require_unsafe(
+                                description,
+                                details,
+                                UnsafetyViolationKind::GeneralAndConstFn,
+                            );
+                        }
                     }
                 }
                 _ => {}
@@ -507,7 +505,7 @@ fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: DefId) -> UnsafetyCheckResult
     // mir_built ensures that body has a computed cache, so we don't (and can't) attempt to
     // recompute it here.
     let body = body.unwrap_read_only();
-    checker.visit_body(body);
+    checker.visit_body(&body);
 
     check_unused_unsafe(tcx, def_id, &checker.used_unsafe, &mut checker.inherited_blocks);
     UnsafetyCheckResult {
diff --git a/src/librustc_mir/transform/cleanup_post_borrowck.rs b/src/librustc_mir/transform/cleanup_post_borrowck.rs
index 3d219ac2c01..446aadd56dc 100644
--- a/src/librustc_mir/transform/cleanup_post_borrowck.rs
+++ b/src/librustc_mir/transform/cleanup_post_borrowck.rs
@@ -11,16 +11,16 @@
 //! temporaries read by [`ForMatchGuard`] reads, and [`DeleteFakeBorrows`]
 //! deletes the initialization of those temporaries.
 //!
-//! [`AscribeUserType`]: rustc::mir::StatementKind::AscribeUserType
-//! [`Shallow`]: rustc::mir::BorrowKind::Shallow
-//! [`FakeRead`]: rustc::mir::StatementKind::FakeRead
-//! [`Nop`]: rustc::mir::StatementKind::Nop
+//! [`AscribeUserType`]: rustc_middle::mir::StatementKind::AscribeUserType
+//! [`Shallow`]: rustc_middle::mir::BorrowKind::Shallow
+//! [`FakeRead`]: rustc_middle::mir::StatementKind::FakeRead
+//! [`Nop`]: rustc_middle::mir::StatementKind::Nop
 
 use crate::transform::{MirPass, MirSource};
-use rustc::mir::visit::MutVisitor;
-use rustc::mir::{BodyAndCache, BorrowKind, Location, Rvalue};
-use rustc::mir::{Statement, StatementKind};
-use rustc::ty::TyCtxt;
+use rustc_middle::mir::visit::MutVisitor;
+use rustc_middle::mir::{BodyAndCache, BorrowKind, Location, Rvalue};
+use rustc_middle::mir::{Statement, StatementKind};
+use rustc_middle::ty::TyCtxt;
 
 pub struct CleanupNonCodegenStatements;
 
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 5fe8f9f3771..c7f63d24c28 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -4,28 +4,27 @@
 use std::borrow::Cow;
 use std::cell::Cell;
 
-use rustc::mir::interpret::{InterpResult, Scalar};
-use rustc::mir::visit::{
+use rustc_ast::ast::Mutability;
+use rustc_data_structures::fx::FxHashMap;
+use rustc_hir::def::DefKind;
+use rustc_hir::HirId;
+use rustc_index::vec::IndexVec;
+use rustc_middle::mir::interpret::{InterpResult, Scalar};
+use rustc_middle::mir::visit::{
     MutVisitor, MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor,
 };
-use rustc::mir::{
+use rustc_middle::mir::{
     read_only, AggregateKind, AssertKind, BasicBlock, BinOp, Body, BodyAndCache, ClearCrossCrate,
     Constant, Local, LocalDecl, LocalKind, Location, Operand, Place, ReadOnlyBodyAndCache, Rvalue,
     SourceInfo, SourceScope, SourceScopeData, Statement, StatementKind, Terminator, TerminatorKind,
     UnOp, RETURN_PLACE,
 };
-use rustc::ty::layout::{
-    HasDataLayout, HasTyCtxt, LayoutError, LayoutOf, Size, TargetDataLayout, TyLayout,
-};
-use rustc::ty::subst::{InternalSubsts, Subst};
-use rustc::ty::{self, ConstKind, Instance, ParamEnv, Ty, TyCtxt, TypeFoldable};
-use rustc_ast::ast::Mutability;
-use rustc_data_structures::fx::FxHashMap;
-use rustc_hir::def::DefKind;
-use rustc_hir::HirId;
-use rustc_index::vec::IndexVec;
+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;
@@ -52,7 +51,7 @@ macro_rules! throw_machine_stop_str {
                 write!(f, $($tt)*)
             }
         }
-        impl rustc::mir::interpret::MachineStopType for Zst {}
+        impl rustc_middle::mir::interpret::MachineStopType for Zst {}
         throw_machine_stop!(Zst)
     }};
 }
@@ -66,7 +65,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
             return;
         }
 
-        use rustc::hir::map::blocks::FnLikeNode;
+        use rustc_middle::hir::map::blocks::FnLikeNode;
         let hir_id = tcx
             .hir()
             .as_local_hir_id(source.def_id())
@@ -183,7 +182,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
 
     fn find_mir_or_eval_fn(
         _ecx: &mut InterpCx<'mir, 'tcx, Self>,
-        _span: Span,
         _instance: ty::Instance<'tcx>,
         _args: &[OpTy<'tcx>],
         _ret: Option<(PlaceTy<'tcx>, BasicBlock)>,
@@ -204,7 +202,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
 
     fn call_intrinsic(
         _ecx: &mut InterpCx<'mir, 'tcx, Self>,
-        _span: Span,
         _instance: ty::Instance<'tcx>,
         _args: &[OpTy<'tcx>],
         _ret: Option<(PlaceTy<'tcx>, BasicBlock)>,
@@ -215,8 +212,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
 
     fn assert_panic(
         _ecx: &mut InterpCx<'mir, 'tcx, Self>,
-        _msg: &rustc::mir::AssertMessage<'tcx>,
-        _unwind: Option<rustc::mir::BasicBlock>,
+        _msg: &rustc_middle::mir::AssertMessage<'tcx>,
+        _unwind: Option<rustc_middle::mir::BasicBlock>,
     ) -> InterpResult<'tcx> {
         bug!("panics terminators are not evaluated in ConstProp")
     }
@@ -274,19 +271,16 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
         _memory_extra: &(),
         _alloc_id: AllocId,
         allocation: &Allocation<Self::PointerTag, Self::AllocExtra>,
-        static_def_id: Option<DefId>,
+        _static_def_id: Option<DefId>,
         is_write: bool,
     ) -> InterpResult<'tcx> {
         if is_write {
             throw_machine_stop_str!("can't write to global");
         }
-        // If the static allocation is mutable or if it has relocations (it may be legal to mutate
-        // the memory behind that in the future), then we can't const prop it.
+        // If the static allocation is mutable, then we can't const prop it as its content
+        // might be different at runtime.
         if allocation.mutability == Mutability::Mut {
-            throw_machine_stop_str!("can't eval mutable globals in ConstProp");
-        }
-        if static_def_id.is_some() && allocation.relocations().len() > 0 {
-            throw_machine_stop_str!("can't eval statics with pointers in ConstProp");
+            throw_machine_stop_str!("can't access mutable globals in ConstProp");
         }
 
         Ok(())
@@ -316,9 +310,9 @@ struct ConstPropagator<'mir, 'tcx> {
 
 impl<'mir, 'tcx> LayoutOf for ConstPropagator<'mir, 'tcx> {
     type Ty = Ty<'tcx>;
-    type TyLayout = Result<TyLayout<'tcx>, LayoutError<'tcx>>;
+    type TyAndLayout = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>;
 
-    fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
+    fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout {
         self.tcx.layout_of(self.param_env.and(ty))
     }
 }
@@ -364,7 +358,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
 
         ecx.push_stack_frame(
             Instance::new(def_id, substs),
-            span,
             dummy_body,
             ret.map(Into::into),
             StackPopCleanup::None { cleanup: false },
@@ -471,7 +464,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         }
     }
 
-    fn eval_place(&mut self, place: &Place<'tcx>) -> Option<OpTy<'tcx>> {
+    fn eval_place(&mut self, place: Place<'tcx>) -> Option<OpTy<'tcx>> {
         trace!("eval_place(place={:?})", place);
         self.use_ecx(|this| this.ecx.eval_place_to_op(place, None))
     }
@@ -479,7 +472,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
     fn eval_operand(&mut self, op: &Operand<'tcx>, source_info: SourceInfo) -> Option<OpTy<'tcx>> {
         match *op {
             Operand::Constant(ref c) => self.eval_constant(c, source_info),
-            Operand::Move(ref place) | Operand::Copy(ref place) => self.eval_place(place),
+            Operand::Move(place) | Operand::Copy(place) => self.eval_place(place),
         }
     }
 
@@ -573,9 +566,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
     fn const_prop(
         &mut self,
         rvalue: &Rvalue<'tcx>,
-        place_layout: TyLayout<'tcx>,
+        place_layout: TyAndLayout<'tcx>,
         source_info: SourceInfo,
-        place: &Place<'tcx>,
+        place: Place<'tcx>,
     ) -> Option<()> {
         // #66397: Don't try to eval into large places as that can cause an OOM
         if place_layout.size >= Size::from_bytes(MAX_ALLOC_LIMIT) {
@@ -778,14 +771,14 @@ impl CanConstProp {
                 trace!("local {:?} can't be const propagated because it's not a temporary", local);
             }
         }
-        cpv.visit_body(body);
+        cpv.visit_body(&body);
         cpv.can_const_prop
     }
 }
 
 impl<'tcx> Visitor<'tcx> for CanConstProp {
     fn visit_local(&mut self, &local: &Local, context: PlaceContext, _: Location) {
-        use rustc::mir::visit::PlaceContext::*;
+        use rustc_middle::mir::visit::PlaceContext::*;
         match context {
             // Constants must have at most one write
             // FIXME(oli-obk): we could be more powerful here, if the multiple writes
@@ -828,7 +821,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
         trace!("visit_statement: {:?}", statement);
         let source_info = statement.source_info;
         self.source_info = Some(source_info);
-        if let StatementKind::Assign(box (ref place, ref mut rval)) = statement.kind {
+        if let StatementKind::Assign(box (place, ref mut rval)) = statement.kind {
             let place_ty: Ty<'tcx> = place.ty(&self.local_decls, self.tcx).ty;
             if let Ok(place_layout) = self.tcx.layout_of(self.param_env.and(place_ty)) {
                 if let Some(local) = place.as_local() {
diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs
index b8ca823a985..a25b554b345 100644
--- a/src/librustc_mir/transform/copy_prop.rs
+++ b/src/librustc_mir/transform/copy_prop.rs
@@ -21,12 +21,12 @@
 
 use crate::transform::{MirPass, MirSource};
 use crate::util::def_use::DefUseAnalysis;
-use rustc::mir::visit::MutVisitor;
-use rustc::mir::{
+use rustc_middle::mir::visit::MutVisitor;
+use rustc_middle::mir::{
     read_only, Body, BodyAndCache, Constant, Local, LocalKind, Location, Operand, Place, Rvalue,
     StatementKind,
 };
-use rustc::ty::TyCtxt;
+use rustc_middle::ty::TyCtxt;
 
 pub struct CopyPropagation;
 
@@ -97,9 +97,8 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation {
                             if let Some(local) = place.as_local() {
                                 if local == dest_local {
                                     let maybe_action = match operand {
-                                        Operand::Copy(ref src_place)
-                                        | Operand::Move(ref src_place) => {
-                                            Action::local_copy(&body, &def_use_analysis, src_place)
+                                        Operand::Copy(src_place) | Operand::Move(src_place) => {
+                                            Action::local_copy(&body, &def_use_analysis, *src_place)
                                         }
                                         Operand::Constant(ref src_constant) => {
                                             Action::constant(src_constant)
@@ -195,7 +194,7 @@ impl<'tcx> Action<'tcx> {
     fn local_copy(
         body: &Body<'tcx>,
         def_use_analysis: &DefUseAnalysis,
-        src_place: &Place<'tcx>,
+        src_place: Place<'tcx>,
     ) -> Option<Action<'tcx>> {
         // The source must be a local.
         let src_local = if let Some(local) = src_place.as_local() {
diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs
index 9f8964ee5a0..3e2be7fd7d5 100644
--- a/src/librustc_mir/transform/deaggregator.rs
+++ b/src/librustc_mir/transform/deaggregator.rs
@@ -1,7 +1,7 @@
 use crate::transform::{MirPass, MirSource};
 use crate::util::expand_aggregate;
-use rustc::mir::*;
-use rustc::ty::TyCtxt;
+use rustc_middle::mir::*;
+use rustc_middle::ty::TyCtxt;
 
 pub struct Deaggregator;
 
diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs
index 795bcb57d06..9933b5cd9f7 100644
--- a/src/librustc_mir/transform/dump_mir.rs
+++ b/src/librustc_mir/transform/dump_mir.rs
@@ -7,8 +7,8 @@ use std::io;
 
 use crate::transform::{MirPass, MirSource};
 use crate::util as mir_util;
-use rustc::mir::{Body, BodyAndCache};
-use rustc::ty::TyCtxt;
+use rustc_middle::mir::{Body, BodyAndCache};
+use rustc_middle::ty::TyCtxt;
 use rustc_session::config::{OutputFilenames, OutputType};
 
 pub struct Marker(pub &'static str);
@@ -46,7 +46,7 @@ pub fn on_mir_pass<'tcx>(
     body: &Body<'tcx>,
     is_after: bool,
 ) {
-    if mir_util::dump_enabled(tcx, pass_name, source) {
+    if mir_util::dump_enabled(tcx, pass_name, source.def_id()) {
         mir_util::dump_mir(
             tcx,
             Some(pass_num),
diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs
index 4ec4ef02061..a7c6b5a98bb 100644
--- a/src/librustc_mir/transform/elaborate_drops.rs
+++ b/src/librustc_mir/transform/elaborate_drops.rs
@@ -9,13 +9,13 @@ use crate::transform::{MirPass, MirSource};
 use crate::util::elaborate_drops::{elaborate_drop, DropFlagState, Unwind};
 use crate::util::elaborate_drops::{DropElaborator, DropFlagMode, DropStyle};
 use crate::util::patch::MirPatch;
-use rustc::mir::*;
-use rustc::ty::layout::VariantIdx;
-use rustc::ty::{self, TyCtxt};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
 use rustc_index::bit_set::BitSet;
+use rustc_middle::mir::*;
+use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::Span;
+use rustc_target::abi::VariantIdx;
 use std::fmt;
 
 pub struct ElaborateDrops;
@@ -346,7 +346,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
 
             let resume_block = self.patch.resume_block();
             match terminator.kind {
-                TerminatorKind::Drop { ref location, target, unwind } => {
+                TerminatorKind::Drop { location, target, unwind } => {
                     self.init_data.seek_before(loc);
                     match self.move_data().rev_lookup.find(location.as_ref()) {
                         LookupResult::Exact(path) => elaborate_drop(
@@ -371,7 +371,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
                         }
                     }
                 }
-                TerminatorKind::DropAndReplace { ref location, ref value, target, unwind } => {
+                TerminatorKind::DropAndReplace { location, ref value, target, unwind } => {
                     assert!(!data.is_cleanup);
 
                     self.elaborate_replace(loc, location, value, target, unwind);
@@ -396,7 +396,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
     fn elaborate_replace(
         &mut self,
         loc: Location,
-        location: &Place<'tcx>,
+        location: Place<'tcx>,
         value: &Operand<'tcx>,
         target: BasicBlock,
         unwind: Option<BasicBlock>,
@@ -407,7 +407,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
         assert!(!data.is_cleanup, "DropAndReplace in unwind path not supported");
 
         let assign = Statement {
-            kind: StatementKind::Assign(box (*location, Rvalue::Use(value.clone()))),
+            kind: StatementKind::Assign(box (location, Rvalue::Use(value.clone()))),
             source_info: terminator.source_info,
         };
 
@@ -459,7 +459,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
                 debug!("elaborate_drop_and_replace({:?}) - untracked {:?}", terminator, parent);
                 self.patch.patch_terminator(
                     bb,
-                    TerminatorKind::Drop { location: *location, target, unwind: Some(unwind) },
+                    TerminatorKind::Drop { location, target, unwind: Some(unwind) },
                 );
             }
         }
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index 1945efb6bf7..53eec1f6dc3 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -56,17 +56,17 @@ use crate::transform::simplify;
 use crate::transform::{MirPass, MirSource};
 use crate::util::dump_mir;
 use crate::util::liveness;
-use rustc::mir::visit::{MutVisitor, PlaceContext, Visitor};
-use rustc::mir::*;
-use rustc::ty::layout::VariantIdx;
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::GeneratorSubsts;
-use rustc::ty::{self, AdtDef, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_index::bit_set::{BitMatrix, BitSet};
 use rustc_index::vec::{Idx, IndexVec};
+use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor};
+use rustc_middle::mir::*;
+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;
 
@@ -469,7 +469,7 @@ fn locals_live_across_suspend_points(
     // Find the MIR locals which do not use StorageLive/StorageDead statements.
     // The storage of these locals are always live.
     let mut ignored = StorageIgnored(BitSet::new_filled(body.local_decls.len()));
-    ignored.visit_body(body);
+    ignored.visit_body(&body);
 
     // Calculate the MIR locals which have been previously
     // borrowed (even if they are still active).
@@ -675,10 +675,9 @@ impl dataflow::ResultsVisitor<'mir, 'tcx> for StorageConflictVisitor<'mir, 'tcx,
 impl<'body, 'tcx, 's> StorageConflictVisitor<'body, 'tcx, 's> {
     fn apply_state(&mut self, flow_state: &BitSet<Local>, loc: Location) {
         // Ignore unreachable blocks.
-        match self.body.basic_blocks()[loc.block].terminator().kind {
-            TerminatorKind::Unreachable => return,
-            _ => (),
-        };
+        if self.body.basic_blocks()[loc.block].terminator().kind == TerminatorKind::Unreachable {
+            return;
+        }
 
         let mut eligible_storage_live = flow_state.clone();
         eligible_storage_live.intersect(&self.stored_locals);
@@ -854,7 +853,7 @@ fn elaborate_generator_drops<'tcx>(
         elaborate_drop(
             &mut elaborator,
             *source_info,
-            &Place::from(SELF_ARG),
+            Place::from(SELF_ARG),
             (),
             *target,
             unwind,
@@ -1079,7 +1078,7 @@ fn create_generator_resume_function<'tcx>(
 
     let mut cases = create_cases(body, &transform, Operation::Resume);
 
-    use rustc::mir::AssertKind::{ResumedAfterPanic, ResumedAfterReturn};
+    use rustc_middle::mir::AssertKind::{ResumedAfterPanic, ResumedAfterReturn};
 
     // Jump to the entry point on the unresumed
     cases.insert(0, (UNRESUMED, BasicBlock::new(0)));
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 16c32e138fd..157dada831a 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -1,14 +1,14 @@
 //! Inlining pass for MIR functions
 
-use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags;
-use rustc::mir::visit::*;
-use rustc::mir::*;
-use rustc::ty::subst::{Subst, SubstsRef};
-use rustc::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
 use rustc_attr as attr;
 use rustc_hir::def_id::DefId;
 use rustc_index::bit_set::BitSet;
 use rustc_index::vec::{Idx, IndexVec};
+use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
+use rustc_middle::mir::visit::*;
+use rustc_middle::mir::*;
+use rustc_middle::ty::subst::{Subst, SubstsRef};
+use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
 use rustc_session::config::Sanitizer;
 use rustc_target::spec::abi::Abi;
 
@@ -450,7 +450,7 @@ impl Inliner<'tcx> {
                 // Place could result in two different locations if `f`
                 // writes to `i`. To prevent this we need to create a temporary
                 // borrow of the place and pass the destination as `*temp` instead.
-                fn dest_needs_borrow(place: &Place<'_>) -> bool {
+                fn dest_needs_borrow(place: Place<'_>) -> bool {
                     for elem in place.projection.iter() {
                         match elem {
                             ProjectionElem::Deref | ProjectionElem::Index(_) => return true,
@@ -461,7 +461,7 @@ impl Inliner<'tcx> {
                     false
                 }
 
-                let dest = if dest_needs_borrow(&destination.0) {
+                let dest = if dest_needs_borrow(destination.0) {
                     debug!("creating temp for return destination");
                     let dest = Rvalue::Ref(
                         self.tcx.lifetimes.re_erased,
diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs
index 48b4d00a2e9..3a60048b0ef 100644
--- a/src/librustc_mir/transform/instcombine.rs
+++ b/src/librustc_mir/transform/instcombine.rs
@@ -1,14 +1,14 @@
 //! Performs various peephole optimizations.
 
 use crate::transform::{MirPass, MirSource};
-use rustc::mir::visit::{MutVisitor, Visitor};
-use rustc::mir::{
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_index::vec::Idx;
+use rustc_middle::mir::visit::{MutVisitor, Visitor};
+use rustc_middle::mir::{
     read_only, Body, BodyAndCache, Constant, Local, Location, Operand, Place, PlaceRef,
     ProjectionElem, Rvalue,
 };
-use rustc::ty::{self, TyCtxt};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_index::vec::Idx;
+use rustc_middle::ty::{self, TyCtxt};
 use std::mem;
 
 pub struct InstCombine;
@@ -26,7 +26,7 @@ impl<'tcx> MirPass<'tcx> for InstCombine {
         let optimizations = {
             let read_only_cache = read_only!(body);
             let mut optimization_finder = OptimizationFinder::new(body, tcx);
-            optimization_finder.visit_body(read_only_cache);
+            optimization_finder.visit_body(&read_only_cache);
             optimization_finder.optimizations
         };
 
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index 50868434baa..18b3e88c86f 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -1,13 +1,13 @@
 use crate::{shim, util};
-use rustc::mir::{BodyAndCache, ConstQualifs, MirPhase, Promoted};
-use rustc::ty::query::Providers;
-use rustc::ty::steal::Steal;
-use rustc::ty::{InstanceDef, TyCtxt, TypeFoldable};
 use rustc_ast::ast;
 use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, DefId, DefIdSet, LOCAL_CRATE};
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_index::vec::IndexVec;
+use rustc_middle::mir::{BodyAndCache, ConstQualifs, MirPhase, Promoted};
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::steal::Steal;
+use rustc_middle::ty::{InstanceDef, TyCtxt, TypeFoldable};
 use rustc_span::Span;
 use std::borrow::Cow;
 
diff --git a/src/librustc_mir/transform/no_landing_pads.rs b/src/librustc_mir/transform/no_landing_pads.rs
index e17c733e8bb..48b31d54fa1 100644
--- a/src/librustc_mir/transform/no_landing_pads.rs
+++ b/src/librustc_mir/transform/no_landing_pads.rs
@@ -2,9 +2,9 @@
 //! specified.
 
 use crate::transform::{MirPass, MirSource};
-use rustc::mir::visit::MutVisitor;
-use rustc::mir::*;
-use rustc::ty::TyCtxt;
+use rustc_middle::mir::visit::MutVisitor;
+use rustc_middle::mir::*;
+use rustc_middle::ty::TyCtxt;
 
 pub struct NoLandingPads<'tcx> {
     tcx: TyCtxt<'tcx>,
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index a27c80d91cf..34fa12e1b56 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -12,14 +12,14 @@
 //! initialization and can otherwise silence errors, if
 //! move analysis runs after promotion on broken MIR.
 
-use rustc::mir::traversal::ReversePostorder;
-use rustc::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
-use rustc::mir::*;
-use rustc::ty::cast::CastTy;
-use rustc::ty::subst::InternalSubsts;
-use rustc::ty::{self, List, TyCtxt, TypeFoldable};
 use rustc_ast::ast::LitKind;
 use rustc_hir::def_id::DefId;
+use rustc_middle::mir::traversal::ReversePostorder;
+use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
+use rustc_middle::mir::*;
+use rustc_middle::ty::cast::CastTy;
+use rustc_middle::ty::subst::InternalSubsts;
+use rustc_middle::ty::{self, List, TyCtxt, TypeFoldable};
 use rustc_span::symbol::sym;
 use rustc_span::{Span, DUMMY_SP};
 
@@ -1064,16 +1064,15 @@ pub fn promote_candidates<'tcx>(
         match candidate {
             Candidate::Repeat(Location { block, statement_index })
             | Candidate::Ref(Location { block, statement_index }) => {
-                match &body[block].statements[statement_index].kind {
-                    StatementKind::Assign(box (place, _)) => {
-                        if let Some(local) = place.as_local() {
-                            if temps[local] == TempState::PromotedOut {
-                                // Already promoted.
-                                continue;
-                            }
+                if let StatementKind::Assign(box (place, _)) =
+                    &body[block].statements[statement_index].kind
+                {
+                    if let Some(local) = place.as_local() {
+                        if temps[local] == TempState::PromotedOut {
+                            // Already promoted.
+                            continue;
                         }
                     }
-                    _ => {}
                 }
             }
             Candidate::Argument { .. } => {}
@@ -1137,15 +1136,12 @@ pub fn promote_candidates<'tcx>(
             _ => true,
         });
         let terminator = block.terminator_mut();
-        match &terminator.kind {
-            TerminatorKind::Drop { location: place, target, .. } => {
-                if let Some(index) = place.as_local() {
-                    if promoted(index) {
-                        terminator.kind = TerminatorKind::Goto { target: *target };
-                    }
+        if let TerminatorKind::Drop { location: place, target, .. } = &terminator.kind {
+            if let Some(index) = place.as_local() {
+                if promoted(index) {
+                    terminator.kind = TerminatorKind::Goto { target: *target };
                 }
             }
-            _ => {}
         }
     }
 
diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs
index b2d21d7a84b..c5b366ef572 100644
--- a/src/librustc_mir/transform/qualify_min_const_fn.rs
+++ b/src/librustc_mir/transform/qualify_min_const_fn.rs
@@ -1,8 +1,8 @@
-use rustc::mir::*;
-use rustc::ty::{self, adjustment::PointerCast, Predicate, Ty, TyCtxt};
 use rustc_attr as attr;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_middle::mir::*;
+use rustc_middle::ty::{self, adjustment::PointerCast, Predicate, Ty, TyCtxt};
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
 use std::borrow::Cow;
@@ -150,9 +150,9 @@ fn check_rvalue(
         Rvalue::Len(place)
         | Rvalue::Discriminant(place)
         | Rvalue::Ref(_, _, place)
-        | Rvalue::AddressOf(_, place) => check_place(tcx, place, span, def_id, body),
+        | Rvalue::AddressOf(_, place) => check_place(tcx, *place, span, def_id, body),
         Rvalue::Cast(CastKind::Misc, operand, cast_ty) => {
-            use rustc::ty::cast::CastTy;
+            use rustc_middle::ty::cast::CastTy;
             let cast_in = CastTy::from_ty(operand.ty(body, tcx)).expect("bad input type for cast");
             let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
             match (cast_in, cast_out) {
@@ -215,7 +215,7 @@ fn check_statement(
     let span = statement.source_info.span;
     match &statement.kind {
         StatementKind::Assign(box (place, rval)) => {
-            check_place(tcx, place, span, def_id, body)?;
+            check_place(tcx, *place, span, def_id, body)?;
             check_rvalue(tcx, body, def_id, rval, span)
         }
 
@@ -225,10 +225,12 @@ fn check_statement(
             Err((span, "loops and conditional expressions are not stable in const fn".into()))
         }
 
-        StatementKind::FakeRead(_, place) => check_place(tcx, place, span, def_id, body),
+        StatementKind::FakeRead(_, place) => check_place(tcx, **place, span, def_id, body),
 
         // just an assignment
-        StatementKind::SetDiscriminant { place, .. } => check_place(tcx, place, span, def_id, body),
+        StatementKind::SetDiscriminant { place, .. } => {
+            check_place(tcx, **place, span, def_id, body)
+        }
 
         StatementKind::LlvmInlineAsm { .. } => {
             Err((span, "cannot use inline assembly in const fn".into()))
@@ -251,7 +253,7 @@ fn check_operand(
     body: &Body<'tcx>,
 ) -> McfResult {
     match operand {
-        Operand::Move(place) | Operand::Copy(place) => check_place(tcx, place, span, def_id, body),
+        Operand::Move(place) | Operand::Copy(place) => check_place(tcx, *place, span, def_id, body),
         Operand::Constant(c) => match c.check_static_ptr(tcx) {
             Some(_) => Err((span, "cannot access `static` items in const fn".into())),
             None => Ok(()),
@@ -261,7 +263,7 @@ fn check_operand(
 
 fn check_place(
     tcx: TyCtxt<'tcx>,
-    place: &Place<'tcx>,
+    place: Place<'tcx>,
     span: Span,
     def_id: DefId,
     body: &Body<'tcx>,
@@ -330,9 +332,9 @@ fn check_terminator(
         | TerminatorKind::Return
         | TerminatorKind::Resume => Ok(()),
 
-        TerminatorKind::Drop { location, .. } => check_place(tcx, location, span, def_id, body),
+        TerminatorKind::Drop { location, .. } => check_place(tcx, *location, span, def_id, body),
         TerminatorKind::DropAndReplace { location, value, .. } => {
-            check_place(tcx, location, span, def_id, body)?;
+            check_place(tcx, *location, span, def_id, body)?;
             check_operand(tcx, value, span, def_id, body)
         }
 
diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/src/librustc_mir/transform/remove_noop_landing_pads.rs
index 91f8b7b1c85..5e4fd061c76 100644
--- a/src/librustc_mir/transform/remove_noop_landing_pads.rs
+++ b/src/librustc_mir/transform/remove_noop_landing_pads.rs
@@ -1,8 +1,8 @@
 use crate::transform::{MirPass, MirSource};
 use crate::util::patch::MirPatch;
-use rustc::mir::*;
-use rustc::ty::TyCtxt;
 use rustc_index::bit_set::BitSet;
+use rustc_middle::mir::*;
+use rustc_middle::ty::TyCtxt;
 
 /// A pass that removes noop landing pads and replaces jumps to them with
 /// `None`. This is important because otherwise LLVM generates terrible
@@ -107,16 +107,13 @@ impl RemoveNoopLandingPads {
                 }
             }
 
-            match body[bb].terminator_mut().unwind_mut() {
-                Some(unwind) => {
-                    if *unwind == Some(resume_block) {
-                        debug!("    removing noop landing pad");
-                        jumps_folded -= 1;
-                        landing_pads_removed += 1;
-                        *unwind = None;
-                    }
+            if let Some(unwind) = body[bb].terminator_mut().unwind_mut() {
+                if *unwind == Some(resume_block) {
+                    debug!("    removing noop landing pad");
+                    jumps_folded -= 1;
+                    landing_pads_removed += 1;
+                    *unwind = None;
                 }
-                _ => {}
             }
 
             let is_nop_landing_pad = self.is_nop_landing_pad(bb, body, &nop_landing_pads);
diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs
index c9a00166f0f..cccf9ff3016 100644
--- a/src/librustc_mir/transform/rustc_peek.rs
+++ b/src/librustc_mir/transform/rustc_peek.rs
@@ -4,10 +4,10 @@ use rustc_span::Span;
 use rustc_target::spec::abi::Abi;
 
 use crate::transform::{MirPass, MirSource};
-use rustc::mir::{self, Body, BodyAndCache, Local, Location};
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_hir::def_id::DefId;
 use rustc_index::bit_set::BitSet;
+use rustc_middle::mir::{self, Body, BodyAndCache, Local, Location};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 
 use crate::dataflow::move_paths::{HasMoveData, MoveData};
 use crate::dataflow::move_paths::{LookupResult, MovePathIndex};
@@ -127,7 +127,7 @@ pub fn sanity_check_via_rustc_peek<'tcx, A>(
                 let loc = Location { block: bb, statement_index };
                 cursor.seek_before(loc);
                 let state = cursor.get();
-                results.analysis.peek_at(tcx, place, state, call);
+                results.analysis.peek_at(tcx, *place, state, call);
             }
 
             _ => {
@@ -231,7 +231,7 @@ pub trait RustcPeekAt<'tcx>: Analysis<'tcx> {
     fn peek_at(
         &self,
         tcx: TyCtxt<'tcx>,
-        place: &mir::Place<'tcx>,
+        place: mir::Place<'tcx>,
         flow_state: &BitSet<Self::Idx>,
         call: PeekCall,
     );
@@ -244,7 +244,7 @@ where
     fn peek_at(
         &self,
         tcx: TyCtxt<'tcx>,
-        place: &mir::Place<'tcx>,
+        place: mir::Place<'tcx>,
         flow_state: &BitSet<Self::Idx>,
         call: PeekCall,
     ) {
@@ -268,7 +268,7 @@ impl<'tcx> RustcPeekAt<'tcx> for MaybeMutBorrowedLocals<'_, 'tcx> {
     fn peek_at(
         &self,
         tcx: TyCtxt<'tcx>,
-        place: &mir::Place<'tcx>,
+        place: mir::Place<'tcx>,
         flow_state: &BitSet<Local>,
         call: PeekCall,
     ) {
diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs
index 4c54a46642f..c2029a223b9 100644
--- a/src/librustc_mir/transform/simplify.rs
+++ b/src/librustc_mir/transform/simplify.rs
@@ -28,11 +28,11 @@
 //! return.
 
 use crate::transform::{MirPass, MirSource};
-use rustc::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
-use rustc::mir::*;
-use rustc::ty::{self, TyCtxt};
 use rustc_index::bit_set::BitSet;
 use rustc_index::vec::{Idx, IndexVec};
+use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
+use rustc_middle::mir::*;
+use rustc_middle::ty::{self, TyCtxt};
 use std::borrow::Cow;
 
 pub struct SimplifyCfg {
@@ -309,7 +309,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyLocals {
         let locals = {
             let read_only_cache = read_only!(body);
             let mut marker = DeclMarker { locals: BitSet::new_empty(body.local_decls.len()), body };
-            marker.visit_body(read_only_cache);
+            marker.visit_body(&read_only_cache);
             // Return pointer and arguments are always live
             marker.locals.insert(RETURN_PLACE);
             for arg in body.args_iter() {
@@ -368,18 +368,22 @@ impl<'a, 'tcx> Visitor<'tcx> for DeclMarker<'a, 'tcx> {
             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/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs
index c233d0b516e..dd666289e39 100644
--- a/src/librustc_mir/transform/simplify_branches.rs
+++ b/src/librustc_mir/transform/simplify_branches.rs
@@ -1,8 +1,8 @@
 //! A pass that simplifies branches when their condition is known.
 
 use crate::transform::{MirPass, MirSource};
-use rustc::mir::*;
-use rustc::ty::TyCtxt;
+use rustc_middle::mir::*;
+use rustc_middle::ty::TyCtxt;
 
 use std::borrow::Cow;
 
diff --git a/src/librustc_mir/transform/simplify_try.rs b/src/librustc_mir/transform/simplify_try.rs
index 1c5f6762c68..7cdd929c7a0 100644
--- a/src/librustc_mir/transform/simplify_try.rs
+++ b/src/librustc_mir/transform/simplify_try.rs
@@ -11,8 +11,8 @@
 
 use crate::transform::{simplify, MirPass, MirSource};
 use itertools::Itertools as _;
-use rustc::mir::*;
-use rustc::ty::{Ty, TyCtxt};
+use rustc_middle::mir::*;
+use rustc_middle::ty::{Ty, TyCtxt};
 use rustc_target::abi::VariantIdx;
 
 /// Simplifies arms of form `Variant(x) => Variant(x)` to just a move.
@@ -89,7 +89,7 @@ fn match_get_variant_field<'tcx>(stmt: &Statement<'tcx>) -> Option<(Local, Local
         StatementKind::Assign(box (place_into, rvalue_from)) => match rvalue_from {
             Rvalue::Use(Operand::Copy(pf)) | Rvalue::Use(Operand::Move(pf)) => {
                 let local_into = place_into.as_local()?;
-                let (local_from, vf) = match_variant_field_place(&pf)?;
+                let (local_from, vf) = match_variant_field_place(*pf)?;
                 Some((local_into, local_from, vf))
             }
             _ => None,
@@ -107,7 +107,7 @@ fn match_set_variant_field<'tcx>(stmt: &Statement<'tcx>) -> Option<(Local, Local
         StatementKind::Assign(box (place_from, rvalue_into)) => match rvalue_into {
             Rvalue::Use(Operand::Move(place_into)) => {
                 let local_into = place_into.as_local()?;
-                let (local_from, vf) = match_variant_field_place(&place_from)?;
+                let (local_from, vf) = match_variant_field_place(*place_from)?;
                 Some((local_into, local_from, vf))
             }
             _ => None,
@@ -137,7 +137,7 @@ struct VarField<'tcx> {
 }
 
 /// Match on `((_LOCAL as Variant).FIELD: TY)`.
-fn match_variant_field_place<'tcx>(place: &Place<'tcx>) -> Option<(Local, VarField<'tcx>)> {
+fn match_variant_field_place<'tcx>(place: Place<'tcx>) -> Option<(Local, VarField<'tcx>)> {
     match place.as_ref() {
         PlaceRef {
             local,
diff --git a/src/librustc_mir/transform/uninhabited_enum_branching.rs b/src/librustc_mir/transform/uninhabited_enum_branching.rs
index 7178e614f0a..0a08c13b479 100644
--- a/src/librustc_mir/transform/uninhabited_enum_branching.rs
+++ b/src/librustc_mir/transform/uninhabited_enum_branching.rs
@@ -1,12 +1,13 @@
 //! A pass that eliminates branches on uninhabited enum variants.
 
 use crate::transform::{MirPass, MirSource};
-use rustc::mir::{
+use rustc_middle::mir::{
     BasicBlock, BasicBlockData, Body, BodyAndCache, Local, Operand, Rvalue, StatementKind,
     TerminatorKind,
 };
-use rustc::ty::layout::{Abi, TyLayout, Variants};
-use rustc::ty::{Ty, TyCtxt};
+use rustc_middle::ty::layout::TyAndLayout;
+use rustc_middle::ty::{Ty, TyCtxt};
+use rustc_target::abi::{Abi, Variants};
 
 pub struct UninhabitedEnumBranching;
 
@@ -49,7 +50,7 @@ fn get_switched_on_type<'tcx>(
 }
 
 fn variant_discriminants<'tcx>(
-    layout: &TyLayout<'tcx>,
+    layout: &TyAndLayout<'tcx>,
     ty: Ty<'tcx>,
     tcx: TyCtxt<'tcx>,
 ) -> Vec<u128> {
diff --git a/src/librustc_mir/transform/unreachable_prop.rs b/src/librustc_mir/transform/unreachable_prop.rs
index c5c84acb6b2..8f636582673 100644
--- a/src/librustc_mir/transform/unreachable_prop.rs
+++ b/src/librustc_mir/transform/unreachable_prop.rs
@@ -4,9 +4,9 @@
 
 use crate::transform::simplify;
 use crate::transform::{MirPass, MirSource};
-use rustc::mir::*;
-use rustc::ty::TyCtxt;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_middle::mir::*;
+use rustc_middle::ty::TyCtxt;
 use std::borrow::Cow;
 
 pub struct UnreachablePropagation;
diff --git a/src/librustc_mir/util/aggregate.rs b/src/librustc_mir/util/aggregate.rs
index 927c8f6dfb2..e77d264b7ce 100644
--- a/src/librustc_mir/util/aggregate.rs
+++ b/src/librustc_mir/util/aggregate.rs
@@ -1,7 +1,7 @@
-use rustc::mir::*;
-use rustc::ty::layout::VariantIdx;
-use rustc::ty::{Ty, TyCtxt};
 use rustc_index::vec::Idx;
+use rustc_middle::mir::*;
+use rustc_middle::ty::{Ty, TyCtxt};
+use rustc_target::abi::VariantIdx;
 
 use std::iter::TrustedLen;
 
diff --git a/src/librustc_mir/util/alignment.rs b/src/librustc_mir/util/alignment.rs
index d7f2abfbe99..202e5e27f1d 100644
--- a/src/librustc_mir/util/alignment.rs
+++ b/src/librustc_mir/util/alignment.rs
@@ -1,5 +1,5 @@
-use rustc::mir::*;
-use rustc::ty::{self, TyCtxt};
+use rustc_middle::mir::*;
+use rustc_middle::ty::{self, TyCtxt};
 
 /// Returns `true` if this place is allowed to be less aligned
 /// than its containing struct (because it is within a packed
@@ -8,7 +8,7 @@ pub fn is_disaligned<'tcx, L>(
     tcx: TyCtxt<'tcx>,
     local_decls: &L,
     param_env: ty::ParamEnv<'tcx>,
-    place: &Place<'tcx>,
+    place: Place<'tcx>,
 ) -> bool
 where
     L: HasLocalDecls<'tcx>,
@@ -34,7 +34,7 @@ where
     }
 }
 
-fn is_within_packed<'tcx, L>(tcx: TyCtxt<'tcx>, local_decls: &L, place: &Place<'tcx>) -> bool
+fn is_within_packed<'tcx, L>(tcx: TyCtxt<'tcx>, local_decls: &L, place: Place<'tcx>) -> bool
 where
     L: HasLocalDecls<'tcx>,
 {
diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs
index 6e6bbabd35b..808dd833774 100644
--- a/src/librustc_mir/util/borrowck_errors.rs
+++ b/src/librustc_mir/util/borrowck_errors.rs
@@ -1,5 +1,5 @@
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_errors::{struct_span_err, DiagnosticBuilder, DiagnosticId};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::{MultiSpan, Span};
 
 impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> {
diff --git a/src/librustc_mir/util/collect_writes.rs b/src/librustc_mir/util/collect_writes.rs
index 6cd21316496..ecf3b08a96e 100644
--- a/src/librustc_mir/util/collect_writes.rs
+++ b/src/librustc_mir/util/collect_writes.rs
@@ -1,7 +1,6 @@
-use rustc::mir::visit::PlaceContext;
-use rustc::mir::visit::Visitor;
-use rustc::mir::ReadOnlyBodyAndCache;
-use rustc::mir::{Local, Location};
+use rustc_middle::mir::visit::PlaceContext;
+use rustc_middle::mir::visit::Visitor;
+use rustc_middle::mir::{Body, Local, Location};
 
 crate trait FindAssignments {
     // Finds all statements that assign directly to local (i.e., X = ...)
@@ -9,10 +8,10 @@ crate trait FindAssignments {
     fn find_assignments(&self, local: Local) -> Vec<Location>;
 }
 
-impl<'a, 'tcx> FindAssignments for ReadOnlyBodyAndCache<'a, 'tcx> {
+impl<'tcx> FindAssignments for Body<'tcx> {
     fn find_assignments(&self, local: Local) -> Vec<Location> {
         let mut visitor = FindLocalAssignmentVisitor { needle: local, locations: vec![] };
-        visitor.visit_body(*self);
+        visitor.visit_body(self);
         visitor.locations
     }
 }
diff --git a/src/librustc_mir/util/def_use.rs b/src/librustc_mir/util/def_use.rs
index aa9ddbdbda9..6b5f6aa991c 100644
--- a/src/librustc_mir/util/def_use.rs
+++ b/src/librustc_mir/util/def_use.rs
@@ -1,11 +1,11 @@
 //! Def-use analysis.
 
-use rustc::mir::visit::{MutVisitor, PlaceContext, Visitor};
-use rustc::mir::{
+use rustc_index::vec::IndexVec;
+use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor};
+use rustc_middle::mir::{
     Body, BodyAndCache, Local, Location, PlaceElem, ReadOnlyBodyAndCache, VarDebugInfo,
 };
-use rustc::ty::TyCtxt;
-use rustc_index::vec::IndexVec;
+use rustc_middle::ty::TyCtxt;
 use std::mem;
 
 pub struct DefUseAnalysis {
@@ -38,7 +38,7 @@ impl DefUseAnalysis {
             var_debug_info_index: 0,
             in_var_debug_info: false,
         };
-        finder.visit_body(body);
+        finder.visit_body(&body);
         self.info = finder.info
     }
 
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index 14895ddfbe4..e3a96ca7896 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::middle::lang_items;
-use rustc::mir::*;
-use rustc::traits::Reveal;
-use rustc::ty::layout::VariantIdx;
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::util::IntTypeExt;
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_hir as hir;
+use rustc_hir::lang_items;
 use rustc_index::vec::Idx;
+use rustc_middle::mir::*;
+use rustc_middle::traits::Reveal;
+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;
@@ -100,7 +100,7 @@ where
 
     source_info: SourceInfo,
 
-    place: &'l Place<'tcx>,
+    place: Place<'tcx>,
     path: D::Path,
     succ: BasicBlock,
     unwind: Unwind,
@@ -109,7 +109,7 @@ where
 pub fn elaborate_drop<'b, 'tcx, D>(
     elaborator: &mut D,
     source_info: SourceInfo,
-    place: &Place<'tcx>,
+    place: Place<'tcx>,
     path: D::Path,
     succ: BasicBlock,
     unwind: Unwind,
@@ -126,7 +126,7 @@ where
     D: DropElaborator<'b, 'tcx>,
     'tcx: 'b,
 {
-    fn place_ty(&self, place: &Place<'tcx>) -> Ty<'tcx> {
+    fn place_ty(&self, place: Place<'tcx>) -> Ty<'tcx> {
         place.ty(self.elaborator.body(), self.tcx()).ty
     }
 
@@ -168,7 +168,7 @@ where
                 self.elaborator.patch().patch_terminator(
                     bb,
                     TerminatorKind::Drop {
-                        location: *self.place,
+                        location: self.place,
                         target: self.succ,
                         unwind: self.unwind.into_option(),
                     },
@@ -195,7 +195,7 @@ where
     /// (the move path is `None` if the field is a rest field).
     fn move_paths_for_fields(
         &self,
-        base_place: &Place<'tcx>,
+        base_place: Place<'tcx>,
         variant_path: D::Path,
         variant: &'tcx ty::VariantDef,
         substs: SubstsRef<'tcx>,
@@ -219,7 +219,7 @@ where
 
     fn drop_subpath(
         &mut self,
-        place: &Place<'tcx>,
+        place: Place<'tcx>,
         path: Option<D::Path>,
         succ: BasicBlock,
         unwind: Unwind,
@@ -267,12 +267,10 @@ where
     ) -> Vec<BasicBlock> {
         Some(succ)
             .into_iter()
-            .chain(fields.iter().rev().zip(unwind_ladder).map(
-                |(&(ref place, path), &unwind_succ)| {
-                    succ = self.drop_subpath(place, path, succ, unwind_succ);
-                    succ
-                },
-            ))
+            .chain(fields.iter().rev().zip(unwind_ladder).map(|(&(place, path), &unwind_succ)| {
+                succ = self.drop_subpath(place, path, succ, unwind_succ);
+                succ
+            }))
             .collect()
     }
 
@@ -315,7 +313,7 @@ where
         debug!("drop_ladder({:?}, {:?})", self, fields);
 
         let mut fields = fields;
-        fields.retain(|&(ref place, _)| {
+        fields.retain(|&(place, _)| {
             self.place_ty(place).needs_drop(self.tcx(), self.elaborator.param_env())
         });
 
@@ -364,7 +362,7 @@ where
         let unwind_succ =
             self.unwind.map(|unwind| self.box_free_block(adt, substs, unwind, Unwind::InCleanup));
 
-        self.drop_subpath(&interior, interior_path, succ, unwind_succ)
+        self.drop_subpath(interior, interior_path, succ, unwind_succ)
     }
 
     fn open_drop_for_adt(&mut self, adt: &'tcx ty::AdtDef, substs: SubstsRef<'tcx>) -> BasicBlock {
@@ -439,8 +437,7 @@ where
                     self.place.clone(),
                     ProjectionElem::Downcast(Some(variant.ident.name), variant_index),
                 );
-                let fields =
-                    self.move_paths_for_fields(&base_place, variant_path, &variant, substs);
+                let fields = self.move_paths_for_fields(base_place, variant_path, &variant, substs);
                 values.push(discr.val);
                 if let Unwind::To(unwind) = unwind {
                     // We can't use the half-ladder from the original
@@ -527,9 +524,9 @@ where
         // way lies only trouble.
         let discr_ty = adt.repr.discr_type().to_ty(self.tcx());
         let discr = Place::from(self.new_temp(discr_ty));
-        let discr_rv = Rvalue::Discriminant(*self.place);
+        let discr_rv = Rvalue::Discriminant(self.place);
         let switch_block = BasicBlockData {
-            statements: vec![self.assign(&discr, discr_rv)],
+            statements: vec![self.assign(discr, discr_rv)],
             terminator: Some(Terminator {
                 source_info: self.source_info,
                 kind: TerminatorKind::SwitchInt {
@@ -560,11 +557,11 @@ where
 
         let result = BasicBlockData {
             statements: vec![self.assign(
-                &Place::from(ref_place),
+                Place::from(ref_place),
                 Rvalue::Ref(
                     tcx.lifetimes.re_erased,
                     BorrowKind::Mut { allow_two_phase_borrow: false },
-                    *self.place,
+                    self.place,
                 ),
             )],
             terminator: Some(Terminator {
@@ -607,7 +604,7 @@ where
         &mut self,
         succ: BasicBlock,
         cur: Local,
-        length_or_end: &Place<'tcx>,
+        length_or_end: Place<'tcx>,
         ety: Ty<'tcx>,
         unwind: Unwind,
         ptr_based: bool,
@@ -617,7 +614,7 @@ where
         let tcx = self.tcx();
 
         let ptr_ty = tcx.mk_ptr(ty::TypeAndMut { ty: ety, mutbl: hir::Mutability::Mut });
-        let ptr = &Place::from(self.new_temp(ptr_ty));
+        let ptr = Place::from(self.new_temp(ptr_ty));
         let can_go = Place::from(self.new_temp(tcx.types.bool));
 
         let one = self.constant_usize(1);
@@ -631,7 +628,7 @@ where
         };
 
         let drop_block = BasicBlockData {
-            statements: vec![self.assign(ptr, ptr_next), self.assign(&Place::from(cur), cur_next)],
+            statements: vec![self.assign(ptr, ptr_next), self.assign(Place::from(cur), cur_next)],
             is_cleanup: unwind.is_cleanup(),
             terminator: Some(Terminator {
                 source_info: self.source_info,
@@ -643,8 +640,8 @@ where
 
         let loop_block = BasicBlockData {
             statements: vec![self.assign(
-                &can_go,
-                Rvalue::BinaryOp(BinOp::Eq, copy(Place::from(cur)), copy(*length_or_end)),
+                can_go,
+                Rvalue::BinaryOp(BinOp::Eq, copy(Place::from(cur)), copy(length_or_end)),
             )],
             is_cleanup: unwind.is_cleanup(),
             terminator: Some(Terminator {
@@ -703,16 +700,16 @@ where
             }
         }
 
-        let move_ = |place: &Place<'tcx>| Operand::Move(*place);
-        let elem_size = &Place::from(self.new_temp(tcx.types.usize));
-        let len = &Place::from(self.new_temp(tcx.types.usize));
+        let move_ = |place: Place<'tcx>| Operand::Move(place);
+        let elem_size = Place::from(self.new_temp(tcx.types.usize));
+        let len = Place::from(self.new_temp(tcx.types.usize));
 
         static USIZE_SWITCH_ZERO: &[u128] = &[0];
 
         let base_block = BasicBlockData {
             statements: vec![
                 self.assign(elem_size, Rvalue::NullaryOp(NullOp::SizeOf, ety)),
-                self.assign(len, Rvalue::Len(*self.place)),
+                self.assign(len, Rvalue::Len(self.place)),
             ],
             is_cleanup: self.unwind.is_cleanup(),
             terminator: Some(Terminator {
@@ -748,10 +745,10 @@ where
         let length_or_end = if ptr_based { Place::from(self.new_temp(iter_ty)) } else { length };
 
         let unwind = self.unwind.map(|unwind| {
-            self.drop_loop(unwind, cur, &length_or_end, ety, Unwind::InCleanup, ptr_based)
+            self.drop_loop(unwind, cur, length_or_end, ety, Unwind::InCleanup, ptr_based)
         });
 
-        let loop_block = self.drop_loop(self.succ, cur, &length_or_end, ety, unwind, ptr_based);
+        let loop_block = self.drop_loop(self.succ, cur, length_or_end, ety, unwind, ptr_based);
 
         let cur = Place::from(cur);
         let drop_block_stmts = if ptr_based {
@@ -761,17 +758,17 @@ where
             // cur = tmp as *mut T;
             // end = Offset(cur, len);
             vec![
-                self.assign(&tmp, Rvalue::AddressOf(Mutability::Mut, *self.place)),
-                self.assign(&cur, Rvalue::Cast(CastKind::Misc, Operand::Move(tmp), iter_ty)),
+                self.assign(tmp, Rvalue::AddressOf(Mutability::Mut, self.place)),
+                self.assign(cur, Rvalue::Cast(CastKind::Misc, Operand::Move(tmp), iter_ty)),
                 self.assign(
-                    &length_or_end,
+                    length_or_end,
                     Rvalue::BinaryOp(BinOp::Offset, Operand::Copy(cur), Operand::Move(length)),
                 ),
             ]
         } else {
             // cur = 0 (length already pushed)
             let zero = self.constant_usize(0);
-            vec![self.assign(&cur, Rvalue::Use(zero))]
+            vec![self.assign(cur, Rvalue::Use(zero))]
         };
         let drop_block = self.elaborator.patch().new_block(BasicBlockData {
             statements: drop_block_stmts,
@@ -935,7 +932,7 @@ where
 
     fn drop_block(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock {
         let block =
-            TerminatorKind::Drop { location: *self.place, target, unwind: unwind.into_option() };
+            TerminatorKind::Drop { location: self.place, target, unwind: unwind.into_option() };
         self.new_block(unwind, block)
     }
 
@@ -992,7 +989,7 @@ where
         })
     }
 
-    fn assign(&self, lhs: &Place<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx> {
-        Statement { source_info: self.source_info, kind: StatementKind::Assign(box (*lhs, rhs)) }
+    fn assign(&self, lhs: Place<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx> {
+        Statement { source_info: self.source_info, kind: StatementKind::Assign(box (lhs, rhs)) }
     }
 }
diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs
index 8291bc95880..aed29a076a4 100644
--- a/src/librustc_mir/util/graphviz.rs
+++ b/src/librustc_mir/util/graphviz.rs
@@ -1,7 +1,7 @@
-use rustc::mir::*;
-use rustc::ty::TyCtxt;
 use rustc_hir::def_id::DefId;
 use rustc_index::vec::Idx;
+use rustc_middle::mir::*;
+use rustc_middle::ty::TyCtxt;
 use std::fmt::Debug;
 use std::io::{self, Write};
 
diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs
index f6c6f555495..a1b7634f0c6 100644
--- a/src/librustc_mir/util/liveness.rs
+++ b/src/librustc_mir/util/liveness.rs
@@ -26,15 +26,15 @@
 
 use crate::transform::MirSource;
 use crate::util::pretty::{dump_enabled, write_basic_block, write_mir_intro};
-use rustc::mir::visit::{
-    MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext, Visitor,
-};
-use rustc::mir::Local;
-use rustc::mir::*;
-use rustc::ty::{self, TyCtxt};
 use rustc_data_structures::work_queue::WorkQueue;
 use rustc_index::bit_set::BitSet;
 use rustc_index::vec::{Idx, IndexVec};
+use rustc_middle::mir::visit::{
+    MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext, Visitor,
+};
+use rustc_middle::mir::Local;
+use rustc_middle::mir::*;
+use rustc_middle::ty::{self, TyCtxt};
 use std::fs;
 use std::io::{self, BufWriter, Write};
 use std::path::{Path, PathBuf};
@@ -265,7 +265,7 @@ pub fn dump_mir<'tcx>(
     body: &Body<'tcx>,
     result: &LivenessResult,
 ) {
-    if !dump_enabled(tcx, pass_name, source) {
+    if !dump_enabled(tcx, pass_name, source.def_id()) {
         return;
     }
     let node_path = ty::print::with_forced_impl_filename_line(|| {
diff --git a/src/librustc_mir/util/patch.rs b/src/librustc_mir/util/patch.rs
index 473692a43f3..46f42f4db05 100644
--- a/src/librustc_mir/util/patch.rs
+++ b/src/librustc_mir/util/patch.rs
@@ -1,6 +1,6 @@
-use rustc::mir::*;
-use rustc::ty::Ty;
 use rustc_index::vec::{Idx, IndexVec};
+use rustc_middle::mir::*;
+use rustc_middle::ty::Ty;
 use rustc_span::Span;
 
 /// This struct represents a patch to MIR, which can add
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index 0368a73832d..a81fcb54580 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -1,13 +1,16 @@
 use super::graphviz::write_mir_fn_graphviz;
 use crate::transform::MirSource;
 use either::Either;
-use rustc::mir::interpret::{read_target_uint, AllocId, Allocation, ConstValue, GlobalAlloc};
-use rustc::mir::visit::Visitor;
-use rustc::mir::*;
-use rustc::ty::{self, layout::Size, TyCtxt, TypeFoldable, TypeVisitor};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_index::vec::Idx;
+use rustc_middle::mir::interpret::{
+    read_target_uint, AllocId, Allocation, ConstValue, GlobalAlloc,
+};
+use rustc_middle::mir::visit::Visitor;
+use rustc_middle::mir::*;
+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 _;
@@ -76,21 +79,21 @@ pub fn dump_mir<'tcx, F>(
 ) where
     F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>,
 {
-    if !dump_enabled(tcx, pass_name, source) {
+    if !dump_enabled(tcx, pass_name, source.def_id()) {
         return;
     }
 
     dump_matched_mir_node(tcx, pass_num, pass_name, disambiguator, source, body, extra_data);
 }
 
-pub fn dump_enabled<'tcx>(tcx: TyCtxt<'tcx>, pass_name: &str, source: MirSource<'tcx>) -> bool {
+pub fn dump_enabled<'tcx>(tcx: TyCtxt<'tcx>, pass_name: &str, def_id: DefId) -> bool {
     let filters = match tcx.sess.opts.debugging_opts.dump_mir {
         None => return false,
         Some(ref filters) => filters,
     };
     let node_path = ty::print::with_forced_impl_filename_line(|| {
         // see notes on #41697 below
-        tcx.def_path_str(source.def_id())
+        tcx.def_path_str(def_id)
     });
     filters.split('|').any(|or_filter| {
         or_filter.split('&').all(|and_filter| {
@@ -389,8 +392,8 @@ impl Visitor<'tcx> for ExtraComments<'tcx> {
 
     fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
         self.super_rvalue(rvalue, location);
-        match rvalue {
-            Rvalue::Aggregate(kind, _) => match **kind {
+        if let Rvalue::Aggregate(kind, _) = rvalue {
+            match **kind {
                 AggregateKind::Closure(def_id, substs) => {
                     self.push("closure");
                     self.push(&format!("+ def_id: {:?}", def_id));
@@ -410,9 +413,7 @@ impl Visitor<'tcx> for ExtraComments<'tcx> {
                 }
 
                 _ => {}
-            },
-
-            _ => {}
+            }
         }
     }
 }
diff --git a/src/librustc_mir_build/Cargo.toml b/src/librustc_mir_build/Cargo.toml
index 96716dbd604..143a3852d73 100644
--- a/src/librustc_mir_build/Cargo.toml
+++ b/src/librustc_mir_build/Cargo.toml
@@ -12,7 +12,7 @@ doctest = false
 [dependencies]
 arena = { path = "../libarena" }
 log = "0.4"
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc_apfloat = { path = "../librustc_apfloat" }
 rustc_attr = { path = "../librustc_attr" }
 rustc_data_structures = { path = "../librustc_data_structures" }
diff --git a/src/librustc_mir_build/build/block.rs b/src/librustc_mir_build/build/block.rs
index df5526ad762..8c41554bc85 100644
--- a/src/librustc_mir_build/build/block.rs
+++ b/src/librustc_mir_build/build/block.rs
@@ -2,14 +2,14 @@ use crate::build::matches::ArmHasGuard;
 use crate::build::ForGuard::OutsideGuard;
 use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
 use crate::hair::*;
-use rustc::mir::*;
+use rustc_middle::mir::*;
 use rustc_hir as hir;
 use rustc_span::Span;
 
 impl<'a, 'tcx> Builder<'a, 'tcx> {
     crate fn ast_block(
         &mut self,
-        destination: &Place<'tcx>,
+        destination: Place<'tcx>,
         block: BasicBlock,
         ast_block: &'tcx hir::Block<'tcx>,
         source_info: SourceInfo,
@@ -43,7 +43,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
     fn ast_block_stmts(
         &mut self,
-        destination: &Place<'tcx>,
+        destination: Place<'tcx>,
         mut block: BasicBlock,
         span: Span,
         stmts: Vec<StmtRef<'tcx>>,
diff --git a/src/librustc_mir_build/build/cfg.rs b/src/librustc_mir_build/build/cfg.rs
index 883aba18ec5..f5828c4ac1f 100644
--- a/src/librustc_mir_build/build/cfg.rs
+++ b/src/librustc_mir_build/build/cfg.rs
@@ -1,7 +1,7 @@
 //! Routines for manipulating the control-flow graph.
 
 use crate::build::CFG;
-use rustc::mir::*;
+use rustc_middle::mir::*;
 
 impl<'tcx> CFG<'tcx> {
     crate fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> {
@@ -34,12 +34,12 @@ impl<'tcx> CFG<'tcx> {
         &mut self,
         block: BasicBlock,
         source_info: SourceInfo,
-        place: &Place<'tcx>,
+        place: Place<'tcx>,
         rvalue: Rvalue<'tcx>,
     ) {
         self.push(
             block,
-            Statement { source_info, kind: StatementKind::Assign(box (*place, rvalue)) },
+            Statement { source_info, kind: StatementKind::Assign(box (place, rvalue)) },
         );
     }
 
@@ -47,7 +47,7 @@ impl<'tcx> CFG<'tcx> {
         &mut self,
         block: BasicBlock,
         source_info: SourceInfo,
-        temp: &Place<'tcx>,
+        temp: Place<'tcx>,
         constant: Constant<'tcx>,
     ) {
         self.push_assign(block, source_info, temp, Rvalue::Use(Operand::Constant(box constant)));
@@ -57,7 +57,7 @@ impl<'tcx> CFG<'tcx> {
         &mut self,
         block: BasicBlock,
         source_info: SourceInfo,
-        place: &Place<'tcx>,
+        place: Place<'tcx>,
     ) {
         self.push_assign(
             block,
diff --git a/src/librustc_mir_build/build/expr/as_constant.rs b/src/librustc_mir_build/build/expr/as_constant.rs
index e4856262975..03ec0b48f8b 100644
--- a/src/librustc_mir_build/build/expr/as_constant.rs
+++ b/src/librustc_mir_build/build/expr/as_constant.rs
@@ -2,8 +2,8 @@
 
 use crate::build::Builder;
 use crate::hair::*;
-use rustc::mir::*;
-use rustc::ty::CanonicalUserTypeAnnotation;
+use rustc_middle::mir::*;
+use rustc_middle::ty::CanonicalUserTypeAnnotation;
 
 impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// Compile `expr`, yielding a compile-time constant. Assumes that
diff --git a/src/librustc_mir_build/build/expr/as_operand.rs b/src/librustc_mir_build/build/expr/as_operand.rs
index efe328d2b3c..783637fa458 100644
--- a/src/librustc_mir_build/build/expr/as_operand.rs
+++ b/src/librustc_mir_build/build/expr/as_operand.rs
@@ -3,8 +3,8 @@
 use crate::build::expr::category::Category;
 use crate::build::{BlockAnd, BlockAndExtension, Builder};
 use crate::hair::*;
-use rustc::middle::region;
-use rustc::mir::*;
+use rustc_middle::middle::region;
+use rustc_middle::mir::*;
 
 impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// Returns an operand suitable for use until the end of the current
diff --git a/src/librustc_mir_build/build/expr/as_place.rs b/src/librustc_mir_build/build/expr/as_place.rs
index 8fa7bc76990..9f74385b336 100644
--- a/src/librustc_mir_build/build/expr/as_place.rs
+++ b/src/librustc_mir_build/build/expr/as_place.rs
@@ -4,10 +4,10 @@ use crate::build::expr::category::Category;
 use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};
 use crate::build::{BlockAnd, BlockAndExtension, Builder};
 use crate::hair::*;
-use rustc::middle::region;
-use rustc::mir::AssertKind::BoundsCheck;
-use rustc::mir::*;
-use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt, Variance};
+use rustc_middle::middle::region;
+use rustc_middle::mir::AssertKind::BoundsCheck;
+use rustc_middle::mir::*;
+use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt, Variance};
 use rustc_span::Span;
 
 use rustc_index::vec::Idx;
@@ -341,12 +341,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let lt = self.temp(bool_ty, expr_span);
 
         // len = len(slice)
-        self.cfg.push_assign(block, source_info, &len, Rvalue::Len(slice));
+        self.cfg.push_assign(block, source_info, len, Rvalue::Len(slice));
         // lt = idx < len
         self.cfg.push_assign(
             block,
             source_info,
-            &lt,
+            lt,
             Rvalue::BinaryOp(BinOp::Lt, Operand::Copy(Place::from(index)), Operand::Copy(len)),
         );
         let msg = BoundsCheck { len: Operand::Move(len), index: Operand::Copy(Place::from(index)) };
@@ -388,7 +388,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         self.cfg.push_assign(
                             block,
                             source_info,
-                            &fake_borrow_temp.into(),
+                            fake_borrow_temp.into(),
                             Rvalue::Ref(
                                 tcx.lifetimes.re_erased,
                                 BorrowKind::Shallow,
diff --git a/src/librustc_mir_build/build/expr/as_rvalue.rs b/src/librustc_mir_build/build/expr/as_rvalue.rs
index 4c7ff504722..20ef763e90c 100644
--- a/src/librustc_mir_build/build/expr/as_rvalue.rs
+++ b/src/librustc_mir_build/build/expr/as_rvalue.rs
@@ -5,10 +5,10 @@ use rustc_index::vec::Idx;
 use crate::build::expr::category::{Category, RvalueFunc};
 use crate::build::{BlockAnd, BlockAndExtension, Builder};
 use crate::hair::*;
-use rustc::middle::region;
-use rustc::mir::AssertKind;
-use rustc::mir::*;
-use rustc::ty::{self, Ty, UpvarSubsts};
+use rustc_middle::middle::region;
+use rustc_middle::mir::AssertKind;
+use rustc_middle::mir::*;
+use rustc_middle::ty::{self, Ty, UpvarSubsts};
 use rustc_span::Span;
 
 impl<'a, 'tcx> Builder<'a, 'tcx> {
@@ -78,7 +78,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     this.cfg.push_assign(
                         block,
                         source_info,
-                        &is_min,
+                        is_min,
                         Rvalue::BinaryOp(BinOp::Eq, arg.to_copy(), minval),
                     );
 
@@ -109,15 +109,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
                 // malloc some memory of suitable type (thus far, uninitialized):
                 let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
-                this.cfg.push_assign(block, source_info, &Place::from(result), box_);
+                this.cfg.push_assign(block, source_info, Place::from(result), box_);
 
                 // initialize the box contents:
                 unpack!(
-                    block = this.into(
-                        &this.hir.tcx().mk_place_deref(Place::from(result)),
-                        block,
-                        value
-                    )
+                    block =
+                        this.into(this.hir.tcx().mk_place_deref(Place::from(result)), block, value)
                 );
                 block.and(Rvalue::Use(Operand::Move(Place::from(result))))
             }
@@ -284,7 +281,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             self.cfg.push_assign(
                 block,
                 source_info,
-                &result_value,
+                result_value,
                 Rvalue::CheckedBinaryOp(op, lhs, rhs),
             );
             let val_fld = Field::new(0);
@@ -317,7 +314,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 self.cfg.push_assign(
                     block,
                     source_info,
-                    &is_zero,
+                    is_zero,
                     Rvalue::BinaryOp(BinOp::Eq, rhs.to_copy(), zero),
                 );
 
@@ -338,13 +335,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     self.cfg.push_assign(
                         block,
                         source_info,
-                        &is_neg_1,
+                        is_neg_1,
                         Rvalue::BinaryOp(BinOp::Eq, rhs.to_copy(), neg_1),
                     );
                     self.cfg.push_assign(
                         block,
                         source_info,
-                        &is_min,
+                        is_min,
                         Rvalue::BinaryOp(BinOp::Eq, lhs.to_copy(), min),
                     );
 
@@ -353,7 +350,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     self.cfg.push_assign(
                         block,
                         source_info,
-                        &of,
+                        of,
                         Rvalue::BinaryOp(BinOp::BitAnd, is_neg_1, is_min),
                     );
 
@@ -428,7 +425,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         this.cfg.push_assign(
             block,
             source_info,
-            &Place::from(temp),
+            Place::from(temp),
             Rvalue::Ref(this.hir.tcx().lifetimes.re_erased, borrow_kind, arg_place),
         );
 
diff --git a/src/librustc_mir_build/build/expr/as_temp.rs b/src/librustc_mir_build/build/expr/as_temp.rs
index 82183e6c96e..73d95575e39 100644
--- a/src/librustc_mir_build/build/expr/as_temp.rs
+++ b/src/librustc_mir_build/build/expr/as_temp.rs
@@ -3,8 +3,8 @@
 use crate::build::scope::DropKind;
 use crate::build::{BlockAnd, BlockAndExtension, Builder};
 use crate::hair::*;
-use rustc::middle::region;
-use rustc::mir::*;
+use rustc_middle::middle::region;
+use rustc_middle::mir::*;
 use rustc_hir as hir;
 use rustc_span::symbol::sym;
 
@@ -66,7 +66,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
             this.local_decls.push(local_decl)
         };
-        let temp_place = &Place::from(temp);
+        let temp_place = Place::from(temp);
 
         match expr.kind {
             // Don't bother with StorageLive and Dead for these temporaries,
diff --git a/src/librustc_mir_build/build/expr/into.rs b/src/librustc_mir_build/build/expr/into.rs
index 62158d3b931..6b93755e9da 100644
--- a/src/librustc_mir_build/build/expr/into.rs
+++ b/src/librustc_mir_build/build/expr/into.rs
@@ -3,8 +3,8 @@
 use crate::build::expr::category::{Category, RvalueFunc};
 use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
 use crate::hair::*;
-use rustc::mir::*;
-use rustc::ty::{self, CanonicalUserTypeAnnotation};
+use rustc_middle::mir::*;
+use rustc_middle::ty::{self, CanonicalUserTypeAnnotation};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
 use rustc_span::symbol::sym;
@@ -16,7 +16,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// is assumed to be uninitialized.
     crate fn into_expr(
         &mut self,
-        destination: &Place<'tcx>,
+        destination: Place<'tcx>,
         mut block: BasicBlock,
         expr: Expr<'tcx>,
     ) -> BlockAnd<()> {
@@ -160,7 +160,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         // introduce a unit temporary as the destination for the loop body.
                         let tmp = this.get_unit_temp();
                         // Execute the body, branching back to the test.
-                        let body_block_end = unpack!(this.into(&tmp, body_block, body));
+                        let body_block_end = unpack!(this.into(tmp, body_block, body));
                         this.cfg.goto(body_block_end, source_info, loop_block);
                     },
                 );
@@ -202,8 +202,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         is_block_tail: None,
                     });
                     let ptr_temp = Place::from(ptr_temp);
-                    let block = unpack!(this.into(&ptr_temp, block, ptr));
-                    this.into(&this.hir.tcx().mk_place_deref(ptr_temp), block, val)
+                    let block = unpack!(this.into(ptr_temp, block, ptr));
+                    this.into(this.hir.tcx().mk_place_deref(ptr_temp), block, val)
                 } else {
                     let args: Vec<_> = args
                         .into_iter()
@@ -228,7 +228,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                             destination: if expr.ty.is_never() {
                                 None
                             } else {
-                                Some((*destination, success))
+                                Some((destination, success))
                             },
                             from_hir_call,
                         },
@@ -373,12 +373,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 this.cfg.terminate(
                     block,
                     source_info,
-                    TerminatorKind::Yield {
-                        value,
-                        resume,
-                        resume_arg: *destination,
-                        drop: cleanup,
-                    },
+                    TerminatorKind::Yield { value, resume, resume_arg: destination, drop: cleanup },
                 );
                 resume.unit()
             }
diff --git a/src/librustc_mir_build/build/expr/stmt.rs b/src/librustc_mir_build/build/expr/stmt.rs
index 1dc530a7bc8..92e1e105185 100644
--- a/src/librustc_mir_build/build/expr/stmt.rs
+++ b/src/librustc_mir_build/build/expr/stmt.rs
@@ -1,8 +1,8 @@
 use crate::build::scope::BreakableTarget;
 use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
 use crate::hair::*;
-use rustc::middle::region;
-use rustc::mir::*;
+use rustc_middle::middle::region;
+use rustc_middle::mir::*;
 
 impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// Builds a block of MIR statements to evaluate the HAIR `expr`.
@@ -50,7 +50,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 } else {
                     let rhs = unpack!(block = this.as_local_rvalue(block, rhs));
                     let lhs = unpack!(block = this.as_place(block, lhs));
-                    this.cfg.push_assign(block, source_info, &lhs, rhs);
+                    this.cfg.push_assign(block, source_info, lhs, rhs);
                 }
 
                 this.block_context.pop();
@@ -82,7 +82,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     block =
                         this.build_binary_op(block, op, expr_span, lhs_ty, Operand::Copy(lhs), rhs)
                 );
-                this.cfg.push_assign(block, source_info, &lhs, result);
+                this.cfg.push_assign(block, source_info, lhs, result);
 
                 this.block_context.pop();
                 block.unit()
diff --git a/src/librustc_mir_build/build/into.rs b/src/librustc_mir_build/build/into.rs
index 1a2a9d2bc05..0baa0c833a5 100644
--- a/src/librustc_mir_build/build/into.rs
+++ b/src/librustc_mir_build/build/into.rs
@@ -6,13 +6,13 @@
 
 use crate::build::{BlockAnd, Builder};
 use crate::hair::*;
-use rustc::mir::*;
+use rustc_middle::mir::*;
 
 pub(in crate::build) trait EvalInto<'tcx> {
     fn eval_into(
         self,
         builder: &mut Builder<'_, 'tcx>,
-        destination: &Place<'tcx>,
+        destination: Place<'tcx>,
         block: BasicBlock,
     ) -> BlockAnd<()>;
 }
@@ -20,7 +20,7 @@ pub(in crate::build) trait EvalInto<'tcx> {
 impl<'a, 'tcx> Builder<'a, 'tcx> {
     crate fn into<E>(
         &mut self,
-        destination: &Place<'tcx>,
+        destination: Place<'tcx>,
         block: BasicBlock,
         expr: E,
     ) -> BlockAnd<()>
@@ -35,7 +35,7 @@ impl<'tcx> EvalInto<'tcx> for ExprRef<'tcx> {
     fn eval_into(
         self,
         builder: &mut Builder<'_, 'tcx>,
-        destination: &Place<'tcx>,
+        destination: Place<'tcx>,
         block: BasicBlock,
     ) -> BlockAnd<()> {
         let expr = builder.hir.mirror(self);
@@ -47,7 +47,7 @@ impl<'tcx> EvalInto<'tcx> for Expr<'tcx> {
     fn eval_into(
         self,
         builder: &mut Builder<'_, 'tcx>,
-        destination: &Place<'tcx>,
+        destination: Place<'tcx>,
         block: BasicBlock,
     ) -> BlockAnd<()> {
         builder.into_expr(destination, block, self)
diff --git a/src/librustc_mir_build/build/matches/mod.rs b/src/librustc_mir_build/build/matches/mod.rs
index e7c7e2b47f2..a4a9271669e 100644
--- a/src/librustc_mir_build/build/matches/mod.rs
+++ b/src/librustc_mir_build/build/matches/mod.rs
@@ -10,16 +10,16 @@ use crate::build::ForGuard::{self, OutsideGuard, RefWithinGuard};
 use crate::build::{BlockAnd, BlockAndExtension, Builder};
 use crate::build::{GuardFrame, GuardFrameLocal, LocalsForNode};
 use crate::hair::{self, *};
-use rustc::middle::region;
-use rustc::mir::*;
-use rustc::ty::layout::VariantIdx;
-use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty};
+use rustc_ast::ast::Name;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir::HirId;
 use rustc_index::bit_set::BitSet;
+use rustc_middle::middle::region;
+use rustc_middle::mir::*;
+use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty};
 use rustc_span::Span;
+use rustc_target::abi::VariantIdx;
 use smallvec::{smallvec, SmallVec};
-use rustc_ast::ast::Name;
 
 // helper functions, broken out by category:
 mod simplify;
@@ -83,7 +83,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// * From each otherwise block to the next prebinding block.
     crate fn match_expr(
         &mut self,
-        destination: &Place<'tcx>,
+        destination: Place<'tcx>,
         span: Span,
         mut block: BasicBlock,
         scrutinee: ExprRef<'tcx>,
@@ -218,7 +218,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// `outer_source_info` is the SourceInfo for the whole match.
     fn lower_match_arms(
         &mut self,
-        destination: &Place<'tcx>,
+        destination: Place<'tcx>,
         scrutinee_place: Place<'tcx>,
         scrutinee_span: Span,
         arm_candidates: Vec<(&'_ Arm<'tcx>, Candidate<'_, 'tcx>)>,
@@ -364,7 +364,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             PatKind::Binding { mode: BindingMode::ByValue, var, subpattern: None, .. } => {
                 let place =
                     self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true);
-                unpack!(block = self.into(&place, block, initializer));
+                unpack!(block = self.into(place, block, initializer));
 
                 // Inject a fake read, see comments on `FakeReadCause::ForLet`.
                 let source_info = self.source_info(irrefutable_pat.span);
@@ -399,7 +399,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             } => {
                 let place =
                     self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true);
-                unpack!(block = self.into(&place, block, initializer));
+                unpack!(block = self.into(place, block, initializer));
 
                 // Inject a fake read, see comments on `FakeReadCause::ForLet`.
                 let pattern_source_info = self.source_info(irrefutable_pat.span);
@@ -1691,7 +1691,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             let scrutinee_source_info = self.source_info(scrutinee_span);
             for &(place, temp) in fake_borrows {
                 let borrow = Rvalue::Ref(re_erased, BorrowKind::Shallow, place);
-                self.cfg.push_assign(block, scrutinee_source_info, &Place::from(temp), borrow);
+                self.cfg.push_assign(block, scrutinee_source_info, Place::from(temp), borrow);
             }
 
             // the block to branch to if the guard fails; if there is no
@@ -1858,7 +1858,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             match binding.binding_mode {
                 BindingMode::ByValue => {
                     let rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, binding.source);
-                    self.cfg.push_assign(block, source_info, &ref_for_guard, rvalue);
+                    self.cfg.push_assign(block, source_info, ref_for_guard, rvalue);
                 }
                 BindingMode::ByRef(borrow_kind) => {
                     let value_for_arm = self.storage_live_binding(
@@ -1870,9 +1870,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     );
 
                     let rvalue = Rvalue::Ref(re_erased, borrow_kind, binding.source);
-                    self.cfg.push_assign(block, source_info, &value_for_arm, rvalue);
+                    self.cfg.push_assign(block, source_info, value_for_arm, rvalue);
                     let rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, value_for_arm);
-                    self.cfg.push_assign(block, source_info, &ref_for_guard, rvalue);
+                    self.cfg.push_assign(block, source_info, ref_for_guard, rvalue);
                 }
             }
         }
@@ -1910,7 +1910,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     Rvalue::Ref(re_erased, borrow_kind, binding.source)
                 }
             };
-            self.cfg.push_assign(block, source_info, &local, rvalue);
+            self.cfg.push_assign(block, source_info, local, rvalue);
         }
     }
 
diff --git a/src/librustc_mir_build/build/matches/simplify.rs b/src/librustc_mir_build/build/matches/simplify.rs
index aea4f5f1b3a..d74d8b5c7f3 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::mir::interpret::truncate;
-use rustc::mir::Place;
-use rustc::ty;
-use rustc::ty::layout::{Integer, IntegerExt, Size};
 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::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 d23a2708dc4..c049842d061 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::matches::{Candidate, MatchPair, Test, TestKind};
 use crate::build::Builder;
 use crate::hair::pattern::compare_const_vals;
 use crate::hair::*;
-use rustc::mir::*;
-use rustc::ty::layout::VariantIdx;
-use rustc::ty::util::IntTypeExt;
-use rustc::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;
 
@@ -202,7 +202,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 );
                 let discr_ty = adt_def.repr.discr_type().to_ty(tcx);
                 let discr = self.temp(discr_ty, test.span);
-                self.cfg.push_assign(block, source_info, &discr, Rvalue::Discriminant(place));
+                self.cfg.push_assign(block, source_info, discr, Rvalue::Discriminant(place));
                 assert_eq!(values.len() + 1, targets.len());
                 self.cfg.terminate(
                     block,
@@ -303,7 +303,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 let actual = self.temp(usize_ty, test.span);
 
                 // actual = len(place)
-                self.cfg.push_assign(block, source_info, &actual, Rvalue::Len(place));
+                self.cfg.push_assign(block, source_info, actual, Rvalue::Len(place));
 
                 // expected = <N>
                 let expected = self.push_usize(block, source_info, len);
@@ -342,7 +342,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let result = self.temp(bool_ty, source_info.span);
 
         // result = op(left, right)
-        self.cfg.push_assign(block, source_info, &result, Rvalue::BinaryOp(op, left, right));
+        self.cfg.push_assign(block, source_info, result, Rvalue::BinaryOp(op, left, right));
 
         // branch based on result
         self.cfg.terminate(
@@ -362,7 +362,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         place: Place<'tcx>,
         mut ty: Ty<'tcx>,
     ) {
-        use rustc::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);
@@ -394,7 +394,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     self.cfg.push_assign(
                         block,
                         source_info,
-                        &temp,
+                        temp,
                         Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), val, ty),
                     );
                     val = Operand::Move(temp);
@@ -404,7 +404,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     self.cfg.push_assign(
                         block,
                         source_info,
-                        &slice,
+                        slice,
                         Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), expect, ty),
                     );
                     expect = Operand::Move(slice);
diff --git a/src/librustc_mir_build/build/matches/util.rs b/src/librustc_mir_build/build/matches/util.rs
index def8d1b2fd8..967a44b9b96 100644
--- a/src/librustc_mir_build/build/matches/util.rs
+++ b/src/librustc_mir_build/build/matches/util.rs
@@ -1,8 +1,8 @@
 use crate::build::matches::MatchPair;
 use crate::build::Builder;
 use crate::hair::*;
-use rustc::mir::*;
-use rustc::ty;
+use rustc_middle::mir::*;
+use rustc_middle::ty;
 use smallvec::SmallVec;
 use std::convert::TryInto;
 use std::u32;
diff --git a/src/librustc_mir_build/build/misc.rs b/src/librustc_mir_build/build/misc.rs
index 3d5145b6960..8f98dd9b70e 100644
--- a/src/librustc_mir_build/build/misc.rs
+++ b/src/librustc_mir_build/build/misc.rs
@@ -3,9 +3,9 @@
 
 use crate::build::Builder;
 
-use rustc::ty::{self, Ty};
+use rustc_middle::ty::{self, Ty};
 
-use rustc::mir::*;
+use rustc_middle::mir::*;
 use rustc_span::{Span, DUMMY_SP};
 
 impl<'a, 'tcx> Builder<'a, 'tcx> {
@@ -55,7 +55,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         self.cfg.push_assign_constant(
             block,
             source_info,
-            &temp,
+            temp,
             Constant {
                 span: source_info.span,
                 user_ty: None,
diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs
index a7ec4f501ae..24395702020 100644
--- a/src/librustc_mir_build/build/mod.rs
+++ b/src/librustc_mir_build/build/mod.rs
@@ -2,17 +2,17 @@ use crate::build;
 use crate::build::scope::DropKind;
 use crate::hair::cx::Cx;
 use crate::hair::{BindingMode, LintLevel, PatKind};
-use rustc::middle::lang_items;
-use rustc::middle::region;
-use rustc::mir::*;
-use rustc::ty::subst::Subst;
-use rustc::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::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_span::symbol::kw;
 use rustc_span::Span;
 use rustc_target::spec::abi::Abi;
@@ -663,7 +663,7 @@ fn construct_const<'a, 'tcx>(
     let mut block = START_BLOCK;
     let ast_expr = &tcx.hir().body(body_id).value;
     let expr = builder.hir.mirror(ast_expr);
-    unpack!(block = builder.into_expr(&Place::return_place(), block, expr));
+    unpack!(block = builder.into_expr(Place::return_place(), block, expr));
 
     let source_info = builder.source_info(span);
     builder.cfg.terminate(block, source_info, TerminatorKind::Return);
@@ -969,7 +969,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
 
         let body = self.hir.mirror(ast_body);
-        self.into(&Place::return_place(), block, body)
+        self.into(Place::return_place(), block, body)
     }
 
     fn set_correct_source_scope_for_arg(
diff --git a/src/librustc_mir_build/build/scope.rs b/src/librustc_mir_build/build/scope.rs
index a63ac06ec3f..3689e5cb9d8 100644
--- a/src/librustc_mir_build/build/scope.rs
+++ b/src/librustc_mir_build/build/scope.rs
@@ -84,8 +84,8 @@ should go to.
 
 use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder, CFG};
 use crate::hair::{Expr, ExprRef, LintLevel};
-use rustc::middle::region;
-use rustc::mir::*;
+use rustc_middle::middle::region;
+use rustc_middle::mir::*;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
 use rustc_hir::GeneratorKind;
@@ -520,10 +520,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             if let Some(value) = value {
                 debug!("stmt_expr Break val block_context.push(SubExpr)");
                 self.block_context.push(BlockFrame::SubExpr);
-                unpack!(block = self.into(&destination, block, value));
+                unpack!(block = self.into(destination, block, value));
                 self.block_context.pop();
             } else {
-                self.cfg.push_assign_unit(block, source_info, &destination)
+                self.cfg.push_assign_unit(block, source_info, destination)
             }
         } else {
             assert!(value.is_none(), "`return` and `break` should have a destination");
diff --git a/src/librustc_mir_build/hair/constant.rs b/src/librustc_mir_build/hair/constant.rs
index d5e5398b9d4..e5af0b5bd6b 100644
--- a/src/librustc_mir_build/hair/constant.rs
+++ b/src/librustc_mir_build/hair/constant.rs
@@ -1,9 +1,10 @@
-use rustc::mir::interpret::{
+use rustc_ast::ast;
+use rustc_middle::mir::interpret::{
     truncate, Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar,
 };
-use rustc::ty::{self, layout::Size, ParamEnv, TyCtxt, TyS};
-use rustc_ast::ast;
+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/block.rs b/src/librustc_mir_build/hair/cx/block.rs
index 07a9d91cd74..c7b53024666 100644
--- a/src/librustc_mir_build/hair/cx/block.rs
+++ b/src/librustc_mir_build/hair/cx/block.rs
@@ -2,9 +2,9 @@ use crate::hair::cx::to_ref::ToRef;
 use crate::hair::cx::Cx;
 use crate::hair::{self, *};
 
-use rustc::middle::region;
-use rustc::ty;
 use rustc_hir as hir;
+use rustc_middle::middle::region;
+use rustc_middle::ty;
 
 use rustc_index::vec::Idx;
 
diff --git a/src/librustc_mir_build/hair/cx/expr.rs b/src/librustc_mir_build/hair/cx/expr.rs
index ba17e2a75aa..21d632b9f6b 100644
--- a/src/librustc_mir_build/hair/cx/expr.rs
+++ b/src/librustc_mir_build/hair/cx/expr.rs
@@ -3,14 +3,16 @@ use crate::hair::cx::to_ref::ToRef;
 use crate::hair::cx::Cx;
 use crate::hair::util::UserAnnotatedTyHelpers;
 use crate::hair::*;
-use rustc::mir::interpret::Scalar;
-use rustc::mir::BorrowKind;
-use rustc::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCast};
-use rustc::ty::subst::{InternalSubsts, SubstsRef};
-use rustc::ty::{self, AdtKind, Ty};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
 use rustc_index::vec::Idx;
+use rustc_middle::mir::interpret::Scalar;
+use rustc_middle::mir::BorrowKind;
+use rustc_middle::ty::adjustment::{
+    Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCast,
+};
+use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
+use rustc_middle::ty::{self, AdtKind, Ty};
 use rustc_span::Span;
 
 impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr<'tcx> {
@@ -478,7 +480,7 @@ fn make_mirror_unadjusted<'a, 'tcx>(
                             ) => {
                                 let idx = adt_def.variant_index_with_ctor_id(variant_ctor_id);
                                 let (d, o) = adt_def.discriminant_def_for_variant(idx);
-                                use rustc::ty::util::IntTypeExt;
+                                use rustc_middle::ty::util::IntTypeExt;
                                 let ty = adt_def.repr.discr_type();
                                 let ty = ty.to_ty(cx.tcx());
                                 Some((d, o, ty))
@@ -631,7 +633,7 @@ trait ToBorrowKind {
 
 impl ToBorrowKind for AutoBorrowMutability {
     fn to_borrow_kind(&self) -> BorrowKind {
-        use rustc::ty::adjustment::AllowTwoPhase;
+        use rustc_middle::ty::adjustment::AllowTwoPhase;
         match *self {
             AutoBorrowMutability::Mut { allow_two_phase_borrow } => BorrowKind::Mut {
                 allow_two_phase_borrow: match allow_two_phase_borrow {
diff --git a/src/librustc_mir_build/hair/cx/mod.rs b/src/librustc_mir_build/hair/cx/mod.rs
index 99caa6a0f95..503bd26d51f 100644
--- a/src/librustc_mir_build/hair/cx/mod.rs
+++ b/src/librustc_mir_build/hair/cx/mod.rs
@@ -5,12 +5,6 @@
 use crate::hair::util::UserAnnotatedTyHelpers;
 use crate::hair::*;
 
-use rustc::middle::region;
-use rustc::mir::interpret::{LitToConstError, LitToConstInput};
-use rustc::ty::layout::VariantIdx;
-use rustc::ty::subst::Subst;
-use rustc::ty::subst::{GenericArg, InternalSubsts};
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_ast::ast;
 use rustc_ast::attr;
 use rustc_hir as hir;
@@ -18,7 +12,13 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::Node;
 use rustc_index::vec::Idx;
 use rustc_infer::infer::InferCtxt;
+use rustc_middle::middle::region;
+use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
+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 ed60c79903d..601e4412512 100644
--- a/src/librustc_mir_build/hair/mod.rs
+++ b/src/librustc_mir_build/hair/mod.rs
@@ -5,16 +5,16 @@
 //! structures.
 
 use self::cx::Cx;
-use rustc::infer::canonical::Canonical;
-use rustc::middle::region;
-use rustc::mir::{BinOp, BorrowKind, Field, UnOp};
-use rustc::ty::adjustment::PointerCast;
-use rustc::ty::layout::VariantIdx;
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::{AdtDef, Const, Ty, UpvarSubsts, UserType};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_middle::infer::canonical::Canonical;
+use rustc_middle::middle::region;
+use rustc_middle::mir::{BinOp, BorrowKind, Field, UnOp};
+use rustc_middle::ty::adjustment::PointerCast;
+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 5c69cea8b91..8c0843124f4 100644
--- a/src/librustc_mir_build/hair/pattern/_match.rs
+++ b/src/librustc_mir_build/hair/pattern/_match.rs
@@ -235,16 +235,17 @@ use rustc_index::vec::Idx;
 use super::{compare_const_vals, PatternFoldable, PatternFolder};
 use super::{FieldPat, Pat, PatKind, PatRange};
 
-use rustc::mir::interpret::{truncate, AllocId, ConstValue, Pointer, Scalar};
-use rustc::mir::Field;
-use rustc::ty::layout::{Integer, IntegerExt, Size, VariantIdx};
-use rustc::ty::{self, Const, Ty, TyCtxt, TypeFoldable, VariantDef};
-use rustc::util::common::ErrorReported;
 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::IntegerExt;
+use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeFoldable, VariantDef};
 use rustc_session::lint;
 use rustc_span::{Span, DUMMY_SP};
+use rustc_target::abi::{Integer, Size, VariantIdx};
 
 use arena::TypedArena;
 
@@ -1974,15 +1975,12 @@ fn slice_pat_covered_by_const<'tcx>(
         .zip(prefix)
         .chain(data[data.len() - suffix.len()..].iter().zip(suffix))
     {
-        match pat.kind {
-            box PatKind::Constant { value } => {
-                let b = value.eval_bits(tcx, param_env, pat.ty);
-                assert_eq!(b as u8 as u128, b);
-                if b as u8 != *ch {
-                    return Ok(false);
-                }
+        if let box PatKind::Constant { value } = pat.kind {
+            let b = value.eval_bits(tcx, param_env, pat.ty);
+            assert_eq!(b as u8 as u128, b);
+            if b as u8 != *ch {
+                return Ok(false);
             }
-            _ => {}
         }
     }
 
@@ -2197,8 +2195,8 @@ fn split_grouped_constructors<'p, 'tcx>(
                 let head_ctors =
                     matrix.heads().filter_map(|pat| pat_constructor(tcx, param_env, pat));
                 for ctor in head_ctors {
-                    match ctor {
-                        Slice(slice) => match slice.pattern_kind() {
+                    if let Slice(slice) = ctor {
+                        match slice.pattern_kind() {
                             FixedLen(len) => {
                                 max_fixed_len = cmp::max(max_fixed_len, len);
                             }
@@ -2206,8 +2204,7 @@ fn split_grouped_constructors<'p, 'tcx>(
                                 max_prefix_len = cmp::max(max_prefix_len, prefix);
                                 max_suffix_len = cmp::max(max_suffix_len, suffix);
                             }
-                        },
-                        _ => {}
+                        }
                     }
                 }
 
diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs
index e29bbf8fa6e..cdbcaea0bef 100644
--- a/src/librustc_mir_build/hair/pattern/check_match.rs
+++ b/src/librustc_mir_build/hair/pattern/check_match.rs
@@ -4,7 +4,6 @@ use super::_match::{expand_pattern, is_useful, MatchCheckCtxt, Matrix, PatStack}
 
 use super::{PatCtxt, PatKind, PatternError};
 
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_ast::ast::Mutability;
 use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
@@ -12,6 +11,7 @@ use rustc_hir::def::*;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::{HirId, Pat};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::lint::builtin::BINDINGS_WITH_VARIANT_NAME;
 use rustc_session::lint::builtin::{IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS};
 use rustc_session::parse::feature_err;
@@ -91,14 +91,14 @@ impl PatCtxt<'_, '_> {
                 }
                 PatternError::FloatBug => {
                     // FIXME(#31407) this is only necessary because float parsing is buggy
-                    ::rustc::mir::interpret::struct_error(
+                    ::rustc_middle::mir::interpret::struct_error(
                         self.tcx.at(pat_span),
                         "could not evaluate float literal (see issue #31407)",
                     )
                     .emit();
                 }
                 PatternError::NonConstPath(span) => {
-                    ::rustc::mir::interpret::struct_error(
+                    ::rustc_middle::mir::interpret::struct_error(
                         self.tcx.at(span),
                         "runtime values cannot be referenced in patterns",
                     )
diff --git a/src/librustc_mir_build/hair/pattern/const_to_pat.rs b/src/librustc_mir_build/hair/pattern/const_to_pat.rs
index ae951e810e3..50034fb02ac 100644
--- a/src/librustc_mir_build/hair/pattern/const_to_pat.rs
+++ b/src/librustc_mir_build/hair/pattern/const_to_pat.rs
@@ -1,8 +1,8 @@
-use rustc::mir::Field;
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_hir as hir;
 use rustc_index::vec::Idx;
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
+use rustc_middle::mir::Field;
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::lint;
 use rustc_span::Span;
 use rustc_trait_selection::traits::predicate_for_trait_def;
diff --git a/src/librustc_mir_build/hair/pattern/mod.rs b/src/librustc_mir_build/hair/pattern/mod.rs
index 6786c356293..2b6d8e920f5 100644
--- a/src/librustc_mir_build/hair/pattern/mod.rs
+++ b/src/librustc_mir_build/hair/pattern/mod.rs
@@ -8,14 +8,6 @@ pub(crate) use self::check_match::check_match;
 
 use crate::hair::util::UserAnnotatedTyHelpers;
 
-use rustc::mir::interpret::{get_slice_bytes, sign_extend, ConstValue, ErrorHandled};
-use rustc::mir::interpret::{LitToConstError, LitToConstInput};
-use rustc::mir::UserTypeProjection;
-use rustc::mir::{BorrowKind, Field, Mutability};
-use rustc::ty::layout::VariantIdx;
-use rustc::ty::subst::{GenericArg, SubstsRef};
-use rustc::ty::{self, AdtDef, DefIdTree, Region, Ty, TyCtxt, UserType};
-use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations};
 use rustc_ast::ast;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
@@ -23,7 +15,17 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
 use rustc_hir::pat_util::EnumerateAndAdjustIterator;
 use rustc_hir::RangeEnd;
 use rustc_index::vec::Idx;
+use rustc_middle::mir::interpret::{get_slice_bytes, sign_extend, ConstValue, ErrorHandled};
+use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
+use rustc_middle::mir::UserTypeProjection;
+use rustc_middle::mir::{BorrowKind, Field, Mutability};
+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;
@@ -1044,9 +1046,9 @@ crate fn compare_const_vals<'tcx>(
                 l.partial_cmp(&r)
             }
             ty::Int(ity) => {
-                use rustc::ty::layout::{Integer, IntegerExt};
                 use rustc_attr::SignedInt;
-                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)))
@@ -1056,18 +1058,15 @@ crate fn compare_const_vals<'tcx>(
     }
 
     if let ty::Str = ty.kind {
-        match (a.val, b.val) {
-            (
-                ty::ConstKind::Value(a_val @ ConstValue::Slice { .. }),
-                ty::ConstKind::Value(b_val @ ConstValue::Slice { .. }),
-            ) => {
-                let a_bytes = get_slice_bytes(&tcx, a_val);
-                let b_bytes = get_slice_bytes(&tcx, b_val);
-                return from_bool(a_bytes == b_bytes);
-            }
-            _ => (),
+        if let (
+            ty::ConstKind::Value(a_val @ ConstValue::Slice { .. }),
+            ty::ConstKind::Value(b_val @ ConstValue::Slice { .. }),
+        ) = (a.val, b.val)
+        {
+            let a_bytes = get_slice_bytes(&tcx, a_val);
+            let b_bytes = get_slice_bytes(&tcx, b_val);
+            return from_bool(a_bytes == b_bytes);
         }
     }
-
     fallback()
 }
diff --git a/src/librustc_mir_build/hair/util.rs b/src/librustc_mir_build/hair/util.rs
index c27844ed0d0..0ea0d5d1b0c 100644
--- a/src/librustc_mir_build/hair/util.rs
+++ b/src/librustc_mir_build/hair/util.rs
@@ -1,5 +1,5 @@
-use rustc::ty::{self, CanonicalUserType, TyCtxt, UserType};
 use rustc_hir as hir;
+use rustc_middle::ty::{self, CanonicalUserType, TyCtxt, UserType};
 
 crate trait UserAnnotatedTyHelpers<'tcx> {
     fn tcx(&self) -> TyCtxt<'tcx>;
diff --git a/src/librustc_mir_build/lib.rs b/src/librustc_mir_build/lib.rs
index 5a8b5a32963..d691071e0e4 100644
--- a/src/librustc_mir_build/lib.rs
+++ b/src/librustc_mir_build/lib.rs
@@ -14,13 +14,13 @@
 #[macro_use]
 extern crate log;
 #[macro_use]
-extern crate rustc;
+extern crate rustc_middle;
 
 mod build;
 mod hair;
 mod lints;
 
-use rustc::ty::query::Providers;
+use rustc_middle::ty::query::Providers;
 
 pub fn provide(providers: &mut Providers<'_>) {
     providers.check_match = hair::pattern::check_match;
diff --git a/src/librustc_mir_build/lints.rs b/src/librustc_mir_build/lints.rs
index 3f927422616..b1628ec58c3 100644
--- a/src/librustc_mir_build/lints.rs
+++ b/src/librustc_mir_build/lints.rs
@@ -1,10 +1,10 @@
-use rustc::hir::map::blocks::FnLikeNode;
-use rustc::mir::{self, Body, TerminatorKind};
-use rustc::ty::subst::InternalSubsts;
-use rustc::ty::{self, AssocItem, AssocItemContainer, Instance, TyCtxt};
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::FnKind;
 use rustc_index::bit_set::BitSet;
+use rustc_middle::hir::map::blocks::FnLikeNode;
+use rustc_middle::mir::{self, Body, TerminatorKind};
+use rustc_middle::ty::subst::InternalSubsts;
+use rustc_middle::ty::{self, AssocItem, AssocItemContainer, Instance, TyCtxt};
 use rustc_session::lint::builtin::UNCONDITIONAL_RECURSION;
 
 crate fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId) {
diff --git a/src/librustc_parse/lexer/mod.rs b/src/librustc_parse/lexer/mod.rs
index ac58cbb9e8d..96321ef2145 100644
--- a/src/librustc_parse/lexer/mod.rs
+++ b/src/librustc_parse/lexer/mod.rs
@@ -1,20 +1,20 @@
 use rustc_ast::token::{self, Token, TokenKind};
 use rustc_ast::util::comments;
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::{error_code, DiagnosticBuilder, FatalError};
-use rustc_lexer::unescape;
+use rustc_errors::{error_code, Applicability, DiagnosticBuilder, FatalError};
 use rustc_lexer::Base;
+use rustc_lexer::{unescape, LexRawStrError, UnvalidatedRawStr, ValidatedRawStr};
 use rustc_session::parse::ParseSess;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{BytePos, Pos, Span};
 
 use log::debug;
 use std::char;
-use std::convert::TryInto;
 
 mod tokentrees;
 mod unescape_error_reporting;
 mod unicode_chars;
+
 use unescape_error_reporting::{emit_unescape_error, push_escaped_char};
 
 #[derive(Clone, Debug)]
@@ -93,9 +93,6 @@ impl<'a> StringReader<'a> {
     }
 
     /// Returns the next token, including trivia like whitespace or comments.
-    ///
-    /// `Err(())` means that some errors were encountered, which can be
-    /// retrieved using `buffer_fatal_errors`.
     pub fn next_token(&mut self) -> Token {
         let start_src_index = self.src_index(self.pos);
         let text: &str = &self.src[start_src_index..self.end_src_index];
@@ -376,30 +373,22 @@ impl<'a> StringReader<'a> {
                 let id = self.symbol_from_to(content_start, content_end);
                 (token::ByteStr, id)
             }
-            rustc_lexer::LiteralKind::RawStr { n_hashes, started, terminated } => {
-                if !started {
-                    self.report_non_started_raw_string(start);
-                }
-                if !terminated {
-                    self.report_unterminated_raw_string(start, n_hashes)
-                }
-                let n_hashes: u16 = self.restrict_n_hashes(start, n_hashes);
+            rustc_lexer::LiteralKind::RawStr(unvalidated_raw_str) => {
+                let valid_raw_str = self.validate_and_report_errors(start, unvalidated_raw_str);
+                let n_hashes = valid_raw_str.num_hashes();
                 let n = u32::from(n_hashes);
+
                 let content_start = start + BytePos(2 + n);
                 let content_end = suffix_start - BytePos(1 + n);
                 self.validate_raw_str_escape(content_start, content_end);
                 let id = self.symbol_from_to(content_start, content_end);
                 (token::StrRaw(n_hashes), id)
             }
-            rustc_lexer::LiteralKind::RawByteStr { n_hashes, started, terminated } => {
-                if !started {
-                    self.report_non_started_raw_string(start);
-                }
-                if !terminated {
-                    self.report_unterminated_raw_string(start, n_hashes)
-                }
-                let n_hashes: u16 = self.restrict_n_hashes(start, n_hashes);
+            rustc_lexer::LiteralKind::RawByteStr(unvalidated_raw_str) => {
+                let validated_raw_str = self.validate_and_report_errors(start, unvalidated_raw_str);
+                let n_hashes = validated_raw_str.num_hashes();
                 let n = u32::from(n_hashes);
+
                 let content_start = start + BytePos(3 + n);
                 let content_end = suffix_start - BytePos(1 + n);
                 self.validate_raw_byte_str_escape(content_start, content_end);
@@ -485,6 +474,26 @@ impl<'a> StringReader<'a> {
         }
     }
 
+    fn validate_and_report_errors(
+        &self,
+        start: BytePos,
+        unvalidated_raw_str: UnvalidatedRawStr,
+    ) -> ValidatedRawStr {
+        match unvalidated_raw_str.validate() {
+            Err(LexRawStrError::InvalidStarter) => self.report_non_started_raw_string(start),
+            Err(LexRawStrError::NoTerminator { expected, found, possible_terminator_offset }) => {
+                self.report_unterminated_raw_string(
+                    start,
+                    expected,
+                    possible_terminator_offset,
+                    found,
+                )
+            }
+            Err(LexRawStrError::TooManyDelimiters) => self.report_too_many_hashes(start),
+            Ok(valid) => valid,
+        }
+    }
+
     fn report_non_started_raw_string(&self, start: BytePos) -> ! {
         let bad_char = self.str_from(start).chars().last().unwrap();
         self.struct_fatal_span_char(
@@ -498,38 +507,51 @@ impl<'a> StringReader<'a> {
         FatalError.raise()
     }
 
-    fn report_unterminated_raw_string(&self, start: BytePos, n_hashes: usize) -> ! {
+    fn report_unterminated_raw_string(
+        &self,
+        start: BytePos,
+        n_hashes: usize,
+        possible_offset: Option<usize>,
+        found_terminators: usize,
+    ) -> ! {
         let mut err = self.sess.span_diagnostic.struct_span_fatal_with_code(
             self.mk_sp(start, start),
             "unterminated raw string",
             error_code!(E0748),
         );
+
         err.span_label(self.mk_sp(start, start), "unterminated raw string");
 
         if n_hashes > 0 {
             err.note(&format!(
                 "this raw string should be terminated with `\"{}`",
-                "#".repeat(n_hashes as usize)
+                "#".repeat(n_hashes)
             ));
         }
 
+        if let Some(possible_offset) = possible_offset {
+            let lo = start + BytePos(possible_offset as u32);
+            let hi = lo + BytePos(found_terminators as u32);
+            let span = self.mk_sp(lo, hi);
+            err.span_suggestion(
+                span,
+                "consider terminating the string here",
+                "#".repeat(n_hashes),
+                Applicability::MaybeIncorrect,
+            );
+        }
+
         err.emit();
         FatalError.raise()
     }
 
-    fn restrict_n_hashes(&self, start: BytePos, n_hashes: usize) -> u16 {
-        match n_hashes.try_into() {
-            Ok(n_hashes) => n_hashes,
-            Err(_) => {
-                self.fatal_span_(
-                    start,
-                    self.pos,
-                    "too many `#` symbols: raw strings may be \
-                                  delimited by up to 65535 `#` symbols",
-                )
-                .raise();
-            }
-        }
+    fn report_too_many_hashes(&self, start: BytePos) -> ! {
+        self.fatal_span_(
+            start,
+            self.pos,
+            "too many `#` symbols: raw strings may be delimited by up to 65535 `#` symbols",
+        )
+        .raise();
     }
 
     fn validate_char_escape(&self, content_start: BytePos, content_end: BytePos) {
diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs
index 13fb85db847..8e2a9513d6b 100644
--- a/src/librustc_parse/lib.rs
+++ b/src/librustc_parse/lib.rs
@@ -4,6 +4,7 @@
 #![feature(crate_visibility_modifier)]
 #![feature(bindings_after_at)]
 #![feature(try_blocks)]
+#![feature(or_patterns)]
 
 use rustc_ast::ast;
 use rustc_ast::token::{self, Nonterminal};
diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs
index c4546dedfcd..12b9b682682 100644
--- a/src/librustc_parse/parser/diagnostics.rs
+++ b/src/librustc_parse/parser/diagnostics.rs
@@ -6,7 +6,7 @@ use rustc_ast::ast::{
 };
 use rustc_ast::ast::{AttrVec, ItemKind, Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind};
 use rustc_ast::ptr::P;
-use rustc_ast::token::{self, TokenKind};
+use rustc_ast::token::{self, Lit, LitKind, TokenKind};
 use rustc_ast::util::parser::AssocOp;
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashSet;
@@ -255,6 +255,10 @@ impl<'a> Parser<'a> {
             }
         }
 
+        if self.check_too_many_raw_str_terminators(&mut err) {
+            return Err(err);
+        }
+
         let sm = self.sess.source_map();
         if self.prev_token.span == DUMMY_SP {
             // Account for macro context where the previous span might not be
@@ -282,6 +286,29 @@ impl<'a> Parser<'a> {
         Err(err)
     }
 
+    fn check_too_many_raw_str_terminators(&mut self, err: &mut DiagnosticBuilder<'_>) -> bool {
+        match (&self.prev_token.kind, &self.token.kind) {
+            (
+                TokenKind::Literal(Lit {
+                    kind: LitKind::StrRaw(n_hashes) | LitKind::ByteStrRaw(n_hashes),
+                    ..
+                }),
+                TokenKind::Pound,
+            ) => {
+                err.set_primary_message("too many `#` when terminating raw string");
+                err.span_suggestion(
+                    self.token.span,
+                    "remove the extra `#`",
+                    String::new(),
+                    Applicability::MachineApplicable,
+                );
+                err.note(&format!("the raw string started with {} `#`s", n_hashes));
+                true
+            }
+            _ => false,
+        }
+    }
+
     pub fn maybe_annotate_with_ascription(
         &mut self,
         err: &mut DiagnosticBuilder<'_>,
@@ -491,7 +518,7 @@ impl<'a> Parser<'a> {
                             .unwrap_or_else(|_| pprust::expr_to_string(&e))
                     };
                     err.span_suggestion_verbose(
-                            inner_op.span.shrink_to_hi(),
+                        inner_op.span.shrink_to_hi(),
                         "split the comparison into two",
                         format!(" && {}", expr_to_str(&r1)),
                         Applicability::MaybeIncorrect,
@@ -1086,7 +1113,7 @@ impl<'a> Parser<'a> {
             self.look_ahead(2, |t| t.is_ident())
             || self.look_ahead(1, |t| t == &token::ModSep)
                 && (self.look_ahead(2, |t| t.is_ident()) ||   // `foo:bar::baz`
-             self.look_ahead(2, |t| t == &token::Lt)) // `foo:bar::<baz>`
+            self.look_ahead(2, |t| t == &token::Lt)) // `foo:bar::<baz>`
     }
 
     pub(super) fn recover_seq_parse_error(
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index b205a4b3222..cbff99f8da6 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -638,6 +638,7 @@ impl<'a> Parser<'a> {
                     ExprKind::MethodCall(_, _) => "a method call",
                     ExprKind::Call(_, _) => "a function call",
                     ExprKind::Await(_) => "`.await`",
+                    ExprKind::Err => return Ok(with_postfix),
                     _ => unreachable!("parse_dot_or_call_expr_with_ shouldn't produce this"),
                 }
             );
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index 6b7a9ec658d..798eb85f36f 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -1496,7 +1496,7 @@ impl<'a> Parser<'a> {
     }
 
     /// 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 @@ impl<'a> Parser<'a> {
     /// 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 fddfe48bf86..b3764d2d47b 100644
--- a/src/librustc_parse/parser/stmt.rs
+++ b/src/librustc_parse/parser/stmt.rs
@@ -165,9 +165,9 @@ impl<'a> Parser<'a> {
                     // 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 c21ac8d04f1..a6015504a32 100644
--- a/src/librustc_parse/parser/ty.rs
+++ b/src/librustc_parse/parser/ty.rs
@@ -127,16 +127,16 @@ impl<'a> Parser<'a> {
         } 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 @@ impl<'a> Parser<'a> {
         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 @@ impl<'a> Parser<'a> {
     ///    |               |        |   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/Cargo.toml b/src/librustc_passes/Cargo.toml
index 8acb88f58d3..0ffc8170b50 100644
--- a/src/librustc_passes/Cargo.toml
+++ b/src/librustc_passes/Cargo.toml
@@ -10,7 +10,7 @@ path = "lib.rs"
 
 [dependencies]
 log = "0.4"
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc_attr = { path = "../librustc_attr" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors" }
diff --git a/src/librustc_passes/check_attr.rs b/src/librustc_passes/check_attr.rs
index 583e1fdc1f0..619a8c6f229 100644
--- a/src/librustc_passes/check_attr.rs
+++ b/src/librustc_passes/check_attr.rs
@@ -4,9 +4,9 @@
 //! conflicts between multiple such attributes attached to the same
 //! item.
 
-use rustc::hir::map::Map;
-use rustc::ty::query::Providers;
-use rustc::ty::TyCtxt;
+use rustc_middle::hir::map::Map;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::TyCtxt;
 
 use rustc_ast::ast::{Attribute, NestedMetaItem};
 use rustc_ast::attr;
diff --git a/src/librustc_passes/check_const.rs b/src/librustc_passes/check_const.rs
index 30737360b9c..f68213cc9c2 100644
--- a/src/librustc_passes/check_const.rs
+++ b/src/librustc_passes/check_const.rs
@@ -7,14 +7,14 @@
 //! errors. We still look for those primitives in the MIR const-checker to ensure nothing slips
 //! through, but errors for structured control flow in a `const` should be emitted here.
 
-use rustc::hir::map::Map;
-use rustc::ty::query::Providers;
-use rustc::ty::TyCtxt;
 use rustc_ast::ast::Mutability;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
+use rustc_middle::hir::map::Map;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::TyCtxt;
 use rustc_session::config::nightly_options;
 use rustc_session::parse::feature_err;
 use rustc_span::{sym, Span, Symbol};
diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs
index 2781c5c125d..830bd255dfc 100644
--- a/src/librustc_passes/dead.rs
+++ b/src/librustc_passes/dead.rs
@@ -2,10 +2,6 @@
 // closely. The idea is that all reachable symbols are live, codes called
 // from live codes are live, and everything else is dead.
 
-use rustc::hir::map::Map;
-use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags;
-use rustc::middle::privacy;
-use rustc::ty::{self, DefIdTree, TyCtxt};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
@@ -13,6 +9,10 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_hir::{Node, PatKind, TyKind};
+use rustc_middle::hir::map::Map;
+use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
+use rustc_middle::middle::privacy;
+use rustc_middle::ty::{self, DefIdTree, TyCtxt};
 use rustc_session::lint;
 
 use rustc_ast::{ast, attr};
@@ -300,12 +300,9 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
     }
 
     fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
-        match ty.kind {
-            TyKind::Def(item_id, _) => {
-                let item = self.tcx.hir().expect_item(item_id.id);
-                intravisit::walk_item(self, item);
-            }
-            _ => (),
+        if let TyKind::Def(item_id, _) = ty.kind {
+            let item = self.tcx.hir().expect_item(item_id.id);
+            intravisit::walk_item(self, item);
         }
         intravisit::walk_ty(self, ty);
     }
diff --git a/src/librustc_passes/diagnostic_items.rs b/src/librustc_passes/diagnostic_items.rs
index ae23e9e35f9..c7210432b1d 100644
--- a/src/librustc_passes/diagnostic_items.rs
+++ b/src/librustc_passes/diagnostic_items.rs
@@ -9,13 +9,13 @@
 //!
 //! * Compiler internal types like `Ty` and `TyCtxt`
 
-use rustc::ty::query::Providers;
-use rustc::ty::TyCtxt;
 use rustc_ast::ast;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::{sym, Symbol};
 
 struct DiagnosticItemCollector<'tcx> {
diff --git a/src/librustc_passes/entry.rs b/src/librustc_passes/entry.rs
index 7e0d0bfe9ab..678859219ea 100644
--- a/src/librustc_passes/entry.rs
+++ b/src/librustc_passes/entry.rs
@@ -1,12 +1,12 @@
-use rustc::hir::map::Map;
-use rustc::ty::query::Providers;
-use rustc::ty::TyCtxt;
 use rustc_ast::attr;
 use rustc_ast::entry::EntryPointType;
 use rustc_errors::struct_span_err;
 use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_hir::{HirId, ImplItem, Item, ItemKind, TraitItem};
+use rustc_middle::hir::map::Map;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::TyCtxt;
 use rustc_session::config::EntryFnType;
 use rustc_session::{config, Session};
 use rustc_span::symbol::sym;
diff --git a/src/librustc_passes/hir_id_validator.rs b/src/librustc_passes/hir_id_validator.rs
index a78e45eebbe..f5611654fc0 100644
--- a/src/librustc_passes/hir_id_validator.rs
+++ b/src/librustc_passes/hir_id_validator.rs
@@ -1,5 +1,3 @@
-use rustc::hir::map::Map;
-use rustc::ty::TyCtxt;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::sync::{par_iter, Lock, ParallelIterator};
 use rustc_hir as hir;
@@ -7,6 +5,8 @@ use rustc_hir::def_id::{LocalDefId, CRATE_DEF_INDEX};
 use rustc_hir::intravisit;
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_hir::{HirId, ItemLocalId};
+use rustc_middle::hir::map::Map;
+use rustc_middle::ty::TyCtxt;
 
 pub fn check_crate(tcx: TyCtxt<'_>) {
     tcx.dep_graph.assert_ignored();
diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs
index 8bfe58da78f..139ffb9699a 100644
--- a/src/librustc_passes/hir_stats.rs
+++ b/src/librustc_passes/hir_stats.rs
@@ -2,14 +2,14 @@
 // pieces of AST and HIR. The resulting numbers are good approximations but not
 // completely accurate (some things might be counted twice, others missed).
 
-use rustc::hir::map::Map;
-use rustc::util::common::to_readable_str;
 use rustc_ast::ast::{self, AttrId, NodeId};
 use rustc_ast::visit as ast_visit;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
 use rustc_hir::intravisit as hir_visit;
 use rustc_hir::HirId;
+use rustc_middle::hir::map::Map;
+use rustc_middle::util::common::to_readable_str;
 use rustc_span::Span;
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
diff --git a/src/librustc_passes/intrinsicck.rs b/src/librustc_passes/intrinsicck.rs
index 1b46aaeefcb..cc1af630cdd 100644
--- a/src/librustc_passes/intrinsicck.rs
+++ b/src/librustc_passes/intrinsicck.rs
@@ -1,13 +1,14 @@
-use rustc::ty::layout::{LayoutError, Pointer, SizeSkeleton, VariantIdx};
-use rustc::ty::query::Providers;
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_index::vec::Idx;
+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/lang_items.rs b/src/librustc_passes/lang_items.rs
index 88e92bbdba1..f1aa76cd223 100644
--- a/src/librustc_passes/lang_items.rs
+++ b/src/librustc_passes/lang_items.rs
@@ -9,8 +9,8 @@
 
 use crate::weak_lang_items;
 
-use rustc::middle::cstore::ExternCrate;
-use rustc::ty::TyCtxt;
+use rustc_middle::middle::cstore::ExternCrate;
+use rustc_middle::ty::TyCtxt;
 
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
@@ -19,7 +19,7 @@ use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_hir::lang_items::{extract, ITEM_REFS};
 use rustc_hir::{LangItem, LanguageItems, Target};
 
-use rustc::ty::query::Providers;
+use rustc_middle::ty::query::Providers;
 
 struct LanguageItemCollector<'tcx> {
     items: LanguageItems,
diff --git a/src/librustc_passes/layout_test.rs b/src/librustc_passes/layout_test.rs
index 9d8b1422bdf..da8ab727ed3 100644
--- a/src/librustc_passes/layout_test.rs
+++ b/src/librustc_passes/layout_test.rs
@@ -1,18 +1,12 @@
-use rustc::ty::layout::HasDataLayout;
-use rustc::ty::layout::HasParamEnv;
-use rustc::ty::layout::HasTyCtxt;
-use rustc::ty::layout::LayoutOf;
-use rustc::ty::layout::TargetDataLayout;
-use rustc::ty::layout::TyLayout;
-use rustc::ty::ParamEnv;
-use rustc::ty::Ty;
-use rustc::ty::TyCtxt;
 use rustc_ast::ast::Attribute;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_hir::ItemKind;
+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 {
@@ -118,9 +112,9 @@ struct UnwrapLayoutCx<'tcx> {
 
 impl LayoutOf for UnwrapLayoutCx<'tcx> {
     type Ty = Ty<'tcx>;
-    type TyLayout = TyLayout<'tcx>;
+    type TyAndLayout = TyAndLayout<'tcx>;
 
-    fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
+    fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout {
         self.tcx.layout_of(self.param_env.and(ty)).unwrap()
     }
 }
diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs
index ab978edb8c3..c81ec83232a 100644
--- a/src/librustc_passes/lib.rs
+++ b/src/librustc_passes/lib.rs
@@ -10,11 +10,11 @@
 #![recursion_limit = "256"]
 
 #[macro_use]
-extern crate rustc;
+extern crate rustc_middle;
 #[macro_use]
 extern crate log;
 
-use rustc::ty::query::Providers;
+use rustc_middle::ty::query::Providers;
 
 mod check_attr;
 mod check_const;
diff --git a/src/librustc_passes/lib_features.rs b/src/librustc_passes/lib_features.rs
index 133e30f6ff0..dd972f37569 100644
--- a/src/librustc_passes/lib_features.rs
+++ b/src/librustc_passes/lib_features.rs
@@ -4,14 +4,14 @@
 // and `#[unstable (..)]`), but are not declared in one single location
 // (unlike lang features), which means we need to collect them instead.
 
-use rustc::hir::map::Map;
-use rustc::middle::lib_features::LibFeatures;
-use rustc::ty::query::Providers;
-use rustc::ty::TyCtxt;
 use rustc_ast::ast::{Attribute, MetaItem, MetaItemKind};
 use rustc_errors::struct_span_err;
 use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
+use rustc_middle::hir::map::Map;
+use rustc_middle::middle::lib_features::LibFeatures;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::Symbol;
 use rustc_span::{sym, Span};
 
diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs
index 5df15a614e8..c9060334a9a 100644
--- a/src/librustc_passes/liveness.rs
+++ b/src/librustc_passes/liveness.rs
@@ -96,9 +96,6 @@
 use self::LiveNodeKind::*;
 use self::VarKind::*;
 
-use rustc::hir::map::Map;
-use rustc::ty::query::Providers;
-use rustc::ty::{self, TyCtxt};
 use rustc_ast::ast;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::Applicability;
@@ -107,6 +104,9 @@ use rustc_hir::def::*;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, FnKind, NestedVisitorMap, Visitor};
 use rustc_hir::{Expr, HirId, HirIdMap, HirIdSet, Node};
+use rustc_middle::hir::map::Map;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::lint;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs
index fa2afae469c..0fce08192bb 100644
--- a/src/librustc_passes/loops.rs
+++ b/src/librustc_passes/loops.rs
@@ -1,13 +1,13 @@
 use Context::*;
 
-use rustc::hir::map::Map;
-use rustc::ty::query::Providers;
-use rustc::ty::TyCtxt;
 use rustc_errors::{struct_span_err, Applicability};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::{Destination, Movability, Node};
+use rustc_middle::hir::map::Map;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::TyCtxt;
 use rustc_session::Session;
 use rustc_span::Span;
 
diff --git a/src/librustc_passes/reachable.rs b/src/librustc_passes/reachable.rs
index 1e9c6c91d38..c0ae6519d2e 100644
--- a/src/librustc_passes/reachable.rs
+++ b/src/librustc_passes/reachable.rs
@@ -5,10 +5,6 @@
 // makes all other generics or inline functions that it references
 // reachable as well.
 
-use rustc::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
-use rustc::middle::privacy;
-use rustc::ty::query::Providers;
-use rustc::ty::{self, TyCtxt};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::sync::Lrc;
 use rustc_hir as hir;
@@ -18,6 +14,10 @@ use rustc_hir::def_id::{CrateNum, DefId};
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_hir::{HirIdSet, Node};
+use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
+use rustc_middle::middle::privacy;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::config;
 use rustc_target::spec::abi::Abi;
 
diff --git a/src/librustc_passes/region.rs b/src/librustc_passes/region.rs
index e771696a5b6..485480d020f 100644
--- a/src/librustc_passes/region.rs
+++ b/src/librustc_passes/region.rs
@@ -6,9 +6,6 @@
 //!
 //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/borrow_check.html
 
-use rustc::middle::region::*;
-use rustc::ty::query::Providers;
-use rustc::ty::TyCtxt;
 use rustc_ast::walk_list;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
@@ -16,6 +13,9 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::{Arm, Block, Expr, Local, Node, Pat, PatKind, Stmt};
 use rustc_index::vec::Idx;
+use rustc_middle::middle::region::*;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::source_map;
 use rustc_span::Span;
 
@@ -27,8 +27,8 @@ pub struct Context {
     /// 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 8fa5a4fbc61..ad81aa30685 100644
--- a/src/librustc_passes/stability.rs
+++ b/src/librustc_passes/stability.rs
@@ -1,11 +1,6 @@
 //! A pass that annotates every item and method with its stability level,
 //! propagating default levels lexically from parent to children ast nodes.
 
-use rustc::hir::map::Map;
-use rustc::middle::privacy::AccessLevels;
-use rustc::middle::stability::{DeprecationEntry, Index};
-use rustc::ty::query::Providers;
-use rustc::ty::TyCtxt;
 use rustc_ast::ast::Attribute;
 use rustc_attr::{self as attr, ConstStability, Stability};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -15,6 +10,11 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::{Generics, HirId, Item, StructField, Variant};
+use rustc_middle::hir::map::Map;
+use rustc_middle::middle::privacy::AccessLevels;
+use rustc_middle::middle::stability::{DeprecationEntry, Index};
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::TyCtxt;
 use rustc_session::lint;
 use rustc_session::parse::feature_err;
 use rustc_session::Session;
@@ -438,7 +438,7 @@ fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
         // 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 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/upvars.rs b/src/librustc_passes/upvars.rs
index 43f39e6c610..fd046d9b66b 100644
--- a/src/librustc_passes/upvars.rs
+++ b/src/librustc_passes/upvars.rs
@@ -1,12 +1,12 @@
 //! Upvar (closure capture) collection from cross-body HIR uses of `Res::Local`s.
 
-use rustc::ty::query::Providers;
-use rustc::ty::TyCtxt;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::{self, HirId};
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::Span;
 
 pub fn provide(providers: &mut Providers<'_>) {
diff --git a/src/librustc_passes/weak_lang_items.rs b/src/librustc_passes/weak_lang_items.rs
index cde489e8d2c..8e56ef0da52 100644
--- a/src/librustc_passes/weak_lang_items.rs
+++ b/src/librustc_passes/weak_lang_items.rs
@@ -1,13 +1,13 @@
 //! Validity checking for weak lang items
 
-use rustc::middle::lang_items;
-use rustc::middle::lang_items::whitelisted;
-use rustc::ty::TyCtxt;
 use rustc_data_structures::fx::FxHashSet;
 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::whitelisted;
+use rustc_middle::ty::TyCtxt;
 use rustc_session::config;
 use rustc_span::symbol::Symbol;
 use rustc_span::Span;
diff --git a/src/librustc_plugin_impl/Cargo.toml b/src/librustc_plugin_impl/Cargo.toml
index 372d6a534c8..38cfbd48de2 100644
--- a/src/librustc_plugin_impl/Cargo.toml
+++ b/src/librustc_plugin_impl/Cargo.toml
@@ -11,7 +11,7 @@ path = "lib.rs"
 doctest = false
 
 [dependencies]
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc_errors = { path = "../librustc_errors" }
 rustc_hir = { path = "../librustc_hir" }
 rustc_lint = { path = "../librustc_lint" }
diff --git a/src/librustc_plugin_impl/build.rs b/src/librustc_plugin_impl/build.rs
index 03e58d758c5..c7841595fe5 100644
--- a/src/librustc_plugin_impl/build.rs
+++ b/src/librustc_plugin_impl/build.rs
@@ -1,11 +1,11 @@
 //! Used by `rustc` when compiling a plugin crate.
 
-use rustc::ty::query::Providers;
-use rustc::ty::TyCtxt;
 use rustc_ast::attr;
 use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 
diff --git a/src/librustc_plugin_impl/load.rs b/src/librustc_plugin_impl/load.rs
index 0810cf56d17..f41bc44d177 100644
--- a/src/librustc_plugin_impl/load.rs
+++ b/src/librustc_plugin_impl/load.rs
@@ -1,10 +1,10 @@
 //! Used by `rustc` when loading a plugin.
 
 use crate::Registry;
-use rustc::middle::cstore::MetadataLoader;
 use rustc_ast::ast::{Crate, Ident};
 use rustc_errors::struct_span_err;
 use rustc_metadata::locator;
+use rustc_middle::middle::cstore::MetadataLoader;
 use rustc_session::Session;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
diff --git a/src/librustc_privacy/Cargo.toml b/src/librustc_privacy/Cargo.toml
index 9854e0f6c53..34146113f0e 100644
--- a/src/librustc_privacy/Cargo.toml
+++ b/src/librustc_privacy/Cargo.toml
@@ -9,7 +9,7 @@ name = "rustc_privacy"
 path = "lib.rs"
 
 [dependencies]
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc_attr = { path = "../librustc_attr" }
 rustc_errors = { path = "../librustc_errors" }
 rustc_hir = { path = "../librustc_hir" }
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 0df1d08cbd8..567022fe405 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -3,13 +3,6 @@
 #![feature(nll)]
 #![recursion_limit = "256"]
 
-use rustc::bug;
-use rustc::hir::map::Map;
-use rustc::middle::privacy::{AccessLevel, AccessLevels};
-use rustc::ty::fold::TypeVisitor;
-use rustc::ty::query::Providers;
-use rustc::ty::subst::InternalSubsts;
-use rustc::ty::{self, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeFoldable};
 use rustc_ast::ast::Ident;
 use rustc_attr as attr;
 use rustc_data_structures::fx::FxHashSet;
@@ -19,6 +12,13 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::intravisit::{self, DeepVisitor, NestedVisitorMap, Visitor};
 use rustc_hir::{AssocItemKind, HirIdSet, Node, PatKind};
+use rustc_middle::bug;
+use rustc_middle::hir::map::Map;
+use rustc_middle::middle::privacy::{AccessLevel, AccessLevels};
+use rustc_middle::ty::fold::TypeVisitor;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::subst::InternalSubsts;
+use rustc_middle::ty::{self, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeFoldable};
 use rustc_session::lint;
 use rustc_span::hygiene::Transparency;
 use rustc_span::symbol::{kw, sym};
@@ -1096,52 +1096,46 @@ impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> {
     }
 
     fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
-        match expr.kind {
-            hir::ExprKind::Struct(ref qpath, fields, ref base) => {
-                let res = self.tables.qpath_res(qpath, expr.hir_id);
-                let adt = self.tables.expr_ty(expr).ty_adt_def().unwrap();
-                let variant = adt.variant_of_res(res);
-                if let Some(ref base) = *base {
-                    // If the expression uses FRU we need to make sure all the unmentioned fields
-                    // are checked for privacy (RFC 736). Rather than computing the set of
-                    // unmentioned fields, just check them all.
-                    for (vf_index, variant_field) in variant.fields.iter().enumerate() {
-                        let field = fields
-                            .iter()
-                            .find(|f| self.tcx.field_index(f.hir_id, self.tables) == vf_index);
-                        let (use_ctxt, span) = match field {
-                            Some(field) => (field.ident.span, field.span),
-                            None => (base.span, base.span),
-                        };
-                        self.check_field(use_ctxt, span, adt, variant_field, true);
-                    }
-                } else {
-                    for field in fields {
-                        let use_ctxt = field.ident.span;
-                        let index = self.tcx.field_index(field.hir_id, self.tables);
-                        self.check_field(use_ctxt, field.span, adt, &variant.fields[index], false);
-                    }
+        if let hir::ExprKind::Struct(ref qpath, fields, ref base) = expr.kind {
+            let res = self.tables.qpath_res(qpath, expr.hir_id);
+            let adt = self.tables.expr_ty(expr).ty_adt_def().unwrap();
+            let variant = adt.variant_of_res(res);
+            if let Some(ref base) = *base {
+                // If the expression uses FRU we need to make sure all the unmentioned fields
+                // are checked for privacy (RFC 736). Rather than computing the set of
+                // unmentioned fields, just check them all.
+                for (vf_index, variant_field) in variant.fields.iter().enumerate() {
+                    let field = fields
+                        .iter()
+                        .find(|f| self.tcx.field_index(f.hir_id, self.tables) == vf_index);
+                    let (use_ctxt, span) = match field {
+                        Some(field) => (field.ident.span, field.span),
+                        None => (base.span, base.span),
+                    };
+                    self.check_field(use_ctxt, span, adt, variant_field, true);
+                }
+            } else {
+                for field in fields {
+                    let use_ctxt = field.ident.span;
+                    let index = self.tcx.field_index(field.hir_id, self.tables);
+                    self.check_field(use_ctxt, field.span, adt, &variant.fields[index], false);
                 }
             }
-            _ => {}
         }
 
         intravisit::walk_expr(self, expr);
     }
 
     fn visit_pat(&mut self, pat: &'tcx hir::Pat<'tcx>) {
-        match pat.kind {
-            PatKind::Struct(ref qpath, fields, _) => {
-                let res = self.tables.qpath_res(qpath, pat.hir_id);
-                let adt = self.tables.pat_ty(pat).ty_adt_def().unwrap();
-                let variant = adt.variant_of_res(res);
-                for field in fields {
-                    let use_ctxt = field.ident.span;
-                    let index = self.tcx.field_index(field.hir_id, self.tables);
-                    self.check_field(use_ctxt, field.span, adt, &variant.fields[index], false);
-                }
+        if let PatKind::Struct(ref qpath, fields, _) = pat.kind {
+            let res = self.tables.qpath_res(qpath, pat.hir_id);
+            let adt = self.tables.pat_ty(pat).ty_adt_def().unwrap();
+            let variant = adt.variant_of_res(res);
+            for field in fields {
+                let use_ctxt = field.ident.span;
+                let index = self.tcx.field_index(field.hir_id, self.tables);
+                self.check_field(use_ctxt, field.span, adt, &variant.fields[index], false);
             }
-            _ => {}
         }
 
         intravisit::walk_pat(self, pat);
diff --git a/src/librustc_query_system/dep_graph/dep_node.rs b/src/librustc_query_system/dep_graph/dep_node.rs
index b1d332da115..99eb3cdc0b0 100644
--- a/src/librustc_query_system/dep_graph/dep_node.rs
+++ b/src/librustc_query_system/dep_graph/dep_node.rs
@@ -26,7 +26,7 @@
 //!   could not be instantiated because the current compilation session
 //!   contained no `DefId` for thing that had been removed.
 //!
-//! `DepNode` definition happens in `librustc` with the `define_dep_nodes!()` macro.
+//! `DepNode` definition happens in `librustc_middle` with the `define_dep_nodes!()` macro.
 //! This macro defines the `DepKind` enum and a corresponding `DepConstructor` enum. The
 //! `DepConstructor` enum links a `DepKind` to the parameters that are needed at runtime in order
 //! to construct a valid `DepNode` fingerprint.
diff --git a/src/librustc_query_system/query/config.rs b/src/librustc_query_system/query/config.rs
index 20dad0bd47e..06e3302b263 100644
--- a/src/librustc_query_system/query/config.rs
+++ b/src/librustc_query_system/query/config.rs
@@ -13,8 +13,8 @@ use std::borrow::Cow;
 use std::fmt::Debug;
 use std::hash::Hash;
 
-// The parameter `CTX` is required in librustc: implementations may need to access the `'tcx`
-// lifetime in `CTX = TyCtxt<'tcx>`.
+// The parameter `CTX` is required in librustc_middle:
+// implementations may need to access the `'tcx` lifetime in `CTX = TyCtxt<'tcx>`.
 pub trait QueryConfig<CTX> {
     const NAME: &'static str;
     const CATEGORY: ProfileCategory;
diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml
index 49f079ad270..420a82d6d2c 100644
--- a/src/librustc_resolve/Cargo.toml
+++ b/src/librustc_resolve/Cargo.toml
@@ -15,7 +15,7 @@ bitflags = "1.2.1"
 log = "0.4"
 rustc_ast = { path = "../librustc_ast" }
 arena = { path = "../libarena" }
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc_ast_lowering = { path = "../librustc_ast_lowering" }
 rustc_ast_pretty = { path = "../librustc_ast_pretty" }
 rustc_attr = { path = "../librustc_attr" }
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 5408c85a4d0..51089f73c28 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -15,10 +15,6 @@ use crate::{
 };
 use crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding};
 
-use rustc::bug;
-use rustc::hir::exports::Export;
-use rustc::middle::cstore::CrateStore;
-use rustc::ty;
 use rustc_ast::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId};
 use rustc_ast::ast::{AssocItem, AssocItemKind, MetaItemKind, StmtKind};
 use rustc_ast::ast::{Ident, Name};
@@ -32,6 +28,10 @@ use rustc_expand::expand::AstFragment;
 use rustc_hir::def::{self, *};
 use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_metadata::creader::LoadedMacro;
+use rustc_middle::bug;
+use rustc_middle::hir::exports::Export;
+use rustc_middle::middle::cstore::CrateStore;
+use rustc_middle::ty;
 use rustc_span::hygiene::{ExpnId, MacroKind};
 use rustc_span::source_map::{respan, Spanned};
 use rustc_span::symbol::{kw, sym};
diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs
index 35876176e3e..dd286723412 100644
--- a/src/librustc_resolve/check_unused.rs
+++ b/src/librustc_resolve/check_unused.rs
@@ -26,12 +26,12 @@
 use crate::imports::ImportKind;
 use crate::Resolver;
 
-use rustc::ty;
 use rustc_ast::ast;
 use rustc_ast::node_id::NodeMap;
 use rustc_ast::visit::{self, Visitor};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::pluralize;
+use rustc_middle::ty;
 use rustc_session::lint::builtin::{MACRO_USE_EXTERN_CRATE, UNUSED_IMPORTS};
 use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc_span::{MultiSpan, Span, DUMMY_SP};
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 78b7e256de2..b51760cee1e 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -2,8 +2,6 @@ use std::cmp::Reverse;
 use std::ptr;
 
 use log::debug;
-use rustc::bug;
-use rustc::ty::{self, DefIdTree};
 use rustc_ast::ast::{self, Ident, Path};
 use rustc_ast::util::lev_distance::find_best_match_for_name;
 use rustc_ast_pretty::pprust;
@@ -13,6 +11,8 @@ use rustc_feature::BUILTIN_ATTRIBUTES;
 use rustc_hir::def::Namespace::{self, *};
 use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind};
 use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_middle::bug;
+use rustc_middle::ty::{self, DefIdTree};
 use rustc_session::Session;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::source_map::SourceMap;
diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs
index 8c7ab8f5b1a..5324e370dbd 100644
--- a/src/librustc_resolve/imports.rs
+++ b/src/librustc_resolve/imports.rs
@@ -9,9 +9,6 @@ use crate::{BindingKey, ModuleKind, ResolutionError, Resolver, Segment};
 use crate::{CrateLint, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet, Weak};
 use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBinding};
 
-use rustc::hir::exports::Export;
-use rustc::ty;
-use rustc::{bug, span_bug};
 use rustc_ast::ast::{Ident, Name, NodeId};
 use rustc_ast::unwrap_or;
 use rustc_ast::util::lev_distance::find_best_match_for_name;
@@ -20,6 +17,9 @@ use rustc_data_structures::ptr_key::PtrKey;
 use rustc_errors::{pluralize, struct_span_err, Applicability};
 use rustc_hir::def::{self, PartialRes};
 use rustc_hir::def_id::DefId;
+use rustc_middle::hir::exports::Export;
+use rustc_middle::ty;
+use rustc_middle::{bug, span_bug};
 use rustc_session::lint::builtin::{PUB_USE_OF_PRIVATE_EXTERN_CRATE, UNUSED_IMPORTS};
 use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc_session::DiagnosticMessageId;
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 4a3c9f338d9..2b90527a825 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -11,7 +11,6 @@ use crate::{path_names_to_string, BindingError, CrateLint, LexicalScopeBinding};
 use crate::{Module, ModuleOrUniformRoot, NameBindingKind, ParentScope, PathResult};
 use crate::{ResolutionError, Resolver, Segment, UseError};
 
-use rustc::{bug, span_bug};
 use rustc_ast::ast::*;
 use rustc_ast::ptr::P;
 use rustc_ast::util::lev_distance::find_best_match_for_name;
@@ -23,6 +22,7 @@ use rustc_hir::def::Namespace::{self, *};
 use rustc_hir::def::{self, CtorKind, DefKind, PartialRes, PerNS};
 use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX};
 use rustc_hir::TraitCandidate;
+use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
 use rustc_span::symbol::{kw, sym};
 use rustc_span::Span;
@@ -1536,20 +1536,18 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         let is_syntactic_ambiguity = !has_sub && bm == BindingMode::ByValue(Mutability::Not);
 
         match res {
-            Res::Def(DefKind::Ctor(_, CtorKind::Const), _)
-            | Res::Def(DefKind::Const, _)
-            | Res::Def(DefKind::ConstParam, _)
-                if is_syntactic_ambiguity =>
-            {
+            Res::SelfCtor(_) // See #70549.
+            | Res::Def(
+                DefKind::Ctor(_, CtorKind::Const) | DefKind::Const | DefKind::ConstParam,
+                _,
+            ) if is_syntactic_ambiguity => {
                 // Disambiguate in favor of a unit struct/variant or constant pattern.
                 if let Some(binding) = binding {
                     self.r.record_use(ident, ValueNS, binding, false);
                 }
                 Some(res)
             }
-            Res::Def(DefKind::Ctor(..), _)
-            | Res::Def(DefKind::Const, _)
-            | Res::Def(DefKind::Static, _) => {
+            Res::Def(DefKind::Ctor(..) | DefKind::Const | DefKind::Static, _) => {
                 // This is unambiguously a fresh binding, either syntactically
                 // (e.g., `IDENT @ PAT` or `ref IDENT`) or because `IDENT` resolves
                 // to something unusable as a pattern (e.g., constructor function),
@@ -1572,7 +1570,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             _ => span_bug!(
                 ident.span,
                 "unexpected resolution for an identifier in pattern: {:?}",
-                res
+                res,
             ),
         }
     }
diff --git a/src/librustc_resolve/late/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs
index bc843fccc4c..71ff9e5cbed 100644
--- a/src/librustc_resolve/late/lifetimes.rs
+++ b/src/librustc_resolve/late/lifetimes.rs
@@ -6,10 +6,6 @@
 //! way. Therefore, we break lifetime name resolution into a separate pass.
 
 use crate::late::diagnostics::{ForLifetimeSpanType, MissingLifetimeSpot};
-use rustc::hir::map::Map;
-use rustc::middle::resolve_lifetime::*;
-use rustc::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
-use rustc::{bug, span_bug};
 use rustc_ast::ast;
 use rustc_ast::attr;
 use rustc_ast::walk_list;
@@ -21,6 +17,10 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE};
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::{GenericArg, GenericParam, LifetimeName, Node, ParamName, QPath};
 use rustc_hir::{GenericParamKind, HirIdMap, HirIdSet, LifetimeParamKind};
+use rustc_middle::hir::map::Map;
+use rustc_middle::middle::resolve_lifetime::*;
+use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
 use rustc_span::symbol::{kw, sym};
 use rustc_span::Span;
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 9d5121cbad5..21f43b6fd4f 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -10,17 +10,13 @@
 #![feature(bool_to_option)]
 #![feature(crate_visibility_modifier)]
 #![feature(nll)]
+#![feature(or_patterns)]
 #![recursion_limit = "256"]
 
 pub use rustc_hir::def::{Namespace, PerNS};
 
 use Determinacy::*;
 
-use rustc::hir::exports::ExportMap;
-use rustc::middle::cstore::{CrateStore, MetadataLoaderDyn};
-use rustc::span_bug;
-use rustc::ty::query::Providers;
-use rustc::ty::{self, DefIdTree, ResolverOutputs};
 use rustc_ast::ast::{self, FloatTy, Ident, IntTy, Name, NodeId, UintTy};
 use rustc_ast::ast::{Crate, CRATE_NODE_ID};
 use rustc_ast::ast::{ItemKind, Path};
@@ -41,6 +37,11 @@ use rustc_hir::definitions::{DefKey, Definitions};
 use rustc_hir::PrimTy::{self, Bool, Char, Float, Int, Str, Uint};
 use rustc_hir::{GlobMap, TraitMap};
 use rustc_metadata::creader::{CStore, CrateLoader};
+use rustc_middle::hir::exports::ExportMap;
+use rustc_middle::middle::cstore::{CrateStore, MetadataLoaderDyn};
+use rustc_middle::span_bug;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::{self, DefIdTree, ResolverOutputs};
 use rustc_session::lint;
 use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
 use rustc_session::Session;
@@ -2807,7 +2808,7 @@ impl<'a> Resolver<'a> {
             ast::Path {
                 span,
                 segments: iter::once(Ident::with_dummy_span(kw::PathRoot))
-                    .chain({ path_str.split("::").skip(1).map(Ident::from_str) })
+                    .chain(path_str.split("::").skip(1).map(Ident::from_str))
                     .map(|i| self.new_ast_path_segment(i))
                     .collect(),
             }
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index a783cfa4811..5efd3daebb9 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -6,8 +6,6 @@ use crate::Namespace::*;
 use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy};
 use crate::{CrateLint, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Weak};
 use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding};
-use rustc::middle::stability;
-use rustc::{span_bug, ty};
 use rustc_ast::ast::{self, Ident, NodeId};
 use rustc_ast_pretty::pprust;
 use rustc_attr::{self as attr, StabilityLevel};
@@ -19,6 +17,8 @@ use rustc_expand::expand::{AstFragment, AstFragmentKind, Invocation, InvocationK
 use rustc_feature::is_builtin_attr_name;
 use rustc_hir::def::{self, DefKind, NonMacroAttrKind};
 use rustc_hir::def_id;
+use rustc_middle::middle::stability;
+use rustc_middle::{span_bug, ty};
 use rustc_session::lint::builtin::UNUSED_MACROS;
 use rustc_session::Session;
 use rustc_span::edition::Edition;
diff --git a/src/librustc_save_analysis/Cargo.toml b/src/librustc_save_analysis/Cargo.toml
index 623da1ddcb4..5948c88054d 100644
--- a/src/librustc_save_analysis/Cargo.toml
+++ b/src/librustc_save_analysis/Cargo.toml
@@ -10,7 +10,7 @@ path = "lib.rs"
 
 [dependencies]
 log = "0.4"
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc_ast = { path = "../librustc_ast" }
 rustc_ast_pretty = { path = "../librustc_ast_pretty" }
 rustc_data_structures = { path = "../librustc_data_structures" }
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index e5637e4e6e6..05eb524dff5 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -13,8 +13,6 @@
 //! DumpVisitor walks the AST and processes it, and Dumper is used for
 //! recording the output.
 
-use rustc::span_bug;
-use rustc::ty::{self, DefIdTree, TyCtxt};
 use rustc_ast::ast::{self, Attribute, NodeId, PatKind};
 use rustc_ast::ptr::P;
 use rustc_ast::token;
@@ -24,6 +22,8 @@ use rustc_ast_pretty::pprust::{bounds_to_string, generic_params_to_string, ty_to
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def::{DefKind as HirDefKind, Res};
 use rustc_hir::def_id::DefId;
+use rustc_middle::span_bug;
+use rustc_middle::ty::{self, DefIdTree, TyCtxt};
 use rustc_session::config::Input;
 use rustc_span::source_map::{respan, DUMMY_SP};
 use rustc_span::*;
@@ -848,10 +848,9 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
         if let Some(ref generic_args) = seg.args {
             if let ast::GenericArgs::AngleBracketed(ref data) = **generic_args {
                 for arg in &data.args {
-                    match arg {
-                        ast::AngleBracketedArg::Arg(ast::GenericArg::Type(ty)) => self.visit_ty(ty),
-                        _ => {}
-                    }
+                    if let ast::AngleBracketedArg::Arg(ast::GenericArg::Type(ty)) = arg {
+                        self.visit_ty(ty)
+                    };
                 }
             }
         }
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index c737c6257a2..24b7be0c9b3 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -8,10 +8,6 @@ mod dumper;
 mod span_utils;
 mod sig;
 
-use rustc::middle::cstore::ExternCrate;
-use rustc::middle::privacy::AccessLevels;
-use rustc::ty::{self, DefIdTree, TyCtxt};
-use rustc::{bug, span_bug};
 use rustc_ast::ast::{self, Attribute, NodeId, PatKind, DUMMY_NODE_ID};
 use rustc_ast::util::comments::strip_doc_comment_decoration;
 use rustc_ast::visit::{self, Visitor};
@@ -20,6 +16,10 @@ use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind as HirDefKind, Res};
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::Node;
+use rustc_middle::middle::cstore::ExternCrate;
+use rustc_middle::middle::privacy::AccessLevels;
+use rustc_middle::ty::{self, DefIdTree, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_session::config::{CrateType, Input, OutputType};
 use rustc_session::output::{filename_for_metadata, out_filename};
 use rustc_span::source_map::Spanned;
@@ -591,7 +591,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
                 Some(Data::RefData(Ref {
                     kind: RefKind::Function,
                     span,
-                    ref_id: def_id.or(decl_id).map(id_from_def_id).unwrap_or_else(|| null_id()),
+                    ref_id: def_id.or(decl_id).map(id_from_def_id).unwrap_or_else(null_id),
                 }))
             }
             ast::ExprKind::Path(_, ref path) => {
diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs
index 663cfa223c7..54481bd124d 100644
--- a/src/librustc_session/config.rs
+++ b/src/librustc_session/config.rs
@@ -1650,7 +1650,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
 
     check_thread_count(&debugging_opts, error_format);
 
-    let incremental = cg.incremental.as_ref().map(|m| PathBuf::from(m));
+    let incremental = cg.incremental.as_ref().map(PathBuf::from);
 
     if debugging_opts.profile && incremental.is_some() {
         early_error(
diff --git a/src/librustc_session/filesearch.rs b/src/librustc_session/filesearch.rs
index 05e6da43ea7..4347512eda0 100644
--- a/src/librustc_session/filesearch.rs
+++ b/src/librustc_session/filesearch.rs
@@ -143,8 +143,8 @@ fn find_libdir(sysroot: &Path) -> Cow<'static, str> {
     // 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 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 1162cff4e0b..b16d513d923 100644
--- a/src/librustc_session/lint.rs
+++ b/src/librustc_session/lint.rs
@@ -195,7 +195,7 @@ pub enum BuiltinLintDiagnostics {
 }
 
 /// Lints that are buffered up early on in the `Session` before the
-/// `LintLevels` is calculated. These are later passed to `librustc`.
+/// `LintLevels` is calculated.
 #[derive(PartialEq)]
 pub struct BufferedEarlyLint {
     /// The span of code that we are linting on.
@@ -207,7 +207,8 @@ pub struct BufferedEarlyLint {
     /// The `NodeId` of the AST node that generated the lint.
     pub node_id: NodeId,
 
-    /// A lint Id that can be passed to `rustc::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 e43908a7914..432f1e17ab3 100644
--- a/src/librustc_session/options.rs
+++ b/src/librustc_session/options.rs
@@ -835,6 +835,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         "the directory the MIR is dumped into"),
     dump_mir_graphviz: bool = (false, parse_bool, [UNTRACKED],
         "in addition to `.mir` files, create graphviz `.dot` files"),
+    dump_mir_dataflow: bool = (false, parse_bool, [UNTRACKED],
+        "in addition to `.mir` files, create graphviz `.dot` files with dataflow results"),
     dump_mir_exclude_pass_number: bool = (false, parse_bool, [UNTRACKED],
         "if set, exclude the pass number when dumping MIR (used in tests)"),
     mir_emit_retag: bool = (false, parse_bool, [TRACKED],
diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs
index b3d75143c56..98d0fa74d62 100644
--- a/src/librustc_session/session.rs
+++ b/src/librustc_session/session.rs
@@ -140,6 +140,15 @@ pub struct Session {
     /// 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 +767,13 @@ impl Session {
             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
@@ -1056,6 +1072,26 @@ fn build_session_(
         _ => 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,6 +1130,7 @@ fn build_session_(
         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);
diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs
index a0c4c90722d..3bcc20d36e7 100644
--- a/src/librustc_span/lib.rs
+++ b/src/librustc_span/lib.rs
@@ -1544,7 +1544,7 @@ fn lookup_line(lines: &[BytePos], pos: BytePos) -> isize {
 
 /// Requirements for a `StableHashingContext` to be used in this crate.
 /// This is a hack to allow using the `HashStable_Generic` derive macro
-/// instead of implementing everything in librustc.
+/// instead of implementing everything in librustc_middle.
 pub trait HashStableContext {
     fn hash_spans(&self) -> bool;
     fn hash_def_id(&mut self, _: DefId, hasher: &mut StableHasher);
diff --git a/src/librustc_symbol_mangling/Cargo.toml b/src/librustc_symbol_mangling/Cargo.toml
index 1e4fc8f7e68..5d091499c8c 100644
--- a/src/librustc_symbol_mangling/Cargo.toml
+++ b/src/librustc_symbol_mangling/Cargo.toml
@@ -16,7 +16,7 @@ rustc-demangle = "0.1.16"
 
 rustc_ast = { path = "../librustc_ast" }
 rustc_span = { path = "../librustc_span" }
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc_hir = { path = "../librustc_hir" }
 rustc_target = { path = "../librustc_target" }
 rustc_data_structures = { path = "../librustc_data_structures" }
diff --git a/src/librustc_symbol_mangling/legacy.rs b/src/librustc_symbol_mangling/legacy.rs
index a891d60b068..01e9356b42f 100644
--- a/src/librustc_symbol_mangling/legacy.rs
+++ b/src/librustc_symbol_mangling/legacy.rs
@@ -1,12 +1,12 @@
-use rustc::ich::NodeIdHashingMode;
-use rustc::mir::interpret::{ConstValue, Scalar};
-use rustc::ty::print::{PrettyPrinter, Print, Printer};
-use rustc::ty::subst::{GenericArg, GenericArgKind};
-use rustc::ty::{self, Instance, Ty, TyCtxt, TypeFoldable};
-use rustc::util::common::record_time;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_hir::def_id::CrateNum;
 use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
+use rustc_middle::ich::NodeIdHashingMode;
+use rustc_middle::mir::interpret::{ConstValue, Scalar};
+use rustc_middle::ty::print::{PrettyPrinter, Print, Printer};
+use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
+use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable};
+use rustc_middle::util::common::record_time;
 
 use log::debug;
 
@@ -308,9 +308,8 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> {
         self = print_prefix(self)?;
 
         // Skip `::{{constructor}}` on tuple/unit structs.
-        match disambiguated_data.data {
-            DefPathData::Ctor => return Ok(self),
-            _ => {}
+        if let DefPathData::Ctor = disambiguated_data.data {
+            return Ok(self);
         }
 
         if self.keep_within_component {
diff --git a/src/librustc_symbol_mangling/lib.rs b/src/librustc_symbol_mangling/lib.rs
index 26cb3410500..2ee2ca3ce28 100644
--- a/src/librustc_symbol_mangling/lib.rs
+++ b/src/librustc_symbol_mangling/lib.rs
@@ -94,15 +94,15 @@
 #![recursion_limit = "256"]
 
 #[macro_use]
-extern crate rustc;
+extern crate rustc_middle;
 
-use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags;
-use rustc::mir::mono::{InstantiationMode, MonoItem};
-use rustc::ty::query::Providers;
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::{self, Instance, TyCtxt};
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_hir::Node;
+use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
+use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::subst::SubstsRef;
+use rustc_middle::ty::{self, Instance, TyCtxt};
 use rustc_session::config::SymbolManglingVersion;
 
 use rustc_span::symbol::Symbol;
diff --git a/src/librustc_symbol_mangling/test.rs b/src/librustc_symbol_mangling/test.rs
index 8f2f2628e7b..a20915dd6fc 100644
--- a/src/librustc_symbol_mangling/test.rs
+++ b/src/librustc_symbol_mangling/test.rs
@@ -4,8 +4,8 @@
 //! def-path. This is used for unit testing the code that generates
 //! paths etc in all kinds of annoying scenarios.
 
-use rustc::ty::{Instance, TyCtxt};
 use rustc_hir as hir;
+use rustc_middle::ty::{Instance, TyCtxt};
 use rustc_span::symbol::{sym, Symbol};
 
 const SYMBOL_NAME: Symbol = sym::rustc_symbol_name;
diff --git a/src/librustc_symbol_mangling/v0.rs b/src/librustc_symbol_mangling/v0.rs
index fb2fde8513a..e3358c5706f 100644
--- a/src/librustc_symbol_mangling/v0.rs
+++ b/src/librustc_symbol_mangling/v0.rs
@@ -1,12 +1,12 @@
-use rustc::ty::print::{Print, Printer};
-use rustc::ty::subst::{GenericArg, GenericArgKind, Subst};
-use rustc::ty::{self, Instance, Ty, TyCtxt, TypeFoldable};
 use rustc_ast::ast::{FloatTy, IntTy, UintTy};
 use rustc_data_structures::base_n;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, DefId};
 use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
+use rustc_middle::ty::print::{Print, Printer};
+use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
+use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable};
 use rustc_target::spec::abi::Abi;
 
 use std::fmt::Write;
diff --git a/src/librustc_target/abi/call/aarch64.rs b/src/librustc_target/abi/call/aarch64.rs
index c8bac5aebc6..1ab7722edab 100644
--- a/src/librustc_target/abi/call/aarch64.rs
+++ b/src/librustc_target/abi/call/aarch64.rs
@@ -1,10 +1,10 @@
 use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
-use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
 
 fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option<Uniform>
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| {
         let size = arg.layout.size;
@@ -26,8 +26,8 @@ where
 
 fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     if !ret.layout.is_aggregate() {
         ret.extend_integer_width_to(32);
@@ -58,8 +58,8 @@ where
 
 fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     if !arg.layout.is_aggregate() {
         arg.extend_integer_width_to(32);
@@ -90,8 +90,8 @@ where
 
 pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     if !fn_abi.ret.is_ignore() {
         classify_ret(cx, &mut fn_abi.ret);
diff --git a/src/librustc_target/abi/call/amdgpu.rs b/src/librustc_target/abi/call/amdgpu.rs
index 704e8b8ffa8..0b4f279fece 100644
--- a/src/librustc_target/abi/call/amdgpu.rs
+++ b/src/librustc_target/abi/call/amdgpu.rs
@@ -1,26 +1,26 @@
 use crate::abi::call::{ArgAbi, FnAbi};
-use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
 
 fn classify_ret<'a, Ty, C>(_cx: &C, ret: &mut ArgAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     ret.extend_integer_width_to(32);
 }
 
 fn classify_arg<'a, Ty, C>(_cx: &C, arg: &mut ArgAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     arg.extend_integer_width_to(32);
 }
 
 pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     if !fn_abi.ret.is_ignore() {
         classify_ret(cx, &mut fn_abi.ret);
diff --git a/src/librustc_target/abi/call/arm.rs b/src/librustc_target/abi/call/arm.rs
index 59ec87e3c9e..26fed3bae4e 100644
--- a/src/librustc_target/abi/call/arm.rs
+++ b/src/librustc_target/abi/call/arm.rs
@@ -1,11 +1,11 @@
 use crate::abi::call::{ArgAbi, Conv, FnAbi, Reg, RegKind, Uniform};
-use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
 use crate::spec::HasTargetSpec;
 
 fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option<Uniform>
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| {
         let size = arg.layout.size;
@@ -27,8 +27,8 @@ where
 
 fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>, vfp: bool)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     if !ret.layout.is_aggregate() {
         ret.extend_integer_width_to(32);
@@ -60,8 +60,8 @@ where
 
 fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, vfp: bool)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     if !arg.layout.is_aggregate() {
         arg.extend_integer_width_to(32);
@@ -82,8 +82,8 @@ where
 
 pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout + HasTargetSpec,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout + HasTargetSpec,
 {
     // If this is a target with a hard-float ABI, and the function is not explicitly
     // `extern "aapcs"`, then we must use the VFP registers for homogeneous aggregates.
diff --git a/src/librustc_target/abi/call/mips.rs b/src/librustc_target/abi/call/mips.rs
index b332b9afe7f..733a7328bd3 100644
--- a/src/librustc_target/abi/call/mips.rs
+++ b/src/librustc_target/abi/call/mips.rs
@@ -1,9 +1,9 @@
 use crate::abi::call::{ArgAbi, FnAbi, Reg, Uniform};
-use crate::abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods};
+use crate::abi::{HasDataLayout, LayoutOf, Size, TyAndLayoutMethods};
 
 fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'_, Ty>, offset: &mut Size)
 where
-    Ty: TyLayoutMethods<'a, C>,
+    Ty: TyAndLayoutMethods<'a, C>,
     C: LayoutOf<Ty = Ty> + HasDataLayout,
 {
     if !ret.layout.is_aggregate() {
@@ -16,7 +16,7 @@ where
 
 fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size)
 where
-    Ty: TyLayoutMethods<'a, C>,
+    Ty: TyAndLayoutMethods<'a, C>,
     C: LayoutOf<Ty = Ty> + HasDataLayout,
 {
     let dl = cx.data_layout();
@@ -37,7 +37,7 @@ where
 
 pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'_, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C>,
+    Ty: TyAndLayoutMethods<'a, C>,
     C: LayoutOf<Ty = Ty> + HasDataLayout,
 {
     let mut offset = Size::ZERO;
diff --git a/src/librustc_target/abi/call/mips64.rs b/src/librustc_target/abi/call/mips64.rs
index 6f8910a011a..81de6306788 100644
--- a/src/librustc_target/abi/call/mips64.rs
+++ b/src/librustc_target/abi/call/mips64.rs
@@ -1,5 +1,5 @@
 use crate::abi::call::{ArgAbi, ArgAttribute, CastTarget, FnAbi, PassMode, Reg, RegKind, Uniform};
-use crate::abi::{self, HasDataLayout, LayoutOf, Size, TyLayout, TyLayoutMethods};
+use crate::abi::{self, HasDataLayout, LayoutOf, Size, TyAndLayout, TyAndLayoutMethods};
 
 fn extend_integer_width_mips<Ty>(arg: &mut ArgAbi<'_, Ty>, bits: u64) {
     // Always sign extend u32 values on 64-bit mips
@@ -19,8 +19,8 @@ fn extend_integer_width_mips<Ty>(arg: &mut ArgAbi<'_, Ty>, bits: u64) {
 
 fn float_reg<'a, Ty, C>(cx: &C, ret: &ArgAbi<'a, Ty>, i: usize) -> Option<Reg>
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     match ret.layout.field(cx, i).abi {
         abi::Abi::Scalar(ref scalar) => match scalar.value {
@@ -34,8 +34,8 @@ where
 
 fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     if !ret.layout.is_aggregate() {
         extend_integer_width_mips(ret, 64);
@@ -49,7 +49,7 @@ where
         // use of float registers to structures (not unions) containing exactly one or two
         // float fields.
 
-        if let abi::FieldPlacement::Arbitrary { .. } = ret.layout.fields {
+        if let abi::FieldsShape::Arbitrary { .. } = ret.layout.fields {
             if ret.layout.fields.count() == 1 {
                 if let Some(reg) = float_reg(cx, ret, 0) {
                     ret.cast_to(reg);
@@ -74,8 +74,8 @@ where
 
 fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     if !arg.layout.is_aggregate() {
         extend_integer_width_mips(arg, 64);
@@ -88,15 +88,15 @@ where
     let mut prefix_index = 0;
 
     match arg.layout.fields {
-        abi::FieldPlacement::Array { .. } => {
+        abi::FieldsShape::Array { .. } => {
             // Arrays are passed indirectly
             arg.make_indirect();
             return;
         }
-        abi::FieldPlacement::Union(_) => {
+        abi::FieldsShape::Union(_) => {
             // Unions and are always treated as a series of 64-bit integer chunks
         }
-        abi::FieldPlacement::Arbitrary { .. } => {
+        abi::FieldsShape::Arbitrary { .. } => {
             // Structures are split up into a series of 64-bit integer chunks, but any aligned
             // doubles not part of another aggregate are passed as floats.
             let mut last_offset = Size::ZERO;
@@ -143,8 +143,8 @@ where
 
 pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     if !fn_abi.ret.is_ignore() {
         classify_ret(cx, &mut fn_abi.ret);
diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs
index 77e7ff1e2a7..b6bfa70005b 100644
--- a/src/librustc_target/abi/call/mod.rs
+++ b/src/librustc_target/abi/call/mod.rs
@@ -1,5 +1,5 @@
-use crate::abi::{self, Abi, Align, FieldPlacement, Size};
-use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+use crate::abi::{self, Abi, Align, FieldsShape, Size};
+use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
 use crate::spec::{self, HasTargetSpec};
 
 mod aarch64;
@@ -264,7 +264,7 @@ impl HomogeneousAggregate {
     }
 }
 
-impl<'a, Ty> TyLayout<'a, Ty> {
+impl<'a, Ty> TyAndLayout<'a, Ty> {
     fn is_aggregate(&self) -> bool {
         match self.abi {
             Abi::Uninhabited | Abi::Scalar(_) | Abi::Vector { .. } => false,
@@ -284,8 +284,8 @@ impl<'a, Ty> TyLayout<'a, Ty> {
     /// specific targets.
     pub fn homogeneous_aggregate<C>(&self, cx: &C) -> Result<HomogeneousAggregate, Heterogeneous>
     where
-        Ty: TyLayoutMethods<'a, C> + Copy,
-        C: LayoutOf<Ty = Ty, TyLayout = Self>,
+        Ty: TyAndLayoutMethods<'a, C> + Copy,
+        C: LayoutOf<Ty = Ty, TyAndLayout = Self>,
     {
         match self.abi {
             Abi::Uninhabited => Err(Heterogeneous),
@@ -315,7 +315,7 @@ impl<'a, Ty> TyLayout<'a, Ty> {
                      start: Size|
                      -> Result<(HomogeneousAggregate, Size), Heterogeneous> {
                         let is_union = match layout.fields {
-                            FieldPlacement::Array { count, .. } => {
+                            FieldsShape::Array { count, .. } => {
                                 assert_eq!(start, Size::ZERO);
 
                                 let result = if count > 0 {
@@ -325,8 +325,8 @@ impl<'a, Ty> TyLayout<'a, Ty> {
                                 };
                                 return Ok((result, layout.size));
                             }
-                            FieldPlacement::Union(_) => true,
-                            FieldPlacement::Arbitrary { .. } => false,
+                            FieldsShape::Union(_) => true,
+                            FieldsShape::Arbitrary { .. } => false,
                         };
 
                         let mut result = HomogeneousAggregate::NoData;
@@ -404,7 +404,7 @@ impl<'a, Ty> TyLayout<'a, Ty> {
 /// or return a value from, a function, under some ABI.
 #[derive(Debug)]
 pub struct ArgAbi<'a, Ty> {
-    pub layout: TyLayout<'a, Ty>,
+    pub layout: TyAndLayout<'a, Ty>,
 
     /// Dummy argument, which is emitted before the real argument.
     pub pad: Option<Reg>,
@@ -413,7 +413,7 @@ pub struct ArgAbi<'a, Ty> {
 }
 
 impl<'a, Ty> ArgAbi<'a, Ty> {
-    pub fn new(layout: TyLayout<'a, Ty>) -> Self {
+    pub fn new(layout: TyAndLayout<'a, Ty>) -> Self {
         ArgAbi { layout, pad: None, mode: PassMode::Direct(ArgAttributes::new()) }
     }
 
@@ -546,13 +546,15 @@ pub struct FnAbi<'a, Ty> {
     pub fixed_count: usize,
 
     pub conv: Conv,
+
+    pub can_unwind: bool,
 }
 
 impl<'a, Ty> FnAbi<'a, Ty> {
     pub fn adjust_for_cabi<C>(&mut self, cx: &C, abi: spec::abi::Abi) -> Result<(), String>
     where
-        Ty: TyLayoutMethods<'a, C> + Copy,
-        C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout + HasTargetSpec,
+        Ty: TyAndLayoutMethods<'a, C> + Copy,
+        C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout + HasTargetSpec,
     {
         match &cx.target_spec().arch[..] {
             "x86" => {
diff --git a/src/librustc_target/abi/call/powerpc64.rs b/src/librustc_target/abi/call/powerpc64.rs
index 93c4e97de10..b740707320f 100644
--- a/src/librustc_target/abi/call/powerpc64.rs
+++ b/src/librustc_target/abi/call/powerpc64.rs
@@ -3,7 +3,7 @@
 // need to be fixed when PowerPC vector support is added.
 
 use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
-use crate::abi::{Endian, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+use crate::abi::{Endian, HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
 use crate::spec::HasTargetSpec;
 
 #[derive(Debug, Clone, Copy, PartialEq)]
@@ -19,8 +19,8 @@ fn is_homogeneous_aggregate<'a, Ty, C>(
     abi: ABI,
 ) -> Option<Uniform>
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| {
         // ELFv1 only passes one-member aggregates transparently.
@@ -43,8 +43,8 @@ where
 
 fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>, abi: ABI)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     if !ret.layout.is_aggregate() {
         ret.extend_integer_width_to(64);
@@ -86,8 +86,8 @@ where
 
 fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, abi: ABI)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     if !arg.layout.is_aggregate() {
         arg.extend_integer_width_to(64);
@@ -116,8 +116,8 @@ where
 
 pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout + HasTargetSpec,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout + HasTargetSpec,
 {
     let abi = if cx.target_spec().target_env == "musl" {
         ELFv2
diff --git a/src/librustc_target/abi/call/riscv.rs b/src/librustc_target/abi/call/riscv.rs
index 11d6c4d8191..0eb8816e434 100644
--- a/src/librustc_target/abi/call/riscv.rs
+++ b/src/librustc_target/abi/call/riscv.rs
@@ -6,7 +6,7 @@
 
 use crate::abi::call::{ArgAbi, ArgAttribute, CastTarget, FnAbi, PassMode, Reg, RegKind, Uniform};
 use crate::abi::{
-    self, Abi, FieldPlacement, HasDataLayout, LayoutOf, Size, TyLayout, TyLayoutMethods,
+    self, Abi, FieldsShape, HasDataLayout, LayoutOf, Size, TyAndLayout, TyAndLayoutMethods,
 };
 use crate::spec::HasTargetSpec;
 
@@ -36,15 +36,15 @@ fn is_riscv_aggregate<'a, Ty>(arg: &ArgAbi<'a, Ty>) -> bool {
 
 fn should_use_fp_conv_helper<'a, Ty, C>(
     cx: &C,
-    arg_layout: &TyLayout<'a, Ty>,
+    arg_layout: &TyAndLayout<'a, Ty>,
     xlen: u64,
     flen: u64,
     field1_kind: &mut RegPassKind,
     field2_kind: &mut RegPassKind,
 ) -> Result<(), CannotUseFpConv>
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>>,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>>,
 {
     match arg_layout.abi {
         Abi::Scalar(ref scalar) => match scalar.value {
@@ -87,12 +87,12 @@ where
         },
         Abi::Vector { .. } | Abi::Uninhabited => return Err(CannotUseFpConv),
         Abi::ScalarPair(..) | Abi::Aggregate { .. } => match arg_layout.fields {
-            FieldPlacement::Union(_) => {
+            FieldsShape::Union(_) => {
                 if !arg_layout.is_zst() {
                     return Err(CannotUseFpConv);
                 }
             }
-            FieldPlacement::Array { count, .. } => {
+            FieldsShape::Array { count, .. } => {
                 for _ in 0..count {
                     let elem_layout = arg_layout.field(cx, 0);
                     should_use_fp_conv_helper(
@@ -105,7 +105,7 @@ where
                     )?;
                 }
             }
-            FieldPlacement::Arbitrary { .. } => {
+            FieldsShape::Arbitrary { .. } => {
                 match arg_layout.variants {
                     abi::Variants::Multiple { .. } => return Err(CannotUseFpConv),
                     abi::Variants::Single { .. } => (),
@@ -122,13 +122,13 @@ where
 
 fn should_use_fp_conv<'a, Ty, C>(
     cx: &C,
-    arg: &TyLayout<'a, Ty>,
+    arg: &TyAndLayout<'a, Ty>,
     xlen: u64,
     flen: u64,
 ) -> Option<FloatConv>
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>>,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>>,
 {
     let mut field1_kind = RegPassKind::Unknown;
     let mut field2_kind = RegPassKind::Unknown;
@@ -146,8 +146,8 @@ where
 
 fn classify_ret<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, xlen: u64, flen: u64) -> bool
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>>,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>>,
 {
     if let Some(conv) = should_use_fp_conv(cx, &arg.layout, xlen, flen) {
         match conv {
@@ -209,8 +209,8 @@ fn classify_arg<'a, Ty, C>(
     avail_gprs: &mut u64,
     avail_fprs: &mut u64,
 ) where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>>,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>>,
 {
     if !is_vararg {
         match should_use_fp_conv(cx, &arg.layout, xlen, flen) {
@@ -300,30 +300,25 @@ fn classify_arg<'a, Ty, C>(
 }
 
 fn extend_integer_width<'a, Ty>(arg: &mut ArgAbi<'a, Ty>, xlen: u64) {
-    match arg.layout.abi {
-        Abi::Scalar(ref scalar) => {
-            match scalar.value {
-                abi::Int(i, _) => {
-                    // 32-bit integers are always sign-extended
-                    if i.size().bits() == 32 && xlen > 32 {
-                        if let PassMode::Direct(ref mut attrs) = arg.mode {
-                            attrs.set(ArgAttribute::SExt);
-                            return;
-                        }
-                    }
+    if let Abi::Scalar(ref scalar) = arg.layout.abi {
+        if let abi::Int(i, _) = scalar.value {
+            // 32-bit integers are always sign-extended
+            if i.size().bits() == 32 && xlen > 32 {
+                if let PassMode::Direct(ref mut attrs) = arg.mode {
+                    attrs.set(ArgAttribute::SExt);
+                    return;
                 }
-                _ => (),
             }
         }
-        _ => (),
     }
+
     arg.extend_integer_width_to(xlen);
 }
 
 pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout + HasTargetSpec,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout + HasTargetSpec,
 {
     let flen = match &cx.target_spec().options.llvm_abiname[..] {
         "ilp32f" | "lp64f" => 32,
diff --git a/src/librustc_target/abi/call/s390x.rs b/src/librustc_target/abi/call/s390x.rs
index d4e9511d087..005dcc62dfd 100644
--- a/src/librustc_target/abi/call/s390x.rs
+++ b/src/librustc_target/abi/call/s390x.rs
@@ -2,11 +2,11 @@
 // for a pre-z13 machine or using -mno-vx.
 
 use crate::abi::call::{ArgAbi, FnAbi, Reg};
-use crate::abi::{self, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+use crate::abi::{self, HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
 
 fn classify_ret<'a, Ty, C>(ret: &mut ArgAbi<'_, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C>,
+    Ty: TyAndLayoutMethods<'a, C>,
     C: LayoutOf<Ty = Ty> + HasDataLayout,
 {
     if !ret.layout.is_aggregate() && ret.layout.size.bits() <= 64 {
@@ -16,10 +16,10 @@ where
     }
 }
 
-fn is_single_fp_element<'a, Ty, C>(cx: &C, layout: TyLayout<'a, Ty>) -> bool
+fn is_single_fp_element<'a, Ty, C>(cx: &C, layout: TyAndLayout<'a, Ty>) -> bool
 where
-    Ty: TyLayoutMethods<'a, C>,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C>,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     match layout.abi {
         abi::Abi::Scalar(ref scalar) => scalar.value.is_float(),
@@ -36,8 +36,8 @@ where
 
 fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     if !arg.layout.is_aggregate() && arg.layout.size.bits() <= 64 {
         arg.extend_integer_width_to(64);
@@ -63,8 +63,8 @@ where
 
 pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     if !fn_abi.ret.is_ignore() {
         classify_ret(&mut fn_abi.ret);
diff --git a/src/librustc_target/abi/call/sparc.rs b/src/librustc_target/abi/call/sparc.rs
index b332b9afe7f..733a7328bd3 100644
--- a/src/librustc_target/abi/call/sparc.rs
+++ b/src/librustc_target/abi/call/sparc.rs
@@ -1,9 +1,9 @@
 use crate::abi::call::{ArgAbi, FnAbi, Reg, Uniform};
-use crate::abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods};
+use crate::abi::{HasDataLayout, LayoutOf, Size, TyAndLayoutMethods};
 
 fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'_, Ty>, offset: &mut Size)
 where
-    Ty: TyLayoutMethods<'a, C>,
+    Ty: TyAndLayoutMethods<'a, C>,
     C: LayoutOf<Ty = Ty> + HasDataLayout,
 {
     if !ret.layout.is_aggregate() {
@@ -16,7 +16,7 @@ where
 
 fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size)
 where
-    Ty: TyLayoutMethods<'a, C>,
+    Ty: TyAndLayoutMethods<'a, C>,
     C: LayoutOf<Ty = Ty> + HasDataLayout,
 {
     let dl = cx.data_layout();
@@ -37,7 +37,7 @@ where
 
 pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'_, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C>,
+    Ty: TyAndLayoutMethods<'a, C>,
     C: LayoutOf<Ty = Ty> + HasDataLayout,
 {
     let mut offset = Size::ZERO;
diff --git a/src/librustc_target/abi/call/sparc64.rs b/src/librustc_target/abi/call/sparc64.rs
index c80f8316feb..a647675e073 100644
--- a/src/librustc_target/abi/call/sparc64.rs
+++ b/src/librustc_target/abi/call/sparc64.rs
@@ -1,12 +1,12 @@
 // FIXME: This needs an audit for correctness and completeness.
 
 use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
-use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
 
 fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option<Uniform>
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| {
         // Ensure we have at most eight uniquely addressable members.
@@ -26,8 +26,8 @@ where
 
 fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     if !ret.layout.is_aggregate() {
         ret.extend_integer_width_to(64);
@@ -52,8 +52,8 @@ where
 
 fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     if !arg.layout.is_aggregate() {
         arg.extend_integer_width_to(64);
@@ -76,8 +76,8 @@ where
 
 pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     if !fn_abi.ret.is_ignore() {
         classify_ret(cx, &mut fn_abi.ret);
diff --git a/src/librustc_target/abi/call/wasm32.rs b/src/librustc_target/abi/call/wasm32.rs
index 9aab64ef272..510f671a501 100644
--- a/src/librustc_target/abi/call/wasm32.rs
+++ b/src/librustc_target/abi/call/wasm32.rs
@@ -1,10 +1,10 @@
 use crate::abi::call::{ArgAbi, FnAbi, Uniform};
-use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
 
 fn unwrap_trivial_aggregate<'a, Ty, C>(cx: &C, val: &mut ArgAbi<'a, Ty>) -> bool
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     if val.layout.is_aggregate() {
         if let Some(unit) = val.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()) {
@@ -20,8 +20,8 @@ where
 
 fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     ret.extend_integer_width_to(32);
     if ret.layout.is_aggregate() {
@@ -33,8 +33,8 @@ where
 
 fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     arg.extend_integer_width_to(32);
     if arg.layout.is_aggregate() {
@@ -46,8 +46,8 @@ where
 
 pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     if !fn_abi.ret.is_ignore() {
         classify_ret(cx, &mut fn_abi.ret);
diff --git a/src/librustc_target/abi/call/x86.rs b/src/librustc_target/abi/call/x86.rs
index e776a8b3fe4..df3dd5d9208 100644
--- a/src/librustc_target/abi/call/x86.rs
+++ b/src/librustc_target/abi/call/x86.rs
@@ -1,5 +1,5 @@
 use crate::abi::call::{ArgAttribute, FnAbi, PassMode, Reg, RegKind};
-use crate::abi::{self, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+use crate::abi::{self, HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
 use crate::spec::HasTargetSpec;
 
 #[derive(PartialEq)]
@@ -8,10 +8,10 @@ pub enum Flavor {
     Fastcall,
 }
 
-fn is_single_fp_element<'a, Ty, C>(cx: &C, layout: TyLayout<'a, Ty>) -> bool
+fn is_single_fp_element<'a, Ty, C>(cx: &C, layout: TyAndLayout<'a, Ty>) -> bool
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     match layout.abi {
         abi::Abi::Scalar(ref scalar) => scalar.value.is_float(),
@@ -28,8 +28,8 @@ where
 
 pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, flavor: Flavor)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout + HasTargetSpec,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout + HasTargetSpec,
 {
     if !fn_abi.ret.is_ignore() {
         if fn_abi.ret.layout.is_aggregate() {
diff --git a/src/librustc_target/abi/call/x86_64.rs b/src/librustc_target/abi/call/x86_64.rs
index 4c192c46786..5f154dc1bc9 100644
--- a/src/librustc_target/abi/call/x86_64.rs
+++ b/src/librustc_target/abi/call/x86_64.rs
@@ -2,7 +2,7 @@
 // https://github.com/jckarter/clay/blob/master/compiler/src/externals.cpp
 
 use crate::abi::call::{ArgAbi, CastTarget, FnAbi, Reg, RegKind};
-use crate::abi::{self, Abi, HasDataLayout, LayoutOf, Size, TyLayout, TyLayoutMethods};
+use crate::abi::{self, Abi, HasDataLayout, LayoutOf, Size, TyAndLayout, TyAndLayoutMethods};
 
 /// Classification of "eightbyte" components.
 // N.B., the order of the variants is from general to specific,
@@ -26,18 +26,18 @@ fn classify_arg<'a, Ty, C>(
     arg: &ArgAbi<'a, Ty>,
 ) -> Result<[Option<Class>; MAX_EIGHTBYTES], Memory>
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     fn classify<'a, Ty, C>(
         cx: &C,
-        layout: TyLayout<'a, Ty>,
+        layout: TyAndLayout<'a, Ty>,
         cls: &mut [Option<Class>],
         off: Size,
     ) -> Result<(), Memory>
     where
-        Ty: TyLayoutMethods<'a, C> + Copy,
-        C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+        Ty: TyAndLayoutMethods<'a, C> + Copy,
+        C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
     {
         if !off.is_aligned(layout.align.abi) {
             if !layout.is_zst() {
@@ -172,8 +172,8 @@ const MAX_SSE_REGS: usize = 8; // XMM0-7
 
 pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
-    Ty: TyLayoutMethods<'a, C> + Copy,
-    C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout,
+    Ty: TyAndLayoutMethods<'a, C> + Copy,
+    C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
 {
     let mut int_regs = MAX_INT_REGS;
     let mut sse_regs = MAX_SSE_REGS;
diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs
index 6976ac9f0d7..4c25363a657 100644
--- a/src/librustc_target/abi/mod.rs
+++ b/src/librustc_target/abi/mod.rs
@@ -577,7 +577,7 @@ pub struct Scalar {
     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
@@ -618,7 +618,7 @@ impl Scalar {
 
 /// Describes how the fields of a type are located in memory.
 #[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)]
-pub enum FieldPlacement {
+pub enum FieldsShape {
     /// All fields start at no offset. The `usize` is the field count.
     ///
     /// In the case of primitives the number of fields is `0`.
@@ -657,38 +657,38 @@ pub enum FieldPlacement {
     },
 }
 
-impl FieldPlacement {
+impl FieldsShape {
     pub fn count(&self) -> usize {
         match *self {
-            FieldPlacement::Union(count) => count,
-            FieldPlacement::Array { count, .. } => {
+            FieldsShape::Union(count) => count,
+            FieldsShape::Array { count, .. } => {
                 let usize_count = count as usize;
                 assert_eq!(usize_count as u64, count);
                 usize_count
             }
-            FieldPlacement::Arbitrary { ref offsets, .. } => offsets.len(),
+            FieldsShape::Arbitrary { ref offsets, .. } => offsets.len(),
         }
     }
 
     pub fn offset(&self, i: usize) -> Size {
         match *self {
-            FieldPlacement::Union(count) => {
+            FieldsShape::Union(count) => {
                 assert!(i < count, "tried to access field {} of union with {} fields", i, count);
                 Size::ZERO
             }
-            FieldPlacement::Array { stride, count } => {
+            FieldsShape::Array { stride, count } => {
                 let i = u64::try_from(i).unwrap();
                 assert!(i < count);
                 stride * i
             }
-            FieldPlacement::Arbitrary { ref offsets, .. } => offsets[i],
+            FieldsShape::Arbitrary { ref offsets, .. } => offsets[i],
         }
     }
 
     pub fn memory_index(&self, i: usize) -> usize {
         match *self {
-            FieldPlacement::Union(_) | FieldPlacement::Array { .. } => i,
-            FieldPlacement::Arbitrary { ref memory_index, .. } => {
+            FieldsShape::Union(_) | FieldsShape::Array { .. } => i,
+            FieldsShape::Arbitrary { ref memory_index, .. } => {
                 let r = memory_index[i];
                 assert_eq!(r as usize as u32, r);
                 r as usize
@@ -704,7 +704,7 @@ impl FieldPlacement {
         let use_small = self.count() <= inverse_small.len();
 
         // We have to write this logic twice in order to keep the array small.
-        if let FieldPlacement::Arbitrary { ref memory_index, .. } = *self {
+        if let FieldsShape::Arbitrary { ref memory_index, .. } = *self {
             if use_small {
                 for i in 0..self.count() {
                     inverse_small[memory_index[i] as usize] = i as u8;
@@ -718,8 +718,8 @@ impl FieldPlacement {
         }
 
         (0..self.count()).map(move |i| match *self {
-            FieldPlacement::Union(_) | FieldPlacement::Array { .. } => i,
-            FieldPlacement::Arbitrary { .. } => {
+            FieldsShape::Union(_) | FieldsShape::Array { .. } => i,
+            FieldsShape::Arbitrary { .. } => {
                 if use_small {
                     inverse_small[i] as usize
                 } else {
@@ -888,7 +888,7 @@ impl Niche {
 pub struct Layout {
     /// Says where the fields are located within the layout.
     /// Primitives and uninhabited enums appear as unions without fields.
-    pub fields: FieldPlacement,
+    pub fields: FieldsShape,
 
     /// Encodes information about multi-variant layouts.
     /// Even with `Multiple` variants, a layout still has its own fields! Those are then
@@ -923,7 +923,7 @@ impl Layout {
         let align = scalar.value.align(cx);
         Layout {
             variants: Variants::Single { index: VariantIdx::new(0) },
-            fields: FieldPlacement::Union(0),
+            fields: FieldsShape::Union(0),
             abi: Abi::Scalar(scalar),
             largest_niche,
             size,
@@ -939,14 +939,13 @@ impl Layout {
 /// to that obtained from `layout_of(ty)`, as we need to produce
 /// layouts for which Rust types do not exist, such as enum variants
 /// or synthetic fields of enums (i.e., discriminants) and fat pointers.
-// FIXME: rename to TyAndLayout.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub struct TyLayout<'a, Ty> {
+pub struct TyAndLayout<'a, Ty> {
     pub ty: Ty,
     pub layout: &'a Layout,
 }
 
-impl<'a, Ty> Deref for TyLayout<'a, Ty> {
+impl<'a, Ty> Deref for TyAndLayout<'a, Ty> {
     type Target = &'a Layout;
     fn deref(&self) -> &&'a Layout {
         &self.layout
@@ -956,15 +955,15 @@ impl<'a, Ty> Deref for TyLayout<'a, Ty> {
 /// Trait for context types that can compute layouts of things.
 pub trait LayoutOf {
     type Ty;
-    type TyLayout;
+    type TyAndLayout;
 
-    fn layout_of(&self, ty: Self::Ty) -> Self::TyLayout;
-    fn spanned_layout_of(&self, ty: Self::Ty, _span: Span) -> Self::TyLayout {
+    fn layout_of(&self, ty: Self::Ty) -> Self::TyAndLayout;
+    fn spanned_layout_of(&self, ty: Self::Ty, _span: Span) -> Self::TyAndLayout {
         self.layout_of(ty)
     }
 }
 
-/// The `TyLayout` above will always be a `MaybeResult<TyLayout<'_, Self>>`.
+/// The `TyAndLayout` above will always be a `MaybeResult<TyAndLayout<'_, Self>>`.
 /// We can't add the bound due to the lifetime, but this trait is still useful when
 /// writing code that's generic over the `LayoutOf` impl.
 pub trait MaybeResult<T> {
@@ -1018,30 +1017,30 @@ pub struct PointeeInfo {
     pub safe: Option<PointerKind>,
 }
 
-pub trait TyLayoutMethods<'a, C: LayoutOf<Ty = Self>>: Sized {
+pub trait TyAndLayoutMethods<'a, C: LayoutOf<Ty = Self>>: Sized {
     fn for_variant(
-        this: TyLayout<'a, Self>,
+        this: TyAndLayout<'a, Self>,
         cx: &C,
         variant_index: VariantIdx,
-    ) -> TyLayout<'a, Self>;
-    fn field(this: TyLayout<'a, Self>, cx: &C, i: usize) -> C::TyLayout;
-    fn pointee_info_at(this: TyLayout<'a, Self>, cx: &C, offset: Size) -> Option<PointeeInfo>;
+    ) -> TyAndLayout<'a, Self>;
+    fn field(this: TyAndLayout<'a, Self>, cx: &C, i: usize) -> C::TyAndLayout;
+    fn pointee_info_at(this: TyAndLayout<'a, Self>, cx: &C, offset: Size) -> Option<PointeeInfo>;
 }
 
-impl<'a, Ty> TyLayout<'a, Ty> {
+impl<'a, Ty> TyAndLayout<'a, Ty> {
     pub fn for_variant<C>(self, cx: &C, variant_index: VariantIdx) -> Self
     where
-        Ty: TyLayoutMethods<'a, C>,
+        Ty: TyAndLayoutMethods<'a, C>,
         C: LayoutOf<Ty = Ty>,
     {
         Ty::for_variant(self, cx, variant_index)
     }
 
-    /// Callers might want to use `C: LayoutOf<Ty=Ty, TyLayout: MaybeResult<Self>>`
+    /// Callers might want to use `C: LayoutOf<Ty=Ty, TyAndLayout: MaybeResult<Self>>`
     /// to allow recursion (see `might_permit_zero_init` below for an example).
-    pub fn field<C>(self, cx: &C, i: usize) -> C::TyLayout
+    pub fn field<C>(self, cx: &C, i: usize) -> C::TyAndLayout
     where
-        Ty: TyLayoutMethods<'a, C>,
+        Ty: TyAndLayoutMethods<'a, C>,
         C: LayoutOf<Ty = Ty>,
     {
         Ty::field(self, cx, i)
@@ -1049,14 +1048,14 @@ impl<'a, Ty> TyLayout<'a, Ty> {
 
     pub fn pointee_info_at<C>(self, cx: &C, offset: Size) -> Option<PointeeInfo>
     where
-        Ty: TyLayoutMethods<'a, C>,
+        Ty: TyAndLayoutMethods<'a, C>,
         C: LayoutOf<Ty = Ty>,
     {
         Ty::pointee_info_at(self, cx, offset)
     }
 }
 
-impl<'a, Ty> TyLayout<'a, Ty> {
+impl<'a, Ty> TyAndLayout<'a, Ty> {
     /// Returns `true` if the layout corresponds to an unsized type.
     pub fn is_unsized(&self) -> bool {
         self.abi.is_unsized()
@@ -1083,8 +1082,8 @@ impl<'a, Ty> TyLayout<'a, Ty> {
     pub fn might_permit_raw_init<C, E>(self, cx: &C, zero: bool) -> Result<bool, E>
     where
         Self: Copy,
-        Ty: TyLayoutMethods<'a, C>,
-        C: LayoutOf<Ty = Ty, TyLayout: MaybeResult<Self, Error = E>> + HasDataLayout,
+        Ty: TyAndLayoutMethods<'a, C>,
+        C: LayoutOf<Ty = Ty, TyAndLayout: MaybeResult<Self, Error = E>> + HasDataLayout,
     {
         let scalar_allows_raw_init = move |s: &Scalar| -> bool {
             if zero {
diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs
index 98190867d49..b2965fb8806 100644
--- a/src/librustc_target/lib.rs
+++ b/src/librustc_target/lib.rs
@@ -25,5 +25,5 @@ pub mod spec;
 
 /// Requirements for a `StableHashingContext` to be used in this crate.
 /// This is a hack to allow using the `HashStable_Generic` derive macro
-/// instead of implementing everything in librustc.
+/// instead of implementing everything in librustc_middle.
 pub trait HashStableContext {}
diff --git a/src/librustc_target/spec/i686_apple_darwin.rs b/src/librustc_target/spec/i686_apple_darwin.rs
index 033b87b110e..b7a34f9740a 100644
--- a/src/librustc_target/spec/i686_apple_darwin.rs
+++ b/src/librustc_target/spec/i686_apple_darwin.rs
@@ -16,7 +16,7 @@ pub fn target() -> TargetResult {
     let llvm_target = super::apple_base::macos_llvm_target(&arch);
 
     Ok(Target {
-        llvm_target: llvm_target,
+        llvm_target,
         target_endian: "little".to_string(),
         target_pointer_width: "32".to_string(),
         target_c_int_width: "32".to_string(),
diff --git a/src/librustc_target/spec/windows_base.rs b/src/librustc_target/spec/windows_base.rs
index 188548b41fe..5f59ca8a5a3 100644
--- a/src/librustc_target/spec/windows_base.rs
+++ b/src/librustc_target/spec/windows_base.rs
@@ -60,6 +60,8 @@ pub fn opts() -> TargetOptions {
             "-lgcc".to_string(),
             "-lgcc_eh".to_string(),
             "-lpthread".to_string(),
+            // libpthread depends on libmsvcrt, so we need to link it *again*.
+            "-lmsvcrt".to_string(),
             "-lkernel32".to_string(),
         ],
     );
diff --git a/src/librustc_target/spec/x86_64_apple_darwin.rs b/src/librustc_target/spec/x86_64_apple_darwin.rs
index e846f42f8f8..31011e84749 100644
--- a/src/librustc_target/spec/x86_64_apple_darwin.rs
+++ b/src/librustc_target/spec/x86_64_apple_darwin.rs
@@ -16,7 +16,7 @@ pub fn target() -> TargetResult {
     let llvm_target = super::apple_base::macos_llvm_target(&arch);
 
     Ok(Target {
-        llvm_target: llvm_target,
+        llvm_target,
         target_endian: "little".to_string(),
         target_pointer_width: "64".to_string(),
         target_c_int_width: "32".to_string(),
diff --git a/src/librustc_trait_selection/Cargo.toml b/src/librustc_trait_selection/Cargo.toml
index 5b2da41d066..254695e53e0 100644
--- a/src/librustc_trait_selection/Cargo.toml
+++ b/src/librustc_trait_selection/Cargo.toml
@@ -13,7 +13,7 @@ doctest = false
 fmt_macros = { path = "../libfmt_macros" }
 log = { version = "0.4", features = ["release_max_level_info", "std"] }
 rustc_attr = { path = "../librustc_attr" }
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc_ast = { path = "../librustc_ast" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors" }
diff --git a/src/librustc_trait_selection/infer.rs b/src/librustc_trait_selection/infer.rs
index 7abcbf45277..24eb22fbd00 100644
--- a/src/librustc_trait_selection/infer.rs
+++ b/src/librustc_trait_selection/infer.rs
@@ -1,14 +1,14 @@
 use crate::traits::query::outlives_bounds::InferCtxtExt as _;
 use crate::traits::{self, TraitEngine, TraitEngineExt};
 
-use rustc::arena::ArenaAllocatable;
-use rustc::infer::canonical::{Canonical, CanonicalizedQueryResponse, QueryResponse};
-use rustc::middle::lang_items;
-use rustc::traits::query::Fallible;
-use rustc::ty::{self, Ty, TypeFoldable};
 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::traits::query::Fallible;
+use rustc_middle::ty::{self, Ty, TypeFoldable};
 use rustc_span::{Span, DUMMY_SP};
 
 use std::fmt::Debug;
diff --git a/src/librustc_trait_selection/lib.rs b/src/librustc_trait_selection/lib.rs
index 739aff4fb94..21315cc89ca 100644
--- a/src/librustc_trait_selection/lib.rs
+++ b/src/librustc_trait_selection/lib.rs
@@ -15,6 +15,7 @@
 #![feature(drain_filter)]
 #![feature(in_band_lifetimes)]
 #![feature(crate_visibility_modifier)]
+#![feature(or_patterns)]
 #![recursion_limit = "512"] // For rustdoc
 
 #[macro_use]
@@ -25,7 +26,7 @@ extern crate rustc_data_structures;
 #[macro_use]
 extern crate log;
 #[macro_use]
-extern crate rustc;
+extern crate rustc_middle;
 
 pub mod infer;
 pub mod opaque_types;
diff --git a/src/librustc_trait_selection/opaque_types.rs b/src/librustc_trait_selection/opaque_types.rs
index 30189d189f2..093873c849a 100644
--- a/src/librustc_trait_selection/opaque_types.rs
+++ b/src/librustc_trait_selection/opaque_types.rs
@@ -1,9 +1,5 @@
 use crate::infer::InferCtxtExt as _;
 use crate::traits::{self, PredicateObligation};
-use rustc::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor};
-use rustc::ty::free_region_map::FreeRegionRelations;
-use rustc::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef};
-use rustc::ty::{self, GenericParamDefKind, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
 use rustc_hir as hir;
@@ -12,6 +8,10 @@ use rustc_hir::Node;
 use rustc_infer::infer::error_reporting::unexpected_hidden_region_diagnostic;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::{self, InferCtxt, InferOk};
+use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor};
+use rustc_middle::ty::free_region_map::FreeRegionRelations;
+use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef};
+use rustc_middle::ty::{self, GenericParamDefKind, Ty, TyCtxt};
 use rustc_session::config::nightly_options;
 use rustc_span::Span;
 
diff --git a/src/librustc_trait_selection/traits/auto_trait.rs b/src/librustc_trait_selection/traits/auto_trait.rs
index bd980e6eb8b..e01f5bfbcb3 100644
--- a/src/librustc_trait_selection/traits/auto_trait.rs
+++ b/src/librustc_trait_selection/traits/auto_trait.rs
@@ -5,8 +5,8 @@ use super::*;
 
 use crate::infer::region_constraints::{Constraint, RegionConstraintData};
 use crate::infer::InferCtxt;
-use rustc::ty::fold::TypeFolder;
-use rustc::ty::{Region, RegionVid};
+use rustc_middle::ty::fold::TypeFolder;
+use rustc_middle::ty::{Region, RegionVid};
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 
@@ -314,19 +314,17 @@ impl AutoTraitFinder<'tcx> {
                 &Ok(Some(ref vtable)) => {
                     // If we see an explicit negative impl (e.g., `impl !Send for MyStruct`),
                     // we immediately bail out, since it's impossible for us to continue.
-                    match vtable {
-                        Vtable::VtableImpl(VtableImplData { impl_def_id, .. }) => {
-                            // Blame 'tidy' for the weird bracket placement.
-                            if infcx.tcx.impl_polarity(*impl_def_id) == ty::ImplPolarity::Negative {
-                                debug!(
-                                    "evaluate_nested_obligations: found explicit negative impl\
+
+                    if let Vtable::VtableImpl(VtableImplData { impl_def_id, .. }) = vtable {
+                        // Blame 'tidy' for the weird bracket placement.
+                        if infcx.tcx.impl_polarity(*impl_def_id) == ty::ImplPolarity::Negative {
+                            debug!(
+                                "evaluate_nested_obligations: found explicit negative impl\
                                         {:?}, bailing out",
-                                    impl_def_id
-                                );
-                                return None;
-                            }
+                                impl_def_id
+                            );
+                            return None;
                         }
-                        _ => {}
                     }
 
                     let obligations = vtable.clone().nested_obligations().into_iter();
@@ -417,80 +415,77 @@ impl AutoTraitFinder<'tcx> {
     ) {
         let mut should_add_new = true;
         user_computed_preds.retain(|&old_pred| {
-            match (&new_pred, old_pred) {
-                (&ty::Predicate::Trait(new_trait, _), ty::Predicate::Trait(old_trait, _)) => {
-                    if new_trait.def_id() == old_trait.def_id() {
-                        let new_substs = new_trait.skip_binder().trait_ref.substs;
-                        let old_substs = old_trait.skip_binder().trait_ref.substs;
-
-                        if !new_substs.types().eq(old_substs.types()) {
-                            // We can't compare lifetimes if the types are different,
-                            // so skip checking `old_pred`.
-                            return true;
-                        }
+            if let (&ty::Predicate::Trait(new_trait, _), ty::Predicate::Trait(old_trait, _)) =
+                (&new_pred, old_pred)
+            {
+                if new_trait.def_id() == old_trait.def_id() {
+                    let new_substs = new_trait.skip_binder().trait_ref.substs;
+                    let old_substs = old_trait.skip_binder().trait_ref.substs;
+
+                    if !new_substs.types().eq(old_substs.types()) {
+                        // We can't compare lifetimes if the types are different,
+                        // so skip checking `old_pred`.
+                        return true;
+                    }
 
-                        for (new_region, old_region) in
-                            new_substs.regions().zip(old_substs.regions())
-                        {
-                            match (new_region, old_region) {
-                                // If both predicates have an `ReLateBound` (a HRTB) in the
-                                // same spot, we do nothing.
-                                (
-                                    ty::RegionKind::ReLateBound(_, _),
-                                    ty::RegionKind::ReLateBound(_, _),
-                                ) => {}
-
-                                (ty::RegionKind::ReLateBound(_, _), _)
-                                | (_, ty::RegionKind::ReVar(_)) => {
-                                    // One of these is true:
-                                    // The new predicate has a HRTB in a spot where the old
-                                    // predicate does not (if they both had a HRTB, the previous
-                                    // match arm would have executed). A HRBT is a 'stricter'
-                                    // bound than anything else, so we want to keep the newer
-                                    // predicate (with the HRBT) in place of the old predicate.
-                                    //
-                                    // OR
-                                    //
-                                    // The old predicate has a region variable where the new
-                                    // predicate has some other kind of region. An region
-                                    // variable isn't something we can actually display to a user,
-                                    // so we choose their new predicate (which doesn't have a region
-                                    // variable).
-                                    //
-                                    // In both cases, we want to remove the old predicate,
-                                    // from `user_computed_preds`, and replace it with the new
-                                    // one. Having both the old and the new
-                                    // predicate in a `ParamEnv` would confuse `SelectionContext`.
-                                    //
-                                    // We're currently in the predicate passed to 'retain',
-                                    // so we return `false` to remove the old predicate from
-                                    // `user_computed_preds`.
-                                    return false;
-                                }
-                                (_, ty::RegionKind::ReLateBound(_, _))
-                                | (ty::RegionKind::ReVar(_), _) => {
-                                    // This is the opposite situation as the previous arm.
-                                    // One of these is true:
-                                    //
-                                    // The old predicate has a HRTB lifetime in a place where the
-                                    // new predicate does not.
-                                    //
-                                    // OR
-                                    //
-                                    // The new predicate has a region variable where the old
-                                    // predicate has some other type of region.
-                                    //
-                                    // We want to leave the old
-                                    // predicate in `user_computed_preds`, and skip adding
-                                    // new_pred to `user_computed_params`.
-                                    should_add_new = false
-                                }
-                                _ => {}
+                    for (new_region, old_region) in new_substs.regions().zip(old_substs.regions()) {
+                        match (new_region, old_region) {
+                            // If both predicates have an `ReLateBound` (a HRTB) in the
+                            // same spot, we do nothing.
+                            (
+                                ty::RegionKind::ReLateBound(_, _),
+                                ty::RegionKind::ReLateBound(_, _),
+                            ) => {}
+
+                            (ty::RegionKind::ReLateBound(_, _), _)
+                            | (_, ty::RegionKind::ReVar(_)) => {
+                                // One of these is true:
+                                // The new predicate has a HRTB in a spot where the old
+                                // predicate does not (if they both had a HRTB, the previous
+                                // match arm would have executed). A HRBT is a 'stricter'
+                                // bound than anything else, so we want to keep the newer
+                                // predicate (with the HRBT) in place of the old predicate.
+                                //
+                                // OR
+                                //
+                                // The old predicate has a region variable where the new
+                                // predicate has some other kind of region. An region
+                                // variable isn't something we can actually display to a user,
+                                // so we choose their new predicate (which doesn't have a region
+                                // variable).
+                                //
+                                // In both cases, we want to remove the old predicate,
+                                // from `user_computed_preds`, and replace it with the new
+                                // one. Having both the old and the new
+                                // predicate in a `ParamEnv` would confuse `SelectionContext`.
+                                //
+                                // We're currently in the predicate passed to 'retain',
+                                // so we return `false` to remove the old predicate from
+                                // `user_computed_preds`.
+                                return false;
+                            }
+                            (_, ty::RegionKind::ReLateBound(_, _))
+                            | (ty::RegionKind::ReVar(_), _) => {
+                                // This is the opposite situation as the previous arm.
+                                // One of these is true:
+                                //
+                                // The old predicate has a HRTB lifetime in a place where the
+                                // new predicate does not.
+                                //
+                                // OR
+                                //
+                                // The new predicate has a region variable where the old
+                                // predicate has some other type of region.
+                                //
+                                // We want to leave the old
+                                // predicate in `user_computed_preds`, and skip adding
+                                // new_pred to `user_computed_params`.
+                                should_add_new = false
                             }
+                            _ => {}
                         }
                     }
                 }
-                _ => {}
             }
             true
         });
diff --git a/src/librustc_trait_selection/traits/codegen/mod.rs b/src/librustc_trait_selection/traits/codegen/mod.rs
index 5c2fc3f305c..e75432a0b72 100644
--- a/src/librustc_trait_selection/traits/codegen/mod.rs
+++ b/src/librustc_trait_selection/traits/codegen/mod.rs
@@ -7,8 +7,8 @@ use crate::infer::{InferCtxt, TyCtxtInferExt};
 use crate::traits::{
     FulfillmentContext, Obligation, ObligationCause, SelectionContext, TraitEngine, Vtable,
 };
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::{self, TyCtxt};
+use rustc_middle::ty::fold::TypeFoldable;
+use rustc_middle::ty::{self, TyCtxt};
 
 /// Attempts to resolve an obligation to a vtable. The result is
 /// a shallow vtable resolution, meaning that we do not
diff --git a/src/librustc_trait_selection/traits/coherence.rs b/src/librustc_trait_selection/traits/coherence.rs
index dc13af99fec..a642ae98231 100644
--- a/src/librustc_trait_selection/traits/coherence.rs
+++ b/src/librustc_trait_selection/traits/coherence.rs
@@ -8,10 +8,10 @@ use crate::infer::{CombinedSnapshot, InferOk, TyCtxtInferExt};
 use crate::traits::select::IntercrateAmbiguityCause;
 use crate::traits::SkipLeakCheck;
 use crate::traits::{self, Normalized, Obligation, ObligationCause, SelectionContext};
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::subst::Subst;
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
+use rustc_middle::ty::fold::TypeFoldable;
+use rustc_middle::ty::subst::Subst;
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::symbol::sym;
 use rustc_span::DUMMY_SP;
 
diff --git a/src/librustc_trait_selection/traits/engine.rs b/src/librustc_trait_selection/traits/engine.rs
index ee4715e0c20..c6a3dfa698e 100644
--- a/src/librustc_trait_selection/traits/engine.rs
+++ b/src/librustc_trait_selection/traits/engine.rs
@@ -1,4 +1,4 @@
-use rustc::ty::TyCtxt;
+use rustc_middle::ty::TyCtxt;
 
 use super::FulfillmentContext;
 use super::TraitEngine;
diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs
index 8cbed43cac0..5a9a96887f6 100644
--- a/src/librustc_trait_selection/traits/error_reporting/mod.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs
@@ -11,22 +11,21 @@ use super::{
 use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::{self, InferCtxt, TyCtxtInferExt};
-use rustc::mir::interpret::ErrorHandled;
-use rustc::ty::error::ExpectedFound;
-use rustc::ty::fast_reject;
-use rustc::ty::fold::TypeFolder;
-use rustc::ty::SubtypePredicate;
-use rustc::ty::{
-    self, AdtKind, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
-};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::{Node, QPath, TyKind, WhereBoundPredicate, WherePredicate};
+use rustc_middle::mir::interpret::ErrorHandled;
+use rustc_middle::ty::error::ExpectedFound;
+use rustc_middle::ty::fast_reject;
+use rustc_middle::ty::fold::TypeFolder;
+use rustc_middle::ty::SubtypePredicate;
+use rustc_middle::ty::{
+    self, AdtKind, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
+};
 use rustc_session::DiagnosticMessageId;
-use rustc_span::source_map::SourceMap;
-use rustc_span::{ExpnKind, Span, DUMMY_SP};
+use rustc_span::{BytePos, ExpnKind, Span, DUMMY_SP};
 use std::fmt;
 
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
@@ -66,7 +65,7 @@ pub trait InferCtxtExt<'tcx> {
     /// 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
@@ -612,10 +611,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     )
                 } 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));
 
@@ -673,43 +672,38 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
     /// 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 {
@@ -722,7 +716,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 kind: hir::TraitItemKind::Fn(ref sig, _),
                 ..
             }) => (
-                self.tcx.sess.source_map().guess_head_span(span),
+                sm.guess_head_span(span),
                 sig.decl
                     .inputs
                     .iter()
@@ -736,16 +730,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     .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
@@ -1679,14 +1669,8 @@ pub fn suggest_constraining_type_param(
     err: &mut DiagnosticBuilder<'_>,
     param_name: &str,
     constraint: &str,
-    source_map: &SourceMap,
-    span: Span,
     def_id: Option<DefId>,
 ) -> bool {
-    const MSG_RESTRICT_BOUND_FURTHER: &str = "consider further restricting this bound with";
-    const MSG_RESTRICT_TYPE: &str = "consider restricting this type parameter with";
-    const MSG_RESTRICT_TYPE_FURTHER: &str = "consider further restricting this type parameter with";
-
     let param = generics.params.iter().find(|p| p.name.ident().as_str() == param_name);
 
     let param = if let Some(param) = param {
@@ -1695,11 +1679,24 @@ pub fn suggest_constraining_type_param(
         return false;
     };
 
+    const MSG_RESTRICT_BOUND_FURTHER: &str = "consider further restricting this bound";
+    let msg_restrict_type = format!("consider restricting type parameter `{}`", param_name);
+    let msg_restrict_type_further =
+        format!("consider further restricting type parameter `{}`", param_name);
+
     if def_id == tcx.lang_items().sized_trait() {
         // Type parameters are already `Sized` by default.
         err.span_label(param.span, &format!("this type parameter needs to be `{}`", constraint));
         return true;
     }
+    let mut suggest_restrict = |span| {
+        err.span_suggestion_verbose(
+            span,
+            MSG_RESTRICT_BOUND_FURTHER,
+            format!(" + {}", constraint),
+            Applicability::MachineApplicable,
+        );
+    };
 
     if param_name.starts_with("impl ") {
         // If there's an `impl Trait` used in argument position, suggest
@@ -1717,19 +1714,15 @@ pub fn suggest_constraining_type_param(
         //             |
         //             replace with: `impl Foo + Bar`
 
-        err.span_help(param.span, &format!("{} `+ {}`", MSG_RESTRICT_BOUND_FURTHER, constraint));
-
-        err.tool_only_span_suggestion(
-            param.span,
-            MSG_RESTRICT_BOUND_FURTHER,
-            format!("{} + {}", param_name, constraint),
-            Applicability::MachineApplicable,
-        );
-
+        suggest_restrict(param.span.shrink_to_hi());
         return true;
     }
 
-    if generics.where_clause.predicates.is_empty() {
+    if generics.where_clause.predicates.is_empty()
+        // Given `trait Base<T = String>: Super<T>` where `T: Copy`, suggest restricting in the
+        // `where` clause instead of `trait Base<T: Copy = String>: Super<T>`.
+        && !matches!(param.kind, hir::GenericParamKind::Type { default: Some(_), .. })
+    {
         if let Some(bounds_span) = param.bounds_span() {
             // If user has provided some bounds, suggest restricting them:
             //
@@ -1744,38 +1737,16 @@ pub fn suggest_constraining_type_param(
             //          --
             //          |
             //          replace with: `T: Bar +`
-
-            err.span_help(
-                bounds_span,
-                &format!("{} `+ {}`", MSG_RESTRICT_BOUND_FURTHER, constraint),
-            );
-
-            let span_hi = param.span.with_hi(span.hi());
-            let span_with_colon = source_map.span_through_char(span_hi, ':');
-
-            if span_hi != param.span && span_with_colon != span_hi {
-                err.tool_only_span_suggestion(
-                    span_with_colon,
-                    MSG_RESTRICT_BOUND_FURTHER,
-                    format!("{}: {} + ", param_name, constraint),
-                    Applicability::MachineApplicable,
-                );
-            }
+            suggest_restrict(bounds_span.shrink_to_hi());
         } else {
             // If user hasn't provided any bounds, suggest adding a new one:
             //
             //   fn foo<T>(t: T) { ... }
             //          - help: consider restricting this type parameter with `T: Foo`
-
-            err.span_help(
-                param.span,
-                &format!("{} `{}: {}`", MSG_RESTRICT_TYPE, param_name, constraint),
-            );
-
-            err.tool_only_span_suggestion(
-                param.span,
-                MSG_RESTRICT_TYPE,
-                format!("{}: {}", param_name, constraint),
+            err.span_suggestion_verbose(
+                param.span.shrink_to_hi(),
+                &msg_restrict_type,
+                format!(": {}", constraint),
                 Applicability::MachineApplicable,
             );
         }
@@ -1839,55 +1810,25 @@ pub fn suggest_constraining_type_param(
             }
         }
 
-        let where_clause_span =
-            generics.where_clause.span_for_predicates_or_empty_place().shrink_to_hi();
+        let where_clause_span = generics.where_clause.span_for_predicates_or_empty_place();
+        // Account for `fn foo<T>(t: T) where T: Foo,` so we don't suggest two trailing commas.
+        let mut trailing_comma = false;
+        if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(where_clause_span) {
+            trailing_comma = snippet.ends_with(",");
+        }
+        let where_clause_span = if trailing_comma {
+            let hi = where_clause_span.hi();
+            Span::new(hi - BytePos(1), hi, where_clause_span.ctxt())
+        } else {
+            where_clause_span.shrink_to_hi()
+        };
 
         match &param_spans[..] {
-            &[] => {
-                err.span_help(
-                    param.span,
-                    &format!("{} `where {}: {}`", MSG_RESTRICT_TYPE, param_name, constraint),
-                );
-
-                err.tool_only_span_suggestion(
-                    where_clause_span,
-                    MSG_RESTRICT_TYPE,
-                    format!(", {}: {}", param_name, constraint),
-                    Applicability::MachineApplicable,
-                );
-            }
-
-            &[&param_span] => {
-                err.span_help(
-                    param_span,
-                    &format!("{} `+ {}`", MSG_RESTRICT_BOUND_FURTHER, constraint),
-                );
-
-                let span_hi = param_span.with_hi(span.hi());
-                let span_with_colon = source_map.span_through_char(span_hi, ':');
-
-                if span_hi != param_span && span_with_colon != span_hi {
-                    err.tool_only_span_suggestion(
-                        span_with_colon,
-                        MSG_RESTRICT_BOUND_FURTHER,
-                        format!("{}: {} +", param_name, constraint),
-                        Applicability::MachineApplicable,
-                    );
-                }
-            }
-
+            &[&param_span] => suggest_restrict(param_span.shrink_to_hi()),
             _ => {
-                err.span_help(
-                    param.span,
-                    &format!(
-                        "{} `where {}: {}`",
-                        MSG_RESTRICT_TYPE_FURTHER, param_name, constraint,
-                    ),
-                );
-
-                err.tool_only_span_suggestion(
+                err.span_suggestion_verbose(
                     where_clause_span,
-                    MSG_RESTRICT_BOUND_FURTHER,
+                    &msg_restrict_type_further,
                     format!(", {}: {}", param_name, constraint),
                     Applicability::MachineApplicable,
                 );
diff --git a/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs b/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs
index 18b2ca89837..213769d721d 100644
--- a/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs
@@ -2,10 +2,10 @@ use super::{
     ObligationCauseCode, OnUnimplementedDirective, OnUnimplementedNote, PredicateObligation,
 };
 use crate::infer::InferCtxt;
-use rustc::ty::subst::Subst;
-use rustc::ty::{self, GenericParamDefKind};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty::subst::Subst;
+use rustc_middle::ty::{self, GenericParamDefKind};
 use rustc_span::symbol::sym;
 
 use super::InferCtxtPrivExt;
@@ -219,11 +219,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         }
         if let ty::Dynamic(traits, _) = self_ty.kind {
             for t in *traits.skip_binder() {
-                match t {
-                    ty::ExistentialPredicate::Trait(trait_ref) => {
-                        flags.push((sym::_Self, Some(self.tcx.def_path_str(trait_ref.def_id))))
-                    }
-                    _ => {}
+                if let ty::ExistentialPredicate::Trait(trait_ref) = t {
+                    flags.push((sym::_Self, Some(self.tcx.def_path_str(trait_ref.def_id))))
                 }
             }
         }
diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
index a4be70df122..fcec29aaa8e 100644
--- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
@@ -5,14 +5,16 @@ use super::{
 use crate::infer::InferCtxt;
 use crate::traits::error_reporting::suggest_constraining_type_param;
 
-use rustc::ty::TypeckTables;
-use rustc::ty::{self, AdtKind, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
 use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder, Style};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::Node;
+use rustc_middle::ty::TypeckTables;
+use rustc_middle::ty::{
+    self, AdtKind, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
+};
 use rustc_span::symbol::{kw, sym};
 use rustc_span::{MultiSpan, Span, DUMMY_SP};
 use std::fmt;
@@ -195,8 +197,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     return;
                 }
 
-                hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })
-                | hir::Node::TraitItem(hir::TraitItem {
+                hir::Node::TraitItem(hir::TraitItem {
                     generics,
                     kind: hir::TraitItemKind::Fn(..),
                     ..
@@ -206,63 +207,31 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     kind: hir::ImplItemKind::Fn(..),
                     ..
                 })
-                | hir::Node::Item(hir::Item {
-                    kind: hir::ItemKind::Trait(_, _, generics, _, _),
-                    ..
-                })
-                | hir::Node::Item(hir::Item {
-                    kind: hir::ItemKind::Impl { generics, .. }, ..
-                }) if projection.is_some() => {
+                | hir::Node::Item(
+                    hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. }
+                    | hir::Item { kind: hir::ItemKind::Trait(_, _, generics, _, _), .. }
+                    | hir::Item { kind: hir::ItemKind::Impl { generics, .. }, .. },
+                ) if projection.is_some() => {
                     // Missing associated type bound.
                     suggest_restriction(&generics, "the associated type", err);
                     return;
                 }
 
-                hir::Node::Item(hir::Item {
-                    kind: hir::ItemKind::Struct(_, generics),
-                    span,
-                    ..
-                })
-                | hir::Node::Item(hir::Item {
-                    kind: hir::ItemKind::Enum(_, generics), span, ..
-                })
-                | hir::Node::Item(hir::Item {
-                    kind: hir::ItemKind::Union(_, generics),
-                    span,
-                    ..
-                })
-                | hir::Node::Item(hir::Item {
-                    kind: hir::ItemKind::Trait(_, _, generics, ..),
-                    span,
-                    ..
-                })
-                | hir::Node::Item(hir::Item {
-                    kind: hir::ItemKind::Impl { generics, .. },
-                    span,
-                    ..
-                })
-                | hir::Node::Item(hir::Item {
-                    kind: hir::ItemKind::Fn(_, generics, _),
-                    span,
-                    ..
-                })
-                | hir::Node::Item(hir::Item {
-                    kind: hir::ItemKind::TyAlias(_, generics),
-                    span,
-                    ..
-                })
-                | hir::Node::Item(hir::Item {
-                    kind: hir::ItemKind::TraitAlias(generics, _),
-                    span,
-                    ..
-                })
-                | hir::Node::Item(hir::Item {
-                    kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. }),
-                    span,
-                    ..
-                })
-                | hir::Node::TraitItem(hir::TraitItem { generics, span, .. })
-                | hir::Node::ImplItem(hir::ImplItem { generics, span, .. })
+                hir::Node::Item(
+                    hir::Item { kind: hir::ItemKind::Struct(_, generics), .. }
+                    | hir::Item { kind: hir::ItemKind::Enum(_, generics), .. }
+                    | hir::Item { kind: hir::ItemKind::Union(_, generics), .. }
+                    | hir::Item { kind: hir::ItemKind::Trait(_, _, generics, ..), .. }
+                    | hir::Item { kind: hir::ItemKind::Impl { generics, .. }, .. }
+                    | hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. }
+                    | hir::Item { kind: hir::ItemKind::TyAlias(_, generics), .. }
+                    | hir::Item { kind: hir::ItemKind::TraitAlias(generics, _), .. }
+                    | hir::Item {
+                        kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. }), ..
+                    },
+                )
+                | hir::Node::TraitItem(hir::TraitItem { generics, .. })
+                | hir::Node::ImplItem(hir::ImplItem { generics, .. })
                     if param_ty =>
                 {
                     // Missing generic type parameter bound.
@@ -274,8 +243,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                         &mut err,
                         &param_name,
                         &constraint,
-                        self.tcx.sess.source_map(),
-                        *span,
                         Some(trait_ref.def_id()),
                     ) {
                         return;
@@ -765,12 +732,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 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,
@@ -808,26 +776,23 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             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/fulfill.rs b/src/librustc_trait_selection/traits/fulfill.rs
index 0578c00fefb..09a33120ba7 100644
--- a/src/librustc_trait_selection/traits/fulfill.rs
+++ b/src/librustc_trait_selection/traits/fulfill.rs
@@ -1,10 +1,10 @@
 use crate::infer::{InferCtxt, TyOrConstInferVar};
-use rustc::ty::error::ExpectedFound;
-use rustc::ty::{self, ToPolyTraitRef, Ty, TypeFoldable};
 use rustc_data_structures::obligation_forest::ProcessResult;
 use rustc_data_structures::obligation_forest::{DoCompleted, Error, ForestObligation};
 use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor};
 use rustc_infer::traits::{TraitEngine, TraitEngineExt as _};
+use rustc_middle::ty::error::ExpectedFound;
+use rustc_middle::ty::{self, ToPolyTraitRef, Ty, TypeFoldable};
 use std::marker::PhantomData;
 
 use super::project;
diff --git a/src/librustc_trait_selection/traits/misc.rs b/src/librustc_trait_selection/traits/misc.rs
index d500cff67c6..7403b936391 100644
--- a/src/librustc_trait_selection/traits/misc.rs
+++ b/src/librustc_trait_selection/traits/misc.rs
@@ -3,9 +3,9 @@
 use crate::infer::InferCtxtExt as _;
 use crate::traits::{self, ObligationCause};
 
-use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc_hir as hir;
 use rustc_infer::infer::TyCtxtInferExt;
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
 
 use crate::traits::error_reporting::InferCtxtExt;
 
diff --git a/src/librustc_trait_selection/traits/mod.rs b/src/librustc_trait_selection/traits/mod.rs
index 43a90c4a6c1..9a853c32eaa 100644
--- a/src/librustc_trait_selection/traits/mod.rs
+++ b/src/librustc_trait_selection/traits/mod.rs
@@ -24,13 +24,13 @@ use crate::infer::outlives::env::OutlivesEnvironment;
 use crate::infer::{InferCtxt, RegionckMode, TyCtxtInferExt};
 use crate::traits::error_reporting::InferCtxtExt as _;
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
-use rustc::middle::region;
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::subst::{InternalSubsts, SubstsRef};
-use rustc::ty::{self, GenericParamDefKind, ToPredicate, Ty, TyCtxt, WithConstness};
-use rustc::util::common::ErrorReported;
+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_span::{Span, DUMMY_SP};
 
 use std::fmt::Debug;
@@ -54,7 +54,6 @@ pub use self::project::{
 };
 pub use self::select::{EvaluationCache, SelectionCache, SelectionContext};
 pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
-pub use self::specialize::find_associated_item;
 pub use self::specialize::specialization_graph::FutureCompatOverlapError;
 pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind;
 pub use self::specialize::{specialization_graph, translate_substs, OverlapError};
@@ -64,8 +63,7 @@ pub use self::structural_match::NonStructuralMatchTy;
 pub use self::util::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs};
 pub use self::util::{expand_trait_aliases, TraitAliasExpander};
 pub use self::util::{
-    get_vtable_index_of_object_method, impl_is_default, impl_item_is_final,
-    predicate_for_trait_def, upcast_choices,
+    get_vtable_index_of_object_method, impl_item_is_final, predicate_for_trait_def, upcast_choices,
 };
 pub use self::util::{
     supertrait_def_ids, supertraits, transitive_bounds, SupertraitDefIds, Supertraits,
diff --git a/src/librustc_trait_selection/traits/object_safety.rs b/src/librustc_trait_selection/traits/object_safety.rs
index 7d4ad61902a..20b3fa908d2 100644
--- a/src/librustc_trait_selection/traits/object_safety.rs
+++ b/src/librustc_trait_selection/traits/object_safety.rs
@@ -13,11 +13,11 @@ use super::elaborate_predicates;
 use crate::infer::TyCtxtInferExt;
 use crate::traits::query::evaluate_obligation::InferCtxtExt;
 use crate::traits::{self, Obligation, ObligationCause};
-use rustc::ty::subst::{InternalSubsts, Subst};
-use rustc::ty::{self, Predicate, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
 use rustc_errors::{Applicability, FatalError};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty::subst::{InternalSubsts, Subst};
+use rustc_middle::ty::{self, Predicate, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
 use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY;
 use rustc_span::symbol::Symbol;
 use rustc_span::Span;
@@ -420,7 +420,7 @@ fn virtual_call_violation_for_method<'tcx>(
         } else {
             // Do sanity check to make sure the receiver actually has the layout of a pointer.
 
-            use rustc::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 19260293ee6..cf29c4249c0 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::ty::{self, GenericParamDefKind, TyCtxt};
-use rustc::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 badd94a5ed9..e4ca7d4cde7 100644
--- a/src/librustc_trait_selection/traits/project.rs
+++ b/src/librustc_trait_selection/traits/project.rs
@@ -17,16 +17,16 @@ use super::{VtableClosureData, VtableFnPointerData, VtableGeneratorData, VtableI
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
 use crate::traits::error_reporting::InferCtxtExt;
-use rustc::ty::fold::{TypeFoldable, TypeFolder};
-use rustc::ty::subst::{InternalSubsts, Subst};
-use rustc::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness};
 use rustc_ast::ast::Ident;
 use rustc_errors::ErrorReported;
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
+use rustc_middle::ty::subst::{InternalSubsts, Subst};
+use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness};
 use rustc_span::symbol::sym;
 use rustc_span::DUMMY_SP;
 
-pub use rustc::traits::Reveal;
+pub use rustc_middle::traits::Reveal;
 
 pub type PolyProjectionObligation<'tcx> = Obligation<'tcx, ty::PolyProjectionPredicate<'tcx>>;
 
@@ -1010,54 +1010,26 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
                 // type.
                 //
                 // NOTE: This should be kept in sync with the similar code in
-                // `rustc::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| ())?;
 
-                let is_default = if node_item.node.is_from_trait() {
-                    // If true, the impl inherited a `type Foo = Bar`
-                    // given in the trait, which is implicitly default.
-                    // Otherwise, the impl did not specify `type` and
-                    // neither did the trait:
-                    //
-                    // ```rust
-                    // trait Foo { type T; }
-                    // impl Foo for Bar { }
-                    // ```
-                    //
-                    // This is an error, but it will be
-                    // reported in `check_impl_items_against_trait`.
-                    // We accept it here but will flag it as
-                    // an error when we confirm the candidate
-                    // (which will ultimately lead to `normalize_to_error`
-                    // being invoked).
-                    false
+                if node_item.is_final() {
+                    // Non-specializable items are always projectable.
+                    true
                 } else {
-                    // If we're looking at a trait *impl*, the item is
-                    // specializable if the impl or the item are marked
-                    // `default`.
-                    node_item.item.defaultness.is_default()
-                        || super::util::impl_is_default(selcx.tcx(), node_item.node.def_id())
-                };
-
-                match is_default {
-                    // Non-specializable items are always projectable
-                    false => true,
-
                     // Only reveal a specializable default if we're past type-checking
                     // 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.
-                    true if obligation.param_env.reveal == Reveal::All => {
+                    if obligation.param_env.reveal == Reveal::All {
                         // NOTE(eddyb) inference variables can resolve to parameters, so
                         // 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()
-                    }
-
-                    true => {
+                        !poly_trait_ref.still_further_specializable()
+                    } else {
                         debug!(
                             "assemble_candidates_from_impls: not eligible due to default: \
                              assoc_ty={} predicate={}",
@@ -1422,7 +1394,8 @@ fn confirm_impl_candidate<'cx, 'tcx>(
         return Progress { ty: tcx.types.err, obligations: nested };
     }
     let substs = obligation.predicate.substs.rebase_onto(tcx, trait_def_id, substs);
-    let substs = translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.node);
+    let substs =
+        translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.defining_node);
     let ty = if let ty::AssocKind::OpaqueTy = assoc_ty.item.kind {
         let item_substs = InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id);
         tcx.mk_opaque(assoc_ty.item.def_id, item_substs)
@@ -1447,7 +1420,7 @@ fn assoc_ty_def(
     selcx: &SelectionContext<'_, '_>,
     impl_def_id: DefId,
     assoc_ty_def_id: DefId,
-) -> Result<specialization_graph::NodeItem<ty::AssocItem>, ErrorReported> {
+) -> Result<specialization_graph::LeafDef, ErrorReported> {
     let tcx = selcx.tcx();
     let assoc_ty_name = tcx.associated_item(assoc_ty_def_id).ident;
     let trait_def_id = tcx.impl_trait_ref(impl_def_id).unwrap().def_id;
@@ -1464,9 +1437,10 @@ fn assoc_ty_def(
         if matches!(item.kind, ty::AssocKind::Type | ty::AssocKind::OpaqueTy)
             && tcx.hygienic_eq(item.ident, assoc_ty_name, trait_def_id)
         {
-            return Ok(specialization_graph::NodeItem {
-                node: specialization_graph::Node::Impl(impl_def_id),
+            return Ok(specialization_graph::LeafDef {
                 item: *item,
+                defining_node: impl_node,
+                finalizing_node: if item.defaultness.is_default() { None } else { Some(impl_node) },
             });
         }
     }
diff --git a/src/librustc_trait_selection/traits/query/dropck_outlives.rs b/src/librustc_trait_selection/traits/query/dropck_outlives.rs
index 03c6cf35e88..64cc5fadeab 100644
--- a/src/librustc_trait_selection/traits/query/dropck_outlives.rs
+++ b/src/librustc_trait_selection/traits/query/dropck_outlives.rs
@@ -2,10 +2,10 @@ use crate::infer::at::At;
 use crate::infer::canonical::OriginalQueryValues;
 use crate::infer::InferOk;
 
-use rustc::ty::subst::GenericArg;
-use rustc::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::subst::GenericArg;
+use rustc_middle::ty::{self, Ty, TyCtxt};
 
-pub use rustc::traits::query::{DropckOutlivesResult, DtorckConstraint};
+pub use rustc_middle::traits::query::{DropckOutlivesResult, DtorckConstraint};
 
 pub trait AtExt<'tcx> {
     fn dropck_outlives(&self, ty: Ty<'tcx>) -> InferOk<'tcx, Vec<GenericArg<'tcx>>>;
diff --git a/src/librustc_trait_selection/traits/query/method_autoderef.rs b/src/librustc_trait_selection/traits/query/method_autoderef.rs
index 80748c5ef38..3c0ebec9335 100644
--- a/src/librustc_trait_selection/traits/query/method_autoderef.rs
+++ b/src/librustc_trait_selection/traits/query/method_autoderef.rs
@@ -1 +1,3 @@
-pub use rustc::traits::query::{CandidateStep, MethodAutoderefBadTy, MethodAutoderefStepsResult};
+pub use rustc_middle::traits::query::{
+    CandidateStep, MethodAutoderefBadTy, MethodAutoderefStepsResult,
+};
diff --git a/src/librustc_trait_selection/traits/query/mod.rs b/src/librustc_trait_selection/traits/query/mod.rs
index 77b5ec669a0..01f4f09e238 100644
--- a/src/librustc_trait_selection/traits/query/mod.rs
+++ b/src/librustc_trait_selection/traits/query/mod.rs
@@ -12,4 +12,4 @@ pub mod normalize;
 pub mod outlives_bounds;
 pub mod type_op;
 
-pub use rustc::traits::query::*;
+pub use rustc_middle::traits::query::*;
diff --git a/src/librustc_trait_selection/traits/query/normalize.rs b/src/librustc_trait_selection/traits/query/normalize.rs
index 77128bc8c8a..28d59b41e56 100644
--- a/src/librustc_trait_selection/traits/query/normalize.rs
+++ b/src/librustc_trait_selection/traits/query/normalize.rs
@@ -7,14 +7,14 @@ use crate::infer::canonical::OriginalQueryValues;
 use crate::infer::{InferCtxt, InferOk};
 use crate::traits::error_reporting::InferCtxtExt;
 use crate::traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
-use rustc::ty::fold::{TypeFoldable, TypeFolder};
-use rustc::ty::subst::Subst;
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_infer::traits::Normalized;
+use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
+use rustc_middle::ty::subst::Subst;
+use rustc_middle::ty::{self, Ty, TyCtxt};
 
 use super::NoSolution;
 
-pub use rustc::traits::query::NormalizationResult;
+pub use rustc_middle::traits::query::NormalizationResult;
 
 pub trait AtExt<'tcx> {
     fn normalize<T>(&self, value: &T) -> Result<Normalized<'tcx, T>, NoSolution>
diff --git a/src/librustc_trait_selection/traits/query/outlives_bounds.rs b/src/librustc_trait_selection/traits/query/outlives_bounds.rs
index 05c96dd520a..a42409515db 100644
--- a/src/librustc_trait_selection/traits/query/outlives_bounds.rs
+++ b/src/librustc_trait_selection/traits/query/outlives_bounds.rs
@@ -2,12 +2,12 @@ use crate::infer::canonical::OriginalQueryValues;
 use crate::infer::InferCtxt;
 use crate::traits::query::NoSolution;
 use crate::traits::{FulfillmentContext, ObligationCause, TraitEngine};
-use rustc::ty::{self, Ty};
 use rustc_hir as hir;
 use rustc_infer::traits::TraitEngineExt as _;
+use rustc_middle::ty::{self, Ty};
 use rustc_span::source_map::Span;
 
-pub use rustc::traits::query::OutlivesBound;
+pub use rustc_middle::traits::query::OutlivesBound;
 
 pub trait InferCtxtExt<'tcx> {
     fn implied_outlives_bounds(
diff --git a/src/librustc_trait_selection/traits/query/type_op/ascribe_user_type.rs b/src/librustc_trait_selection/traits/query/type_op/ascribe_user_type.rs
index b14b79f0907..86b015767f0 100644
--- a/src/librustc_trait_selection/traits/query/type_op/ascribe_user_type.rs
+++ b/src/librustc_trait_selection/traits/query/type_op/ascribe_user_type.rs
@@ -1,8 +1,8 @@
 use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse};
 use crate::traits::query::Fallible;
-use rustc::ty::{ParamEnvAnd, TyCtxt};
+use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
 
-pub use rustc::traits::query::type_op::AscribeUserType;
+pub use rustc_middle::traits::query::type_op::AscribeUserType;
 
 impl<'tcx> super::QueryTypeOp<'tcx> for AscribeUserType<'tcx> {
     type QueryResponse = ();
diff --git a/src/librustc_trait_selection/traits/query/type_op/eq.rs b/src/librustc_trait_selection/traits/query/type_op/eq.rs
index 3b6fbc7d8dd..490114aacd1 100644
--- a/src/librustc_trait_selection/traits/query/type_op/eq.rs
+++ b/src/librustc_trait_selection/traits/query/type_op/eq.rs
@@ -1,8 +1,8 @@
 use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse};
 use crate::traits::query::Fallible;
-use rustc::ty::{ParamEnvAnd, TyCtxt};
+use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
 
-pub use rustc::traits::query::type_op::Eq;
+pub use rustc_middle::traits::query::type_op::Eq;
 
 impl<'tcx> super::QueryTypeOp<'tcx> for Eq<'tcx> {
     type QueryResponse = ();
diff --git a/src/librustc_trait_selection/traits/query/type_op/implied_outlives_bounds.rs b/src/librustc_trait_selection/traits/query/type_op/implied_outlives_bounds.rs
index 3dad546872e..cf7f0a553c7 100644
--- a/src/librustc_trait_selection/traits/query/type_op/implied_outlives_bounds.rs
+++ b/src/librustc_trait_selection/traits/query/type_op/implied_outlives_bounds.rs
@@ -1,7 +1,7 @@
 use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse};
 use crate::traits::query::outlives_bounds::OutlivesBound;
 use crate::traits::query::Fallible;
-use rustc::ty::{ParamEnvAnd, Ty, TyCtxt};
+use rustc_middle::ty::{ParamEnvAnd, Ty, TyCtxt};
 
 #[derive(Clone, Debug, HashStable, TypeFoldable, Lift)]
 pub struct ImpliedOutlivesBounds<'tcx> {
diff --git a/src/librustc_trait_selection/traits/query/type_op/mod.rs b/src/librustc_trait_selection/traits/query/type_op/mod.rs
index 1644746c16e..763cf12afa6 100644
--- a/src/librustc_trait_selection/traits/query/type_op/mod.rs
+++ b/src/librustc_trait_selection/traits/query/type_op/mod.rs
@@ -4,8 +4,8 @@ use crate::infer::canonical::{
 use crate::infer::{InferCtxt, InferOk};
 use crate::traits::query::Fallible;
 use crate::traits::ObligationCause;
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::{ParamEnvAnd, TyCtxt};
+use rustc_middle::ty::fold::TypeFoldable;
+use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
 use std::fmt;
 use std::rc::Rc;
 
@@ -19,7 +19,7 @@ pub mod prove_predicate;
 use self::prove_predicate::ProvePredicate;
 pub mod subtype;
 
-pub use rustc::traits::query::type_op::*;
+pub use rustc_middle::traits::query::type_op::*;
 
 /// "Type ops" are used in NLL to perform some particular action and
 /// extract out the resulting region constraints (or an error if it
diff --git a/src/librustc_trait_selection/traits/query/type_op/normalize.rs b/src/librustc_trait_selection/traits/query/type_op/normalize.rs
index d2eec53bf80..729b66ac21c 100644
--- a/src/librustc_trait_selection/traits/query/type_op/normalize.rs
+++ b/src/librustc_trait_selection/traits/query/type_op/normalize.rs
@@ -1,10 +1,10 @@
 use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse};
 use crate::traits::query::Fallible;
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt};
+use rustc_middle::ty::fold::TypeFoldable;
+use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt};
 use std::fmt;
 
-pub use rustc::traits::query::type_op::Normalize;
+pub use rustc_middle::traits::query::type_op::Normalize;
 
 impl<'tcx, T> super::QueryTypeOp<'tcx> for Normalize<T>
 where
diff --git a/src/librustc_trait_selection/traits/query/type_op/outlives.rs b/src/librustc_trait_selection/traits/query/type_op/outlives.rs
index b94948cffd6..5a27e57860e 100644
--- a/src/librustc_trait_selection/traits/query/type_op/outlives.rs
+++ b/src/librustc_trait_selection/traits/query/type_op/outlives.rs
@@ -1,7 +1,7 @@
 use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse};
 use crate::traits::query::dropck_outlives::{trivial_dropck_outlives, DropckOutlivesResult};
 use crate::traits::query::Fallible;
-use rustc::ty::{ParamEnvAnd, Ty, TyCtxt};
+use rustc_middle::ty::{ParamEnvAnd, Ty, TyCtxt};
 
 #[derive(Copy, Clone, Debug, HashStable, TypeFoldable, Lift)]
 pub struct DropckOutlives<'tcx> {
diff --git a/src/librustc_trait_selection/traits/query/type_op/prove_predicate.rs b/src/librustc_trait_selection/traits/query/type_op/prove_predicate.rs
index 8c68f7db9e5..981745af805 100644
--- a/src/librustc_trait_selection/traits/query/type_op/prove_predicate.rs
+++ b/src/librustc_trait_selection/traits/query/type_op/prove_predicate.rs
@@ -1,8 +1,8 @@
 use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse};
 use crate::traits::query::Fallible;
-use rustc::ty::{ParamEnvAnd, Predicate, TyCtxt};
+use rustc_middle::ty::{ParamEnvAnd, Predicate, TyCtxt};
 
-pub use rustc::traits::query::type_op::ProvePredicate;
+pub use rustc_middle::traits::query::type_op::ProvePredicate;
 
 impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
     type QueryResponse = ();
diff --git a/src/librustc_trait_selection/traits/query/type_op/subtype.rs b/src/librustc_trait_selection/traits/query/type_op/subtype.rs
index 053411b0cac..57290b66914 100644
--- a/src/librustc_trait_selection/traits/query/type_op/subtype.rs
+++ b/src/librustc_trait_selection/traits/query/type_op/subtype.rs
@@ -1,8 +1,8 @@
 use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse};
 use crate::traits::query::Fallible;
-use rustc::ty::{ParamEnvAnd, TyCtxt};
+use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
 
-pub use rustc::traits::query::type_op::Subtype;
+pub use rustc_middle::traits::query::type_op::Subtype;
 
 impl<'tcx> super::QueryTypeOp<'tcx> for Subtype<'tcx> {
     type QueryResponse = ();
diff --git a/src/librustc_trait_selection/traits/select.rs b/src/librustc_trait_selection/traits/select.rs
index 2d6fabea6ec..3d95824cdf0 100644
--- a/src/librustc_trait_selection/traits/select.rs
+++ b/src/librustc_trait_selection/traits/select.rs
@@ -35,17 +35,19 @@ use super::{
 use crate::infer::{CombinedSnapshot, InferCtxt, InferOk, PlaceholderMap, TypeFreshener};
 use crate::traits::error_reporting::InferCtxtExt;
 use crate::traits::project::ProjectionCacheKeyExt;
-use rustc::dep_graph::{DepKind, DepNodeIndex};
-use rustc::middle::lang_items;
-use rustc::ty::fast_reject;
-use rustc::ty::relate::TypeRelation;
-use rustc::ty::subst::{Subst, SubstsRef};
-use rustc::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
 use rustc_ast::attr;
 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::ty::fast_reject;
+use rustc_middle::ty::relate::TypeRelation;
+use rustc_middle::ty::subst::{Subst, SubstsRef};
+use rustc_middle::ty::{
+    self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
+};
 use rustc_span::symbol::sym;
 use rustc_target::spec::abi::Abi;
 
@@ -55,7 +57,7 @@ use std::fmt::{self, Display};
 use std::iter;
 use std::rc::Rc;
 
-pub use rustc::traits::select::*;
+pub use rustc_middle::traits::select::*;
 
 pub struct SelectionContext<'cx, 'tcx> {
     infcx: &'cx InferCtxt<'cx, 'tcx>,
diff --git a/src/librustc_trait_selection/traits/specialize/mod.rs b/src/librustc_trait_selection/traits/specialize/mod.rs
index 732716ef865..fabd8c89b72 100644
--- a/src/librustc_trait_selection/traits/specialize/mod.rs
+++ b/src/librustc_trait_selection/traits/specialize/mod.rs
@@ -15,12 +15,12 @@ use specialization_graph::GraphExt;
 use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
 use crate::traits::select::IntercrateAmbiguityCause;
 use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine};
-use rustc::lint::LintDiagnosticBuilder;
-use rustc::ty::subst::{InternalSubsts, Subst, SubstsRef};
-use rustc::ty::{self, TyCtxt, TypeFoldable};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::struct_span_err;
 use rustc_hir::def_id::DefId;
+use rustc_middle::lint::LintDiagnosticBuilder;
+use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
+use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
 use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS;
 use rustc_span::DUMMY_SP;
@@ -112,48 +112,6 @@ pub fn translate_substs<'a, 'tcx>(
     source_substs.rebase_onto(infcx.tcx, source_impl, target_substs)
 }
 
-/// Given a selected impl described by `impl_data`, returns the
-/// definition and substitutions for the method with the name `name`
-/// the kind `kind`, and trait method substitutions `substs`, in
-/// that impl, a less specialized impl, or the trait default,
-/// whichever applies.
-pub fn find_associated_item<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-    item: &ty::AssocItem,
-    substs: SubstsRef<'tcx>,
-    impl_data: &super::VtableImplData<'tcx, ()>,
-) -> (DefId, SubstsRef<'tcx>) {
-    debug!("find_associated_item({:?}, {:?}, {:?}, {:?})", param_env, item, substs, impl_data);
-    assert!(!substs.needs_infer());
-
-    let trait_def_id = tcx.trait_id_of_impl(impl_data.impl_def_id).unwrap();
-    let trait_def = tcx.trait_def(trait_def_id);
-
-    if let Ok(ancestors) = trait_def.ancestors(tcx, impl_data.impl_def_id) {
-        match ancestors.leaf_def(tcx, item.ident, item.kind) {
-            Some(node_item) => {
-                let substs = tcx.infer_ctxt().enter(|infcx| {
-                    let param_env = param_env.with_reveal_all();
-                    let substs = substs.rebase_onto(tcx, trait_def_id, impl_data.substs);
-                    let substs = translate_substs(
-                        &infcx,
-                        param_env,
-                        impl_data.impl_def_id,
-                        substs,
-                        node_item.node,
-                    );
-                    infcx.tcx.erase_regions(&substs)
-                });
-                (node_item.item.def_id, substs)
-            }
-            None => bug!("{:?} not found in {:?}", item, impl_data.impl_def_id),
-        }
-    } else {
-        (item.def_id, substs)
-    }
-}
-
 /// Is `impl1` a specialization of `impl2`?
 ///
 /// Specialization is determined by the sets of types to which the impls apply;
diff --git a/src/librustc_trait_selection/traits/specialize/specialization_graph.rs b/src/librustc_trait_selection/traits/specialize/specialization_graph.rs
index 17d4a22b9dd..56b8354d68c 100644
--- a/src/librustc_trait_selection/traits/specialize/specialization_graph.rs
+++ b/src/librustc_trait_selection/traits/specialize/specialization_graph.rs
@@ -1,11 +1,11 @@
 use super::OverlapError;
 
 use crate::traits;
-use rustc::ty::fast_reject::{self, SimplifiedType};
-use rustc::ty::{self, TyCtxt, TypeFoldable};
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty::fast_reject::{self, SimplifiedType};
+use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
 
-pub use rustc::traits::specialization_graph::*;
+pub use rustc_middle::traits::specialization_graph::*;
 
 #[derive(Copy, Clone, Debug)]
 pub enum FutureCompatOverlapErrorKind {
diff --git a/src/librustc_trait_selection/traits/structural_match.rs b/src/librustc_trait_selection/traits/structural_match.rs
index 42c9c246078..fbe1fcb08f2 100644
--- a/src/librustc_trait_selection/traits/structural_match.rs
+++ b/src/librustc_trait_selection/traits/structural_match.rs
@@ -2,9 +2,9 @@ use crate::infer::{InferCtxt, TyCtxtInferExt};
 use crate::traits::ObligationCause;
 use crate::traits::{self, ConstPatternStructural, TraitEngine};
 
-use rustc::ty::{self, AdtDef, Ty, TyCtxt, TypeFoldable, TypeVisitor};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
+use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeFoldable, TypeVisitor};
 use rustc_span::Span;
 
 #[derive(Debug)]
diff --git a/src/librustc_trait_selection/traits/util.rs b/src/librustc_trait_selection/traits/util.rs
index cd4595e76cc..725c41c1e2c 100644
--- a/src/librustc_trait_selection/traits/util.rs
+++ b/src/librustc_trait_selection/traits/util.rs
@@ -3,273 +3,13 @@ use rustc_span::Span;
 use smallvec::smallvec;
 use smallvec::SmallVec;
 
-use rustc::ty::outlives::Component;
-use rustc::ty::subst::{GenericArg, Subst, SubstsRef};
-use rustc::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness};
 use rustc_data_structures::fx::FxHashSet;
-use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty::subst::{GenericArg, Subst, SubstsRef};
+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
@@ -451,40 +191,6 @@ impl Iterator for SupertraitDefIds<'tcx> {
 // 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.
@@ -651,22 +357,8 @@ pub fn generator_trait_ref_and_outputs(
     ty::Binder::bind((trait_ref, sig.skip_binder().yield_ty, sig.skip_binder().return_ty))
 }
 
-pub fn impl_is_default(tcx: TyCtxt<'_>, node_item_def_id: DefId) -> bool {
-    match tcx.hir().as_local_hir_id(node_item_def_id) {
-        Some(hir_id) => {
-            let item = tcx.hir().expect_item(hir_id);
-            if let hir::ItemKind::Impl { defaultness, .. } = item.kind {
-                defaultness.is_default()
-            } else {
-                false
-            }
-        }
-        None => tcx.impl_defaultness(node_item_def_id).is_default(),
-    }
-}
-
 pub fn impl_item_is_final(tcx: TyCtxt<'_>, assoc_item: &ty::AssocItem) -> bool {
-    assoc_item.defaultness.is_final() && !impl_is_default(tcx, assoc_item.container.id())
+    assoc_item.defaultness.is_final() && tcx.impl_defaultness(assoc_item.container.id()).is_final()
 }
 
 pub enum TupleArgumentsFlag {
diff --git a/src/librustc_trait_selection/traits/wf.rs b/src/librustc_trait_selection/traits/wf.rs
index aa129d2b81c..1eb41e0b4d1 100644
--- a/src/librustc_trait_selection/traits/wf.rs
+++ b/src/librustc_trait_selection/traits/wf.rs
@@ -1,11 +1,11 @@
 use crate::infer::InferCtxt;
 use crate::opaque_types::required_region_bounds;
 use crate::traits::{self, AssocTypeBoundData};
-use rustc::middle::lang_items;
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+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};
 use rustc_span::Span;
 
@@ -737,17 +737,14 @@ fn get_generic_bound_spans(
 }
 
 fn is_self_path(kind: &hir::TyKind<'_>) -> bool {
-    match kind {
-        hir::TyKind::Path(hir::QPath::Resolved(None, path)) => {
-            let mut s = path.segments.iter();
-            if let (Some(segment), None) = (s.next(), s.next()) {
-                if segment.ident.name == kw::SelfUpper {
-                    // `type(Self)`
-                    return true;
-                }
+    if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = kind {
+        let mut s = path.segments.iter();
+        if let (Some(segment), None) = (s.next(), s.next()) {
+            if segment.ident.name == kw::SelfUpper {
+                // `type(Self)`
+                return true;
             }
         }
-        _ => {}
     }
     false
 }
diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml
index 5e33efb1cf9..432004c1049 100644
--- a/src/librustc_traits/Cargo.toml
+++ b/src/librustc_traits/Cargo.toml
@@ -10,7 +10,7 @@ path = "lib.rs"
 
 [dependencies]
 log = { version = "0.4" }
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_hir = { path = "../librustc_hir" }
 rustc_macros = { path = "../librustc_macros" }
diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs
index 7068723f534..93b15e146ec 100644
--- a/src/librustc_traits/dropck_outlives.rs
+++ b/src/librustc_traits/dropck_outlives.rs
@@ -1,11 +1,11 @@
-use rustc::ty::query::Providers;
-use rustc::ty::subst::{InternalSubsts, Subst};
-use rustc::ty::{self, ParamEnvAnd, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::canonical::{Canonical, QueryResponse};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::TraitEngineExt as _;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::subst::{InternalSubsts, Subst};
+use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt};
 use rustc_span::source_map::{Span, DUMMY_SP};
 use rustc_trait_selection::traits::query::dropck_outlives::trivial_dropck_outlives;
 use rustc_trait_selection::traits::query::dropck_outlives::{
diff --git a/src/librustc_traits/evaluate_obligation.rs b/src/librustc_traits/evaluate_obligation.rs
index 87895d8e384..e6afc15fa15 100644
--- a/src/librustc_traits/evaluate_obligation.rs
+++ b/src/librustc_traits/evaluate_obligation.rs
@@ -1,6 +1,6 @@
-use rustc::ty::query::Providers;
-use rustc::ty::{ParamEnvAnd, TyCtxt};
 use rustc_infer::infer::TyCtxtInferExt;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
 use rustc_span::source_map::DUMMY_SP;
 use rustc_trait_selection::traits::query::CanonicalPredicateGoal;
 use rustc_trait_selection::traits::{
diff --git a/src/librustc_traits/implied_outlives_bounds.rs b/src/librustc_traits/implied_outlives_bounds.rs
index 4505a1e59d9..33ecbe72a8c 100644
--- a/src/librustc_traits/implied_outlives_bounds.rs
+++ b/src/librustc_traits/implied_outlives_bounds.rs
@@ -1,13 +1,14 @@
 //! Provider for the `implied_outlives_bounds` query.
-//! Do not call this query directory. See [`rustc::traits::query::implied_outlives_bounds`].
+//! Do not call this query directory. See
+//! [`rustc_trait_selection::traits::query::type_op::implied_outlives_bounds`].
 
-use rustc::ty::outlives::Component;
-use rustc::ty::query::Providers;
-use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc_hir as hir;
 use rustc_infer::infer::canonical::{self, Canonical};
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::TraitEngineExt as _;
+use rustc_middle::ty::outlives::Component;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc_span::source_map::DUMMY_SP;
 use rustc_trait_selection::infer::InferCtxtBuilderExt;
 use rustc_trait_selection::traits::query::outlives_bounds::OutlivesBound;
diff --git a/src/librustc_traits/lib.rs b/src/librustc_traits/lib.rs
index 894e3ef3a8f..49953e65c9a 100644
--- a/src/librustc_traits/lib.rs
+++ b/src/librustc_traits/lib.rs
@@ -9,7 +9,7 @@
 #[macro_use]
 extern crate log;
 #[macro_use]
-extern crate rustc;
+extern crate rustc_middle;
 
 mod dropck_outlives;
 mod evaluate_obligation;
@@ -19,7 +19,7 @@ mod normalize_erasing_regions;
 mod normalize_projection_ty;
 mod type_op;
 
-use rustc::ty::query::Providers;
+use rustc_middle::ty::query::Providers;
 
 pub fn provide(p: &mut Providers<'_>) {
     dropck_outlives::provide(p);
diff --git a/src/librustc_traits/lowering/environment.rs b/src/librustc_traits/lowering/environment.rs
index ed6259d4573..28d5d25dd1b 100644
--- a/src/librustc_traits/lowering/environment.rs
+++ b/src/librustc_traits/lowering/environment.rs
@@ -1,9 +1,9 @@
-use rustc::traits::{
-    Clause, Clauses, DomainGoal, Environment, FromEnv, ProgramClause, ProgramClauseCategory,
-};
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def_id::DefId;
+use rustc_middle::traits::{
+    Clause, Clauses, DomainGoal, Environment, FromEnv, ProgramClause, ProgramClauseCategory,
+};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 
 struct ClauseVisitor<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
diff --git a/src/librustc_traits/lowering/mod.rs b/src/librustc_traits/lowering/mod.rs
index e3f9bd78073..6cbd505f37e 100644
--- a/src/librustc_traits/lowering/mod.rs
+++ b/src/librustc_traits/lowering/mod.rs
@@ -1,19 +1,19 @@
 mod environment;
 
-use rustc::hir::map::Map;
-use rustc::traits::{
-    Clause, Clauses, DomainGoal, FromEnv, GoalKind, PolyDomainGoal, ProgramClause,
-    ProgramClauseCategory, WellFormed, WhereClause,
-};
-use rustc::ty::query::Providers;
-use rustc::ty::subst::{InternalSubsts, Subst};
-use rustc::ty::{self, List, TyCtxt};
 use rustc_ast::ast;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::definitions::DefPathData;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
+use rustc_middle::hir::map::Map;
+use rustc_middle::traits::{
+    Clause, Clauses, DomainGoal, FromEnv, GoalKind, PolyDomainGoal, ProgramClause,
+    ProgramClauseCategory, WellFormed, WhereClause,
+};
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::subst::{InternalSubsts, Subst};
+use rustc_middle::ty::{self, List, TyCtxt};
 use rustc_span::symbol::sym;
 
 use std::iter;
@@ -91,7 +91,7 @@ where
 
 impl<'tcx> Lower<PolyDomainGoal<'tcx>> for ty::Predicate<'tcx> {
     fn lower(&self) -> PolyDomainGoal<'tcx> {
-        use rustc::ty::Predicate;
+        use rustc_middle::ty::Predicate;
 
         match self {
             Predicate::Trait(predicate, _) => predicate.lower(),
diff --git a/src/librustc_traits/normalize_erasing_regions.rs b/src/librustc_traits/normalize_erasing_regions.rs
index 065cf38eb24..ad6c753edff 100644
--- a/src/librustc_traits/normalize_erasing_regions.rs
+++ b/src/librustc_traits/normalize_erasing_regions.rs
@@ -1,8 +1,8 @@
-use rustc::traits::query::NoSolution;
-use rustc::ty::query::Providers;
-use rustc::ty::subst::GenericArg;
-use rustc::ty::{self, ParamEnvAnd, TyCtxt};
 use rustc_infer::infer::TyCtxtInferExt;
+use rustc_middle::traits::query::NoSolution;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::subst::GenericArg;
+use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt};
 use rustc_trait_selection::traits::query::normalize::AtExt;
 use rustc_trait_selection::traits::{Normalized, ObligationCause};
 use std::sync::atomic::Ordering;
diff --git a/src/librustc_traits/normalize_projection_ty.rs b/src/librustc_traits/normalize_projection_ty.rs
index 57abff769de..11c97b03c44 100644
--- a/src/librustc_traits/normalize_projection_ty.rs
+++ b/src/librustc_traits/normalize_projection_ty.rs
@@ -1,9 +1,9 @@
-use rustc::ty::query::Providers;
-use rustc::ty::{ParamEnvAnd, TyCtxt};
 use rustc_hir as hir;
 use rustc_infer::infer::canonical::{Canonical, QueryResponse};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::TraitEngineExt as _;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
 use rustc_span::DUMMY_SP;
 use rustc_trait_selection::infer::InferCtxtBuilderExt;
 use rustc_trait_selection::traits::query::{
diff --git a/src/librustc_traits/type_op.rs b/src/librustc_traits/type_op.rs
index 7ed828c9167..aeb31c2cb73 100644
--- a/src/librustc_traits/type_op.rs
+++ b/src/librustc_traits/type_op.rs
@@ -1,14 +1,14 @@
-use rustc::ty::query::Providers;
-use rustc::ty::subst::{GenericArg, Subst, UserSelfTy, UserSubsts};
-use rustc::ty::{
-    FnSig, Lift, ParamEnv, ParamEnvAnd, PolyFnSig, Predicate, Ty, TyCtxt, TypeFoldable, Variance,
-};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::at::ToTrace;
 use rustc_infer::infer::canonical::{Canonical, QueryResponse};
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::TraitEngineExt as _;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::subst::{GenericArg, Subst, UserSelfTy, UserSubsts};
+use rustc_middle::ty::{
+    FnSig, Lift, ParamEnv, ParamEnvAnd, PolyFnSig, Predicate, Ty, TyCtxt, TypeFoldable, Variance,
+};
 use rustc_span::DUMMY_SP;
 use rustc_trait_selection::infer::InferCtxtBuilderExt;
 use rustc_trait_selection::infer::InferCtxtExt;
diff --git a/src/librustc_ty/Cargo.toml b/src/librustc_ty/Cargo.toml
index cf0b4b82eea..37d1ed38d79 100644
--- a/src/librustc_ty/Cargo.toml
+++ b/src/librustc_ty/Cargo.toml
@@ -10,7 +10,7 @@ path = "lib.rs"
 
 [dependencies]
 log = "0.4"
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_hir = { path = "../librustc_hir" }
 rustc_infer = { path = "../librustc_infer" }
diff --git a/src/librustc_ty/common_traits.rs b/src/librustc_ty/common_traits.rs
index 311ba383f30..265b811571a 100644
--- a/src/librustc_ty/common_traits.rs
+++ b/src/librustc_ty/common_traits.rs
@@ -1,8 +1,8 @@
 //! Queries for checking whether a type implements one of a few common traits.
 
-use rustc::middle::lang_items;
-use rustc::ty::{self, Ty, TyCtxt};
+use rustc_hir::lang_items;
 use rustc_infer::infer::TyCtxtInferExt;
+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 a5abe7b6413..677e373f2f4 100644
--- a/src/librustc_ty/instance.rs
+++ b/src/librustc_ty/instance.rs
@@ -1,9 +1,11 @@
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::{self, Instance, TyCtxt, TypeFoldable};
 use rustc_hir::def_id::DefId;
+use rustc_infer::infer::TyCtxtInferExt;
+use rustc_middle::ty::subst::SubstsRef;
+use rustc_middle::ty::{self, Instance, TyCtxt, TypeFoldable};
 use rustc_span::sym;
 use rustc_target::spec::abi::Abi;
 use rustc_trait_selection::traits;
+use traits::{translate_substs, Reveal};
 
 use log::debug;
 
@@ -82,21 +84,54 @@ fn resolve_associated_item<'tcx>(
     // the actual function:
     match vtbl {
         traits::VtableImpl(impl_data) => {
-            let (def_id, substs) =
-                traits::find_associated_item(tcx, param_env, trait_item, rcvr_substs, &impl_data);
-
-            let resolved_item = tcx.associated_item(def_id);
+            debug!(
+                "resolving VtableImpl: {:?}, {:?}, {:?}, {:?}",
+                param_env, trait_item, rcvr_substs, impl_data
+            );
+            assert!(!rcvr_substs.needs_infer());
+            assert!(!trait_ref.needs_infer());
+
+            let trait_def_id = tcx.trait_id_of_impl(impl_data.impl_def_id).unwrap();
+            let trait_def = tcx.trait_def(trait_def_id);
+            let leaf_def = trait_def
+                .ancestors(tcx, impl_data.impl_def_id)
+                .ok()?
+                .leaf_def(tcx, trait_item.ident, trait_item.kind)
+                .unwrap_or_else(|| {
+                    bug!("{:?} not found in {:?}", trait_item, impl_data.impl_def_id);
+                });
+            let def_id = leaf_def.item.def_id;
+
+            let substs = tcx.infer_ctxt().enter(|infcx| {
+                let param_env = param_env.with_reveal_all();
+                let substs = rcvr_substs.rebase_onto(tcx, trait_def_id, impl_data.substs);
+                let substs = translate_substs(
+                    &infcx,
+                    param_env,
+                    impl_data.impl_def_id,
+                    substs,
+                    leaf_def.defining_node,
+                );
+                infcx.tcx.erase_regions(&substs)
+            });
 
             // 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::traits::project::assemble_candidates_from_impls()`.
-            let eligible = if !resolved_item.defaultness.is_default() {
+            // `rustc_trait_selection::traits::project::assemble_candidates_from_impls()`.
+            let eligible = if leaf_def.is_final() {
+                // Non-specializable items are always projectable.
                 true
-            } else if param_env.reveal == traits::Reveal::All {
-                !trait_ref.needs_subst()
             } else {
-                false
+                // Only reveal a specializable default if we're past type-checking
+                // 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.still_further_specializable()
+                } else {
+                    false
+                }
             };
 
             if !eligible {
diff --git a/src/librustc_ty/lib.rs b/src/librustc_ty/lib.rs
index f9ee4e20d27..04909b8b0c1 100644
--- a/src/librustc_ty/lib.rs
+++ b/src/librustc_ty/lib.rs
@@ -10,11 +10,11 @@
 #![recursion_limit = "256"]
 
 #[macro_use]
-extern crate rustc;
+extern crate rustc_middle;
 #[macro_use]
 extern crate log;
 
-use rustc::ty::query::Providers;
+use rustc_middle::ty::query::Providers;
 
 mod common_traits;
 pub mod instance;
diff --git a/src/librustc_ty/needs_drop.rs b/src/librustc_ty/needs_drop.rs
index 37af8168f87..6b0104e164b 100644
--- a/src/librustc_ty/needs_drop.rs
+++ b/src/librustc_ty/needs_drop.rs
@@ -1,10 +1,10 @@
 //! Check whether a type has (potentially) non-trivial drop glue.
 
-use rustc::ty::subst::Subst;
-use rustc::ty::util::{needs_drop_components, AlwaysRequiresDrop};
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty::subst::Subst;
+use rustc_middle::ty::util::{needs_drop_components, AlwaysRequiresDrop};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::DUMMY_SP;
 
 type NeedsDropResult<T> = Result<T, AlwaysRequiresDrop>;
diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs
index 4b522997537..aefe61f60b8 100644
--- a/src/librustc_ty/ty.rs
+++ b/src/librustc_ty/ty.rs
@@ -1,9 +1,9 @@
-use rustc::hir::map as hir_map;
-use rustc::ty::subst::Subst;
-use rustc::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness};
 use rustc_data_structures::svh::Svh;
 use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
+use rustc_middle::hir::map as hir_map;
+use rustc_middle::ty::subst::Subst;
+use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness};
 use rustc_session::CrateDisambiguator;
 use rustc_span::symbol::Symbol;
 use rustc_span::Span;
@@ -165,6 +165,16 @@ fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItem {
     )
 }
 
+fn impl_defaultness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Defaultness {
+    let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
+    let item = tcx.hir().expect_item(hir_id);
+    if let hir::ItemKind::Impl { defaultness, .. } = item.kind {
+        defaultness
+    } else {
+        bug!("`impl_defaultness` called on {:?}", item);
+    }
+}
+
 /// Calculates the `Sized` constraint.
 ///
 /// In fact, there are only a few options for the types in the constraint:
@@ -371,6 +381,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
         crate_hash,
         instance_def_size_estimate,
         issue33140_self_ty,
+        impl_defaultness,
         ..*providers
     };
 }
diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml
index e61a36f844f..8aaa29bc582 100644
--- a/src/librustc_typeck/Cargo.toml
+++ b/src/librustc_typeck/Cargo.toml
@@ -13,7 +13,7 @@ doctest = false
 [dependencies]
 arena = { path = "../libarena" }
 log = "0.4"
-rustc = { path = "../librustc" }
+rustc_middle = { path = "../librustc_middle" }
 rustc_attr = { path = "../librustc_attr" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors" }
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 07630d7969e..c3ebcbfc832 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -6,22 +6,24 @@
 // 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::ty::subst::{self, InternalSubsts, Subst, SubstsRef};
-use rustc::ty::{self, Const, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
-use rustc::ty::{GenericParamDef, GenericParamDefKind};
 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::{
+    self, Const, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
+};
+use rustc_middle::ty::{GenericParamDef, GenericParamDefKind};
 use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, LATE_BOUND_LIFETIME_ARGUMENTS};
 use rustc_session::parse::feature_err;
 use rustc_session::Session;
@@ -1783,9 +1785,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 ));
             }
         }
-
-        match (&potential_assoc_types[..], &trait_bounds) {
-            ([], [bound]) => match &bound.trait_ref.path.segments[..] {
+        if let ([], [bound]) = (&potential_assoc_types[..], &trait_bounds) {
+            match &bound.trait_ref.path.segments[..] {
                 // FIXME: `trait_ref.path.span` can point to a full path with multiple
                 // segments, even though `trait_ref.path.segments` is of length `1`. Work
                 // around that bug here, even though it should be fixed elsewhere.
@@ -1817,8 +1818,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         .collect();
                 }
                 _ => {}
-            },
-            _ => {}
+            }
         }
         names.sort();
         trait_bound_spans.sort();
@@ -2440,6 +2440,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                             continue;
                         }
                         err_for_ct = true;
+                        has_err = true;
                         (ct.span, "const")
                     }
                 };
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index b44bab2675d..16af168ce1a 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -1,9 +1,9 @@
 use crate::check::coercion::CoerceMany;
 use crate::check::{Diverges, Expectation, FnCtxt, Needs};
-use rustc::ty::Ty;
 use rustc_hir as hir;
 use rustc_hir::ExprKind;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use rustc_middle::ty::Ty;
 use rustc_span::Span;
 use rustc_trait_selection::traits::ObligationCauseCode;
 use rustc_trait_selection::traits::{IfExpressionCause, MatchExpressionArmCause, ObligationCause};
diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs
index 2315b42aec5..0dab172230e 100644
--- a/src/librustc_typeck/check/autoderef.rs
+++ b/src/librustc_typeck/check/autoderef.rs
@@ -1,13 +1,13 @@
 use super::method::MethodCallee;
 use super::{FnCtxt, Needs, PlaceOp};
 
-use rustc::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
-use rustc::ty::{self, TraitRef, Ty, TyCtxt, WithConstness};
-use rustc::ty::{ToPredicate, TypeFoldable};
 use rustc_ast::ast::Ident;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_infer::infer::{InferCtxt, InferOk};
+use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
+use rustc_middle::ty::{self, TraitRef, Ty, TyCtxt, WithConstness};
+use rustc_middle::ty::{ToPredicate, TypeFoldable};
 use rustc_session::DiagnosticMessageId;
 use rustc_span::Span;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index 074951684ef..0d254412203 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -3,9 +3,6 @@ use super::method::MethodCallee;
 use super::{Expectation, FnCtxt, Needs, TupleArgumentsFlag};
 use crate::type_error_struct;
 
-use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc_ast::ast::Ident;
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
@@ -13,6 +10,11 @@ use rustc_hir::def::Res;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::{infer, traits};
+use rustc_middle::ty::adjustment::{
+    Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
+};
+use rustc_middle::ty::subst::SubstsRef;
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc_span::Span;
 use rustc_target::spec::abi;
 
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 2875d38a996..5de0184f2bb 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -32,16 +32,15 @@ use super::FnCtxt;
 
 use crate::hir::def_id::DefId;
 use crate::type_error_struct;
-use crate::util::common::ErrorReported;
-use rustc::middle::lang_items;
-use rustc::ty::adjustment::AllowTwoPhase;
-use rustc::ty::cast::{CastKind, CastTy};
-use rustc::ty::error::TypeError;
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::{self, Ty, TypeAndMut, TypeFoldable};
 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_hir::lang_items;
+use rustc_middle::ty::adjustment::AllowTwoPhase;
+use rustc_middle::ty::cast::{CastKind, CastTy};
+use rustc_middle::ty::error::TypeError;
+use rustc_middle::ty::subst::SubstsRef;
+use rustc_middle::ty::{self, Ty, TypeAndMut, TypeFoldable};
 use rustc_session::lint;
 use rustc_session::Session;
 use rustc_span::Span;
@@ -526,8 +525,8 @@ impl<'a, 'tcx> CastCheck<'tcx> {
     /// can return Ok and create type errors in the fcx rather than returning
     /// directly. coercion-cast is handled in check instead of here.
     fn do_check(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<CastKind, CastError> {
-        use rustc::ty::cast::CastTy::*;
-        use rustc::ty::cast::IntTy::*;
+        use rustc_middle::ty::cast::CastTy::*;
+        use rustc_middle::ty::cast::IntTy::*;
 
         let (t_from, t_cast) = match (CastTy::from_ty(self.expr_ty), CastTy::from_ty(self.cast_ty))
         {
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index a277220b1a2..2ccf7890c30 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -3,15 +3,16 @@
 use super::{check_fn, Expectation, FnCtxt, GeneratorTypes};
 
 use crate::astconv::AstConv;
-use crate::middle::{lang_items, region};
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::subst::InternalSubsts;
-use rustc::ty::{self, GenericParamDefKind, Ty};
+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};
+use rustc_middle::ty::fold::TypeFoldable;
+use rustc_middle::ty::subst::InternalSubsts;
+use rustc_middle::ty::{self, GenericParamDefKind, Ty};
 use rustc_span::source_map::Span;
 use rustc_target::spec::abi::Abi;
 use rustc_trait_selection::traits::error_reporting::ArgKind;
@@ -431,18 +432,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         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/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 2dc2a48ecbc..5a97a2af120 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -52,18 +52,18 @@
 
 use crate::astconv::AstConv;
 use crate::check::{FnCtxt, Needs};
-use rustc::ty::adjustment::{
-    Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
-};
-use rustc::ty::error::TypeError;
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::relate::RelateResult;
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::{self, Ty, TypeAndMut};
 use rustc_errors::{struct_span_err, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::{Coercion, InferOk, InferResult};
+use rustc_middle::ty::adjustment::{
+    Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
+};
+use rustc_middle::ty::error::TypeError;
+use rustc_middle::ty::fold::TypeFoldable;
+use rustc_middle::ty::relate::RelateResult;
+use rustc_middle::ty::subst::SubstsRef;
+use rustc_middle::ty::{self, Ty, TypeAndMut};
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::sym;
 use rustc_span::{self, Span};
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 412f687b43e..24db25a1f34 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -1,14 +1,13 @@
-use rustc::ty::error::{ExpectedFound, TypeError};
-use rustc::ty::subst::{InternalSubsts, Subst};
-use rustc::ty::util::ExplicitSelf;
-use rustc::ty::{self, GenericParamDefKind, TyCtxt};
-use rustc::util::common::ErrorReported;
-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;
 use rustc_hir::{GenericParamKind, ImplItemKind, TraitItemKind};
 use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
+use rustc_middle::ty::error::{ExpectedFound, TypeError};
+use rustc_middle::ty::subst::{InternalSubsts, Subst};
+use rustc_middle::ty::util::ExplicitSelf;
+use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt};
 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/demand.rs b/src/librustc_typeck/check/demand.rs
index f7ffb5a2218..369bb183bcd 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -4,12 +4,12 @@ use rustc_trait_selection::infer::InferCtxtExt as _;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc_trait_selection::traits::{self, ObligationCause};
 
-use rustc::ty::adjustment::AllowTwoPhase;
-use rustc::ty::{self, AssocItem, Ty};
 use rustc_ast::util::parser::PREC_POSTFIX;
 use rustc_errors::{Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::{is_range_literal, Node};
+use rustc_middle::ty::adjustment::AllowTwoPhase;
+use rustc_middle::ty::{self, AssocItem, Ty};
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 
diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs
index e48ebbbb235..72220d93d92 100644
--- a/src/librustc_typeck/check/dropck.rs
+++ b/src/librustc_typeck/check/dropck.rs
@@ -1,16 +1,15 @@
 use crate::check::regionck::RegionCtxt;
 use crate::hir;
 use crate::hir::def_id::DefId;
-use crate::util::common::ErrorReported;
-use rustc::middle::region;
-use rustc::ty::error::TypeError;
-use rustc::ty::relate::{Relate, RelateResult, TypeRelation};
-use rustc::ty::subst::{Subst, SubstsRef};
-use rustc::ty::{self, Predicate, Ty, TyCtxt};
-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 _;
+use rustc_middle::middle::region;
+use rustc_middle::ty::error::TypeError;
+use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
+use rustc_middle::ty::subst::{Subst, SubstsRef};
+use rustc_middle::ty::{self, Predicate, Ty, TyCtxt};
 use rustc_span::Span;
 use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
 use rustc_trait_selection::traits::query::dropck_outlives::AtExt;
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 8cd6f7b8c88..9c57ffaf055 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -15,24 +15,26 @@ use crate::check::FnCtxt;
 use crate::check::Needs;
 use crate::check::TupleArgumentsFlag::DontTupleArguments;
 use crate::type_error_struct;
-use crate::util::common::ErrorReported;
-
-use rustc::middle::lang_items;
-use rustc::ty;
-use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
-use rustc::ty::Ty;
-use rustc::ty::TypeFoldable;
-use rustc::ty::{AdtKind, Visibility};
+
 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::ty;
+use rustc_middle::ty::adjustment::{
+    Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
+};
+use rustc_middle::ty::Ty;
+use rustc_middle::ty::TypeFoldable;
+use rustc_middle::ty::{AdtKind, Visibility};
 use rustc_span::hygiene::DesugaringKind;
 use rustc_span::source_map::Span;
 use rustc_span::symbol::{kw, sym, Symbol};
diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs
index cdf68256a7a..db9c8c35c2c 100644
--- a/src/librustc_typeck/check/generator_interior.rs
+++ b/src/librustc_typeck/check/generator_interior.rs
@@ -4,14 +4,14 @@
 //! types computed here.
 
 use super::FnCtxt;
-use rustc::middle::region::{self, YieldData};
-use rustc::ty::{self, Ty};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::{Expr, ExprKind, Pat, PatKind};
+use rustc_middle::middle::region::{self, YieldData};
+use rustc_middle::ty::{self, Ty};
 use rustc_span::Span;
 
 struct InteriorVisitor<'a, 'tcx> {
@@ -205,7 +205,7 @@ pub fn resolve_interior<'a, 'tcx>(
 }
 
 // This visitor has to have the same visit_expr calls as RegionResolutionVisitor in
-// librustc/middle/region.rs since `expr_count` is compared against the results
+// librustc_middle/middle/region.rs since `expr_count` is compared against the results
 // there.
 impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
     type Map = intravisit::ErasedMap<'tcx>;
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index 6f9d8a8e58f..05028ff0b2c 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -3,11 +3,11 @@
 
 use crate::require_same_types;
 
-use rustc::traits::{ObligationCause, ObligationCauseCode};
-use rustc::ty::subst::Subst;
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
+use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
+use rustc_middle::ty::subst::Subst;
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::symbol::Symbol;
 use rustc_target::spec::abi::Abi;
 
@@ -275,7 +275,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
             "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/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index d340d6ff5c2..a16555b3df0 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -4,13 +4,13 @@ use crate::astconv::AstConv;
 use crate::check::{callee, FnCtxt, Needs, PlaceOp};
 use crate::hir::def_id::DefId;
 use crate::hir::GenericArg;
-use rustc::ty::adjustment::{Adjust, Adjustment, OverloadedDeref, PointerCast};
-use rustc::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::subst::{Subst, SubstsRef};
-use rustc::ty::{self, GenericParamDefKind, Ty};
 use rustc_hir as hir;
 use rustc_infer::infer::{self, InferOk};
+use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref, PointerCast};
+use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
+use rustc_middle::ty::fold::TypeFoldable;
+use rustc_middle::ty::subst::{Subst, SubstsRef};
+use rustc_middle::ty::{self, GenericParamDefKind, Ty};
 use rustc_span::Span;
 use rustc_trait_selection::traits;
 
@@ -551,12 +551,11 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
             }
 
             // If we have an autoref followed by unsizing at the end, fix the unsize target.
-            match adjustments[..] {
-                [.., Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. }, Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), ref mut target }] =>
-                {
-                    *target = method.sig.inputs()[0];
-                }
-                _ => {}
+
+            if let [.., Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. }, Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), ref mut target }] =
+                adjustments[..]
+            {
+                *target = method.sig.inputs()[0];
             }
         }
     }
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index 962f9807546..deaff19de08 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -11,10 +11,6 @@ pub use self::CandidateSource::*;
 pub use self::MethodError::*;
 
 use crate::check::FnCtxt;
-use rustc::ty::subst::Subst;
-use rustc::ty::subst::{InternalSubsts, SubstsRef};
-use rustc::ty::GenericParamDefKind;
-use rustc::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TypeFoldable, WithConstness};
 use rustc_ast::ast;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Applicability, DiagnosticBuilder};
@@ -22,6 +18,10 @@ use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Namespace};
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::{self, InferOk};
+use rustc_middle::ty::subst::Subst;
+use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
+use rustc_middle::ty::GenericParamDefKind;
+use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TypeFoldable, WithConstness};
 use rustc_span::Span;
 use rustc_trait_selection::traits;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 45b1c7d6ea7..7e7d84c1996 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -8,12 +8,6 @@ use crate::check::FnCtxt;
 use crate::hir::def::DefKind;
 use crate::hir::def_id::DefId;
 
-use rustc::middle::stability;
-use rustc::ty::subst::{InternalSubsts, Subst, SubstsRef};
-use rustc::ty::GenericParamDefKind;
-use rustc::ty::{
-    self, ParamEnvAnd, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
-};
 use rustc_ast::ast;
 use rustc_ast::util::lev_distance::{find_best_match_for_name, lev_distance};
 use rustc_data_structures::fx::FxHashSet;
@@ -26,6 +20,12 @@ use rustc_infer::infer::canonical::{Canonical, QueryResponse};
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
 use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
+use rustc_middle::middle::stability;
+use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
+use rustc_middle::ty::GenericParamDefKind;
+use rustc_middle::ty::{
+    self, ParamEnvAnd, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
+};
 use rustc_session::config::nightly_options;
 use rustc_session::lint;
 use rustc_span::{symbol::Symbol, Span, DUMMY_SP};
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 688820029fe..add706b5fcc 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -2,10 +2,6 @@
 //! found or is otherwise invalid.
 
 use crate::check::FnCtxt;
-use crate::middle::lang_items::FnOnceTraitLangItem;
-use rustc::hir::map as hir_map;
-use rustc::ty::print::with_crate_prefix;
-use rustc::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
 use rustc_ast::ast;
 use rustc_ast::util::lev_distance;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -14,8 +10,14 @@ use rustc_hir as hir;
 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;
+use rustc_middle::ty::print::with_crate_prefix;
+use rustc_middle::ty::{
+    self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
+};
 use rustc_span::symbol::kw;
 use rustc_span::{source_map, FileName, Span};
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
@@ -556,26 +558,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                         .hir()
                                         .as_local_hir_id(def.did)
                                         .map(|id| self.tcx.hir().get(id));
-                                    match node {
-                                        Some(hir::Node::Item(hir::Item { kind, .. })) => {
-                                            if let Some(g) = kind.generics() {
-                                                let key = match &g.where_clause.predicates[..] {
-                                                    [.., pred] => {
-                                                        (pred.span().shrink_to_hi(), false)
-                                                    }
-                                                    [] => (
-                                                        g.where_clause
-                                                            .span_for_predicates_or_empty_place(),
-                                                        true,
-                                                    ),
-                                                };
-                                                type_params
-                                                    .entry(key)
-                                                    .or_insert_with(FxHashSet::default)
-                                                    .insert(obligation.to_owned());
-                                            }
+                                    if let Some(hir::Node::Item(hir::Item { kind, .. })) = node {
+                                        if let Some(g) = kind.generics() {
+                                            let key = match &g.where_clause.predicates[..] {
+                                                [.., pred] => (pred.span().shrink_to_hi(), false),
+                                                [] => (
+                                                    g.where_clause
+                                                        .span_for_predicates_or_empty_place(),
+                                                    true,
+                                                ),
+                                            };
+                                            type_params
+                                                .entry(key)
+                                                .or_insert_with(FxHashSet::default)
+                                                .insert(obligation.to_owned());
                                         }
-                                        _ => {}
                                     }
                                 }
                             }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index f188ee0a13c..293c4feac62 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -88,33 +88,19 @@ mod wfcheck;
 pub mod writeback;
 
 use crate::astconv::{AstConv, GenericArgCountMismatch, PathSeg};
-use crate::middle::lang_items;
-use rustc::hir::map::blocks::FnLikeNode;
-use rustc::middle::region;
-use rustc::mir::interpret::ConstValue;
-use rustc::ty::adjustment::{
-    Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
-};
-use rustc::ty::fold::{TypeFoldable, TypeFolder};
-use rustc::ty::layout::VariantIdx;
-use rustc::ty::query::Providers;
-use rustc::ty::subst::{GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSelfTy, UserSubsts};
-use rustc::ty::util::{Discr, IntTypeExt, Representability};
-use rustc::ty::{
-    self, AdtKind, CanonicalUserType, Const, GenericParamDefKind, RegionKind, ToPolyTraitRef,
-    ToPredicate, Ty, TyCtxt, UserType, WithConstness,
-};
 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};
@@ -122,6 +108,22 @@ use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
 use rustc_infer::infer::{self, InferCtxt, InferOk, InferResult, TyCtxtInferExt};
+use rustc_middle::hir::map::blocks::FnLikeNode;
+use rustc_middle::middle::region;
+use rustc_middle::mir::interpret::ConstValue;
+use rustc_middle::ty::adjustment::{
+    Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
+};
+use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::subst::{
+    GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSelfTy, UserSubsts,
+};
+use rustc_middle::ty::util::{Discr, IntTypeExt, Representability};
+use rustc_middle::ty::{
+    self, AdtKind, CanonicalUserType, Const, GenericParamDefKind, RegionKind, ToPolyTraitRef,
+    ToPredicate, Ty, TyCtxt, UserType, WithConstness,
+};
 use rustc_session::config::{self, EntryFnType};
 use rustc_session::lint;
 use rustc_session::parse::feature_err;
@@ -130,6 +132,7 @@ use rustc_span::hygiene::DesugaringKind;
 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};
@@ -149,7 +152,7 @@ use std::ops::{self, Deref};
 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;
@@ -1940,7 +1943,7 @@ fn check_specialization_validity<'tcx>(
             // grandparent. In that case, if parent is a `default impl`, inherited items use the
             // "defaultness" from the grandparent, else they are final.
             None => {
-                if traits::impl_is_default(tcx, parent_impl.def_id()) {
+                if tcx.impl_defaultness(parent_impl.def_id()).is_default() {
                     None
                 } else {
                     Some(Err(parent_impl.def_id()))
@@ -2112,10 +2115,10 @@ fn check_impl_items_against_trait<'tcx>(
         for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() {
             let is_implemented = ancestors
                 .leaf_def(tcx, trait_item.ident, trait_item.kind)
-                .map(|node_item| !node_item.node.is_from_trait())
+                .map(|node_item| !node_item.defining_node.is_from_trait())
                 .unwrap_or(false);
 
-            if !is_implemented && !traits::impl_is_default(tcx, impl_id) {
+            if !is_implemented && tcx.impl_defaultness(impl_id).is_final() {
                 if !trait_item.defaultness.has_value() {
                     missing_items.push(*trait_item);
                 }
@@ -3439,8 +3442,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     // In that case, fallback to Error.
     // The return value indicates whether fallback has occurred.
     fn fallback_if_possible(&self, ty: Ty<'tcx>, mode: FallbackMode) -> bool {
-        use rustc::ty::error::UnconstrainedNumeric::Neither;
-        use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
+        use rustc_middle::ty::error::UnconstrainedNumeric::Neither;
+        use rustc_middle::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
 
         assert!(ty.is_ty_infer());
         let fallback = match self.type_is_unconstrained_numeric(ty) {
diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
index 657926a1825..cac9113fd5d 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/src/librustc_typeck/check/op.rs
@@ -2,13 +2,15 @@
 
 use super::method::MethodCallee;
 use super::{FnCtxt, Needs};
-use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
-use rustc::ty::TyKind::{Adt, Array, Char, FnDef, Never, Ref, Str, Tuple, Uint};
-use rustc::ty::{self, Ty, TypeFoldable};
 use rustc_ast::ast::Ident;
 use rustc_errors::{self, struct_span_err, Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use rustc_middle::ty::adjustment::{
+    Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
+};
+use rustc_middle::ty::TyKind::{Adt, Array, Char, FnDef, Never, Ref, Str, Tuple, Uint};
+use rustc_middle::ty::{self, Ty, TypeFoldable};
 use rustc_span::Span;
 use rustc_trait_selection::infer::InferCtxtExt;
 
@@ -479,7 +481,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// 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<'_>,
@@ -512,24 +514,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 .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/pat.rs b/src/librustc_typeck/check/pat.rs
index ec703d5ec9e..b3cace8298a 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -1,6 +1,4 @@
 use crate::check::FnCtxt;
-use rustc::ty::subst::GenericArg;
-use rustc::ty::{self, BindingMode, Ty, TypeFoldable};
 use rustc_ast::ast;
 use rustc_ast::util::lev_distance::find_best_match_for_name;
 use rustc_data_structures::fx::FxHashMap;
@@ -11,6 +9,8 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator;
 use rustc_hir::{HirId, Pat, PatKind};
 use rustc_infer::infer;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use rustc_middle::ty::subst::GenericArg;
+use rustc_middle::ty::{self, BindingMode, Ty, TypeFoldable};
 use rustc_span::hygiene::DesugaringKind;
 use rustc_span::source_map::{Span, Spanned};
 use rustc_trait_selection::traits::{ObligationCause, Pattern};
@@ -1355,16 +1355,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) -> Ty<'tcx> {
         let err = self.tcx.types.err;
         let expected = self.structurally_resolved_type(span, expected);
-        let (inner_ty, slice_ty, expected) = match expected.kind {
+        let (element_ty, slice_ty, inferred) = match expected.kind {
             // An array, so we might have something like `let [a, b, c] = [0, 1, 2];`.
-            ty::Array(inner_ty, len) => {
+            ty::Array(element_ty, len) => {
                 let min = before.len() as u64 + after.len() as u64;
-                let slice_ty = self
-                    .check_array_pat_len(span, slice, len, min)
-                    .map_or(err, |len| self.tcx.mk_array(inner_ty, len));
-                (inner_ty, slice_ty, expected)
+                let (slice_ty, expected) =
+                    self.check_array_pat_len(span, element_ty, expected, slice, len, min);
+                (element_ty, slice_ty, expected)
             }
-            ty::Slice(inner_ty) => (inner_ty, expected, expected),
+            ty::Slice(element_ty) => (element_ty, expected, expected),
             // The expected type must be an array or slice, but was neither, so error.
             _ => {
                 if !expected.references_error() {
@@ -1376,7 +1375,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Type check all the patterns before `slice`.
         for elt in before {
-            self.check_pat(&elt, inner_ty, def_bm, ti);
+            self.check_pat(&elt, element_ty, def_bm, ti);
         }
         // Type check the `slice`, if present, against its expected type.
         if let Some(slice) = slice {
@@ -1384,22 +1383,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
         // Type check the elements after `slice`, if present.
         for elt in after {
-            self.check_pat(&elt, inner_ty, def_bm, ti);
+            self.check_pat(&elt, element_ty, def_bm, ti);
         }
-        expected
+        inferred
     }
 
     /// Type check the length of an array pattern.
     ///
-    /// Return the length of the variable length pattern,
-    /// if it exists and there are no errors.
+    /// Returns both the type of the variable length pattern
+    /// (or `tcx.err` in case there is none),
+    /// and the potentially inferred array type.
     fn check_array_pat_len(
         &self,
         span: Span,
+        element_ty: Ty<'tcx>,
+        arr_ty: Ty<'tcx>,
         slice: Option<&'tcx Pat<'tcx>>,
         len: &ty::Const<'tcx>,
         min_len: u64,
-    ) -> Option<u64> {
+    ) -> (Ty<'tcx>, Ty<'tcx>) {
         if let Some(len) = len.try_eval_usize(self.tcx, self.param_env) {
             // Now we know the length...
             if slice.is_none() {
@@ -1409,21 +1411,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if min_len != len {
                     self.error_scrutinee_inconsistent_length(span, min_len, len);
                 }
-            } else if let r @ Some(_) = len.checked_sub(min_len) {
+            } else if let Some(pat_len) = len.checked_sub(min_len) {
                 // The variable-length pattern was there,
                 // so it has an array type with the remaining elements left as its size...
-                return r;
+                return (self.tcx.mk_array(element_ty, pat_len), arr_ty);
             } else {
                 // ...however, in this case, there were no remaining elements.
                 // That is, the slice pattern requires more than the array type offers.
                 self.error_scrutinee_with_rest_inconsistent_length(span, min_len, len);
             }
+        } else if slice.is_none() {
+            // We have a pattern with a fixed length,
+            // which we can use to infer the length of the array.
+            let updated_arr_ty = self.tcx.mk_array(element_ty, min_len);
+            self.demand_eqtype(span, updated_arr_ty, arr_ty);
+            return (self.tcx.types.err, updated_arr_ty);
         } else {
-            // No idea what the length is, which happens if we have e.g.,
-            // `let [a, b] = arr` where `arr: [T; N]` where `const N: usize`.
+            // We have a variable-length pattern and don't know the array length.
+            // This happens if we have e.g.,
+            // `let [a, b, ..] = arr` where `arr: [T; N]` where `const N: usize`.
             self.error_scrutinee_unfixed_length(span);
         }
-        None
+        (self.tcx.types.err, arr_ty)
     }
 
     fn error_scrutinee_inconsistent_length(&self, span: Span, min_len: u64, size: u64) {
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index a1345895689..393f9f8bdfb 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -76,15 +76,15 @@ use crate::check::dropck;
 use crate::check::FnCtxt;
 use crate::mem_categorization as mc;
 use crate::middle::region;
-use rustc::ty::adjustment;
-use rustc::ty::subst::{GenericArgKind, SubstsRef};
-use rustc::ty::{self, Ty};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::PatKind;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{self, RegionObligation, RegionckMode};
+use rustc_middle::ty::adjustment;
+use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
+use rustc_middle::ty::{self, Ty};
 use rustc_span::Span;
 use rustc_trait_selection::infer::OutlivesEnvironmentExt;
 use rustc_trait_selection::opaque_types::InferCtxtExt;
diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs
index ff4e2cdab78..c6c11ee9d9b 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/src/librustc_typeck/check/upvar.rs
@@ -35,7 +35,6 @@ use super::FnCtxt;
 use crate::expr_use_visitor as euv;
 use crate::mem_categorization as mc;
 use crate::mem_categorization::PlaceBase;
-use rustc::ty::{self, Ty, TyCtxt, UpvarSubsts};
 use rustc_ast::ast;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_hir as hir;
@@ -43,6 +42,7 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_infer::infer::UpvarRegion;
+use rustc_middle::ty::{self, Ty, TyCtxt, UpvarSubsts};
 use rustc_span::Span;
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index c89c4b028b4..30a53cbc397 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -1,19 +1,19 @@
 use crate::check::{FnCtxt, Inherited};
 use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
 
-use rustc::middle::lang_items;
-use rustc::ty::subst::{InternalSubsts, Subst};
-use rustc::ty::trait_def::TraitSpecializationKind;
-use rustc::ty::{
-    self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
-};
 use rustc_ast::ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
 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::ty::subst::{InternalSubsts, Subst};
+use rustc_middle::ty::trait_def::TraitSpecializationKind;
+use rustc_middle::ty::{
+    self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
+};
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index 65f81ef033d..2b2ebb3135f 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -4,15 +4,15 @@
 
 use crate::check::FnCtxt;
 
-use rustc::ty::adjustment::{Adjust, Adjustment, PointerCast};
-use rustc::ty::fold::{TypeFoldable, TypeFolder};
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_data_structures::sync::Lrc;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefIdSet;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
 use rustc_infer::infer::InferCtxt;
+use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
+use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 use rustc_trait_selection::opaque_types::InferCtxtExt;
@@ -213,18 +213,17 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
 
                     tables.adjustments_mut().get_mut(base.hir_id).map(|a| {
                         // Discard the need for a mutable borrow
-                        match a.pop() {
-                            // Extra adjustment made when indexing causes a drop
-                            // of size information - we need to get rid of it
-                            // Since this is "after" the other adjustment to be
-                            // discarded, we do an extra `pop()`
-                            Some(Adjustment {
-                                kind: Adjust::Pointer(PointerCast::Unsize), ..
-                            }) => {
-                                // So the borrow discard actually happens here
-                                a.pop();
-                            }
-                            _ => {}
+
+                        // Extra adjustment made when indexing causes a drop
+                        // of size information - we need to get rid of it
+                        // Since this is "after" the other adjustment to be
+                        // discarded, we do an extra `pop()`
+                        if let Some(Adjustment {
+                            kind: Adjust::Pointer(PointerCast::Unsize), ..
+                        }) = a.pop()
+                        {
+                            // So the borrow discard actually happens here
+                            a.pop();
                         }
                     });
                 }
diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs
index 9d8113e7b3f..f552b53d8ba 100644
--- a/src/librustc_typeck/check_unused.rs
+++ b/src/librustc_typeck/check_unused.rs
@@ -1,10 +1,10 @@
-use rustc::ty::TyCtxt;
 use rustc_ast::ast;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, DefIdSet, LOCAL_CRATE};
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
+use rustc_middle::ty::TyCtxt;
 use rustc_session::lint;
 use rustc_span::Span;
 
diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs
index c71f2331759..384a22d010e 100644
--- a/src/librustc_typeck/coherence/builtin.rs
+++ b/src/librustc_typeck/coherence/builtin.rs
@@ -1,18 +1,18 @@
 //! Check properties that are required by built-in traits and set
 //! up data structures required by type-checking/codegen.
 
-use rustc::middle::lang_items::UnsizeTraitLangItem;
-use rustc::middle::region;
-use rustc::ty::adjustment::CoerceUnsizedInfo;
-use rustc::ty::TypeFoldable;
-use rustc::ty::{self, Ty, TyCtxt};
 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::region;
+use rustc_middle::ty::adjustment::CoerceUnsizedInfo;
+use rustc_middle::ty::TypeFoldable;
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
 use rustc_trait_selection::traits::misc::{can_type_implement_copy, CopyImplementationError};
 use rustc_trait_selection::traits::predicate_for_trait_def;
diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs
index c6ee9ab60ab..9ace9f424b7 100644
--- a/src/librustc_typeck/coherence/inherent_impls.rs
+++ b/src/librustc_typeck/coherence/inherent_impls.rs
@@ -7,11 +7,11 @@
 //! `tcx.inherent_impls(def_id)`). That value, however,
 //! is computed by selecting an idea from this table.
 
-use rustc::ty::{self, CrateInherentImpls, TyCtxt};
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
+use rustc_middle::ty::{self, CrateInherentImpls, TyCtxt};
 
 use rustc_ast::ast;
 use rustc_span::Span;
diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/src/librustc_typeck/coherence/inherent_impls_overlap.rs
index 7513759c76b..be77d049cae 100644
--- a/src/librustc_typeck/coherence/inherent_impls_overlap.rs
+++ b/src/librustc_typeck/coherence/inherent_impls_overlap.rs
@@ -1,8 +1,8 @@
-use rustc::ty::TyCtxt;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
+use rustc_middle::ty::TyCtxt;
 use rustc_trait_selection::traits::{self, SkipLeakCheck};
 
 pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, crate_num: CrateNum) {
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index 6ed4f62c4be..0df08b7bc8b 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -5,10 +5,10 @@
 // done by the orphan and overlap modules. Then we build up various
 // mappings. That mapping code resides here.
 
-use rustc::ty::query::Providers;
-use rustc::ty::{self, TyCtxt, TypeFoldable};
 use rustc_errors::struct_span_err;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
 use rustc_span::Span;
 use rustc_trait_selection::traits;
 
diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs
index cc0ad364177..d77f2bd0d8b 100644
--- a/src/librustc_typeck/coherence/orphan.rs
+++ b/src/librustc_typeck/coherence/orphan.rs
@@ -1,11 +1,11 @@
 //! Orphan checker: every impl either implements a trait defined in this
 //! crate or pertains to a type defined in this crate.
 
-use rustc::ty::{self, TyCtxt};
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_infer::infer::TyCtxtInferExt;
+use rustc_middle::ty::{self, TyCtxt};
 use rustc_trait_selection::traits;
 
 pub fn check(tcx: TyCtxt<'_>) {
diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs
index 3b25f67aacc..b281092ea63 100644
--- a/src/librustc_typeck/coherence/unsafety.rs
+++ b/src/librustc_typeck/coherence/unsafety.rs
@@ -1,11 +1,11 @@
 //! Unsafety checker: every impl either implements a trait defined in this
 //! crate or pertains to a type defined in this crate.
 
-use rustc::ty::TyCtxt;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_hir::Unsafety;
+use rustc_middle::ty::TyCtxt;
 
 pub fn check(tcx: TyCtxt<'_>) {
     let mut unsafety = UnsafetyChecker { tcx };
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 31123c5cf02..13c6670f6b2 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -17,18 +17,7 @@
 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::hir::map::blocks::FnLikeNode;
-use rustc::hir::map::Map;
-use rustc::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
-use rustc::mir::mono::Linkage;
-use rustc::ty::query::Providers;
-use rustc::ty::subst::{InternalSubsts, Subst};
-use rustc::ty::util::Discr;
-use rustc::ty::util::IntTypeExt;
-use rustc::ty::{self, AdtKind, Const, ToPolyTraitRef, Ty, TyCtxt};
-use rustc::ty::{ReprOptions, ToPredicate, WithConstness};
 use rustc_ast::ast;
 use rustc_ast::ast::{Ident, MetaItemKind};
 use rustc_attr::{list_contains_name, mark_used, InlineAttr, OptimizeAttr};
@@ -39,7 +28,18 @@ use rustc_hir as hir;
 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;
+use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
+use rustc_middle::mir::mono::Linkage;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::subst::{InternalSubsts, Subst};
+use rustc_middle::ty::util::Discr;
+use rustc_middle::ty::util::IntTypeExt;
+use rustc_middle::ty::{self, AdtKind, Const, ToPolyTraitRef, Ty, TyCtxt};
+use rustc_middle::ty::{ReprOptions, ToPredicate, WithConstness};
 use rustc_session::lint;
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::{kw, sym, Symbol};
@@ -2301,7 +2301,7 @@ fn from_target_feature(
 }
 
 fn linkage_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: &str) -> Linkage {
-    use rustc::mir::mono::Linkage::*;
+    use rustc_middle::mir::mono::Linkage::*;
 
     // Use the names from src/llvm/docs/LangRef.rst here. Most types are only
     // applicable to variable declarations and may not really make sense for
@@ -2569,7 +2569,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
     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 23613caa993..e6099b98dc8 100644
--- a/src/librustc_typeck/collect/type_of.rs
+++ b/src/librustc_typeck/collect/type_of.rs
@@ -1,7 +1,3 @@
-use rustc::hir::map::Map;
-use rustc::ty::subst::{GenericArgKind, InternalSubsts, Subst};
-use rustc::ty::util::IntTypeExt;
-use rustc::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{struct_span_err, Applicability, StashKey};
 use rustc_hir as hir;
@@ -10,6 +6,10 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit;
 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::util::IntTypeExt;
+use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable};
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::{Span, DUMMY_SP};
@@ -655,7 +655,11 @@ fn infer_placeholder_type(
         }
     }
 
-    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/constrained_generic_params.rs b/src/librustc_typeck/constrained_generic_params.rs
index b16aa6ff3b2..07ff3bc85cc 100644
--- a/src/librustc_typeck/constrained_generic_params.rs
+++ b/src/librustc_typeck/constrained_generic_params.rs
@@ -1,6 +1,6 @@
-use rustc::ty::fold::{TypeFoldable, TypeVisitor};
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashSet;
+use rustc_middle::ty::fold::{TypeFoldable, TypeVisitor};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::source_map::Span;
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
diff --git a/src/librustc_typeck/expr_use_visitor.rs b/src/librustc_typeck/expr_use_visitor.rs
index 4eb6a6bda02..b6d7309f86a 100644
--- a/src/librustc_typeck/expr_use_visitor.rs
+++ b/src/librustc_typeck/expr_use_visitor.rs
@@ -7,12 +7,12 @@ pub use self::ConsumeMode::*;
 // Export these here so that Clippy can use them.
 pub use mc::{Place, PlaceBase, Projection};
 
-use rustc::ty::{self, adjustment, TyCtxt};
 use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::DefId;
 use rustc_hir::PatKind;
 use rustc_infer::infer::InferCtxt;
+use rustc_middle::ty::{self, adjustment, TyCtxt};
 
 use crate::mem_categorization as mc;
 use rustc_span::Span;
diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs
index 42cb4fcf85d..0635ad5babc 100644
--- a/src/librustc_typeck/impl_wf_check.rs
+++ b/src/librustc_typeck/impl_wf_check.rs
@@ -11,13 +11,13 @@
 use crate::constrained_generic_params as cgp;
 use min_specialization::check_min_specialization;
 
-use rustc::ty::query::Providers;
-use rustc::ty::{self, TyCtxt, TypeFoldable};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
 use rustc_span::Span;
 
 use std::collections::hash_map::Entry::{Occupied, Vacant};
diff --git a/src/librustc_typeck/impl_wf_check/min_specialization.rs b/src/librustc_typeck/impl_wf_check/min_specialization.rs
index ef94500f5c4..559e478df06 100644
--- a/src/librustc_typeck/impl_wf_check/min_specialization.rs
+++ b/src/librustc_typeck/impl_wf_check/min_specialization.rs
@@ -67,16 +67,16 @@
 
 use crate::constrained_generic_params as cgp;
 
-use rustc::middle::region::ScopeTree;
-use rustc::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
-use rustc::ty::trait_def::TraitSpecializationKind;
-use rustc::ty::{self, InstantiatedPredicates, TyCtxt, TypeFoldable};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{InferCtxt, RegionckMode, TyCtxtInferExt};
 use rustc_infer::traits::specialization_graph::Node;
+use rustc_middle::middle::region::ScopeTree;
+use rustc_middle::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
+use rustc_middle::ty::trait_def::TraitSpecializationKind;
+use rustc_middle::ty::{self, InstantiatedPredicates, TyCtxt, TypeFoldable};
 use rustc_span::Span;
 use rustc_trait_selection::traits::{self, translate_substs, wf};
 
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index fd854c75018..7ea6c1c1786 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -72,7 +72,7 @@ This API is completely unstable and subject to change.
 extern crate log;
 
 #[macro_use]
-extern crate rustc;
+extern crate rustc_middle;
 
 // This is used by Clippy.
 pub mod expr_use_visitor;
@@ -89,18 +89,17 @@ mod outlives;
 mod structured_errors;
 mod variance;
 
-use rustc::middle;
-use rustc::ty::query::Providers;
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::{self, Ty, TyCtxt};
-use rustc::util;
-use rustc::util::common::ErrorReported;
-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;
 use rustc_infer::infer::{InferOk, TyCtxtInferExt};
 use rustc_infer::traits::TraitEngineExt as _;
+use rustc_middle::middle;
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::subst::SubstsRef;
+use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::util;
 use rustc_session::config::EntryFnType;
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::spec::abi::Abi;
diff --git a/src/librustc_typeck/mem_categorization.rs b/src/librustc_typeck/mem_categorization.rs
index e76c67794e7..47f61290f5f 100644
--- a/src/librustc_typeck/mem_categorization.rs
+++ b/src/librustc_typeck/mem_categorization.rs
@@ -48,9 +48,9 @@
 //! result of `*x'`, effectively, where `x'` is a `Categorization::Upvar` reference
 //! tied to `x`. The type of `x'` will be a borrowed pointer.
 
-use rustc::ty::adjustment;
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::adjustment;
+use rustc_middle::ty::fold::TypeFoldable;
+use rustc_middle::ty::{self, Ty, TyCtxt};
 
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_hir as hir;
diff --git a/src/librustc_typeck/outlives/explicit.rs b/src/librustc_typeck/outlives/explicit.rs
index 7500c39cf21..168f2077147 100644
--- a/src/librustc_typeck/outlives/explicit.rs
+++ b/src/librustc_typeck/outlives/explicit.rs
@@ -1,6 +1,6 @@
-use rustc::ty::{self, OutlivesPredicate, TyCtxt};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty::{self, OutlivesPredicate, TyCtxt};
 
 use super::utils::*;
 
diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/src/librustc_typeck/outlives/implicit_infer.rs
index 44473fee643..df7c535ff3b 100644
--- a/src/librustc_typeck/outlives/implicit_infer.rs
+++ b/src/librustc_typeck/outlives/implicit_infer.rs
@@ -1,10 +1,10 @@
-use rustc::ty::subst::{GenericArg, GenericArgKind, Subst};
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_hir::Node;
+use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::Span;
 
 use super::explicit::ExplicitPredicatesMap;
diff --git a/src/librustc_typeck/outlives/mod.rs b/src/librustc_typeck/outlives/mod.rs
index f7b6e0fce5a..2d9b39a7f61 100644
--- a/src/librustc_typeck/outlives/mod.rs
+++ b/src/librustc_typeck/outlives/mod.rs
@@ -1,9 +1,9 @@
 use hir::Node;
-use rustc::ty::query::Providers;
-use rustc::ty::subst::GenericArgKind;
-use rustc::ty::{self, CratePredicatesMap, TyCtxt};
 use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::subst::GenericArgKind;
+use rustc_middle::ty::{self, CratePredicatesMap, TyCtxt};
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 
diff --git a/src/librustc_typeck/outlives/test.rs b/src/librustc_typeck/outlives/test.rs
index 980d58ad939..655f938493a 100644
--- a/src/librustc_typeck/outlives/test.rs
+++ b/src/librustc_typeck/outlives/test.rs
@@ -1,7 +1,7 @@
-use rustc::ty::TyCtxt;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::sym;
 
 pub fn test_inferred_outlives(tcx: TyCtxt<'_>) {
diff --git a/src/librustc_typeck/outlives/utils.rs b/src/librustc_typeck/outlives/utils.rs
index e1bd78e5113..3bbe3e34a6a 100644
--- a/src/librustc_typeck/outlives/utils.rs
+++ b/src/librustc_typeck/outlives/utils.rs
@@ -1,6 +1,6 @@
-use rustc::ty::outlives::Component;
-use rustc::ty::subst::{GenericArg, GenericArgKind};
-use rustc::ty::{self, Region, RegionKind, Ty, TyCtxt};
+use rustc_middle::ty::outlives::Component;
+use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
+use rustc_middle::ty::{self, Region, RegionKind, Ty, TyCtxt};
 use rustc_span::Span;
 use smallvec::smallvec;
 use std::collections::BTreeMap;
diff --git a/src/librustc_typeck/structured_errors.rs b/src/librustc_typeck/structured_errors.rs
index a4f8472ae28..83125a3e2fe 100644
--- a/src/librustc_typeck/structured_errors.rs
+++ b/src/librustc_typeck/structured_errors.rs
@@ -1,5 +1,5 @@
-use rustc::ty::{Ty, TypeFoldable};
 use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId};
+use rustc_middle::ty::{Ty, TypeFoldable};
 use rustc_session::Session;
 use rustc_span::Span;
 
diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs
index 11612066d44..2871fa606b5 100644
--- a/src/librustc_typeck/variance/constraints.rs
+++ b/src/librustc_typeck/variance/constraints.rs
@@ -4,10 +4,10 @@
 //! We walk the set of items and, for each member, generate new constraints.
 
 use hir::def_id::DefId;
-use rustc::ty::subst::{GenericArgKind, SubstsRef};
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_hir as hir;
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
+use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 
 use super::terms::VarianceTerm::*;
 use super::terms::*;
diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs
index 3cbb42bb5f3..47652b7b696 100644
--- a/src/librustc_typeck/variance/mod.rs
+++ b/src/librustc_typeck/variance/mod.rs
@@ -4,10 +4,10 @@
 //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/variance.html
 
 use hir::Node;
-use rustc::ty::query::Providers;
-use rustc::ty::{self, CrateVariancesMap, TyCtxt};
 use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
+use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::{self, CrateVariancesMap, TyCtxt};
 
 /// Defines the `TermsContext` basically houses an arena where we can
 /// allocate terms.
diff --git a/src/librustc_typeck/variance/solve.rs b/src/librustc_typeck/variance/solve.rs
index e285f44123a..4fc46ce93ee 100644
--- a/src/librustc_typeck/variance/solve.rs
+++ b/src/librustc_typeck/variance/solve.rs
@@ -5,9 +5,9 @@
 //! optimal solution to the constraints. The final variance for each
 //! inferred is then written into the `variance_map` in the tcx.
 
-use rustc::ty;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty;
 
 use super::constraints::*;
 use super::terms::VarianceTerm::*;
diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs
index 7e6ec96b379..e3ea0bf20e3 100644
--- a/src/librustc_typeck/variance/terms.rs
+++ b/src/librustc_typeck/variance/terms.rs
@@ -10,10 +10,10 @@
 // a variable.
 
 use arena::TypedArena;
-use rustc::ty::{self, TyCtxt};
 use rustc_hir as hir;
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_hir::HirIdMap;
+use rustc_middle::ty::{self, TyCtxt};
 use std::fmt;
 
 use self::VarianceTerm::*;
diff --git a/src/librustc_typeck/variance/test.rs b/src/librustc_typeck/variance/test.rs
index ee94b1015a1..a25252ccd3d 100644
--- a/src/librustc_typeck/variance/test.rs
+++ b/src/librustc_typeck/variance/test.rs
@@ -1,7 +1,7 @@
-use rustc::ty::TyCtxt;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::sym;
 
 pub fn test_variance(tcx: TyCtxt<'_>) {
diff --git a/src/librustc_typeck/variance/xform.rs b/src/librustc_typeck/variance/xform.rs
index aed0dfca91a..027f0859fcd 100644
--- a/src/librustc_typeck/variance/xform.rs
+++ b/src/librustc_typeck/variance/xform.rs
@@ -1,4 +1,4 @@
-use rustc::ty;
+use rustc_middle::ty;
 
 pub fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance {
     // Greatest lower bound of the variance lattice as
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index c85b21a5500..73df844a91b 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -1,6 +1,7 @@
-use rustc::ty::{self, Region, RegionVid, TypeFoldable};
 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};
 
 use std::fmt::Debug;
@@ -497,11 +498,8 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                     // of the type.
                     // Therefore, we make sure that we never add a ?Sized
                     // bound for projections
-                    match &ty {
-                        &Type::QPath { .. } => {
-                            has_sized.insert(ty.clone());
-                        }
-                        _ => {}
+                    if let Type::QPath { .. } = ty {
+                        has_sized.insert(ty.clone());
                     }
 
                     if bounds.is_empty() {
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index e66f8697717..d987505e427 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -1,10 +1,10 @@
 use crate::rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
-use rustc::ty::subst::Subst;
-use rustc::ty::{ToPredicate, WithConstness};
 use rustc_hir as hir;
 use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_infer::infer::{InferOk, TyCtxtInferExt};
 use rustc_infer::traits;
+use rustc_middle::ty::subst::Subst;
+use rustc_middle::ty::{ToPredicate, WithConstness};
 use rustc_span::DUMMY_SP;
 
 use super::*;
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 510eae82834..0906d2f3845 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -2,7 +2,6 @@
 
 use std::iter::once;
 
-use rustc::ty;
 use rustc_ast::ast;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
@@ -10,6 +9,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::Mutability;
 use rustc_metadata::creader::LoadedMacro;
+use rustc_middle::ty;
 use rustc_mir::const_eval::is_min_const_fn;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::Span;
@@ -20,7 +20,7 @@ use crate::doctree;
 
 use super::Clean;
 
-type Attrs<'hir> = rustc::ty::Attributes<'hir>;
+type Attrs<'hir> = rustc_middle::ty::Attributes<'hir>;
 
 /// Attempt to inline a definition into this AST.
 ///
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 7dfcf0a637e..e027db8b56c 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -9,12 +9,6 @@ mod simplify;
 pub mod types;
 pub mod utils;
 
-use rustc::middle::lang_items;
-use rustc::middle::resolve_lifetime as rl;
-use rustc::middle::stability;
-use rustc::ty::fold::TypeFolder;
-use rustc::ty::subst::InternalSubsts;
-use rustc::ty::{self, AdtKind, Lift, Ty, TyCtxt};
 use rustc_ast::ast::{self, Ident};
 use rustc_attr as attr;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -23,6 +17,11 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
 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::resolve_lifetime as rl;
+use rustc_middle::middle::stability;
+use rustc_middle::ty::fold::TypeFolder;
+use rustc_middle::ty::subst::InternalSubsts;
+use rustc_middle::ty::{self, AdtKind, Lift, Ty, TyCtxt};
 use rustc_mir::const_eval::is_min_const_fn;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{kw, sym};
@@ -480,7 +479,7 @@ impl Clean<WherePredicate> for hir::WherePredicate<'_> {
 
 impl<'a> Clean<Option<WherePredicate>> for ty::Predicate<'a> {
     fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
-        use rustc::ty::Predicate;
+        use rustc_middle::ty::Predicate;
 
         match *self {
             Predicate::Trait(ref pred, _) => Some(pred.clean(cx)),
@@ -521,11 +520,8 @@ impl<'tcx> Clean<Option<WherePredicate>>
     fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
         let ty::OutlivesPredicate(ref a, ref b) = *self;
 
-        match (a, b) {
-            (ty::ReEmpty(_), ty::ReEmpty(_)) => {
-                return None;
-            }
-            _ => {}
+        if let (ty::ReEmpty(_), ty::ReEmpty(_)) = (a, b) {
+            return None;
         }
 
         Some(WherePredicate::RegionPredicate {
@@ -539,9 +535,8 @@ impl<'tcx> Clean<Option<WherePredicate>> for ty::OutlivesPredicate<Ty<'tcx>, ty:
     fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
         let ty::OutlivesPredicate(ref ty, ref lt) = *self;
 
-        match lt {
-            ty::ReEmpty(_) => return None,
-            _ => {}
+        if let ty::ReEmpty(_) = lt {
+            return None;
         }
 
         Some(WherePredicate::BoundPredicate {
@@ -2186,7 +2181,7 @@ impl Clean<Vec<Item>> for doctree::ExternCrate<'_> {
                 cx,
                 res,
                 self.name,
-                Some(rustc::ty::Attributes::Borrowed(self.attrs)),
+                Some(rustc_middle::ty::Attributes::Borrowed(self.attrs)),
                 &mut visited,
             ) {
                 return items;
@@ -2239,15 +2234,12 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
         } else {
             let name = self.name;
             if !please_inline {
-                match path.res {
-                    Res::Def(DefKind::Mod, did) => {
-                        if !did.is_local() && did.index == CRATE_DEF_INDEX {
-                            // if we're `pub use`ing an extern crate root, don't inline it unless we
-                            // were specifically asked for it
-                            denied = true;
-                        }
+                if let Res::Def(DefKind::Mod, did) = path.res {
+                    if !did.is_local() && did.index == CRATE_DEF_INDEX {
+                        // if we're `pub use`ing an extern crate root, don't inline it unless we
+                        // were specifically asked for it
+                        denied = true;
                     }
-                    _ => {}
                 }
             }
             if !denied {
@@ -2256,7 +2248,7 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
                     cx,
                     path.res,
                     name,
-                    Some(rustc::ty::Attributes::Borrowed(self.attrs)),
+                    Some(rustc_middle::ty::Attributes::Borrowed(self.attrs)),
                     &mut visited,
                 ) {
                     return items;
@@ -2426,10 +2418,9 @@ impl From<GenericBound> for SimpleBound {
             GenericBound::TraitBound(t, mod_) => match t.trait_ {
                 Type::ResolvedPath { path, param_names, .. } => SimpleBound::TraitBound(
                     path.segments,
-                    param_names.map_or_else(
-                        || Vec::new(),
-                        |v| v.iter().map(|p| SimpleBound::from(p.clone())).collect(),
-                    ),
+                    param_names.map_or_else(Vec::new, |v| {
+                        v.iter().map(|p| SimpleBound::from(p.clone())).collect()
+                    }),
                     t.generic_params,
                     mod_,
                 ),
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index 2b59c60f0b7..1404d45ea89 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -1,7 +1,7 @@
 //! Simplification of where-clauses and parameter bounds into a prettier and
 //! more canonical form.
 //!
-//! Currently all cross-crate-inlined function use `rustc::ty` to reconstruct
+//! Currently all cross-crate-inlined function use `rustc_middle::ty` to reconstruct
 //! the AST (e.g., see all of `clean::inline`), but this is not always a
 //! non-lossy transformation. The current format of storage for where-clauses
 //! for functions and such is simply a list of predicates. One example of this
@@ -14,8 +14,8 @@
 use std::collections::BTreeMap;
 use std::mem;
 
-use rustc::ty;
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty;
 
 use crate::clean;
 use crate::clean::GenericArgs as PP;
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 73f2c399e56..2e5ecacee12 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -8,9 +8,6 @@ use std::rc::Rc;
 use std::sync::Arc;
 use std::{slice, vec};
 
-use rustc::middle::lang_items;
-use rustc::middle::stability;
-use rustc::ty::layout::VariantIdx;
 use rustc_ast::ast::{self, AttrStyle, Ident};
 use rustc_ast::attr;
 use rustc_ast::util::comments::strip_doc_comment_decoration;
@@ -18,12 +15,15 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 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::stability;
 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/clean/utils.rs b/src/librustdoc/clean/utils.rs
index b3bfb559749..9e96015d306 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -9,13 +9,13 @@ use crate::clean::{
 use crate::core::DocContext;
 
 use itertools::Itertools;
-use rustc::mir::interpret::{sign_extend, ConstValue, Scalar};
-use rustc::ty::subst::{GenericArgKind, SubstsRef};
-use rustc::ty::{self, DefIdTree, Ty};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
+use rustc_middle::mir::interpret::{sign_extend, ConstValue, Scalar};
+use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
+use rustc_middle::ty::{self, DefIdTree, Ty};
 use rustc_span::symbol::{kw, sym, Symbol};
 use std::mem;
 
@@ -121,7 +121,7 @@ pub fn external_generic_args(
     let args: Vec<_> = substs
         .iter()
         .filter_map(|kind| match kind.unpack() {
-            GenericArgKind::Lifetime(lt) => lt.clean(cx).map(|lt| GenericArg::Lifetime(lt)),
+            GenericArgKind::Lifetime(lt) => lt.clean(cx).map(GenericArg::Lifetime),
             GenericArgKind::Type(_) if skip_self => {
                 skip_self = false;
                 None
@@ -198,27 +198,24 @@ pub fn get_real_types(
         }) {
             let bounds = where_pred.get_bounds().unwrap_or_else(|| &[]);
             for bound in bounds.iter() {
-                match *bound {
-                    GenericBound::TraitBound(ref poly_trait, _) => {
-                        for x in poly_trait.generic_params.iter() {
-                            if !x.is_type() {
-                                continue;
-                            }
-                            if let Some(ty) = x.get_type() {
-                                let adds = get_real_types(generics, &ty, cx, recurse + 1);
-                                if !adds.is_empty() {
-                                    res.extend(adds);
-                                } else if !ty.is_full_generic() {
-                                    if let Some(did) = ty.def_id() {
-                                        if let Some(kind) = cx.tcx.def_kind(did).clean(cx) {
-                                            res.insert((ty, kind));
-                                        }
+                if let GenericBound::TraitBound(ref poly_trait, _) = *bound {
+                    for x in poly_trait.generic_params.iter() {
+                        if !x.is_type() {
+                            continue;
+                        }
+                        if let Some(ty) = x.get_type() {
+                            let adds = get_real_types(generics, &ty, cx, recurse + 1);
+                            if !adds.is_empty() {
+                                res.extend(adds);
+                            } else if !ty.is_full_generic() {
+                                if let Some(did) = ty.def_id() {
+                                    if let Some(kind) = cx.tcx.def_kind(did).clean(cx) {
+                                        res.insert((ty, kind));
                                     }
                                 }
                             }
                         }
                     }
-                    _ => {}
                 }
             }
         }
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index fe3a9b6b3dc..98f4b592fea 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -1,6 +1,3 @@
-use rustc::middle::cstore::CrateStore;
-use rustc::middle::privacy::AccessLevels;
-use rustc::ty::{Ty, TyCtxt};
 use rustc_ast::ast::CRATE_NODE_ID;
 use rustc_attr as attr;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -12,6 +9,9 @@ use rustc_hir::def::Namespace::TypeNS;
 use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
 use rustc_hir::HirId;
 use rustc_interface::interface;
+use rustc_middle::middle::cstore::CrateStore;
+use rustc_middle::middle::privacy::AccessLevels;
+use rustc_middle::ty::{Ty, TyCtxt};
 use rustc_resolve as resolve;
 use rustc_session::config::ErrorOutputType;
 use rustc_session::lint;
@@ -103,7 +103,7 @@ impl<'tcx> DocContext<'tcx> {
     }
 
     // This is an ugly hack, but it's the simplest way to handle synthetic impls without greatly
-    // refactoring either librustdoc or librustc. In particular, allowing new DefIds to be
+    // refactoring either librustdoc or librustc_middle. In particular, allowing new DefIds to be
     // registered after the AST is constructed would require storing the defid mapping in a
     // RefCell, decreasing the performance for normal compilation for very little gain.
     //
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index e13bf270440..9fe3e35d197 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -448,7 +448,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
         if !self.started {
             self.started = true;
         }
-        while let Some(event) = self.inner.next() {
+        if let Some(event) = self.inner.next() {
             let mut is_start = true;
             let is_allowed_tag = match event {
                 Event::Start(Tag::CodeBlock(_)) | Event::End(Tag::CodeBlock(_)) => {
@@ -944,75 +944,70 @@ crate fn rust_code_blocks(md: &str) -> Vec<RustCodeBlock> {
     let mut p = Parser::new_ext(md, opts()).into_offset_iter();
 
     while let Some((event, offset)) = p.next() {
-        match event {
-            Event::Start(Tag::CodeBlock(syntax)) => {
-                let (syntax, code_start, code_end, range, is_fenced) = match syntax {
-                    CodeBlockKind::Fenced(syntax) => {
-                        let syntax = syntax.as_ref();
-                        let lang_string = if syntax.is_empty() {
-                            LangString::all_false()
-                        } else {
-                            LangString::parse(&*syntax, ErrorCodes::Yes, false)
-                        };
-                        if !lang_string.rust {
+        if let Event::Start(Tag::CodeBlock(syntax)) = event {
+            let (syntax, code_start, code_end, range, is_fenced) = match syntax {
+                CodeBlockKind::Fenced(syntax) => {
+                    let syntax = syntax.as_ref();
+                    let lang_string = if syntax.is_empty() {
+                        LangString::all_false()
+                    } else {
+                        LangString::parse(&*syntax, ErrorCodes::Yes, false)
+                    };
+                    if !lang_string.rust {
+                        continue;
+                    }
+                    let syntax = if syntax.is_empty() { None } else { Some(syntax.to_owned()) };
+                    let (code_start, mut code_end) = match p.next() {
+                        Some((Event::Text(_), offset)) => (offset.start, offset.end),
+                        Some((_, sub_offset)) => {
+                            let code = Range { start: sub_offset.start, end: sub_offset.start };
+                            code_blocks.push(RustCodeBlock {
+                                is_fenced: true,
+                                range: offset,
+                                code,
+                                syntax,
+                            });
                             continue;
                         }
-                        let syntax = if syntax.is_empty() { None } else { Some(syntax.to_owned()) };
-                        let (code_start, mut code_end) = match p.next() {
-                            Some((Event::Text(_), offset)) => (offset.start, offset.end),
-                            Some((_, sub_offset)) => {
-                                let code = Range { start: sub_offset.start, end: sub_offset.start };
-                                code_blocks.push(RustCodeBlock {
-                                    is_fenced: true,
-                                    range: offset,
-                                    code,
-                                    syntax,
-                                });
-                                continue;
-                            }
-                            None => {
-                                let code = Range { start: offset.end, end: offset.end };
-                                code_blocks.push(RustCodeBlock {
-                                    is_fenced: true,
-                                    range: offset,
-                                    code,
-                                    syntax,
-                                });
-                                continue;
-                            }
-                        };
-                        while let Some((Event::Text(_), offset)) = p.next() {
-                            code_end = offset.end;
+                        None => {
+                            let code = Range { start: offset.end, end: offset.end };
+                            code_blocks.push(RustCodeBlock {
+                                is_fenced: true,
+                                range: offset,
+                                code,
+                                syntax,
+                            });
+                            continue;
                         }
-                        (syntax, code_start, code_end, offset, true)
+                    };
+                    while let Some((Event::Text(_), offset)) = p.next() {
+                        code_end = offset.end;
                     }
-                    CodeBlockKind::Indented => {
-                        // The ending of the offset goes too far sometime so we reduce it by one in
-                        // these cases.
-                        if offset.end > offset.start
-                            && md.get(offset.end..=offset.end) == Some(&"\n")
-                        {
-                            (
-                                None,
-                                offset.start,
-                                offset.end,
-                                Range { start: offset.start, end: offset.end - 1 },
-                                false,
-                            )
-                        } else {
-                            (None, offset.start, offset.end, offset, false)
-                        }
+                    (syntax, code_start, code_end, offset, true)
+                }
+                CodeBlockKind::Indented => {
+                    // The ending of the offset goes too far sometime so we reduce it by one in
+                    // these cases.
+                    if offset.end > offset.start && md.get(offset.end..=offset.end) == Some(&"\n") {
+                        (
+                            None,
+                            offset.start,
+                            offset.end,
+                            Range { start: offset.start, end: offset.end - 1 },
+                            false,
+                        )
+                    } else {
+                        (None, offset.start, offset.end, offset, false)
                     }
-                };
+                }
+            };
 
-                code_blocks.push(RustCodeBlock {
-                    is_fenced,
-                    range,
-                    code: Range { start: code_start, end: code_end },
-                    syntax,
-                });
-            }
-            _ => (),
+            code_blocks.push(RustCodeBlock {
+                is_fenced,
+                range,
+                code: Range { start: code_start, end: code_end },
+                syntax,
+            });
         }
     }
 
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index eb7a367acf4..f51f47a8d33 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -42,8 +42,6 @@ use std::rc::Rc;
 use std::str;
 use std::sync::Arc;
 
-use rustc::middle::privacy::AccessLevels;
-use rustc::middle::stability;
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::flock;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -51,6 +49,8 @@ use rustc_feature::UnstableFeatures;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::Mutability;
+use rustc_middle::middle::privacy::AccessLevels;
+use rustc_middle::middle::stability;
 use rustc_span::edition::Edition;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::source_map::FileName;
@@ -782,7 +782,7 @@ themePicker.onblur = handleThemeButtonsBlur;
                         .split('"')
                         .next()
                         .map(|s| s.to_owned())
-                        .unwrap_or_else(|| String::new()),
+                        .unwrap_or_else(String::new),
                 );
             }
         }
@@ -2158,7 +2158,7 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
                     docs = MarkdownSummaryLine(doc_value, &myitem.links()).to_string(),
                     class = myitem.type_(),
                     add = add,
-                    stab = stab.unwrap_or_else(|| String::new()),
+                    stab = stab.unwrap_or_else(String::new),
                     unsafety_flag = unsafety_flag,
                     href = item_path(myitem.type_(), myitem.name.as_ref().unwrap()),
                     title = [full_path(cx, myitem), myitem.type_().to_string()]
@@ -4593,12 +4593,9 @@ fn collect_paths_for_type(first_ty: clean::Type) -> Vec<String> {
                 let get_extern = || cache.external_paths.get(&did).map(|s| s.0.clone());
                 let fqp = cache.exact_paths.get(&did).cloned().or_else(get_extern);
 
-                match fqp {
-                    Some(path) => {
-                        out.push(path.join("::"));
-                    }
-                    _ => {}
-                };
+                if let Some(path) = fqp {
+                    out.push(path.join("::"));
+                }
             }
             clean::Type::Tuple(tys) => {
                 work.extend(tys.into_iter());
diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs
index b93738319a6..d9f6f7b466a 100644
--- a/src/librustdoc/html/render/cache.rs
+++ b/src/librustdoc/html/render/cache.rs
@@ -1,8 +1,8 @@
 use crate::clean::{self, AttributesExt, GetDefId};
 use crate::fold::DocFolder;
-use rustc::middle::privacy::AccessLevels;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
+use rustc_middle::middle::privacy::AccessLevels;
 use rustc_span::source_map::FileName;
 use rustc_span::symbol::sym;
 use std::collections::BTreeMap;
@@ -590,7 +590,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
     for item in search_index {
         item.parent_idx = item.parent.and_then(|defid| {
             if defid_to_pathid.contains_key(&defid) {
-                defid_to_pathid.get(&defid).map(|x| *x)
+                defid_to_pathid.get(&defid).copied()
             } else {
                 let pathid = lastpathid;
                 defid_to_pathid.insert(defid, pathid);
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 3c5df0247c1..99860a103d7 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -16,7 +16,6 @@
 
 extern crate env_logger;
 extern crate getopts;
-extern crate rustc;
 extern crate rustc_ast;
 extern crate rustc_ast_pretty;
 extern crate rustc_attr;
@@ -33,6 +32,7 @@ extern crate rustc_interface;
 extern crate rustc_lexer;
 extern crate rustc_lint;
 extern crate rustc_metadata;
+extern crate rustc_middle;
 extern crate rustc_mir;
 extern crate rustc_parse;
 extern crate rustc_resolve;
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 2525773f0ed..a6b24d49a83 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1,4 +1,3 @@
-use rustc::ty;
 use rustc_ast::ast::{self, Ident};
 use rustc_errors::Applicability;
 use rustc_expand::base::SyntaxExtensionKind;
@@ -10,6 +9,7 @@ use rustc_hir::def::{
     PerNS, Res,
 };
 use rustc_hir::def_id::DefId;
+use rustc_middle::ty;
 use rustc_resolve::ParentScope;
 use rustc_session::lint;
 use rustc_span::symbol::Symbol;
@@ -880,7 +880,7 @@ fn handle_variant(
     res: Res,
     extra_fragment: &Option<String>,
 ) -> Result<(Res, Option<String>), ErrorKind> {
-    use rustc::ty::DefIdTree;
+    use rustc_middle::ty::DefIdTree;
 
     if extra_fragment.is_some() {
         return Err(ErrorKind::AnchorFailure("variants cannot be followed by anchors"));
diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs
index 38f371783e9..1afa9c7a268 100644
--- a/src/librustdoc/passes/mod.rs
+++ b/src/librustdoc/passes/mod.rs
@@ -1,8 +1,8 @@
 //! Contains information about "passes", used to modify crate information during the documentation
 //! process.
 
-use rustc::middle::privacy::AccessLevels;
 use rustc_hir::def_id::{DefId, DefIdSet};
+use rustc_middle::middle::privacy::AccessLevels;
 use rustc_session::lint;
 use rustc_span::{InnerSpan, Span, DUMMY_SP};
 use std::mem;
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 93305a1f87a..7841d5eef58 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -1,18 +1,19 @@
-use rustc::hir::map::Map;
-use rustc::util::common::ErrorReported;
 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_session::{self, config, DiagnosticOutput, Session};
 use rustc_span::edition::Edition;
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::sym;
 use rustc_span::{BytePos, FileName, Pos, Span, DUMMY_SP};
 use rustc_target::spec::TargetTriple;
+use std::collections::HashMap;
 use std::env;
 use std::io::{self, Write};
 use std::panic;
@@ -190,10 +191,23 @@ enum TestFailure {
     UnexpectedRunPass,
 }
 
+enum DirState {
+    Temp(tempfile::TempDir),
+    Perm(PathBuf),
+}
+
+impl DirState {
+    fn path(&self) -> &std::path::Path {
+        match self {
+            DirState::Temp(t) => t.path(),
+            DirState::Perm(p) => p.as_path(),
+        }
+    }
+}
+
 fn run_test(
     test: &str,
     cratename: &str,
-    filename: &FileName,
     line: usize,
     options: Options,
     should_panic: bool,
@@ -206,47 +220,11 @@ fn run_test(
     mut error_codes: Vec<String>,
     opts: &TestOptions,
     edition: Edition,
+    outdir: DirState,
+    path: PathBuf,
 ) -> Result<(), TestFailure> {
     let (test, line_offset) = make_test(test, Some(cratename), as_test_harness, opts, edition);
 
-    // FIXME(#44940): if doctests ever support path remapping, then this filename
-    // needs to be the result of `SourceMap::span_to_unmapped_path`.
-    let path = match filename {
-        FileName::Real(path) => path.clone(),
-        _ => PathBuf::from(r"doctest.rs"),
-    };
-
-    enum DirState {
-        Temp(tempfile::TempDir),
-        Perm(PathBuf),
-    }
-
-    impl DirState {
-        fn path(&self) -> &std::path::Path {
-            match self {
-                DirState::Temp(t) => t.path(),
-                DirState::Perm(p) => p.as_path(),
-            }
-        }
-    }
-
-    let outdir = if let Some(mut path) = options.persist_doctests {
-        path.push(format!(
-            "{}_{}",
-            filename.to_string().rsplit('/').next().unwrap().replace(".", "_"),
-            line
-        ));
-        std::fs::create_dir_all(&path).expect("Couldn't create directory for doctest executables");
-
-        DirState::Perm(path)
-    } else {
-        DirState::Temp(
-            TempFileBuilder::new()
-                .prefix("rustdoctest")
-                .tempdir()
-                .expect("rustdoc needs a tempdir"),
-        )
-    };
     let output_file = outdir.path().join("rust_out");
 
     let rustc_binary = options
@@ -639,6 +617,7 @@ pub struct Collector {
     position: Span,
     source_map: Option<Lrc<SourceMap>>,
     filename: Option<PathBuf>,
+    visited_tests: HashMap<(String, usize), usize>,
 }
 
 impl Collector {
@@ -662,6 +641,7 @@ impl Collector {
             position: DUMMY_SP,
             source_map,
             filename,
+            visited_tests: HashMap::new(),
         }
     }
 
@@ -705,6 +685,48 @@ impl Tester for Collector {
         let target = self.options.target.clone();
         let target_str = target.to_string();
 
+        // FIXME(#44940): if doctests ever support path remapping, then this filename
+        // needs to be the result of `SourceMap::span_to_unmapped_path`.
+        let path = match &filename {
+            FileName::Real(path) => path.clone(),
+            _ => PathBuf::from(r"doctest.rs"),
+        };
+
+        let outdir = if let Some(mut path) = options.persist_doctests.clone() {
+            // For example `module/file.rs` would become `module_file_rs`
+            let folder_name = filename
+                .to_string()
+                .chars()
+                .map(|c| if c == '/' || c == '.' { '_' } else { c })
+                .collect::<String>();
+
+            path.push(format!(
+                "{name}_{line}_{number}",
+                name = folder_name,
+                number = {
+                    // Increases the current test number, if this file already
+                    // exists or it creates a new entry with a test number of 0.
+                    self.visited_tests
+                        .entry((folder_name.clone(), line))
+                        .and_modify(|v| *v += 1)
+                        .or_insert(0)
+                },
+                line = line,
+            ));
+
+            std::fs::create_dir_all(&path)
+                .expect("Couldn't create directory for doctest executables");
+
+            DirState::Perm(path)
+        } else {
+            DirState::Temp(
+                TempFileBuilder::new()
+                    .prefix("rustdoctest")
+                    .tempdir()
+                    .expect("rustdoc needs a tempdir"),
+            )
+        };
+
         debug!("creating test {}: {}", name, test);
         self.tests.push(testing::TestDescAndFn {
             desc: testing::TestDesc {
@@ -723,7 +745,6 @@ impl Tester for Collector {
                 let res = run_test(
                     &test,
                     &cratename,
-                    &filename,
                     line,
                     options,
                     config.should_panic,
@@ -736,6 +757,8 @@ impl Tester for Collector {
                     config.error_codes,
                     &opts,
                     edition,
+                    outdir,
+                    path,
                 );
 
                 if let Err(err) = res {
diff --git a/src/librustdoc/theme.rs b/src/librustdoc/theme.rs
index 9dd1d3706ff..c8eb271c807 100644
--- a/src/librustdoc/theme.rs
+++ b/src/librustdoc/theme.rs
@@ -8,18 +8,6 @@ use rustc_errors::Handler;
 #[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 @@ pub fn test_theme_against<P: AsRef<Path>>(
     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/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index e49395c6fd4..bf4c4487927 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -1,14 +1,14 @@
 //! The Rust AST Visitor. Extracts useful information and massages it into a form
 //! usable for `clean`.
 
-use rustc::middle::privacy::AccessLevel;
-use rustc::ty::TyCtxt;
 use rustc_ast::ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::Node;
+use rustc_middle::middle::privacy::AccessLevel;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym};
diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs
index 12ffd6cac81..ea2f5f8abc7 100644
--- a/src/librustdoc/visit_lib.rs
+++ b/src/librustdoc/visit_lib.rs
@@ -1,8 +1,8 @@
-use rustc::middle::privacy::{AccessLevel, AccessLevels};
-use rustc::ty::{TyCtxt, Visibility};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
+use rustc_middle::middle::privacy::{AccessLevel, AccessLevels};
+use rustc_middle::ty::{TyCtxt, Visibility};
 use rustc_span::symbol::sym;
 
 use crate::clean::{AttributesExt, NestedAttributesExt};
diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs
index 25f3ddcbeba..9840cfa4304 100644
--- a/src/libstd/alloc.rs
+++ b/src/libstd/alloc.rs
@@ -61,6 +61,7 @@
 
 #![stable(feature = "alloc_module", since = "1.28.0")]
 
+use core::intrinsics;
 use core::ptr::NonNull;
 use core::sync::atomic::{AtomicPtr, Ordering};
 use core::{mem, ptr};
@@ -138,59 +139,99 @@ pub struct System;
 #[unstable(feature = "allocator_api", issue = "32838")]
 unsafe impl AllocRef for System {
     #[inline]
-    fn alloc(&mut self, layout: Layout) -> Result<(NonNull<u8>, usize), AllocErr> {
-        if layout.size() == 0 {
-            Ok((layout.dangling(), 0))
-        } else {
-            unsafe {
-                NonNull::new(GlobalAlloc::alloc(self, layout))
-                    .ok_or(AllocErr)
-                    .map(|p| (p, layout.size()))
+    fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr> {
+        unsafe {
+            let size = layout.size();
+            if size == 0 {
+                Ok(MemoryBlock { ptr: layout.dangling(), size: 0 })
+            } else {
+                let raw_ptr = match init {
+                    AllocInit::Uninitialized => GlobalAlloc::alloc(self, layout),
+                    AllocInit::Zeroed => GlobalAlloc::alloc_zeroed(self, layout),
+                };
+                let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
+                Ok(MemoryBlock { ptr, size })
             }
         }
     }
 
     #[inline]
-    fn alloc_zeroed(&mut self, layout: Layout) -> Result<(NonNull<u8>, usize), AllocErr> {
-        if layout.size() == 0 {
-            Ok((layout.dangling(), 0))
-        } else {
-            unsafe {
-                NonNull::new(GlobalAlloc::alloc_zeroed(self, layout))
-                    .ok_or(AllocErr)
-                    .map(|p| (p, layout.size()))
-            }
+    unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
+        if layout.size() != 0 {
+            GlobalAlloc::dealloc(self, ptr.as_ptr(), layout)
         }
     }
 
     #[inline]
-    unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
-        if layout.size() != 0 {
-            GlobalAlloc::dealloc(self, ptr.as_ptr(), layout)
+    unsafe fn grow(
+        &mut self,
+        ptr: NonNull<u8>,
+        layout: Layout,
+        new_size: usize,
+        placement: ReallocPlacement,
+        init: AllocInit,
+    ) -> Result<MemoryBlock, AllocErr> {
+        let size = layout.size();
+        debug_assert!(
+            new_size >= size,
+            "`new_size` must be greater than or equal to `memory.size()`"
+        );
+
+        if size == new_size {
+            return Ok(MemoryBlock { ptr, size });
+        }
+
+        match placement {
+            ReallocPlacement::InPlace => Err(AllocErr),
+            ReallocPlacement::MayMove if layout.size() == 0 => {
+                let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
+                self.alloc(new_layout, init)
+            }
+            ReallocPlacement::MayMove => {
+                // `realloc` probably checks for `new_size > size` or something similar.
+                intrinsics::assume(new_size > size);
+                let ptr = GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size);
+                let memory =
+                    MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size };
+                init.init_offset(memory, size);
+                Ok(memory)
+            }
         }
     }
 
     #[inline]
-    unsafe fn realloc(
+    unsafe fn shrink(
         &mut self,
         ptr: NonNull<u8>,
         layout: Layout,
         new_size: usize,
-    ) -> Result<(NonNull<u8>, usize), AllocErr> {
-        match (layout.size(), new_size) {
-            (0, 0) => Ok((layout.dangling(), 0)),
-            (0, _) => self.alloc(Layout::from_size_align_unchecked(new_size, layout.align())),
-            (_, 0) => {
+        placement: ReallocPlacement,
+    ) -> Result<MemoryBlock, AllocErr> {
+        let size = layout.size();
+        debug_assert!(
+            new_size <= size,
+            "`new_size` must be smaller than or equal to `memory.size()`"
+        );
+
+        if size == new_size {
+            return Ok(MemoryBlock { ptr, size });
+        }
+
+        match placement {
+            ReallocPlacement::InPlace => Err(AllocErr),
+            ReallocPlacement::MayMove if new_size == 0 => {
                 self.dealloc(ptr, layout);
-                Ok((layout.dangling(), 0))
+                Ok(MemoryBlock { ptr: layout.dangling(), size: 0 })
+            }
+            ReallocPlacement::MayMove => {
+                // `realloc` probably checks for `new_size < size` or something similar.
+                intrinsics::assume(new_size < size);
+                let ptr = GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size);
+                Ok(MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size })
             }
-            (_, _) => NonNull::new(GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size))
-                .ok_or(AllocErr)
-                .map(|p| (p, new_size)),
         }
     }
 }
-
 static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut());
 
 /// Registers a custom allocation error hook, replacing any that was previously registered.
@@ -238,9 +279,7 @@ pub fn rust_oom(layout: Layout) -> ! {
     let hook: fn(Layout) =
         if hook.is_null() { default_alloc_error_hook } else { unsafe { mem::transmute(hook) } };
     hook(layout);
-    unsafe {
-        crate::sys::abort_internal();
-    }
+    unsafe { crate::sys::abort_internal() }
 }
 
 #[cfg(not(test))]
@@ -250,10 +289,10 @@ pub fn rust_oom(layout: Layout) -> ! {
 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/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/error.rs b/src/libstd/error.rs
index b394f2efc2e..24b57f12e8d 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -15,7 +15,7 @@
 
 use core::array;
 
-use crate::alloc::{AllocErr, CannotReallocInPlace, LayoutErr};
+use crate::alloc::{AllocErr, LayoutErr};
 use crate::any::TypeId;
 use crate::backtrace::Backtrace;
 use crate::borrow::Cow;
@@ -409,13 +409,6 @@ impl Error for AllocErr {}
 )]
 impl Error for LayoutErr {}
 
-#[unstable(
-    feature = "allocator_api",
-    reason = "the precise API and guarantees it provides may be tweaked.",
-    issue = "32838"
-)]
-impl Error for CannotReallocInPlace {}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Error for str::ParseBoolError {
     #[allow(deprecated)]
diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index 20425aea8d5..ac8f305ae91 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -284,7 +284,7 @@ impl f32 {
     /// 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]
@@ -962,7 +962,7 @@ impl f32 {
     /// 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 a1128a589a6..798738e50a7 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -280,7 +280,7 @@ impl f64 {
     /// 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]
@@ -928,7 +928,7 @@ impl f64 {
     /// 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 e20fcfafa22..119bdfcb0f4 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -734,7 +734,7 @@ impl OpenOptions {
     /// 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 @@ impl OpenOptions {
     /// 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 @@ impl OpenOptions {
     /// 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 @@ impl OpenOptions {
     /// 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 @@ impl OpenOptions {
     /// 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 @@ impl OpenOptions {
     /// 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 @@ impl OpenOptions {
     ///                              .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/io/stdio.rs b/src/libstd/io/stdio.rs
index 9a82ae7626d..a064c552c84 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -496,7 +496,7 @@ pub fn stdout() -> Stdout {
         unsafe {
             let ret = Arc::new(ReentrantMutex::new(RefCell::new(LineWriter::new(stdout))));
             ret.init();
-            return ret;
+            ret
         }
     }
 }
@@ -664,7 +664,7 @@ pub fn stderr() -> Stderr {
             *INSTANCE.lock().borrow_mut() = Maybe::Real(stderr);
         }
     });
-    return Stderr { inner: &INSTANCE };
+    Stderr { inner: &INSTANCE }
 }
 
 impl Stderr {
diff --git a/src/libstd/sys/cloudabi/stack_overflow.rs b/src/libstd/sys/cloudabi/stack_overflow.rs
index e97831b2c28..9339b143731 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 3afcae7ae75..a15dc8653e8 100644
--- a/src/libstd/sys/cloudabi/thread.rs
+++ b/src/libstd/sys/cloudabi/thread.rs
@@ -5,7 +5,6 @@ use crate::mem;
 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 @@ unsafe impl Sync for Thread {}
 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 @@ impl Thread {
         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/stack_overflow.rs b/src/libstd/sys/hermit/stack_overflow.rs
index 65a1b17acce..121fe42011d 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 00d760d02e8..8a718a8915b 100644
--- a/src/libstd/sys/hermit/thread.rs
+++ b/src/libstd/sys/hermit/thread.rs
@@ -7,8 +7,6 @@ use crate::sys::hermit::abi;
 use crate::time::Duration;
 use core::u32;
 
-use crate::sys_common::thread::*;
-
 pub type Tid = abi::Tid;
 
 pub struct Thread {
@@ -26,7 +24,7 @@ impl Thread {
         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,
@@ -36,16 +34,19 @@ impl Thread {
             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()>)();
             }
         }
     }
diff --git a/src/libstd/sys/sgx/stack_overflow.rs b/src/libstd/sys/sgx/stack_overflow.rs
index a2d13d11849..b96652a8330 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/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs
index 07d0fbf61fe..f389c60615f 100644
--- a/src/libstd/sys/unix/process/process_unix.rs
+++ b/src/libstd/sys/unix/process/process_unix.rs
@@ -72,7 +72,7 @@ impl Command {
             }
         };
 
-        let mut p = Process { pid: pid, status: None };
+        let mut p = Process { pid, status: None };
         drop(output);
         let mut bytes = [0; 8];
 
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 674d4c71138..aab5a92a7ad 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -3,11 +3,9 @@ use crate::ffi::CStr;
 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 @@ unsafe fn pthread_attr_setstacksize(
 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 @@ impl Thread {
             }
         };
 
-        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 e0d104b5f3e..4d0196e4b4d 100644
--- a/src/libstd/sys/vxworks/thread.rs
+++ b/src/libstd/sys/vxworks/thread.rs
@@ -3,11 +3,9 @@ use crate::ffi::CStr;
 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 @@ unsafe fn pthread_attr_setstacksize(
 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 @@ impl Thread {
             }
         };
 
-        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/wasi/alloc.rs b/src/libstd/sys/wasi/alloc.rs
index e9760d050e1..bc614162784 100644
--- a/src/libstd/sys/wasi/alloc.rs
+++ b/src/libstd/sys/wasi/alloc.rs
@@ -10,7 +10,7 @@ unsafe impl GlobalAlloc for System {
         if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
             libc::malloc(layout.size()) as *mut u8
         } else {
-            libc::aligned_alloc(layout.size(), layout.align()) as *mut u8
+            libc::aligned_alloc(layout.align(), layout.size()) as *mut u8
         }
     }
 
diff --git a/src/libstd/sys/wasm/stack_overflow.rs b/src/libstd/sys/wasm/stack_overflow.rs
index cbf62b6e5b7..32555394cd5 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/handle.rs b/src/libstd/sys/windows/handle.rs
index f2ad057b6b6..d00381792e3 100644
--- a/src/libstd/sys/windows/handle.rs
+++ b/src/libstd/sys/windows/handle.rs
@@ -115,8 +115,7 @@ impl RawHandle {
     ) -> io::Result<Option<usize>> {
         let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
         let mut amt = 0;
-        let res =
-            cvt({ c::ReadFile(self.0, buf.as_ptr() as c::LPVOID, len, &mut amt, overlapped) });
+        let res = cvt(c::ReadFile(self.0, buf.as_ptr() as c::LPVOID, len, &mut amt, overlapped));
         match res {
             Ok(_) => Ok(Some(amt as usize)),
             Err(e) => {
@@ -139,7 +138,7 @@ impl RawHandle {
         unsafe {
             let mut bytes = 0;
             let wait = if wait { c::TRUE } else { c::FALSE };
-            let res = cvt({ c::GetOverlappedResult(self.raw(), overlapped, &mut bytes, wait) });
+            let res = cvt(c::GetOverlappedResult(self.raw(), overlapped, &mut bytes, wait));
             match res {
                 Ok(_) => Ok(bytes as usize),
                 Err(e) => {
diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs
index cc4ae405906..a0da2498bb7 100644
--- a/src/libstd/sys/windows/os.rs
+++ b/src/libstd/sys/windows/os.rs
@@ -94,7 +94,7 @@ impl Iterator for Env {
                 if *self.cur == 0 {
                     return None;
                 }
-                let p = &*self.cur as *const u16;
+                let p = self.cur as *const u16;
                 let mut len = 0;
                 while *p.offset(len) != 0 {
                     len += 1;
diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs
index c828243a59b..38839ea5e90 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 @@ pub struct Thread {
 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 @@ impl Thread {
             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 6ab0d5cbe9c..f3a8bef8f71 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
-Subproject 992e608cfc5d1c126a23c640222fd396a3bdeb9
+Subproject 130721d6f4e6cba3b910ccdf5e0aa62b9dffc95
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 00000000000..ca2df19096e
--- /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/incremental/const-generics/issue-61516.rs b/src/test/incremental/const-generics/issue-61516.rs
index a7465b77267..a193bf998dc 100644
--- a/src/test/incremental/const-generics/issue-61516.rs
+++ b/src/test/incremental/const-generics/issue-61516.rs
@@ -4,7 +4,7 @@
 
 struct FakeArray<T, const N: usize>(T);
 
-impl<T, const N: usize> FakeArray<T, { N }> {
+impl<T, const N: usize> FakeArray<T, N> {
     fn len(&self) -> usize {
         N
     }
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 00000000000..067fa879b40
--- /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 00000000000..bba8bc82fe7
--- /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 abac66d95c5..78a7f722538 100644
--- a/src/test/mir-opt/simplify_try.rs
+++ b/src/test/mir-opt/simplify_try.rs
@@ -183,25 +183,24 @@ fn main() {
 // 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 @@ fn main() {
 //         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 0e6c39e0aff..2875ee57930 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,7 +1,8 @@
 #![feature(rustc_private)]
 
-extern crate rustc;
 extern crate rustc_codegen_ssa;
+extern crate rustc_errors;
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_data_structures;
 extern crate rustc_driver;
@@ -11,14 +12,14 @@ extern crate rustc_span;
 extern crate rustc_symbol_mangling;
 extern crate rustc_target;
 
-use rustc::dep_graph::DepGraph;
-use rustc::middle::cstore::{EncodedMetadata, MetadataLoader, MetadataLoaderDyn};
-use rustc::ty::query::Providers;
-use rustc::ty::TyCtxt;
-use rustc::util::common::ErrorReported;
 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_session::config::OutputFilenames;
 use rustc_session::Session;
 use rustc_span::symbol::Symbol;
diff --git a/src/test/ui-fulldeps/auxiliary/lto-syntax-extension-plugin.rs b/src/test/ui-fulldeps/auxiliary/lto-syntax-extension-plugin.rs
index 89bc9a2b9db..5fbb3efabb3 100644
--- a/src/test/ui-fulldeps/auxiliary/lto-syntax-extension-plugin.rs
+++ b/src/test/ui-fulldeps/auxiliary/lto-syntax-extension-plugin.rs
@@ -3,7 +3,7 @@
 #![feature(plugin_registrar)]
 #![feature(rustc_private)]
 
-extern crate rustc;
+extern crate rustc_middle;
 extern crate rustc_driver;
 
 use rustc_driver::plugin::Registry;
diff --git a/src/test/ui-fulldeps/auxiliary/outlive-expansion-phase.rs b/src/test/ui-fulldeps/auxiliary/outlive-expansion-phase.rs
index e5c4f5b8f7a..6584b905f5e 100644
--- a/src/test/ui-fulldeps/auxiliary/outlive-expansion-phase.rs
+++ b/src/test/ui-fulldeps/auxiliary/outlive-expansion-phase.rs
@@ -3,7 +3,7 @@
 #![feature(plugin_registrar)]
 #![feature(box_syntax, rustc_private)]
 
-extern crate rustc;
+extern crate rustc_middle;
 extern crate rustc_driver;
 
 use std::any::Any;
diff --git a/src/test/ui-fulldeps/auxiliary/rlib-crate-test.rs b/src/test/ui-fulldeps/auxiliary/rlib-crate-test.rs
index 1c0de98da56..e8e8ae2985a 100644
--- a/src/test/ui-fulldeps/auxiliary/rlib-crate-test.rs
+++ b/src/test/ui-fulldeps/auxiliary/rlib-crate-test.rs
@@ -3,7 +3,7 @@
 #![crate_type = "rlib"]
 #![feature(plugin_registrar, rustc_private)]
 
-extern crate rustc;
+extern crate rustc_middle;
 extern crate rustc_driver;
 
 use rustc_driver::plugin::Registry;
diff --git a/src/test/ui-fulldeps/hash-stable-is-unstable.rs b/src/test/ui-fulldeps/hash-stable-is-unstable.rs
index d79ef62c312..d93e21cf791 100644
--- a/src/test/ui-fulldeps/hash-stable-is-unstable.rs
+++ b/src/test/ui-fulldeps/hash-stable-is-unstable.rs
@@ -2,7 +2,7 @@
 
 extern crate rustc_data_structures;
 //~^ use of unstable library feature 'rustc_private'
-extern crate rustc;
+extern crate rustc_middle;
 //~^ use of unstable library feature 'rustc_private'
 extern crate rustc_macros;
 //~^ use of unstable library feature 'rustc_private'
diff --git a/src/test/ui-fulldeps/hash-stable-is-unstable.stderr b/src/test/ui-fulldeps/hash-stable-is-unstable.stderr
index bc5e2d89378..3c30e0402d9 100644
--- a/src/test/ui-fulldeps/hash-stable-is-unstable.stderr
+++ b/src/test/ui-fulldeps/hash-stable-is-unstable.stderr
@@ -10,8 +10,8 @@ LL | extern crate rustc_data_structures;
 error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
   --> $DIR/hash-stable-is-unstable.rs:5:1
    |
-LL | extern crate rustc;
-   | ^^^^^^^^^^^^^^^^^^^
+LL | extern crate rustc_middle;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #27812 <https://github.com/rust-lang/rust/issues/27812> for more information
    = help: add `#![feature(rustc_private)]` to the crate attributes to enable
diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs
index 8d9cbe45fc6..f6f0c038536 100644
--- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs
+++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs
@@ -3,7 +3,7 @@
 #![feature(rustc_private)]
 #![deny(rustc::lint_pass_impl_without_macro)]
 
-extern crate rustc;
+extern crate rustc_middle;
 extern crate rustc_session;
 
 use rustc_session::lint::{LintArray, LintPass};
diff --git a/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref.rs b/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref.rs
index 7564c024580..e0fdbaeac30 100644
--- a/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref.rs
+++ b/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref.rs
@@ -4,9 +4,9 @@
 #![deny(rustc::ty_pass_by_reference)]
 #![allow(unused)]
 
-extern crate rustc;
+extern crate rustc_middle;
 
-use rustc::ty::{Ty, TyCtxt};
+use rustc_middle::ty::{Ty, TyCtxt};
 
 fn ty_by_ref(
     ty_val: Ty<'_>,
diff --git a/src/test/ui-fulldeps/internal-lints/qualified_ty_ty_ctxt.rs b/src/test/ui-fulldeps/internal-lints/qualified_ty_ty_ctxt.rs
index 0040230ec7d..32b987338c0 100644
--- a/src/test/ui-fulldeps/internal-lints/qualified_ty_ty_ctxt.rs
+++ b/src/test/ui-fulldeps/internal-lints/qualified_ty_ty_ctxt.rs
@@ -4,9 +4,9 @@
 #![deny(rustc::usage_of_qualified_ty)]
 #![allow(unused)]
 
-extern crate rustc;
+extern crate rustc_middle;
 
-use rustc::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 
 macro_rules! qualified_macro {
     ($a:ident) => {
diff --git a/src/test/ui-fulldeps/internal-lints/ty_tykind_usage.rs b/src/test/ui-fulldeps/internal-lints/ty_tykind_usage.rs
index f716a78a031..66b594a1b09 100644
--- a/src/test/ui-fulldeps/internal-lints/ty_tykind_usage.rs
+++ b/src/test/ui-fulldeps/internal-lints/ty_tykind_usage.rs
@@ -2,9 +2,9 @@
 
 #![feature(rustc_private)]
 
-extern crate rustc;
+extern crate rustc_middle;
 
-use rustc::ty::{self, Ty, TyKind};
+use rustc_middle::ty::{self, Ty, TyKind};
 
 #[deny(rustc::usage_of_ty_tykind)]
 fn main() {
diff --git a/src/test/ui-fulldeps/pathless-extern-unstable.rs b/src/test/ui-fulldeps/pathless-extern-unstable.rs
index 00b3ec5409f..524b0c2f73a 100644
--- a/src/test/ui-fulldeps/pathless-extern-unstable.rs
+++ b/src/test/ui-fulldeps/pathless-extern-unstable.rs
@@ -1,10 +1,10 @@
 // ignore-stage1
 // edition:2018
-// compile-flags:--extern rustc
+// compile-flags:--extern rustc_middle
 
-// Test that `--extern rustc` fails with `rustc_private`.
+// Test that `--extern rustc_middle` fails with `rustc_private`.
 
-pub use rustc;
+pub use rustc_middle;
 //~^ ERROR use of unstable library feature 'rustc_private'
 
 fn main() {}
diff --git a/src/test/ui-fulldeps/pathless-extern-unstable.stderr b/src/test/ui-fulldeps/pathless-extern-unstable.stderr
index 09f1e600b25..dcc3cddd32c 100644
--- a/src/test/ui-fulldeps/pathless-extern-unstable.stderr
+++ b/src/test/ui-fulldeps/pathless-extern-unstable.stderr
@@ -1,8 +1,8 @@
 error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
   --> $DIR/pathless-extern-unstable.rs:7:9
    |
-LL | pub use rustc;
-   |         ^^^^^
+LL | pub use rustc_middle;
+   |         ^^^^^^^^^^^^
    |
    = note: see issue #27812 <https://github.com/rust-lang/rust/issues/27812> for more information
    = help: add `#![feature(rustc_private)]` to the crate attributes to enable
diff --git a/src/test/ui-fulldeps/undef_mask.rs b/src/test/ui-fulldeps/undef_mask.rs
index 0caccad6229..656d0b451bc 100644
--- a/src/test/ui-fulldeps/undef_mask.rs
+++ b/src/test/ui-fulldeps/undef_mask.rs
@@ -4,10 +4,11 @@
 
 #![feature(rustc_private)]
 
-extern crate rustc;
+extern crate rustc_middle;
+extern crate rustc_target;
 
-use rustc::mir::interpret::UndefMask;
-use rustc::ty::layout::Size;
+use rustc_middle::mir::interpret::UndefMask;
+use rustc_target::abi::Size;
 
 fn main() {
     let mut mask = UndefMask::new(Size::from_bytes(500), false);
diff --git a/src/test/ui/allocator/custom.rs b/src/test/ui/allocator/custom.rs
index c275db14b42..184e4706a4c 100644
--- a/src/test/ui/allocator/custom.rs
+++ b/src/test/ui/allocator/custom.rs
@@ -7,7 +7,7 @@
 
 extern crate helper;
 
-use std::alloc::{self, Global, AllocRef, System, Layout};
+use std::alloc::{self, AllocInit, AllocRef, Global, Layout, System};
 use std::sync::atomic::{AtomicUsize, Ordering};
 
 static HITS: AtomicUsize = AtomicUsize::new(0);
@@ -37,10 +37,10 @@ fn main() {
     unsafe {
         let layout = Layout::from_size_align(4, 2).unwrap();
 
-        let (ptr, _) = Global.alloc(layout.clone()).unwrap();
-        helper::work_with(&ptr);
+        let memory = Global.alloc(layout.clone(), AllocInit::Uninitialized).unwrap();
+        helper::work_with(&memory.ptr);
         assert_eq!(HITS.load(Ordering::SeqCst), n + 1);
-        Global.dealloc(ptr, layout.clone());
+        Global.dealloc(memory.ptr, layout);
         assert_eq!(HITS.load(Ordering::SeqCst), n + 2);
 
         let s = String::with_capacity(10);
@@ -49,10 +49,10 @@ fn main() {
         drop(s);
         assert_eq!(HITS.load(Ordering::SeqCst), n + 4);
 
-        let (ptr, _) = System.alloc(layout.clone()).unwrap();
+        let memory = System.alloc(layout.clone(), AllocInit::Uninitialized).unwrap();
         assert_eq!(HITS.load(Ordering::SeqCst), n + 4);
-        helper::work_with(&ptr);
-        System.dealloc(ptr, layout);
+        helper::work_with(&memory.ptr);
+        System.dealloc(memory.ptr, layout);
         assert_eq!(HITS.load(Ordering::SeqCst), n + 4);
     }
 }
diff --git a/src/test/ui/allocator/xcrate-use.rs b/src/test/ui/allocator/xcrate-use.rs
index e4746d1a7ec..7de1ab7a553 100644
--- a/src/test/ui/allocator/xcrate-use.rs
+++ b/src/test/ui/allocator/xcrate-use.rs
@@ -9,8 +9,8 @@
 extern crate custom;
 extern crate helper;
 
-use std::alloc::{Global, AllocRef, System, Layout};
-use std::sync::atomic::{Ordering, AtomicUsize};
+use std::alloc::{AllocInit, AllocRef, Global, Layout, System};
+use std::sync::atomic::{AtomicUsize, Ordering};
 
 #[global_allocator]
 static GLOBAL: custom::A = custom::A(AtomicUsize::new(0));
@@ -20,16 +20,16 @@ fn main() {
         let n = GLOBAL.0.load(Ordering::SeqCst);
         let layout = Layout::from_size_align(4, 2).unwrap();
 
-        let (ptr, _) = Global.alloc(layout.clone()).unwrap();
-        helper::work_with(&ptr);
+        let memory = Global.alloc(layout.clone(), AllocInit::Uninitialized).unwrap();
+        helper::work_with(&memory.ptr);
         assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 1);
-        Global.dealloc(ptr, layout.clone());
+        Global.dealloc(memory.ptr, layout);
         assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2);
 
-        let (ptr, _) = System.alloc(layout.clone()).unwrap();
+        let memory = System.alloc(layout.clone(), AllocInit::Uninitialized).unwrap();
         assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2);
-        helper::work_with(&ptr);
-        System.dealloc(ptr, layout);
+        helper::work_with(&memory.ptr);
+        System.dealloc(memory.ptr, layout);
         assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2);
     }
 }
diff --git a/src/test/ui/array-slice-vec/infer_array_len.rs b/src/test/ui/array-slice-vec/infer_array_len.rs
new file mode 100644
index 00000000000..22fe7cb8838
--- /dev/null
+++ b/src/test/ui/array-slice-vec/infer_array_len.rs
@@ -0,0 +1,21 @@
+// see issue #70529
+struct A;
+
+impl From<A> for [u8; 2] {
+    fn from(a: A) -> Self {
+        [0; 2]
+    }
+}
+
+impl From<A> for [u8; 3] {
+    fn from(a: A) -> Self {
+        [0; 3]
+    }
+}
+
+
+fn main() {
+    let a = A;
+    let [_, _] = a.into();
+    //~^ ERROR type annotations needed
+}
diff --git a/src/test/ui/array-slice-vec/infer_array_len.stderr b/src/test/ui/array-slice-vec/infer_array_len.stderr
new file mode 100644
index 00000000000..6eed4ce4f0c
--- /dev/null
+++ b/src/test/ui/array-slice-vec/infer_array_len.stderr
@@ -0,0 +1,11 @@
+error[E0282]: type annotations needed
+  --> $DIR/infer_array_len.rs:19:9
+   |
+LL |     let [_, _] = a.into();
+   |         ^^^^^^ consider giving this pattern a type
+   |
+   = note: type must be known at this point
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/array-slice-vec/match_arr_unknown_len.rs b/src/test/ui/array-slice-vec/match_arr_unknown_len.rs
new file mode 100644
index 00000000000..7f3da75ddcb
--- /dev/null
+++ b/src/test/ui/array-slice-vec/match_arr_unknown_len.rs
@@ -0,0 +1,11 @@
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+fn is_123<const N: usize>(x: [u32; N]) -> bool {
+    match x {
+        [1, 2] => true, //~ ERROR mismatched types
+        _ => false
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr b/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr
new file mode 100644
index 00000000000..9edb139028b
--- /dev/null
+++ b/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr
@@ -0,0 +1,20 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+  --> $DIR/match_arr_unknown_len.rs:1:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0308]: mismatched types
+  --> $DIR/match_arr_unknown_len.rs:6:9
+   |
+LL |         [1, 2] => true,
+   |         ^^^^^^ expected `2usize`, found `N`
+   |
+   = note: expected array `[u32; 2]`
+              found array `[u32; _]`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/array-slice-vec/vec-fixed-length.rs b/src/test/ui/array-slice-vec/vec-fixed-length.rs
index 5db02ee066b..908c39c7951 100644
--- a/src/test/ui/array-slice-vec/vec-fixed-length.rs
+++ b/src/test/ui/array-slice-vec/vec-fixed-length.rs
@@ -9,7 +9,7 @@ fn test_big_vec() {}
 #[cfg(target_pointer_width = "64")]
 fn test_big_vec()
 {
-    assert_eq!(size_of::<[u8; (1 << 32)]>(), (1 << 32));
+    assert_eq!(size_of::<[u8; 1 << 32]>(), (1 << 32));
 }
 
 fn main() {
diff --git a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr
index ec60db47f44..946a1f1a07a 100644
--- a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr
+++ b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr
@@ -7,11 +7,10 @@ LL |     const Y: usize;
 LL |     let _array = [4; <A as Foo>::Y];
    |                      ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A`
    |
-help: consider further restricting this bound with `+ Foo`
-  --> $DIR/associated-const-type-parameter-arrays-2.rs:15:16
+help: consider further restricting this bound
    |
-LL | pub fn test<A: Foo, B: Foo>() {
-   |                ^^^
+LL | pub fn test<A: Foo + Foo, B: Foo>() {
+   |                    ^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-const/associated-const-type-parameter-arrays.stderr b/src/test/ui/associated-const/associated-const-type-parameter-arrays.stderr
index 3d38deb5a87..ac40e390cfb 100644
--- a/src/test/ui/associated-const/associated-const-type-parameter-arrays.stderr
+++ b/src/test/ui/associated-const/associated-const-type-parameter-arrays.stderr
@@ -7,11 +7,10 @@ LL |     const Y: usize;
 LL |     let _array: [u32; <A as Foo>::Y];
    |                       ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A`
    |
-help: consider further restricting this bound with `+ Foo`
-  --> $DIR/associated-const-type-parameter-arrays.rs:15:16
+help: consider further restricting this bound
    |
-LL | pub fn test<A: Foo, B: Foo>() {
-   |                ^^^
+LL | pub fn test<A: Foo + Foo, B: Foo>() {
+   |                    ^^^^^
 
 error: aborting due to previous error
 
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 00000000000..510a13ea5b1
--- /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 00000000000..510a13ea5b1
--- /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 00000000000..510a13ea5b1
--- /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/consts/issue-69020.rs b/src/test/ui/associated-const/issue-69020-assoc-const-arith-overflow.rs
index e079feb04d4..850f65ae9d1 100644
--- a/src/test/ui/consts/issue-69020.rs
+++ b/src/test/ui/associated-const/issue-69020-assoc-const-arith-overflow.rs
@@ -9,21 +9,40 @@ 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.
+// 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-types/associated-types-invalid-trait-ref-issue-18865.stderr b/src/test/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr
index bac663dfea2..1df12787353 100644
--- a/src/test/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr
+++ b/src/test/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr
@@ -4,11 +4,10 @@ error[E0277]: the trait bound `T: Foo<usize>` is not satisfied
 LL |     let u: <T as Foo<usize>>::Bar = t.get_bar();
    |            ^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo<usize>` is not implemented for `T`
    |
-help: consider further restricting this bound with `+ Foo<usize>`
-  --> $DIR/associated-types-invalid-trait-ref-issue-18865.rs:9:8
+help: consider further restricting this bound
    |
-LL | fn f<T:Foo<isize>>(t: &T) {
-   |        ^^^^^^^^^^
+LL | fn f<T:Foo<isize> + Foo<usize>>(t: &T) {
+   |                   ^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr b/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr
index 770845167cf..0b5dee611e4 100644
--- a/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr
+++ b/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr
@@ -4,11 +4,10 @@ error[E0277]: the trait bound `T: Get` is not satisfied
 LL |     fn uhoh<T>(foo: <T as Get>::Value) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: Get`
-  --> $DIR/associated-types-no-suitable-bound.rs:11:13
+help: consider restricting type parameter `T`
    |
-LL |     fn uhoh<T>(foo: <T as Get>::Value) {}
-   |             ^
+LL |     fn uhoh<T: Get>(foo: <T as Get>::Value) {}
+   |              ^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-types/defaults-suitability.stderr b/src/test/ui/associated-types/defaults-suitability.stderr
index 60e1821b300..54e39c4367d 100644
--- a/src/test/ui/associated-types/defaults-suitability.stderr
+++ b/src/test/ui/associated-types/defaults-suitability.stderr
@@ -23,12 +23,11 @@ LL | trait Foo<T> {
 LL |     type Bar: Clone = Vec<T>;
    |               ^^^^^ the trait `std::clone::Clone` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::clone::Clone`
-  --> $DIR/defaults-suitability.rs:32:11
-   |
-LL | trait Foo<T> {
-   |           ^
    = note: required because of the requirements on the impl of `std::clone::Clone` for `std::vec::Vec<T>`
+help: consider restricting type parameter `T`
+   |
+LL | trait Foo<T: std::clone::Clone> {
+   |            ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `(): Foo<Self>` is not satisfied
   --> $DIR/defaults-suitability.rs:39:17
@@ -119,11 +118,10 @@ LL | |     type Baz = T;
 LL | | }
    | |_- required by `Foo3`
    |
-help: consider restricting this type parameter with `where T: std::clone::Clone`
-  --> $DIR/defaults-suitability.rs:88:12
+help: consider further restricting type parameter `T`
    |
-LL | trait Foo3<T> where
-   |            ^
+LL |     Self::Baz: Clone, T: std::clone::Clone
+   |                     ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
   --> $DIR/defaults-suitability.rs:27:5
diff --git a/src/test/ui/associated-types/defaults-unsound-62211-1.stderr b/src/test/ui/associated-types/defaults-unsound-62211-1.stderr
index 9c4a1260139..cfca7cc1011 100644
--- a/src/test/ui/associated-types/defaults-unsound-62211-1.stderr
+++ b/src/test/ui/associated-types/defaults-unsound-62211-1.stderr
@@ -47,11 +47,10 @@ LL | impl<T> UncheckedCopy for T {}
    |
    = help: the trait `std::fmt::Display` is not implemented for `T`
    = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
-help: consider restricting this type parameter with `T: std::fmt::Display`
-  --> $DIR/defaults-unsound-62211-1.rs:41:6
+help: consider restricting type parameter `T`
    |
-LL | impl<T> UncheckedCopy for T {}
-   |      ^
+LL | impl<T: std::fmt::Display> UncheckedCopy for T {}
+   |       ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `T: std::ops::Deref` is not satisfied
   --> $DIR/defaults-unsound-62211-1.rs:41:9
@@ -59,11 +58,10 @@ error[E0277]: the trait bound `T: std::ops::Deref` is not satisfied
 LL | impl<T> UncheckedCopy for T {}
    |         ^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::ops::Deref`
-  --> $DIR/defaults-unsound-62211-1.rs:41:6
+help: consider restricting type parameter `T`
    |
-LL | impl<T> UncheckedCopy for T {}
-   |      ^
+LL | impl<T: std::ops::Deref> UncheckedCopy for T {}
+   |       ^^^^^^^^^^^^^^^^^
 
 error[E0277]: cannot add-assign `&'static str` to `T`
   --> $DIR/defaults-unsound-62211-1.rs:41:9
@@ -72,11 +70,10 @@ LL | impl<T> UncheckedCopy for T {}
    |         ^^^^^^^^^^^^^ no implementation for `T += &'static str`
    |
    = help: the trait `std::ops::AddAssign<&'static str>` is not implemented for `T`
-help: consider restricting this type parameter with `T: std::ops::AddAssign<&'static str>`
-  --> $DIR/defaults-unsound-62211-1.rs:41:6
+help: consider restricting type parameter `T`
    |
-LL | impl<T> UncheckedCopy for T {}
-   |      ^
+LL | impl<T: std::ops::AddAssign<&'static str>> UncheckedCopy for T {}
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
   --> $DIR/defaults-unsound-62211-1.rs:41:9
@@ -84,11 +81,10 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
 LL | impl<T> UncheckedCopy for T {}
    |         ^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/defaults-unsound-62211-1.rs:41:6
+help: consider restricting type parameter `T`
    |
-LL | impl<T> UncheckedCopy for T {}
-   |      ^
+LL | impl<T: std::marker::Copy> UncheckedCopy for T {}
+   |       ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/associated-types/defaults-unsound-62211-2.stderr b/src/test/ui/associated-types/defaults-unsound-62211-2.stderr
index 4602fbc99fa..1dcfbf538e4 100644
--- a/src/test/ui/associated-types/defaults-unsound-62211-2.stderr
+++ b/src/test/ui/associated-types/defaults-unsound-62211-2.stderr
@@ -47,11 +47,10 @@ LL | impl<T> UncheckedCopy for T {}
    |
    = help: the trait `std::fmt::Display` is not implemented for `T`
    = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
-help: consider restricting this type parameter with `T: std::fmt::Display`
-  --> $DIR/defaults-unsound-62211-2.rs:41:6
+help: consider restricting type parameter `T`
    |
-LL | impl<T> UncheckedCopy for T {}
-   |      ^
+LL | impl<T: std::fmt::Display> UncheckedCopy for T {}
+   |       ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `T: std::ops::Deref` is not satisfied
   --> $DIR/defaults-unsound-62211-2.rs:41:9
@@ -59,11 +58,10 @@ error[E0277]: the trait bound `T: std::ops::Deref` is not satisfied
 LL | impl<T> UncheckedCopy for T {}
    |         ^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::ops::Deref`
-  --> $DIR/defaults-unsound-62211-2.rs:41:6
+help: consider restricting type parameter `T`
    |
-LL | impl<T> UncheckedCopy for T {}
-   |      ^
+LL | impl<T: std::ops::Deref> UncheckedCopy for T {}
+   |       ^^^^^^^^^^^^^^^^^
 
 error[E0277]: cannot add-assign `&'static str` to `T`
   --> $DIR/defaults-unsound-62211-2.rs:41:9
@@ -72,11 +70,10 @@ LL | impl<T> UncheckedCopy for T {}
    |         ^^^^^^^^^^^^^ no implementation for `T += &'static str`
    |
    = help: the trait `std::ops::AddAssign<&'static str>` is not implemented for `T`
-help: consider restricting this type parameter with `T: std::ops::AddAssign<&'static str>`
-  --> $DIR/defaults-unsound-62211-2.rs:41:6
+help: consider restricting type parameter `T`
    |
-LL | impl<T> UncheckedCopy for T {}
-   |      ^
+LL | impl<T: std::ops::AddAssign<&'static str>> UncheckedCopy for T {}
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
   --> $DIR/defaults-unsound-62211-2.rs:41:9
@@ -84,11 +81,10 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
 LL | impl<T> UncheckedCopy for T {}
    |         ^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/defaults-unsound-62211-2.rs:41:6
+help: consider restricting type parameter `T`
    |
-LL | impl<T> UncheckedCopy for T {}
-   |      ^
+LL | impl<T: std::marker::Copy> UncheckedCopy for T {}
+   |       ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 8 previous errors
 
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 00000000000..e78231a6851
--- /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 00000000000..d2fa7e58f6a
--- /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 aa142ebd78c..3ee7ab2e9d1 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 0624c049048..2417b592c7d 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 @@ LL |     async { let (); }.await;
    |     ^^^^^^^^^^^^^^^^^^^^^^^ 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 @@ LL | |     }.await;
    | |___________^ 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 | fn main() {
 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/bad/bad-method-typaram-kind.stderr b/src/test/ui/bad/bad-method-typaram-kind.stderr
index 97323632212..81fc961e3de 100644
--- a/src/test/ui/bad/bad-method-typaram-kind.stderr
+++ b/src/test/ui/bad/bad-method-typaram-kind.stderr
@@ -5,11 +5,10 @@ LL |     1.bar::<T>();
    |       ^^^ `T` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `T`
-help: consider further restricting this bound with `+ std::marker::Send`
-  --> $DIR/bad-method-typaram-kind.rs:1:10
+help: consider further restricting this bound
    |
-LL | fn foo<T:'static>() {
-   |          ^^^^^^^
+LL | fn foo<T:'static + std::marker::Send>() {
+   |                  ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/binop/binop-consume-args.stderr b/src/test/ui/binop/binop-consume-args.stderr
index 3fe7c9cbff4..acdc03e3726 100644
--- a/src/test/ui/binop/binop-consume-args.stderr
+++ b/src/test/ui/binop/binop-consume-args.stderr
@@ -8,11 +8,10 @@ LL |     lhs + rhs;
 LL |     drop(lhs);
    |          ^^^ value used here after move
    |
-help: consider further restricting this bound with `+ Copy`
-  --> $DIR/binop-consume-args.rs:5:11
+help: consider further restricting this bound
    |
-LL | fn add<A: Add<B, Output=()>, B>(lhs: A, rhs: B) {
-   |           ^^^^^^^^^^^^^^^^^
+LL | fn add<A: Add<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+   |                             ^^^^^^
 
 error[E0382]: use of moved value: `rhs`
   --> $DIR/binop-consume-args.rs:8:10
@@ -25,11 +24,10 @@ LL |     drop(lhs);
 LL |     drop(rhs);
    |          ^^^ value used here after move
    |
-help: consider restricting this type parameter with `B: Copy`
-  --> $DIR/binop-consume-args.rs:5:30
+help: consider restricting type parameter `B`
    |
-LL | fn add<A: Add<B, Output=()>, B>(lhs: A, rhs: B) {
-   |                              ^
+LL | fn add<A: Add<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+   |                               ^^^^^^
 
 error[E0382]: use of moved value: `lhs`
   --> $DIR/binop-consume-args.rs:13:10
@@ -41,11 +39,10 @@ LL |     lhs - rhs;
 LL |     drop(lhs);
    |          ^^^ value used here after move
    |
-help: consider further restricting this bound with `+ Copy`
-  --> $DIR/binop-consume-args.rs:11:11
+help: consider further restricting this bound
    |
-LL | fn sub<A: Sub<B, Output=()>, B>(lhs: A, rhs: B) {
-   |           ^^^^^^^^^^^^^^^^^
+LL | fn sub<A: Sub<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+   |                             ^^^^^^
 
 error[E0382]: use of moved value: `rhs`
   --> $DIR/binop-consume-args.rs:14:10
@@ -58,11 +55,10 @@ LL |     drop(lhs);
 LL |     drop(rhs);
    |          ^^^ value used here after move
    |
-help: consider restricting this type parameter with `B: Copy`
-  --> $DIR/binop-consume-args.rs:11:30
+help: consider restricting type parameter `B`
    |
-LL | fn sub<A: Sub<B, Output=()>, B>(lhs: A, rhs: B) {
-   |                              ^
+LL | fn sub<A: Sub<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+   |                               ^^^^^^
 
 error[E0382]: use of moved value: `lhs`
   --> $DIR/binop-consume-args.rs:19:10
@@ -74,11 +70,10 @@ LL |     lhs * rhs;
 LL |     drop(lhs);
    |          ^^^ value used here after move
    |
-help: consider further restricting this bound with `+ Copy`
-  --> $DIR/binop-consume-args.rs:17:11
+help: consider further restricting this bound
    |
-LL | fn mul<A: Mul<B, Output=()>, B>(lhs: A, rhs: B) {
-   |           ^^^^^^^^^^^^^^^^^
+LL | fn mul<A: Mul<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+   |                             ^^^^^^
 
 error[E0382]: use of moved value: `rhs`
   --> $DIR/binop-consume-args.rs:20:10
@@ -91,11 +86,10 @@ LL |     drop(lhs);
 LL |     drop(rhs);
    |          ^^^ value used here after move
    |
-help: consider restricting this type parameter with `B: Copy`
-  --> $DIR/binop-consume-args.rs:17:30
+help: consider restricting type parameter `B`
    |
-LL | fn mul<A: Mul<B, Output=()>, B>(lhs: A, rhs: B) {
-   |                              ^
+LL | fn mul<A: Mul<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+   |                               ^^^^^^
 
 error[E0382]: use of moved value: `lhs`
   --> $DIR/binop-consume-args.rs:25:10
@@ -107,11 +101,10 @@ LL |     lhs / rhs;
 LL |     drop(lhs);
    |          ^^^ value used here after move
    |
-help: consider further restricting this bound with `+ Copy`
-  --> $DIR/binop-consume-args.rs:23:11
+help: consider further restricting this bound
    |
-LL | fn div<A: Div<B, Output=()>, B>(lhs: A, rhs: B) {
-   |           ^^^^^^^^^^^^^^^^^
+LL | fn div<A: Div<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+   |                             ^^^^^^
 
 error[E0382]: use of moved value: `rhs`
   --> $DIR/binop-consume-args.rs:26:10
@@ -124,11 +117,10 @@ LL |     drop(lhs);
 LL |     drop(rhs);
    |          ^^^ value used here after move
    |
-help: consider restricting this type parameter with `B: Copy`
-  --> $DIR/binop-consume-args.rs:23:30
+help: consider restricting type parameter `B`
    |
-LL | fn div<A: Div<B, Output=()>, B>(lhs: A, rhs: B) {
-   |                              ^
+LL | fn div<A: Div<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+   |                               ^^^^^^
 
 error[E0382]: use of moved value: `lhs`
   --> $DIR/binop-consume-args.rs:31:10
@@ -140,11 +132,10 @@ LL |     lhs % rhs;
 LL |     drop(lhs);
    |          ^^^ value used here after move
    |
-help: consider further restricting this bound with `+ Copy`
-  --> $DIR/binop-consume-args.rs:29:11
+help: consider further restricting this bound
    |
-LL | fn rem<A: Rem<B, Output=()>, B>(lhs: A, rhs: B) {
-   |           ^^^^^^^^^^^^^^^^^
+LL | fn rem<A: Rem<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+   |                             ^^^^^^
 
 error[E0382]: use of moved value: `rhs`
   --> $DIR/binop-consume-args.rs:32:10
@@ -157,11 +148,10 @@ LL |     drop(lhs);
 LL |     drop(rhs);
    |          ^^^ value used here after move
    |
-help: consider restricting this type parameter with `B: Copy`
-  --> $DIR/binop-consume-args.rs:29:30
+help: consider restricting type parameter `B`
    |
-LL | fn rem<A: Rem<B, Output=()>, B>(lhs: A, rhs: B) {
-   |                              ^
+LL | fn rem<A: Rem<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+   |                               ^^^^^^
 
 error[E0382]: use of moved value: `lhs`
   --> $DIR/binop-consume-args.rs:37:10
@@ -173,11 +163,10 @@ LL |     lhs & rhs;
 LL |     drop(lhs);
    |          ^^^ value used here after move
    |
-help: consider further restricting this bound with `+ Copy`
-  --> $DIR/binop-consume-args.rs:35:14
+help: consider further restricting this bound
    |
-LL | fn bitand<A: BitAnd<B, Output=()>, B>(lhs: A, rhs: B) {
-   |              ^^^^^^^^^^^^^^^^^^^^
+LL | fn bitand<A: BitAnd<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+   |                                   ^^^^^^
 
 error[E0382]: use of moved value: `rhs`
   --> $DIR/binop-consume-args.rs:38:10
@@ -190,11 +179,10 @@ LL |     drop(lhs);
 LL |     drop(rhs);
    |          ^^^ value used here after move
    |
-help: consider restricting this type parameter with `B: Copy`
-  --> $DIR/binop-consume-args.rs:35:36
+help: consider restricting type parameter `B`
    |
-LL | fn bitand<A: BitAnd<B, Output=()>, B>(lhs: A, rhs: B) {
-   |                                    ^
+LL | fn bitand<A: BitAnd<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+   |                                     ^^^^^^
 
 error[E0382]: use of moved value: `lhs`
   --> $DIR/binop-consume-args.rs:43:10
@@ -206,11 +194,10 @@ LL |     lhs | rhs;
 LL |     drop(lhs);
    |          ^^^ value used here after move
    |
-help: consider further restricting this bound with `+ Copy`
-  --> $DIR/binop-consume-args.rs:41:13
+help: consider further restricting this bound
    |
-LL | fn bitor<A: BitOr<B, Output=()>, B>(lhs: A, rhs: B) {
-   |             ^^^^^^^^^^^^^^^^^^^
+LL | fn bitor<A: BitOr<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+   |                                 ^^^^^^
 
 error[E0382]: use of moved value: `rhs`
   --> $DIR/binop-consume-args.rs:44:10
@@ -223,11 +210,10 @@ LL |     drop(lhs);
 LL |     drop(rhs);
    |          ^^^ value used here after move
    |
-help: consider restricting this type parameter with `B: Copy`
-  --> $DIR/binop-consume-args.rs:41:34
+help: consider restricting type parameter `B`
    |
-LL | fn bitor<A: BitOr<B, Output=()>, B>(lhs: A, rhs: B) {
-   |                                  ^
+LL | fn bitor<A: BitOr<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+   |                                   ^^^^^^
 
 error[E0382]: use of moved value: `lhs`
   --> $DIR/binop-consume-args.rs:49:10
@@ -239,11 +225,10 @@ LL |     lhs ^ rhs;
 LL |     drop(lhs);
    |          ^^^ value used here after move
    |
-help: consider further restricting this bound with `+ Copy`
-  --> $DIR/binop-consume-args.rs:47:14
+help: consider further restricting this bound
    |
-LL | fn bitxor<A: BitXor<B, Output=()>, B>(lhs: A, rhs: B) {
-   |              ^^^^^^^^^^^^^^^^^^^^
+LL | fn bitxor<A: BitXor<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+   |                                   ^^^^^^
 
 error[E0382]: use of moved value: `rhs`
   --> $DIR/binop-consume-args.rs:50:10
@@ -256,11 +241,10 @@ LL |     drop(lhs);
 LL |     drop(rhs);
    |          ^^^ value used here after move
    |
-help: consider restricting this type parameter with `B: Copy`
-  --> $DIR/binop-consume-args.rs:47:36
+help: consider restricting type parameter `B`
    |
-LL | fn bitxor<A: BitXor<B, Output=()>, B>(lhs: A, rhs: B) {
-   |                                    ^
+LL | fn bitxor<A: BitXor<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+   |                                     ^^^^^^
 
 error[E0382]: use of moved value: `lhs`
   --> $DIR/binop-consume-args.rs:55:10
@@ -272,11 +256,10 @@ LL |     lhs << rhs;
 LL |     drop(lhs);
    |          ^^^ value used here after move
    |
-help: consider further restricting this bound with `+ Copy`
-  --> $DIR/binop-consume-args.rs:53:11
+help: consider further restricting this bound
    |
-LL | fn shl<A: Shl<B, Output=()>, B>(lhs: A, rhs: B) {
-   |           ^^^^^^^^^^^^^^^^^
+LL | fn shl<A: Shl<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+   |                             ^^^^^^
 
 error[E0382]: use of moved value: `rhs`
   --> $DIR/binop-consume-args.rs:56:10
@@ -289,11 +272,10 @@ LL |     drop(lhs);
 LL |     drop(rhs);
    |          ^^^ value used here after move
    |
-help: consider restricting this type parameter with `B: Copy`
-  --> $DIR/binop-consume-args.rs:53:30
+help: consider restricting type parameter `B`
    |
-LL | fn shl<A: Shl<B, Output=()>, B>(lhs: A, rhs: B) {
-   |                              ^
+LL | fn shl<A: Shl<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+   |                               ^^^^^^
 
 error[E0382]: use of moved value: `lhs`
   --> $DIR/binop-consume-args.rs:61:10
@@ -305,11 +287,10 @@ LL |     lhs >> rhs;
 LL |     drop(lhs);
    |          ^^^ value used here after move
    |
-help: consider further restricting this bound with `+ Copy`
-  --> $DIR/binop-consume-args.rs:59:11
+help: consider further restricting this bound
    |
-LL | fn shr<A: Shr<B, Output=()>, B>(lhs: A, rhs: B) {
-   |           ^^^^^^^^^^^^^^^^^
+LL | fn shr<A: Shr<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+   |                             ^^^^^^
 
 error[E0382]: use of moved value: `rhs`
   --> $DIR/binop-consume-args.rs:62:10
@@ -322,11 +303,10 @@ LL |     drop(lhs);
 LL |     drop(rhs);
    |          ^^^ value used here after move
    |
-help: consider restricting this type parameter with `B: Copy`
-  --> $DIR/binop-consume-args.rs:59:30
+help: consider restricting type parameter `B`
    |
-LL | fn shr<A: Shr<B, Output=()>, B>(lhs: A, rhs: B) {
-   |                              ^
+LL | fn shr<A: Shr<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+   |                               ^^^^^^
 
 error: aborting due to 20 previous errors
 
diff --git a/src/test/ui/binop/binop-move-semantics.stderr b/src/test/ui/binop/binop-move-semantics.stderr
index 31b594eeab4..6d5ac9cab30 100644
--- a/src/test/ui/binop/binop-move-semantics.stderr
+++ b/src/test/ui/binop/binop-move-semantics.stderr
@@ -9,11 +9,10 @@ LL |     +
 LL |     x;
    |     ^ value used here after move
    |
-help: consider further restricting this bound with `+ Copy`
-  --> $DIR/binop-move-semantics.rs:5:19
+help: consider further restricting this bound
    |
-LL | fn double_move<T: Add<Output=()>>(x: T) {
-   |                   ^^^^^^^^^^^^^^
+LL | fn double_move<T: Add<Output=()> + Copy>(x: T) {
+   |                                  ^^^^^^
 
 error[E0382]: borrow of moved value: `x`
   --> $DIR/binop-move-semantics.rs:14:5
@@ -26,11 +25,10 @@ LL |     +
 LL |     x.clone();
    |     ^ value borrowed here after move
    |
-help: consider further restricting this bound with `+ Copy`
-  --> $DIR/binop-move-semantics.rs:11:24
+help: consider further restricting this bound
    |
-LL | fn move_then_borrow<T: Add<Output=()> + Clone>(x: T) {
-   |                        ^^^^^^^^^^^^^^^^^^^^^^
+LL | fn move_then_borrow<T: Add<Output=()> + Clone + Copy>(x: T) {
+   |                                               ^^^^^^
 
 error[E0505]: cannot move out of `x` because it is borrowed
   --> $DIR/binop-move-semantics.rs:21:5
diff --git a/src/test/ui/block-fn-coerce.rs b/src/test/ui/block-fn-coerce.rs
index fc5f51d46b2..d993ad99459 100644
--- a/src/test/ui/block-fn-coerce.rs
+++ b/src/test/ui/block-fn-coerce.rs
@@ -1,4 +1,5 @@
 // run-pass
+#![allow(unused_braces)]
 
 fn force<F>(f: F) -> isize where F: FnOnce() -> isize { return f(); }
 
diff --git a/src/test/ui/borrowck/borrowck-unboxed-closures.stderr b/src/test/ui/borrowck/borrowck-unboxed-closures.stderr
index 33a0b0286df..a51cda548ef 100644
--- a/src/test/ui/borrowck/borrowck-unboxed-closures.stderr
+++ b/src/test/ui/borrowck/borrowck-unboxed-closures.stderr
@@ -26,11 +26,10 @@ LL |     f(1, 2);
 LL |     f(1, 2);
    |     ^ value used here after move
    |
-help: consider further restricting this bound with `+ Copy`
-  --> $DIR/borrowck-unboxed-closures.rs:10:8
+help: consider further restricting this bound
    |
-LL | fn c<F:FnOnce(isize, isize) -> isize>(f: F) {
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | fn c<F:FnOnce(isize, isize) -> isize + Copy>(f: F) {
+   |                                      ^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/bound-suggestions.fixed b/src/test/ui/bound-suggestions.fixed
index c77421c97e7..9c98200db51 100644
--- a/src/test/ui/bound-suggestions.fixed
+++ b/src/test/ui/bound-suggestions.fixed
@@ -13,7 +13,7 @@ fn test_no_bounds<T: std::fmt::Debug>(t: T) {
 }
 
 #[allow(dead_code)]
-fn test_one_bound<T: std::fmt::Debug +  Sized>(t: T) {
+fn test_one_bound<T: Sized + std::fmt::Debug>(t: T) {
     println!("{:?}", t);
     //~^ ERROR doesn't implement
 }
@@ -25,7 +25,7 @@ fn test_no_bounds_where<X, Y>(x: X, y: Y) where X: std::fmt::Debug, Y: std::fmt:
 }
 
 #[allow(dead_code)]
-fn test_one_bound_where<X>(x: X) where X: std::fmt::Debug + Sized {
+fn test_one_bound_where<X>(x: X) where X: Sized + std::fmt::Debug {
     println!("{:?}", x);
     //~^ ERROR doesn't implement
 }
diff --git a/src/test/ui/bound-suggestions.stderr b/src/test/ui/bound-suggestions.stderr
index 1e85c2bf36e..b9bc503f530 100644
--- a/src/test/ui/bound-suggestions.stderr
+++ b/src/test/ui/bound-suggestions.stderr
@@ -5,13 +5,12 @@ LL |     println!("{:?}", t);
    |                      ^ `impl Sized` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
    |
    = help: the trait `std::fmt::Debug` is not implemented for `impl Sized`
-help: consider further restricting this bound with `+ std::fmt::Debug`
-  --> $DIR/bound-suggestions.rs:4:17
-   |
-LL | fn test_impl(t: impl Sized) {
-   |                 ^^^^^^^^^^
    = 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)
+help: consider further restricting this bound
+   |
+LL | fn test_impl(t: impl Sized + std::fmt::Debug) {
+   |                            ^^^^^^^^^^^^^^^^^
 
 error[E0277]: `T` doesn't implement `std::fmt::Debug`
   --> $DIR/bound-suggestions.rs:11:22
@@ -20,13 +19,12 @@ LL |     println!("{:?}", t);
    |                      ^ `T` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
    |
    = help: the trait `std::fmt::Debug` is not implemented for `T`
-help: consider restricting this type parameter with `T: std::fmt::Debug`
-  --> $DIR/bound-suggestions.rs:10:19
-   |
-LL | fn test_no_bounds<T>(t: T) {
-   |                   ^
    = 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)
+help: consider restricting type parameter `T`
+   |
+LL | fn test_no_bounds<T: std::fmt::Debug>(t: T) {
+   |                    ^^^^^^^^^^^^^^^^^
 
 error[E0277]: `T` doesn't implement `std::fmt::Debug`
   --> $DIR/bound-suggestions.rs:17:22
@@ -35,13 +33,12 @@ LL |     println!("{:?}", t);
    |                      ^ `T` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
    |
    = help: the trait `std::fmt::Debug` is not implemented for `T`
-help: consider further restricting this bound with `+ std::fmt::Debug`
-  --> $DIR/bound-suggestions.rs:16:22
-   |
-LL | fn test_one_bound<T: Sized>(t: T) {
-   |                      ^^^^^
    = 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)
+help: consider further restricting this bound
+   |
+LL | fn test_one_bound<T: Sized + std::fmt::Debug>(t: T) {
+   |                            ^^^^^^^^^^^^^^^^^
 
 error[E0277]: `Y` doesn't implement `std::fmt::Debug`
   --> $DIR/bound-suggestions.rs:23:30
@@ -50,13 +47,12 @@ LL |     println!("{:?} {:?}", x, y);
    |                              ^ `Y` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
    |
    = help: the trait `std::fmt::Debug` is not implemented for `Y`
-help: consider restricting this type parameter with `where Y: std::fmt::Debug`
-  --> $DIR/bound-suggestions.rs:22:28
-   |
-LL | fn test_no_bounds_where<X, Y>(x: X, y: Y) where X: std::fmt::Debug {
-   |                            ^
    = 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)
+help: consider further restricting type parameter `Y`
+   |
+LL | fn test_no_bounds_where<X, Y>(x: X, y: Y) where X: std::fmt::Debug, Y: std::fmt::Debug {
+   |                                                                   ^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `X` doesn't implement `std::fmt::Debug`
   --> $DIR/bound-suggestions.rs:29:22
@@ -65,13 +61,12 @@ LL |     println!("{:?}", x);
    |                      ^ `X` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
    |
    = help: the trait `std::fmt::Debug` is not implemented for `X`
-help: consider further restricting this bound with `+ std::fmt::Debug`
-  --> $DIR/bound-suggestions.rs:28:40
-   |
-LL | fn test_one_bound_where<X>(x: X) where X: Sized {
-   |                                        ^^^^^^^^
    = 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)
+help: consider further restricting this bound
+   |
+LL | fn test_one_bound_where<X>(x: X) where X: Sized + std::fmt::Debug {
+   |                                                 ^^^^^^^^^^^^^^^^^
 
 error[E0277]: `X` doesn't implement `std::fmt::Debug`
   --> $DIR/bound-suggestions.rs:35:22
@@ -80,13 +75,12 @@ LL |     println!("{:?}", x);
    |                      ^ `X` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
    |
    = help: the trait `std::fmt::Debug` is not implemented for `X`
-help: consider further restricting this type parameter with `where X: std::fmt::Debug`
-  --> $DIR/bound-suggestions.rs:34:27
-   |
-LL | fn test_many_bounds_where<X>(x: X) where X: Sized, X: Sized {
-   |                           ^
    = 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)
+help: consider further restricting type parameter `X`
+   |
+LL | fn test_many_bounds_where<X>(x: X) where X: Sized, X: Sized, X: std::fmt::Debug {
+   |                                                            ^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr b/src/test/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr
index a38705c834a..ea5215e458d 100644
--- a/src/test/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr
+++ b/src/test/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr
@@ -5,12 +5,11 @@ LL | impl <T: Sync+'static> Foo for (T,) { }
    |                        ^^^ `T` cannot be sent between threads safely
    |
    = help: within `(T,)`, the trait `std::marker::Send` is not implemented for `T`
-help: consider further restricting this bound with `+ std::marker::Send`
-  --> $DIR/builtin-superkinds-double-superkind.rs:6:10
-   |
-LL | impl <T: Sync+'static> Foo for (T,) { }
-   |          ^^^^^^^^^^^^
    = note: required because it appears within the type `(T,)`
+help: consider further restricting this bound
+   |
+LL | impl <T: Sync+'static + std::marker::Send> Foo for (T,) { }
+   |                       ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `T` cannot be shared between threads safely
   --> $DIR/builtin-superkinds-double-superkind.rs:9:16
@@ -19,12 +18,11 @@ LL | impl <T: Send> Foo for (T,T) { }
    |                ^^^ `T` cannot be shared between threads safely
    |
    = help: within `(T, T)`, the trait `std::marker::Sync` is not implemented for `T`
-help: consider further restricting this bound with `+ std::marker::Sync`
-  --> $DIR/builtin-superkinds-double-superkind.rs:9:10
-   |
-LL | impl <T: Send> Foo for (T,T) { }
-   |          ^^^^
    = note: required because it appears within the type `(T, T)`
+help: consider further restricting this bound
+   |
+LL | impl <T: Send + std::marker::Sync> Foo for (T,T) { }
+   |               ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr b/src/test/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr
index f379d97bd76..ba6595f68d5 100644
--- a/src/test/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr
+++ b/src/test/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr
@@ -5,12 +5,11 @@ LL | impl <T:Sync+'static> RequiresRequiresShareAndSend for X<T> { }
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `T` cannot be sent between threads safely
    |
    = help: within `X<T>`, the trait `std::marker::Send` is not implemented for `T`
-help: consider further restricting this bound with `+ std::marker::Send`
-  --> $DIR/builtin-superkinds-in-metadata.rs:13:9
-   |
-LL | impl <T:Sync+'static> RequiresRequiresShareAndSend for X<T> { }
-   |         ^^^^^^^^^^^^
    = note: required because it appears within the type `X<T>`
+help: consider further restricting this bound
+   |
+LL | impl <T:Sync+'static + std::marker::Send> RequiresRequiresShareAndSend for X<T> { }
+   |                      ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr b/src/test/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr
index 996f39bfb66..bef33d1fd05 100644
--- a/src/test/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr
+++ b/src/test/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr
@@ -5,11 +5,10 @@ LL | impl <T: Sync+'static> Foo for T { }
    |                        ^^^ `T` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `T`
-help: consider further restricting this bound with `+ std::marker::Send`
-  --> $DIR/builtin-superkinds-typaram-not-send.rs:5:10
+help: consider further restricting this bound
    |
-LL | impl <T: Sync+'static> Foo for T { }
-   |          ^^^^^^^^^^^^
+LL | impl <T: Sync+'static + std::marker::Send> Foo for T { }
+   |                       ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/cleanup-rvalue-scopes.rs b/src/test/ui/cleanup-rvalue-scopes.rs
index f51f13abf79..c5dd87c0f5a 100644
--- a/src/test/ui/cleanup-rvalue-scopes.rs
+++ b/src/test/ui/cleanup-rvalue-scopes.rs
@@ -1,5 +1,5 @@
 // run-pass
-
+#![allow(unused_braces)]
 #![allow(non_snake_case)]
 #![allow(unused_variables)]
 // Test that destructors for rvalue temporaries run either at end of
diff --git a/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr b/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr
index b4135af7d77..f565948f479 100644
--- a/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr
+++ b/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr
@@ -8,11 +8,10 @@ LL | fn foo<F>(blk: F) -> X<F> where F: FnOnce() + 'static {
    |                      ^^^^ `F` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `F`
-help: consider further restricting this bound with `+ std::marker::Send`
-  --> $DIR/closure-bounds-cant-promote-superkind-in-struct.rs:5:33
+help: consider further restricting this bound
    |
-LL | fn foo<F>(blk: F) -> X<F> where F: FnOnce() + 'static {
-   |                                 ^^^^^^^^^^^^^^^^^^^^^
+LL | fn foo<F>(blk: F) -> X<F> where F: FnOnce() + 'static + std::marker::Send {
+   |                                                       ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/closure-bounds-subtype.stderr b/src/test/ui/closures/closure-bounds-subtype.stderr
index 47504de814d..f746f8502b8 100644
--- a/src/test/ui/closures/closure-bounds-subtype.stderr
+++ b/src/test/ui/closures/closure-bounds-subtype.stderr
@@ -8,11 +8,10 @@ LL |     take_const_owned(f);
    |                      ^ `F` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `F`
-help: consider further restricting this bound with `+ std::marker::Sync`
-  --> $DIR/closure-bounds-subtype.rs:11:30
+help: consider further restricting this bound
    |
-LL | fn give_owned<F>(f: F) where F: FnOnce() + Send {
-   |                              ^^^^^^^^^^^^^^^^^^
+LL | fn give_owned<F>(f: F) where F: FnOnce() + Send + std::marker::Sync {
+   |                                                 ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.polonius.stderr b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.polonius.stderr
index 2a7461fb469..df60416709f 100644
--- a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.polonius.stderr
+++ b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.polonius.stderr
@@ -2,7 +2,7 @@ error[E0521]: borrowed data escapes outside of closure
   --> $DIR/expect-region-supply-region.rs:18:9
    |
 LL |     let mut f: Option<&u32> = None;
-   |         ----- `f` is declared here, outside of the closure body
+   |         ----- `f` declared here, outside of the closure body
 LL |     closure_expecting_bound(|x| {
    |                              - `x` is a reference that is only valid in the closure body
 LL |         f = Some(x);
@@ -12,7 +12,7 @@ error[E0521]: borrowed data escapes outside of closure
   --> $DIR/expect-region-supply-region.rs:28:9
    |
 LL |     let mut f: Option<&u32> = None;
-   |         ----- `f` is declared here, outside of the closure body
+   |         ----- `f` declared here, outside of the closure body
 LL |     closure_expecting_bound(|x: &u32| {
    |                              - `x` is a reference that is only valid in the closure body
 LL |         f = Some(x);
@@ -33,7 +33,7 @@ error[E0521]: borrowed data escapes outside of closure
   --> $DIR/expect-region-supply-region.rs:42:9
    |
 LL |     let mut f: Option<&u32> = None;
-   |         ----- `f` is declared here, outside of the closure body
+   |         ----- `f` declared here, outside of the closure body
 ...
 LL |     closure_expecting_bound(|x: &'x u32| {
    |                              - `x` is a reference that is only valid in the closure body
diff --git a/src/test/ui/closures/closure-move-sync.rs b/src/test/ui/closures/closure-move-sync.rs
index 87388247fbf..580cd1af4f3 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 2187823d758..a1fc427bc17 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 @@ LL |     F: Send + 'static,
    |
    = 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 @@ LL |     F: Send + 'static,
    |
    = 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/closures/issue-67123.stderr b/src/test/ui/closures/issue-67123.stderr
index f14478d7278..5a6dfb2fdf9 100644
--- a/src/test/ui/closures/issue-67123.stderr
+++ b/src/test/ui/closures/issue-67123.stderr
@@ -6,12 +6,11 @@ LL |     || { t; t; };
    |          |
    |          value moved here
    |
-help: consider restricting this type parameter with `T: Copy`
-  --> $DIR/issue-67123.rs:1:8
-   |
-LL | fn foo<T>(t: T) {
-   |        ^
    = note: move occurs because `t` has type `T`, which does not implement the `Copy` trait
+help: consider restricting type parameter `T`
+   |
+LL | fn foo<T: Copy>(t: T) {
+   |         ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coerce/coerce-expect-unsized.rs b/src/test/ui/coerce/coerce-expect-unsized.rs
index b44aa6ab377..d486fdf73ab 100644
--- a/src/test/ui/coerce/coerce-expect-unsized.rs
+++ b/src/test/ui/coerce/coerce-expect-unsized.rs
@@ -1,4 +1,5 @@
 // run-pass
+#![allow(unused_braces)]
 #![feature(box_syntax)]
 
 use std::cell::RefCell;
diff --git a/src/test/ui/coerce/coerce-overloaded-autoderef.rs b/src/test/ui/coerce/coerce-overloaded-autoderef.rs
index 3fe18103ef8..d5484607c8b 100644
--- a/src/test/ui/coerce/coerce-overloaded-autoderef.rs
+++ b/src/test/ui/coerce/coerce-overloaded-autoderef.rs
@@ -1,4 +1,5 @@
 // run-pass
+#![allow(unused_braces)]
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/const-generics/infer_arg_from_pat.rs b/src/test/ui/const-generics/infer_arg_from_pat.rs
new file mode 100644
index 00000000000..a4e3d3dee4a
--- /dev/null
+++ b/src/test/ui/const-generics/infer_arg_from_pat.rs
@@ -0,0 +1,27 @@
+// run-pass
+//
+// see issue #70529
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+struct A<const N: usize> {
+    arr: [u8; N],
+}
+
+impl<const N: usize> A<N> {
+    fn new() -> Self {
+        A {
+            arr: [0; N],
+        }
+    }
+
+    fn value(&self) -> usize {
+        N
+    }
+}
+
+fn main() {
+    let a = A::new();
+    let [_, _] = a.arr;
+    assert_eq!(a.value(), 2);
+}
diff --git a/src/test/ui/const-generics/infer_arg_from_pat.stderr b/src/test/ui/const-generics/infer_arg_from_pat.stderr
new file mode 100644
index 00000000000..ad6bf3e235a
--- /dev/null
+++ b/src/test/ui/const-generics/infer_arg_from_pat.stderr
@@ -0,0 +1,8 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+  --> $DIR/infer_arg_from_pat.rs:4:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
diff --git a/src/test/ui/const-generics/infer_arr_len_from_pat.rs b/src/test/ui/const-generics/infer_arr_len_from_pat.rs
new file mode 100644
index 00000000000..70633bbb141
--- /dev/null
+++ b/src/test/ui/const-generics/infer_arr_len_from_pat.rs
@@ -0,0 +1,13 @@
+// check-pass
+//
+// see issue #70529
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+fn as_chunks<const N: usize>() -> [u8; N] {
+    loop {}
+}
+
+fn main() {
+    let [_, _] = as_chunks();
+}
diff --git a/src/test/ui/const-generics/infer_arr_len_from_pat.stderr b/src/test/ui/const-generics/infer_arr_len_from_pat.stderr
new file mode 100644
index 00000000000..6f5b601e14c
--- /dev/null
+++ b/src/test/ui/const-generics/infer_arr_len_from_pat.stderr
@@ -0,0 +1,8 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+  --> $DIR/infer_arr_len_from_pat.rs:4:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
diff --git a/src/test/ui/const-generics/issues/issue-61336-2.stderr b/src/test/ui/const-generics/issues/issue-61336-2.stderr
index 9ced427b93c..ef9e3b86694 100644
--- a/src/test/ui/const-generics/issues/issue-61336-2.stderr
+++ b/src/test/ui/const-generics/issues/issue-61336-2.stderr
@@ -12,12 +12,11 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
 LL |     [x; { N }]
    |     ^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/issue-61336-2.rs:8:6
-   |
-LL | fn g<T, const N: usize>(x: T) -> [T; N] {
-   |      ^
    = note: the `Copy` trait is required because the repeated element will be copied
+help: consider restricting type parameter `T`
+   |
+LL | fn g<T: std::marker::Copy, const N: usize>(x: T) -> [T; N] {
+   |       ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/issues/issue-61336.stderr b/src/test/ui/const-generics/issues/issue-61336.stderr
index ace7955fbdd..88d81c66d1f 100644
--- a/src/test/ui/const-generics/issues/issue-61336.stderr
+++ b/src/test/ui/const-generics/issues/issue-61336.stderr
@@ -12,12 +12,11 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
 LL |     [x; N]
    |     ^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/issue-61336.rs:8:6
-   |
-LL | fn g<T, const N: usize>(x: T) -> [T; N] {
-   |      ^
    = note: the `Copy` trait is required because the repeated element will be copied
+help: consider restricting type parameter `T`
+   |
+LL | fn g<T: std::marker::Copy, const N: usize>(x: T) -> [T; N] {
+   |       ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/issues/issue-62220.rs b/src/test/ui/const-generics/issues/issue-62220.rs
new file mode 100644
index 00000000000..c95b3063201
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-62220.rs
@@ -0,0 +1,22 @@
+// build-pass
+#![allow(incomplete_features)]
+
+#![feature(const_generics)]
+pub struct Vector<T, const N: usize>([T; N]);
+
+pub type TruncatedVector<T, const N: usize> = Vector<T, { N - 1 }>;
+
+impl<T, const N: usize> Vector<T, { N }> {
+    /// Drop the last component and return the vector with one fewer dimension.
+    pub fn trunc(self) -> (TruncatedVector<T, { N }>, T) {
+        unimplemented!()
+    }
+}
+
+fn vec4<T>(a: T, b: T, c: T, d: T) -> Vector<T, 4> {
+    Vector([a, b, c, d])
+}
+
+fn main() {
+    let (_xyz, _w): (TruncatedVector<u32, 4>, u32) = vec4(0u32, 1, 2, 3).trunc();
+}
diff --git a/src/test/ui/const-generics/issues/issue-62504.rs b/src/test/ui/const-generics/issues/issue-62504.rs
index cd3cfaac3b9..212e16253f6 100644
--- a/src/test/ui/const-generics/issues/issue-62504.rs
+++ b/src/test/ui/const-generics/issues/issue-62504.rs
@@ -7,13 +7,13 @@ trait HasSize {
     const SIZE: usize;
 }
 
-impl<const X: usize> HasSize for ArrayHolder<{ X }> {
+impl<const X: usize> HasSize for ArrayHolder<X> {
     const SIZE: usize = X;
 }
 
 struct ArrayHolder<const X: usize>([u32; X]);
 
-impl<const X: usize> ArrayHolder<{ X }> {
+impl<const X: usize> ArrayHolder<X> {
     pub const fn new() -> Self {
         ArrayHolder([0; Self::SIZE])
         //~^ ERROR: mismatched types
diff --git a/src/test/ui/const-generics/issues/issue-70125-2.rs b/src/test/ui/const-generics/issues/issue-70125-2.rs
index ea7a68c2f93..a3eca0dd7d9 100644
--- a/src/test/ui/const-generics/issues/issue-70125-2.rs
+++ b/src/test/ui/const-generics/issues/issue-70125-2.rs
@@ -13,4 +13,4 @@ trait Foo<const X: usize> {
     }
 }
 
-impl Foo<{3}> for () {}
+impl Foo<3> for () {}
diff --git a/src/test/ui/const-generics/unused_braces.rs b/src/test/ui/const-generics/unused_braces.rs
new file mode 100644
index 00000000000..05234faf714
--- /dev/null
+++ b/src/test/ui/const-generics/unused_braces.rs
@@ -0,0 +1,13 @@
+// check-pass
+#![warn(unused_braces)]
+
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+struct A<const N: usize>;
+
+fn main() {
+    let _: A<7>; // ok
+    let _: A<{ 7 }>; //~ WARN unnecessary braces
+    let _: A<{ 3 + 5 }>; // ok
+}
diff --git a/src/test/ui/const-generics/unused_braces.stderr b/src/test/ui/const-generics/unused_braces.stderr
new file mode 100644
index 00000000000..fc3da6096e7
--- /dev/null
+++ b/src/test/ui/const-generics/unused_braces.stderr
@@ -0,0 +1,20 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+  --> $DIR/unused_braces.rs:4:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: unnecessary braces around const expression
+  --> $DIR/unused_braces.rs:11:14
+   |
+LL |     let _: A<{ 7 }>;
+   |              ^^^^^ help: remove these braces
+   |
+note: the lint level is defined here
+  --> $DIR/unused_braces.rs:2:9
+   |
+LL | #![warn(unused_braces)]
+   |         ^^^^^^^^^^^^^
+
diff --git a/src/test/ui/consts/const-block.rs b/src/test/ui/consts/const-block.rs
index 7172a34c8cf..ec99c70f6e0 100644
--- a/src/test/ui/consts/const-block.rs
+++ b/src/test/ui/consts/const-block.rs
@@ -1,5 +1,5 @@
 // run-pass
-
+#![allow(unused_braces)]
 #![allow(dead_code)]
 #![allow(unused_unsafe)]
 
diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr
index cede356a6b8..f1e91920f17 100644
--- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr
+++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr
@@ -5,7 +5,8 @@ LL |     unsafe { std::mem::transmute(()) }
    |              ^^^^^^^^^^^^^^^^^^^^^^^
    |              |
    |              transmuting to uninhabited type
-   |              inside call to `foo` at $DIR/validate_uninhabited_zsts.rs:14:26
+   |              inside `foo` at $DIR/validate_uninhabited_zsts.rs:5:14
+   |              inside `FOO` at $DIR/validate_uninhabited_zsts.rs:14:26
 ...
 LL | const FOO: [Empty; 3] = [foo(); 3];
    | -----------------------------------
diff --git a/src/test/ui/consts/const-size_of-cycle.rs b/src/test/ui/consts/const-size_of-cycle.rs
index c94bb4fbb27..1f56c8bd8e6 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 aac3622c6de..730ad57de81 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 @@ LL |     pub fn size_of<T>() -> usize;
    = 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 c48a106ef46..00000000000
--- 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 c48a106ef46..00000000000
--- 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 c48a106ef46..00000000000
--- 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/miri_unleashed/abi-mismatch.stderr b/src/test/ui/consts/miri_unleashed/abi-mismatch.stderr
index c7e902132e9..8ed1431dd31 100644
--- a/src/test/ui/consts/miri_unleashed/abi-mismatch.stderr
+++ b/src/test/ui/consts/miri_unleashed/abi-mismatch.stderr
@@ -17,7 +17,8 @@ LL |     my_fn();
    |     ^^^^^^^
    |     |
    |     calling a function with ABI C using caller ABI Rust
-   |     inside call to `call_rust_fn` at $DIR/abi-mismatch.rs:13:17
+   |     inside `call_rust_fn` at $DIR/abi-mismatch.rs:9:5
+   |     inside `VAL` at $DIR/abi-mismatch.rs:13:17
 ...
 LL | const VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) });
    | --------------------------------------------------------------------------------------
diff --git a/src/test/ui/consts/miri_unleashed/drop.rs b/src/test/ui/consts/miri_unleashed/drop.rs
index d2c34bcd4ae..2f39148d697 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 2439d527bd1..902ccf81ac0 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();
    |         ^^
@@ -12,12 +12,15 @@ LL | |     // Code here does not matter - this is replaced by the
 LL | |     // real drop glue by the compiler.
 LL | |     drop_in_place(to_drop)
 LL | | }
-   | |_^ calling non-const function `<std::vec::Vec<i32> as std::ops::Drop>::drop`
+   | | ^
+   | | |
+   | |_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 call to `std::intrinsics::drop_in_place::<std::vec::Vec<i32>> - shim(Some(std::vec::Vec<i32>))` 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 6c4beaf2ea5..a7902f20467 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 21753074007..4c591d5ee81 100644
--- a/src/test/ui/consts/offset_from_ub.stderr
+++ b/src/test/ui/consts/offset_from_ub.stderr
@@ -5,9 +5,10 @@ LL |           intrinsics::ptr_offset_from(self, origin)
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |           |
    |           ptr_offset_from cannot compute offset of pointers into different allocations.
-   |           inside call to `std::ptr::const_ptr::<impl *const Struct>::offset_from` at $DIR/offset_from_ub.rs:22:27
+   |           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:17:27
    | 
-  ::: $DIR/offset_from_ub.rs:16:1
+  ::: $DIR/offset_from_ub.rs:11:1
    |
 LL | / pub const DIFFERENT_ALLOC: usize = {
 LL | |
@@ -27,9 +28,10 @@ LL |           intrinsics::ptr_offset_from(self, origin)
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |           |
    |           unable to turn bytes into a pointer
-   |           inside call to `std::ptr::const_ptr::<impl *const u8>::offset_from` at $DIR/offset_from_ub.rs:28:14
+   |           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:23:14
    | 
-  ::: $DIR/offset_from_ub.rs:26:1
+  ::: $DIR/offset_from_ub.rs:21:1
    |
 LL | / pub const NOT_PTR: usize = {
 LL | |
@@ -44,9 +46,10 @@ LL |           intrinsics::ptr_offset_from(self, origin)
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |           |
    |           exact_div: 1isize cannot be divided by 2isize without remainder
-   |           inside call to `std::ptr::const_ptr::<impl *const u16>::offset_from` at $DIR/offset_from_ub.rs:36:14
+   |           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: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 | |
@@ -64,9 +67,10 @@ LL |           intrinsics::ptr_offset_from(self, origin)
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |           |
    |           invalid use of NULL pointer
-   |           inside call to `std::ptr::const_ptr::<impl *const u8>::offset_from` at $DIR/offset_from_ub.rs:42:14
+   |           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:37:14
    | 
-  ::: $DIR/offset_from_ub.rs:39:1
+  ::: $DIR/offset_from_ub.rs:34:1
    |
 LL | / pub const OFFSET_FROM_NULL: isize = {
 LL | |
@@ -82,9 +86,10 @@ LL |           intrinsics::ptr_offset_from(self, origin)
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |           |
    |           unable to turn bytes into a pointer
-   |           inside call to `std::ptr::const_ptr::<impl *const u8>::offset_from` at $DIR/offset_from_ub.rs:49:14
+   |           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: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/consts/uninhabited-const-issue-61744.stderr b/src/test/ui/consts/uninhabited-const-issue-61744.stderr
index 1f3e2cf5b2f..ca232380897 100644
--- a/src/test/ui/consts/uninhabited-const-issue-61744.stderr
+++ b/src/test/ui/consts/uninhabited-const-issue-61744.stderr
@@ -4,76 +4,140 @@ error[E0080]: evaluation of constant value failed
 LL |     hint_unreachable()
    |     ------------------
    |     |
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
-   |     inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+   |     inside `fake_type::<i32>` at $DIR/uninhabited-const-issue-61744.rs:4:5
 ...
 LL |     fake_type()
    |     ^^^^^^^^^^^
    |     |
    |     reached the configured maximum number of stack frames
-   |     inside call to `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+   |     inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
 
 error: any use of this value will cause an error
   --> $DIR/uninhabited-const-issue-61744.rs:12:36
diff --git a/src/test/ui/copy-a-resource.rs b/src/test/ui/copy-a-resource.rs
index 1a647692018..55f2dd4ee6d 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 71d2eead355..a5c961a061a 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 fa5afd24192..0f642d63a1d 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 f15aba97ded..be446feb847 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 7c416fdcfb1..b556d442420 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 8ef2d3d3023..bbb8776f4fd 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 c013ccd934e..9bb4f486c3e 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 8c740733e2f..0e410e795e0 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 5a78a92b823..f151636f848 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 75a59fbf035..889128a6623 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 39461d67d16..7a62885324e 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 1860c5f2ff6..0024199ca59 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 060983d3673..949597bc8f6 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 ab3c5ef3c1d..77779a55b68 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 109c8f23cdf..b2a39708ceb 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 e0a76d52515..f64c33c2bcc 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 b52e2879a4c..cf91c9436a6 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 2f5cba09e4c..0013bcf8325 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 1855c7fba88..cea973c91a7 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 58ec131d541..7e0039e8a79 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 bf60b12ac48..71fd5829e75 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 b97dda719ab..492847fc022 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 8b89b756720..463f7d230ca 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 d976891f41f..fa7b27e770f 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 36e6ae81e27..d2dab8687f7 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 f886c29c4db..704825c7b38 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 4282515862c..c6c0d432108 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 0b5470138a5..8d2499614d8 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 d290ee5ae0f..df310039847 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 76904d67235..22db0bf08b7 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 6458b63139d..abf6526b900 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 ff94b989d26..eaf14691ff0 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 fc04b1a2c06..3018a7b6d03 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 889c725c843..32f4265a4d2 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 daff0b27553..8ce7df18f06 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 70b8a85d107..b8d6277b9be 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 12a9edae630..fa5e2af6be8 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 61897392a72..ae431d221ca 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 344b85d7b91..3822bce1466 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 fb929ad985b..db32193cee0 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 196996c64c3..62355cc2d96 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 7e73392fd51..d0286ad17e4 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 6282a69076b..72738931d10 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 68df309e046..aabbd0a1d1b 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 e7bc7cf1c43..53d4c2c22b5 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 5e1ed335094..eaac3dafd08 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 3b623558d2a..4e09c270986 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 d9692e56431..0ae36bcb8bf 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 f935d580259..d66faa086de 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 c669636c850..8ff4b4687be 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 @@ LL |      x: Error
    = 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 a0c56818358..66edf460b31 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 ff98edea4dc..b4a12b1c410 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 @@ LL |      Error
    = 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 c190dd00396..ce5c67af77f 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 200b8e2d503..b4f6c51ac3c 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 @@ LL |     x: Error
    = 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 dfc9c03ddc7..eaa62831136 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 9e3d1309c22..2e6b1d71199 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 @@ LL |     Error
    = 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 beef639462e..4e7a8d71a18 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 6433d1f5e27..0be75972e8c 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 @@ LL |      x: Error
    = 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 @@ LL |      x: Error
    = 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 @@ LL |      x: Error
    = 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 @@ LL |      x: Error
    = 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 b02828da0d2..d0a6c5ab52a 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 b1be7dd05f9..64290023c6d 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 @@ LL |      Error
    = 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 @@ LL |      Error
    = 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 @@ LL |      Error
    = 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 @@ LL |      Error
    = 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 bfcfc3d5dfd..a596a2e3295 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 064c91fd7dd..dcd81589e92 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 @@ LL |     x: Error
    = 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 @@ LL |     x: Error
    = 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 @@ LL |     x: Error
    = 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 @@ LL |     x: Error
    = 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 c8bdd6423a0..6dd16234710 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 5b627022cca..8dbf103d2da 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 @@ LL |     Error
    = 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 @@ LL |     Error
    = 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 @@ LL |     Error
    = 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 @@ LL |     Error
    = 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 d1af5b458cc..6463a7664de 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 ead13132324..a587c342384 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 @@ LL | pub macro Eq($item:item) {
    | ------------------------ 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 7f1d064cf3f..c7612fd50a7 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 fcc44b7635c..e48bc74d357 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 75faad80579..f4730697e18 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 d43dc6fd649..68aff4638c8 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/E0297.rs b/src/test/ui/error-codes/E0297.rs
index b26ede9c8e2..27c7960d977 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 3ad841875e6..b2d181b838f 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/error-codes/E0730.rs b/src/test/ui/error-codes/E0730.rs
index e5048d6e6e3..66a6e1c817a 100644
--- a/src/test/ui/error-codes/E0730.rs
+++ b/src/test/ui/error-codes/E0730.rs
@@ -3,7 +3,7 @@
 
 fn is_123<const N: usize>(x: [u32; N]) -> bool {
     match x {
-        [1, 2, 3] => true, //~ ERROR cannot pattern-match on an array without a fixed length
+        [1, 2, ..] => true, //~ ERROR cannot pattern-match on an array without a fixed length
         _ => false
     }
 }
diff --git a/src/test/ui/error-codes/E0730.stderr b/src/test/ui/error-codes/E0730.stderr
index 9309ee99064..fb53ae31c0b 100644
--- a/src/test/ui/error-codes/E0730.stderr
+++ b/src/test/ui/error-codes/E0730.stderr
@@ -9,8 +9,8 @@ LL | #![feature(const_generics)]
 error[E0730]: cannot pattern-match on an array without a fixed length
   --> $DIR/E0730.rs:6:9
    |
-LL |         [1, 2, 3] => true,
-   |         ^^^^^^^^^
+LL |         [1, 2, ..] => true,
+   |         ^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/expr-block-generic-unique1.rs b/src/test/ui/expr-block-generic-unique1.rs
index c14191f2ffc..d081cb2be7e 100644
--- a/src/test/ui/expr-block-generic-unique1.rs
+++ b/src/test/ui/expr-block-generic-unique1.rs
@@ -1,5 +1,5 @@
 // run-pass
-
+#![allow(unused_braces)]
 #![feature(box_syntax)]
 
 fn test_generic<T, F>(expected: Box<T>, eq: F) where T: Clone, F: FnOnce(Box<T>, Box<T>) -> bool {
diff --git a/src/test/ui/expr-block-generic-unique2.rs b/src/test/ui/expr-block-generic-unique2.rs
index 90ebc02931a..9362eb86fc3 100644
--- a/src/test/ui/expr-block-generic-unique2.rs
+++ b/src/test/ui/expr-block-generic-unique2.rs
@@ -1,5 +1,5 @@
 // run-pass
-
+#![allow(unused_braces)]
 #![feature(box_syntax)]
 
 fn test_generic<T, F>(expected: T, eq: F) where T: Clone, F: FnOnce(T, T) -> bool {
diff --git a/src/test/ui/expr-block-generic.rs b/src/test/ui/expr-block-generic.rs
index ec93f59722d..29c7c42219c 100644
--- a/src/test/ui/expr-block-generic.rs
+++ b/src/test/ui/expr-block-generic.rs
@@ -1,4 +1,5 @@
 // run-pass
+#![allow(unused_braces)]
 
 fn test_generic<T: Clone, F>(expected: T, eq: F) where F: FnOnce(T, T) -> bool {
     let actual: T = { expected.clone() };
diff --git a/src/test/ui/expr-block-unique.rs b/src/test/ui/expr-block-unique.rs
index fe1a7d9f1fb..eff3fd3a151 100644
--- a/src/test/ui/expr-block-unique.rs
+++ b/src/test/ui/expr-block-unique.rs
@@ -1,5 +1,5 @@
 // run-pass
-
+#![allow(unused_braces)]
 #![feature(box_syntax)]
 
 pub fn main() { let x: Box<_> = { box 100 }; assert_eq!(*x, 100); }
diff --git a/src/test/ui/expr-block.rs b/src/test/ui/expr-block.rs
index 549ccf9774f..ff87595c934 100644
--- a/src/test/ui/expr-block.rs
+++ b/src/test/ui/expr-block.rs
@@ -1,10 +1,7 @@
 // run-pass
-
+#![allow(unused_braces)]
 #![allow(dead_code)]
 
-
-
-
 // Tests for standalone blocks as expressions
 
 fn test_basic() { let rs: bool = { true }; assert!((rs)); }
diff --git a/src/test/ui/expr-fn.rs b/src/test/ui/expr-fn.rs
index af809f563fc..253cbfd5d38 100644
--- a/src/test/ui/expr-fn.rs
+++ b/src/test/ui/expr-fn.rs
@@ -1,4 +1,5 @@
 // run-pass
+#![allow(unused_braces)]
 
 fn test_int() {
     fn f() -> isize { 10 }
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 d2e52299c0d..f0cc9ea7055 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 06c2e6e5192..823dad2c95e 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 10b151ffa75..41a7dfc3f37 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/functions-closures/closure-inference.rs b/src/test/ui/functions-closures/closure-inference.rs
index 96878445245..1877414f099 100644
--- a/src/test/ui/functions-closures/closure-inference.rs
+++ b/src/test/ui/functions-closures/closure-inference.rs
@@ -1,5 +1,5 @@
 // run-pass
-
+#![allow(unused_braces)]
 
 fn foo(i: isize) -> isize { i + 1 }
 
diff --git a/src/test/ui/functions-closures/closure-inference2.rs b/src/test/ui/functions-closures/closure-inference2.rs
index f2dfa5888aa..4ce132e86ca 100644
--- a/src/test/ui/functions-closures/closure-inference2.rs
+++ b/src/test/ui/functions-closures/closure-inference2.rs
@@ -1,6 +1,6 @@
 // run-pass
 // Test a rather underspecified example:
-
+#![allow(unused_braces)]
 
 pub fn main() {
     let f = {|i| i};
diff --git a/src/test/ui/generic-associated-types/impl_bounds.stderr b/src/test/ui/generic-associated-types/impl_bounds.stderr
index 486b538045e..d5560c81337 100644
--- a/src/test/ui/generic-associated-types/impl_bounds.stderr
+++ b/src/test/ui/generic-associated-types/impl_bounds.stderr
@@ -34,13 +34,12 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
 LL |     type C where Self: Copy = String;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/impl_bounds.rs:14:6
-   |
-LL | impl<T> Foo for Fooy<T> {
-   |      ^
    = note: required because of the requirements on the impl of `std::marker::Copy` for `Fooy<T>`
    = note: the requirement `Fooy<T>: std::marker::Copy` appears on the associated impl type but not on the corresponding associated trait type
+help: consider restricting type parameter `T`
+   |
+LL | impl<T: std::marker::Copy> Foo for Fooy<T> {
+   |       ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/generic-associated-types/iterable.rs b/src/test/ui/generic-associated-types/iterable.rs
index 616421112db..105ab4a8adc 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 e18c6cec64e..b5bc0c76c2f 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 @@ LL |     type Item;
    = 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 @@ LL |     type Item;
    = 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 @@ LL |     fn iter<'a>(&'a self) -> Self::Iter<'a> {
    = 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/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr
index 6307a9b380e..268ff057421 100644
--- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr
+++ b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr
@@ -9,11 +9,10 @@ LL |     where B : for<'ccx> Bar<'ccx>
 LL |     want_bar_for_any_ccx(b);
    |                          ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
    |
-help: consider further restricting this bound with `+ for<'ccx> Bar<'ccx>`
-  --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:44:11
+help: consider further restricting this bound
    |
-LL |     where B : Qux
-   |           ^^^^^^^
+LL |     where B : Qux + for<'ccx> Bar<'ccx>
+   |                   ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr
index 762c7c05f7a..2e20d2fe6dd 100644
--- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr
+++ b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr
@@ -9,11 +9,10 @@ LL | fn want_foo_for_any_tcx<F>(f: &F)
 LL |     where F : for<'tcx> Foo<'tcx>
    |               ------------------- required by this bound in `want_foo_for_any_tcx`
    |
-help: consider further restricting this bound with `+ for<'tcx> Foo<'tcx>`
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:15:11
+help: consider further restricting this bound
    |
-LL |     where F : Foo<'x>
-   |           ^^^^^^^^^^^
+LL |     where F : Foo<'x> + for<'tcx> Foo<'tcx>
+   |                       ^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
   --> $DIR/hrtb-higher-ranker-supertraits.rs:35:26
@@ -26,11 +25,10 @@ LL | fn want_bar_for_any_ccx<B>(b: &B)
 LL |     where B : for<'ccx> Bar<'ccx>
    |               ------------------- required by this bound in `want_bar_for_any_ccx`
    |
-help: consider further restricting this bound with `+ for<'ccx> Bar<'ccx>`
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:29:11
+help: consider further restricting this bound
    |
-LL |     where B : Bar<'x>
-   |           ^^^^^^^^^^^
+LL |     where B : Bar<'x> + for<'ccx> Bar<'ccx>
+   |                       ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.polonius.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.polonius.stderr
index 558d643cde8..676a934569c 100644
--- a/src/test/ui/hrtb/hrtb-perfect-forwarding.polonius.stderr
+++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.polonius.stderr
@@ -39,6 +39,7 @@ LL | |     // Not OK -- The forwarding impl for `Foo` requires that `Bar` also
 ...  |
 LL | |     foo_hrtb_bar_not(&mut t);
    | |     ------------------------ recursive call site
+LL | |
 LL | | }
    | |_^ cannot return without recursing
    |
@@ -51,7 +52,7 @@ LL |     foo_hrtb_bar_not(&mut t);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: function cannot return without recursing
-  --> $DIR/hrtb-perfect-forwarding.rs:49:1
+  --> $DIR/hrtb-perfect-forwarding.rs:50:1
    |
 LL | / fn foo_hrtb_bar_hrtb<T>(mut t: T)
 LL | |     where T : for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>
diff --git a/src/test/ui/impl-trait/impl-generic-mismatch.rs b/src/test/ui/impl-trait/impl-generic-mismatch.rs
index 615dd6d2f6f..ba678bb032d 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 0c294d1e485..8d8daa063e0 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 @@ LL |     fn foo(&self, _: &impl Debug) { }
    |          --           ^^^^^^^^^^
 
 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 @@ LL |     fn bar<U: Debug>(&self, _: &U) { }
    |           ^^^^^^^^^^            ^
 
 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/impl-trait/issue-55872-1.stderr b/src/test/ui/impl-trait/issue-55872-1.stderr
index d62b8b1c253..6cb2c9fb892 100644
--- a/src/test/ui/impl-trait/issue-55872-1.stderr
+++ b/src/test/ui/impl-trait/issue-55872-1.stderr
@@ -4,13 +4,12 @@ error[E0277]: the trait bound `S: std::marker::Copy` is not satisfied in `(S, T)
 LL |     type E = impl Copy;
    |     ^^^^^^^^^^^^^^^^^^^ within `(S, T)`, the trait `std::marker::Copy` is not implemented for `S`
    |
-help: consider further restricting this bound with `+ std::marker::Copy`
-  --> $DIR/issue-55872-1.rs:11:9
-   |
-LL | impl<S: Default> Bar for S {
-   |         ^^^^^^^
    = note: required because it appears within the type `(S, T)`
    = note: the return type of a function must have a statically known size
+help: consider further restricting this bound
+   |
+LL | impl<S: Default + std::marker::Copy> Bar for S {
+   |                 ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied in `(S, T)`
   --> $DIR/issue-55872-1.rs:12:5
@@ -18,13 +17,12 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied in `(S, T)
 LL |     type E = impl Copy;
    |     ^^^^^^^^^^^^^^^^^^^ within `(S, T)`, the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider further restricting this bound with `+ std::marker::Copy`
-  --> $DIR/issue-55872-1.rs:16:15
-   |
-LL |     fn foo<T: Default>() -> Self::E {
-   |               ^^^^^^^
    = note: required because it appears within the type `(S, T)`
    = note: the return type of a function must have a statically known size
+help: consider further restricting this bound
+   |
+LL |     fn foo<T: Default + std::marker::Copy>() -> Self::E {
+   |                       ^^^^^^^^^^^^^^^^^^^
 
 error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
   --> $DIR/issue-55872-1.rs:16:37
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.polonius.stderr b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.polonius.stderr
index 72e8fa33d7b..6ce3aaf49eb 100644
--- a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.polonius.stderr
+++ b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.polonius.stderr
@@ -1,10 +1,13 @@
 error: lifetime may not live long enough
-  --> $DIR/error-handling.rs:13:56
+  --> $DIR/error-handling.rs:23:16
    |
 LL | fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> {
-   |        --  -- lifetime `'b` defined here               ^^^^^^^^^ opaque type requires that `'a` must outlive `'b`
+   |        --  -- lifetime `'b` defined here
    |        |
    |        lifetime `'a` defined here
+...
+LL |         let _: &'b i32 = *u.0;
+   |                ^^^^^^^ type annotation requires that `'a` must outlive `'b`
    |
    = help: consider adding the following bound: `'a: 'b`
 
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 8c23def95b8..6ff3ab73639 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 e344d059147..3269945a252 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 @@ LL | define_other_core!();
    = 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 b07a7f107da..1b524ec3833 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 374e308a639..c1c4ec9ed7b 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 e6586de4ab6..ddc882cccf3 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 2378e412172..1a726be4aa6 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 @@ LL | pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
    = 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/intrinsics/intrinsic-alignment.rs b/src/test/ui/intrinsics/intrinsic-alignment.rs
index 02e3139d294..896651361be 100644
--- a/src/test/ui/intrinsics/intrinsic-alignment.rs
+++ b/src/test/ui/intrinsics/intrinsic-alignment.rs
@@ -56,16 +56,6 @@ mod m {
 #[cfg(target_os = "windows")]
 mod m {
     #[main]
-    #[cfg(target_arch = "x86")]
-    pub fn main() {
-        unsafe {
-            assert_eq!(::rusti::pref_align_of::<u64>(), 8);
-            assert_eq!(::rusti::min_align_of::<u64>(), 8);
-        }
-    }
-
-    #[main]
-    #[cfg(target_arch = "x86_64")]
     pub fn main() {
         unsafe {
             assert_eq!(::rusti::pref_align_of::<u64>(), 8);
diff --git a/src/test/ui/intrinsics/intrinsic-move-val-cleanups.rs b/src/test/ui/intrinsics/intrinsic-move-val-cleanups.rs
index a2068429af5..9804c421db0 100644
--- a/src/test/ui/intrinsics/intrinsic-move-val-cleanups.rs
+++ b/src/test/ui/intrinsics/intrinsic-move-val-cleanups.rs
@@ -1,4 +1,5 @@
 // run-pass
+#![allow(unused_braces)]
 #![allow(unused_unsafe)]
 #![allow(unreachable_code)]
 // ignore-emscripten no threads support
diff --git a/src/test/ui/issues/issue-17546.rs b/src/test/ui/issues/issue-17546.rs
index c93a03cdec6..dbfdad25e5b 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 2d532cdb9d8..5bbe6d3b171 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 @@ LL |     fn new() -> Result<MyEnum, String> {
    |                 ^^^^^^
 
 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 @@ LL |     use std::result::Result;
      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 @@ LL | use std::result::Result;
      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 a13b7783370..46733566cf3 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 a24dc8a259d..0c3d75c08ff 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-21837.stderr b/src/test/ui/issues/issue-21837.stderr
index cfc294b5fa2..ff0c1ca64e2 100644
--- a/src/test/ui/issues/issue-21837.stderr
+++ b/src/test/ui/issues/issue-21837.stderr
@@ -7,11 +7,10 @@ LL | pub struct Foo<T: Bound>(T);
 LL | impl<T> Trait2 for Foo<T> {}
    |         ^^^^^^ the trait `Bound` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: Bound`
-  --> $DIR/issue-21837.rs:8:6
+help: consider restricting type parameter `T`
    |
-LL | impl<T> Trait2 for Foo<T> {}
-   |      ^
+LL | impl<T: Bound> Trait2 for Foo<T> {}
+   |       ^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-23898.rs b/src/test/ui/issues/issue-23898.rs
index a8787f279b7..3de365675ad 100644
--- a/src/test/ui/issues/issue-23898.rs
+++ b/src/test/ui/issues/issue-23898.rs
@@ -1,4 +1,5 @@
 // run-pass
+#![allow(unused_parens)]
 #![allow(non_camel_case_types)]
 
 // Note: This test was used to demonstrate #5873 (now #23898).
diff --git a/src/test/ui/issues/issue-27033.rs b/src/test/ui/issues/issue-27033.rs
index 2798e510904..a23819a20f9 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 c0de0f14268..3bd7469afff 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 @@ LL | pub use crate::option::Option::{self, None, Some};
    |                                       ---- 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 f00c2304733..7b443b41526 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 6e11dd40288..0cdc501d568 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-28777.rs b/src/test/ui/issues/issue-28777.rs
index 74de00adadb..1f426b7185e 100644
--- a/src/test/ui/issues/issue-28777.rs
+++ b/src/test/ui/issues/issue-28777.rs
@@ -1,4 +1,5 @@
 // run-pass
+#![allow(unused_braces)]
 fn main() {
     let v1 = { 1 + {2} * {3} };
     let v2 =   1 + {2} * {3}  ;
diff --git a/src/test/ui/issues/issue-31173.rs b/src/test/ui/issues/issue-31173.rs
index 25be266c528..26195318380 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 20bfdeea4b1..62c9e566d86 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 @@ LL |         .cloned()
    = 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 @@ LL | pub struct TakeWhile<I, P> {
    | -------------------------- 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-34721.fixed b/src/test/ui/issues/issue-34721.fixed
index ba2810ee3d7..f135ad3836e 100644
--- a/src/test/ui/issues/issue-34721.fixed
+++ b/src/test/ui/issues/issue-34721.fixed
@@ -18,7 +18,7 @@ pub mod bar {
 mod baz {
     use bar;
     use Foo;
-    pub fn baz<T: Copy +  Foo>(x: T) -> T {
+    pub fn baz<T: Foo + Copy>(x: T) -> T {
         if 0 == 1 {
             bar::bar(x.zero())
         } else {
diff --git a/src/test/ui/issues/issue-34721.stderr b/src/test/ui/issues/issue-34721.stderr
index 5c51d044446..6cfed20f43a 100644
--- a/src/test/ui/issues/issue-34721.stderr
+++ b/src/test/ui/issues/issue-34721.stderr
@@ -13,11 +13,10 @@ LL |         };
 LL |         x.zero()
    |         ^ value used here after move
    |
-help: consider further restricting this bound with `+ Copy`
-  --> $DIR/issue-34721.rs:21:19
+help: consider further restricting this bound
    |
-LL |     pub fn baz<T: Foo>(x: T) -> T {
-   |                   ^^^
+LL |     pub fn baz<T: Foo + Copy>(x: T) -> T {
+   |                       ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-38857.rs b/src/test/ui/issues/issue-38857.rs
index c0695f82165..81d881c100b 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 1a287e94baf..ed700ff95e5 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-43784-associated-type.stderr b/src/test/ui/issues/issue-43784-associated-type.stderr
index 2f50a53f26c..21cd39d01fa 100644
--- a/src/test/ui/issues/issue-43784-associated-type.stderr
+++ b/src/test/ui/issues/issue-43784-associated-type.stderr
@@ -9,11 +9,10 @@ LL | impl<T> Complete for T {
 LL |     type Assoc = T;
    |     ^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/issue-43784-associated-type.rs:13:6
+help: consider restricting type parameter `T`
    |
-LL | impl<T> Complete for T {
-   |      ^
+LL | impl<T: std::marker::Copy> Complete for T {
+   |       ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-43784-supertrait.stderr b/src/test/ui/issues/issue-43784-supertrait.stderr
index 1795db32a57..2fb0583ee7d 100644
--- a/src/test/ui/issues/issue-43784-supertrait.stderr
+++ b/src/test/ui/issues/issue-43784-supertrait.stderr
@@ -4,11 +4,10 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
 LL | impl<T> Complete for T {}
    |         ^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/issue-43784-supertrait.rs:8:6
+help: consider restricting type parameter `T`
    |
-LL | impl<T> Complete for T {}
-   |      ^
+LL | impl<T: std::marker::Copy> Complete for T {}
+   |       ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-69725.rs b/src/test/ui/issues/issue-69725.rs
index a8e72e9459e..b8130b41f21 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 439fae95111..d9d61fe66f7 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 00000000000..942b99b742b
--- /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 00000000000..3561f401277
--- /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 00000000000..c2683157f79
--- /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 00000000000..467c15cc52d
--- /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 1571cd2bbf6..5221f2c529b 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 94f489e209e..e86896a5681 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 3845a9aa017..12aa059766b 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 48c2f556f1d..20ecf6bac76 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/kindck/kindck-impl-type-params.nll.stderr b/src/test/ui/kindck/kindck-impl-type-params.nll.stderr
index 593f55a5172..a2f70a8c240 100644
--- a/src/test/ui/kindck/kindck-impl-type-params.nll.stderr
+++ b/src/test/ui/kindck/kindck-impl-type-params.nll.stderr
@@ -5,13 +5,12 @@ LL |     let a = &t as &dyn Gettable<T>;
    |             ^^ `T` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `T`
-help: consider restricting this type parameter with `T: std::marker::Send`
-  --> $DIR/kindck-impl-type-params.rs:16:6
-   |
-LL | fn f<T>(val: T) {
-   |      ^
    = note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
    = note: required for the cast to the object type `dyn Gettable<T>`
+help: consider restricting type parameter `T`
+   |
+LL | fn f<T: std::marker::Send>(val: T) {
+   |       ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
   --> $DIR/kindck-impl-type-params.rs:18:13
@@ -19,13 +18,12 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
 LL |     let a = &t as &dyn Gettable<T>;
    |             ^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/kindck-impl-type-params.rs:16:6
-   |
-LL | fn f<T>(val: T) {
-   |      ^
    = note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
    = note: required for the cast to the object type `dyn Gettable<T>`
+help: consider restricting type parameter `T`
+   |
+LL | fn f<T: std::marker::Copy>(val: T) {
+   |       ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `T` cannot be sent between threads safely
   --> $DIR/kindck-impl-type-params.rs:25:31
@@ -34,13 +32,12 @@ LL |     let a: &dyn Gettable<T> = &t;
    |                               ^^ `T` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `T`
-help: consider restricting this type parameter with `T: std::marker::Send`
-  --> $DIR/kindck-impl-type-params.rs:23:6
-   |
-LL | fn g<T>(val: T) {
-   |      ^
    = note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
    = note: required for the cast to the object type `dyn Gettable<T>`
+help: consider restricting type parameter `T`
+   |
+LL | fn g<T: std::marker::Send>(val: T) {
+   |       ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
   --> $DIR/kindck-impl-type-params.rs:25:31
@@ -48,13 +45,12 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
 LL |     let a: &dyn Gettable<T> = &t;
    |                               ^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/kindck-impl-type-params.rs:23:6
-   |
-LL | fn g<T>(val: T) {
-   |      ^
    = note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
    = note: required for the cast to the object type `dyn Gettable<T>`
+help: consider restricting type parameter `T`
+   |
+LL | fn g<T: std::marker::Copy>(val: T) {
+   |       ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied
   --> $DIR/kindck-impl-type-params.rs:38:13
diff --git a/src/test/ui/kindck/kindck-impl-type-params.stderr b/src/test/ui/kindck/kindck-impl-type-params.stderr
index 42318623b4d..cc98f1d9f34 100644
--- a/src/test/ui/kindck/kindck-impl-type-params.stderr
+++ b/src/test/ui/kindck/kindck-impl-type-params.stderr
@@ -5,13 +5,12 @@ LL |     let a = &t as &dyn Gettable<T>;
    |             ^^ `T` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `T`
-help: consider restricting this type parameter with `T: std::marker::Send`
-  --> $DIR/kindck-impl-type-params.rs:16:6
-   |
-LL | fn f<T>(val: T) {
-   |      ^
    = note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
    = note: required for the cast to the object type `dyn Gettable<T>`
+help: consider restricting type parameter `T`
+   |
+LL | fn f<T: std::marker::Send>(val: T) {
+   |       ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
   --> $DIR/kindck-impl-type-params.rs:18:13
@@ -19,13 +18,12 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
 LL |     let a = &t as &dyn Gettable<T>;
    |             ^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/kindck-impl-type-params.rs:16:6
-   |
-LL | fn f<T>(val: T) {
-   |      ^
    = note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
    = note: required for the cast to the object type `dyn Gettable<T>`
+help: consider restricting type parameter `T`
+   |
+LL | fn f<T: std::marker::Copy>(val: T) {
+   |       ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `T` cannot be sent between threads safely
   --> $DIR/kindck-impl-type-params.rs:25:31
@@ -34,13 +32,12 @@ LL |     let a: &dyn Gettable<T> = &t;
    |                               ^^ `T` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `T`
-help: consider restricting this type parameter with `T: std::marker::Send`
-  --> $DIR/kindck-impl-type-params.rs:23:6
-   |
-LL | fn g<T>(val: T) {
-   |      ^
    = note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
    = note: required for the cast to the object type `dyn Gettable<T>`
+help: consider restricting type parameter `T`
+   |
+LL | fn g<T: std::marker::Send>(val: T) {
+   |       ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
   --> $DIR/kindck-impl-type-params.rs:25:31
@@ -48,13 +45,12 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
 LL |     let a: &dyn Gettable<T> = &t;
    |                               ^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/kindck-impl-type-params.rs:23:6
-   |
-LL | fn g<T>(val: T) {
-   |      ^
    = note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
    = note: required for the cast to the object type `dyn Gettable<T>`
+help: consider restricting type parameter `T`
+   |
+LL | fn g<T: std::marker::Copy>(val: T) {
+   |       ^^^^^^^^^^^^^^^^^^^
 
 error[E0477]: the type `&'a isize` does not fulfill the required lifetime
   --> $DIR/kindck-impl-type-params.rs:32:13
diff --git a/src/test/ui/lint/lint-unnecessary-parens.rs b/src/test/ui/lint/lint-unnecessary-parens.rs
index 5ce1f576081..623cd04d9bc 100644
--- a/src/test/ui/lint/lint-unnecessary-parens.rs
+++ b/src/test/ui/lint/lint-unnecessary-parens.rs
@@ -48,11 +48,11 @@ fn main() {
     if (true) {} //~ ERROR unnecessary parentheses around `if` condition
     while (true) {} //~ ERROR unnecessary parentheses around `while` condition
     //~^ WARN denote infinite loops with
-    match (true) { //~ ERROR unnecessary parentheses around `match` head expression
+    match (true) { //~ ERROR unnecessary parentheses around `match` scrutinee expression
         _ => {}
     }
-    if let 1 = (1) {} //~ ERROR unnecessary parentheses around `let` head expression
-    while let 1 = (2) {} //~ ERROR unnecessary parentheses around `let` head expression
+    if let 1 = (1) {} //~ ERROR unnecessary parentheses around `let` scrutinee expression
+    while let 1 = (2) {} //~ ERROR unnecessary parentheses around `let` scrutinee expression
     let v = X { y: false };
     // struct lits needs parens, so these shouldn't warn.
     if (v == X { y: true }) {}
diff --git a/src/test/ui/lint/lint-unnecessary-parens.stderr b/src/test/ui/lint/lint-unnecessary-parens.stderr
index 8858c953273..15184ba36ae 100644
--- a/src/test/ui/lint/lint-unnecessary-parens.stderr
+++ b/src/test/ui/lint/lint-unnecessary-parens.stderr
@@ -72,19 +72,19 @@ LL |     while (true) {}
    |
    = note: `#[warn(while_true)]` on by default
 
-error: unnecessary parentheses around `match` head expression
+error: unnecessary parentheses around `match` scrutinee expression
   --> $DIR/lint-unnecessary-parens.rs:51:11
    |
 LL |     match (true) {
    |           ^^^^^^ help: remove these parentheses
 
-error: unnecessary parentheses around `let` head expression
+error: unnecessary parentheses around `let` scrutinee expression
   --> $DIR/lint-unnecessary-parens.rs:54:16
    |
 LL |     if let 1 = (1) {}
    |                ^^^ help: remove these parentheses
 
-error: unnecessary parentheses around `let` head expression
+error: unnecessary parentheses around `let` scrutinee expression
   --> $DIR/lint-unnecessary-parens.rs:55:19
    |
 LL |     while let 1 = (2) {}
diff --git a/src/test/ui/lint/unused_braces.rs b/src/test/ui/lint/unused_braces.rs
new file mode 100644
index 00000000000..de456ee6c23
--- /dev/null
+++ b/src/test/ui/lint/unused_braces.rs
@@ -0,0 +1,31 @@
+// check-pass
+#![warn(unused_braces, unused_parens)]
+
+fn main() {
+    let _ = (7);
+    //~^WARN unnecessary parentheses
+
+    let _ = { 7 };
+    //~^ WARN unnecessary braces
+
+    if let 7 = { 7 } {
+        //~^ WARN unnecessary braces
+    }
+
+    let _: [u8; { 3 }];
+    //~^ WARN unnecessary braces
+
+    // do not emit error for multiline blocks.
+    let _ = {
+        7
+    };
+
+    // do not emit error for unsafe blocks.
+    let _ = unsafe { 7 };
+
+    // do not emit error, as the `{` would then
+    // be parsed as part of the `return`.
+    if { return } {
+
+    }
+}
diff --git a/src/test/ui/lint/unused_braces.stderr b/src/test/ui/lint/unused_braces.stderr
new file mode 100644
index 00000000000..72f425ffc3e
--- /dev/null
+++ b/src/test/ui/lint/unused_braces.stderr
@@ -0,0 +1,36 @@
+warning: unnecessary parentheses around assigned value
+  --> $DIR/unused_braces.rs:5:13
+   |
+LL |     let _ = (7);
+   |             ^^^ help: remove these parentheses
+   |
+note: the lint level is defined here
+  --> $DIR/unused_braces.rs:2:24
+   |
+LL | #![warn(unused_braces, unused_parens)]
+   |                        ^^^^^^^^^^^^^
+
+warning: unnecessary braces around assigned value
+  --> $DIR/unused_braces.rs:8:13
+   |
+LL |     let _ = { 7 };
+   |             ^^^^^ help: remove these braces
+   |
+note: the lint level is defined here
+  --> $DIR/unused_braces.rs:2:9
+   |
+LL | #![warn(unused_braces, unused_parens)]
+   |         ^^^^^^^^^^^^^
+
+warning: unnecessary braces around `let` scrutinee expression
+  --> $DIR/unused_braces.rs:11:16
+   |
+LL |     if let 7 = { 7 } {
+   |                ^^^^^ help: remove these braces
+
+warning: unnecessary braces around const expression
+  --> $DIR/unused_braces.rs:15:17
+   |
+LL |     let _: [u8; { 3 }];
+   |                 ^^^^^ help: remove these braces
+
diff --git a/src/test/ui/lint/unused_parens_borrow.rs b/src/test/ui/lint/unused_parens_borrow.rs
new file mode 100644
index 00000000000..98dbbecfedd
--- /dev/null
+++ b/src/test/ui/lint/unused_parens_borrow.rs
@@ -0,0 +1,22 @@
+// check-pass
+#![warn(unused_braces)]
+
+// changing `&{ expr }` to `&expr` changes the semantic of the program
+// so we should not warn this case
+
+#[repr(packed)]
+struct A {
+    a: u8,
+    b: u32,
+}
+
+fn main() {
+    let a = A {
+        a: 42,
+        b: 1729,
+    };
+
+    let _ = &{ a.b };
+    let _ = { a.b };
+    //~^ WARN unnecessary braces
+}
diff --git a/src/test/ui/lint/unused_parens_borrow.stderr b/src/test/ui/lint/unused_parens_borrow.stderr
new file mode 100644
index 00000000000..7e3839ae4e0
--- /dev/null
+++ b/src/test/ui/lint/unused_parens_borrow.stderr
@@ -0,0 +1,12 @@
+warning: unnecessary braces around assigned value
+  --> $DIR/unused_parens_borrow.rs:20:13
+   |
+LL |     let _ = { a.b };
+   |             ^^^^^^^ help: remove these braces
+   |
+note: the lint level is defined here
+  --> $DIR/unused_parens_borrow.rs:2:9
+   |
+LL | #![warn(unused_braces)]
+   |         ^^^^^^^^^^^^^
+
diff --git a/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr b/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr
index c3bf77a3a6f..5fb67fd7c95 100644
--- a/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr
+++ b/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr
@@ -46,14 +46,14 @@ LL |     while(true && false) {
    |          ^^^^^^^^^^^^^^^ help: remove these parentheses
 
 "}
-{"message":"unnecessary parentheses around `for` head expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":987,"byte_end":995,"line_start":44,"line_end":44,"column_start":18,"column_end":26,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){
+{"message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":987,"byte_end":995,"line_start":44,"line_end":44,"column_start":18,"column_end":26,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){
   --> $DIR/unused_parens_remove_json_suggestion.rs:44:18
    |
 LL |         for _ in (0 .. 3){
    |                  ^^^^^^^^ help: remove these parentheses
 
 "}
-{"message":"unnecessary parentheses around `for` head expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1088,"byte_end":1096,"line_start":49,"line_end":49,"column_start":14,"column_end":22,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {
+{"message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1088,"byte_end":1096,"line_start":49,"line_end":49,"column_start":14,"column_end":22,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {
   --> $DIR/unused_parens_remove_json_suggestion.rs:49:14
    |
 LL |     for _ in (0 .. 3) {
diff --git a/src/test/ui/macros/macro-name-typo.rs b/src/test/ui/macros/macro-name-typo.rs
index b2892f3b6c2..1ddc419d302 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 00afbde8932..5604341fa34 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 3c3948ca3c3..68eb350a956 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 53645906743..3e3a0b3879b 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 716a0005ba3..a96b99ae4ff 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 ed163750a6e..665e92f2424 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/malformed/malformed-regressions.stderr b/src/test/ui/malformed/malformed-regressions.stderr
index b14f99be50c..13c12ff7213 100644
--- a/src/test/ui/malformed/malformed-regressions.stderr
+++ b/src/test/ui/malformed/malformed-regressions.stderr
@@ -26,7 +26,7 @@ LL | #[inline = ""]
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
-error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ cfg = "...")]`
+error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...")]`
   --> $DIR/malformed-regressions.rs:7:1
    |
 LL | #[link]
@@ -35,7 +35,7 @@ LL | #[link]
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
-error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ cfg = "...")]`
+error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...")]`
   --> $DIR/malformed-regressions.rs:9:1
    |
 LL | #[link = ""]
diff --git a/src/test/ui/mismatched_types/issue-36053-2.rs b/src/test/ui/mismatched_types/issue-36053-2.rs
index 36211b4ce70..9035e3380b0 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 f8c0470172d..2793acf8857 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 @@ LL | pub struct Filter<I, P> {
    | ----------------------- 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/moves/moves-based-on-type-no-recursive-stack-closure.stderr b/src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr
index 552273b8ba9..a30bfa66c5a 100644
--- a/src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr
+++ b/src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr
@@ -17,11 +17,10 @@ LL |     let mut r = R {c: Box::new(f)};
 LL |     f(&mut r, false)
    |     ^ value borrowed here after move
    |
-help: consider further restricting this bound with `+ Copy`
-  --> $DIR/moves-based-on-type-no-recursive-stack-closure.rs:30:35
+help: consider further restricting this bound
    |
-LL | fn conspirator<F>(mut f: F) where F: FnMut(&mut R, bool) {
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^
+LL | fn conspirator<F>(mut f: F) where F: FnMut(&mut R, bool) + Copy {
+   |                                                          ^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/nll/outlives-suggestion-simple.polonius.stderr b/src/test/ui/nll/outlives-suggestion-simple.polonius.stderr
index 815744618f6..dbbda62d208 100644
--- a/src/test/ui/nll/outlives-suggestion-simple.polonius.stderr
+++ b/src/test/ui/nll/outlives-suggestion-simple.polonius.stderr
@@ -72,6 +72,8 @@ LL |     (x, x)
    |
    = help: consider adding the following bound: `'a: 'c`
 
+help: add bound `'a: 'b + 'c`
+
 error: lifetime may not live long enough
   --> $DIR/outlives-suggestion-simple.rs:31:9
    |
@@ -106,16 +108,16 @@ LL |         self.x
    |
    = help: consider adding the following bound: `'b: 'a`
 
-error[E0521]: borrowed data escapes outside of function
+error[E0521]: borrowed data escapes outside of associated function
   --> $DIR/outlives-suggestion-simple.rs:73:9
    |
 LL |     fn get_bar(&self) -> Bar2 {
    |                -----
    |                |
-   |                `self` is declared here, outside of the function body
-   |                `self` is a reference that is only valid in the function body
+   |                `self` declared here, outside of the associated function body
+   |                `self` is a reference that is only valid in the associated function body
 LL |         Bar2::new(&self)
-   |         ^^^^^^^^^^^^^^^^ `self` escapes the function body here
+   |         ^^^^^^^^^^^^^^^^ `self` escapes the associated function body here
 
 error: aborting due to 10 previous errors
 
diff --git a/src/test/ui/nll/user-annotations/closure-substs.polonius.stderr b/src/test/ui/nll/user-annotations/closure-substs.polonius.stderr
index d5bcdf64441..46b6c04dcbc 100644
--- a/src/test/ui/nll/user-annotations/closure-substs.polonius.stderr
+++ b/src/test/ui/nll/user-annotations/closure-substs.polonius.stderr
@@ -50,7 +50,7 @@ error[E0521]: borrowed data escapes outside of closure
   --> $DIR/closure-substs.rs:29:9
    |
 LL |     |x: &i32, b: fn(&'static i32)| {
-   |      -        - `b` is declared here, outside of the closure body
+   |      -        - `b` declared here, outside of the closure body
    |      |
    |      `x` is a reference that is only valid in the closure body
 LL |         b(x);
diff --git a/src/test/ui/no-send-res-ports.rs b/src/test/ui/no-send-res-ports.rs
index 6a1965f7cd3..e10f447365e 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 65946ee8a20..13683cf86db 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 | |
 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 186731f2e72..ddaaee436ae 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 dd67a110d22..78d212f7a7b 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 731f4ab9c78..11b6eb736e9 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 472ce34870a..994eb65ae15 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/once-cant-call-twice-on-heap.stderr b/src/test/ui/once-cant-call-twice-on-heap.stderr
index d4884469ce4..7133a32431a 100644
--- a/src/test/ui/once-cant-call-twice-on-heap.stderr
+++ b/src/test/ui/once-cant-call-twice-on-heap.stderr
@@ -8,11 +8,10 @@ LL |     blk();
 LL |     blk();
    |     ^^^ value used here after move
    |
-help: consider further restricting this bound with `+ Copy`
-  --> $DIR/once-cant-call-twice-on-heap.rs:7:10
+help: consider further restricting this bound
    |
-LL | fn foo<F:FnOnce()>(blk: F) {
-   |          ^^^^^^^^
+LL | fn foo<F:FnOnce() + Copy>(blk: F) {
+   |                   ^^^^^^
 
 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 e38b7b65089..b9c0bf834dd 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 4a1d7e275be..73e3552e3ec 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 @@ LL | fn main() {}
    |              ^
 
 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 @@ LL | fn main() {}
    |              ^
 
 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 @@ LL | fn main() {}
    |              ^
 
 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 15cd3df860b..80a450dbd36 100644
--- a/src/test/ui/parser/issue-63116.stderr
+++ b/src/test/ui/parser/issue-63116.stderr
@@ -12,7 +12,7 @@ error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `;`
 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/issue-70549-resolve-after-recovered-self-ctor.rs b/src/test/ui/parser/issue-70549-resolve-after-recovered-self-ctor.rs
new file mode 100644
index 00000000000..aeccd0d9f76
--- /dev/null
+++ b/src/test/ui/parser/issue-70549-resolve-after-recovered-self-ctor.rs
@@ -0,0 +1,18 @@
+struct S {}
+
+impl S {
+    fn foo(&mur Self) {}
+    //~^ ERROR expected identifier, found keyword `Self`
+    //~| ERROR expected one of `:`, `@`
+    //~| ERROR the `Self` constructor can only be used with
+    fn bar(&'static mur Self) {}
+    //~^ ERROR unexpected lifetime
+    //~| ERROR expected identifier, found keyword `Self`
+    //~| ERROR expected one of `:`, `@`
+    //~| ERROR the `Self` constructor can only be used with
+
+    fn baz(&mur Self @ _) {}
+    //~^ ERROR expected one of `:`, `@`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-70549-resolve-after-recovered-self-ctor.stderr b/src/test/ui/parser/issue-70549-resolve-after-recovered-self-ctor.stderr
new file mode 100644
index 00000000000..421f1454036
--- /dev/null
+++ b/src/test/ui/parser/issue-70549-resolve-after-recovered-self-ctor.stderr
@@ -0,0 +1,56 @@
+error: expected identifier, found keyword `Self`
+  --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:4:17
+   |
+LL |     fn foo(&mur Self) {}
+   |                 ^^^^ expected identifier, found keyword
+
+error: expected one of `:`, `@`, or `|`, found keyword `Self`
+  --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:4:17
+   |
+LL |     fn foo(&mur Self) {}
+   |            -----^^^^
+   |            |    |
+   |            |    expected one of `:`, `@`, or `|`
+   |            help: declare the type after the parameter binding: `<identifier>: <type>`
+
+error: unexpected lifetime `'static` in pattern
+  --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:13
+   |
+LL |     fn bar(&'static mur Self) {}
+   |             ^^^^^^^ help: remove the lifetime
+
+error: expected identifier, found keyword `Self`
+  --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:25
+   |
+LL |     fn bar(&'static mur Self) {}
+   |                         ^^^^ expected identifier, found keyword
+
+error: expected one of `:`, `@`, or `|`, found keyword `Self`
+  --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:25
+   |
+LL |     fn bar(&'static mur Self) {}
+   |            -------------^^^^
+   |            |            |
+   |            |            expected one of `:`, `@`, or `|`
+   |            help: declare the type after the parameter binding: `<identifier>: <type>`
+
+error: expected one of `:`, `@`, or `|`, found keyword `Self`
+  --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:14:17
+   |
+LL |     fn baz(&mur Self @ _) {}
+   |                 ^^^^ expected one of `:`, `@`, or `|`
+
+error: the `Self` constructor can only be used with tuple or unit structs
+  --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:4:17
+   |
+LL |     fn foo(&mur Self) {}
+   |                 ^^^^ help: use curly brackets: `Self { /* fields */ }`
+
+error: the `Self` constructor can only be used with tuple or unit structs
+  --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:25
+   |
+LL |     fn bar(&'static mur Self) {}
+   |                         ^^^^ help: use curly brackets: `Self { /* fields */ }`
+
+error: aborting due to 8 previous errors
+
diff --git a/src/test/ui/parser/issue-70552-ascription-in-parens-after-call.rs b/src/test/ui/parser/issue-70552-ascription-in-parens-after-call.rs
new file mode 100644
index 00000000000..9b6dd7db4be
--- /dev/null
+++ b/src/test/ui/parser/issue-70552-ascription-in-parens-after-call.rs
@@ -0,0 +1,3 @@
+fn main() {
+    expr as fun()(:); //~ ERROR expected expression
+}
diff --git a/src/test/ui/parser/issue-70552-ascription-in-parens-after-call.stderr b/src/test/ui/parser/issue-70552-ascription-in-parens-after-call.stderr
new file mode 100644
index 00000000000..f03c92e1b1f
--- /dev/null
+++ b/src/test/ui/parser/issue-70552-ascription-in-parens-after-call.stderr
@@ -0,0 +1,8 @@
+error: expected expression, found `:`
+  --> $DIR/issue-70552-ascription-in-parens-after-call.rs:2:19
+   |
+LL |     expr as fun()(:);
+   |                   ^ expected expression
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/raw-str-unbalanced.rs b/src/test/ui/parser/raw-str-unbalanced.rs
deleted file mode 100644
index 5a1d1be11b6..00000000000
--- a/src/test/ui/parser/raw-str-unbalanced.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-static s: &'static str =
-    r#"
-      "## //~ ERROR expected one of `.`, `;`, `?`, or an operator, found `#`
-;
diff --git a/src/test/ui/parser/raw-str-unbalanced.stderr b/src/test/ui/parser/raw-str-unbalanced.stderr
deleted file mode 100644
index ddb75722bef..00000000000
--- a/src/test/ui/parser/raw-str-unbalanced.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: expected one of `.`, `;`, `?`, or an operator, found `#`
-  --> $DIR/raw-str-unbalanced.rs:3:9
-   |
-LL |       "##
-   |         ^ expected one of `.`, `;`, `?`, or an operator
-
-error: aborting due to previous error
-
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 00000000000..bdfc29a3d57
--- /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 00000000000..3a7e2a4b14a
--- /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/raw-byte-string-eof.rs b/src/test/ui/parser/raw/raw-byte-string-eof.rs
index b74907b72b0..b74907b72b0 100644
--- a/src/test/ui/parser/raw-byte-string-eof.rs
+++ b/src/test/ui/parser/raw/raw-byte-string-eof.rs
diff --git a/src/test/ui/parser/raw-byte-string-eof.stderr b/src/test/ui/parser/raw/raw-byte-string-eof.stderr
index d5f22e2a1a8..a76668e8051 100644
--- a/src/test/ui/parser/raw-byte-string-eof.stderr
+++ b/src/test/ui/parser/raw/raw-byte-string-eof.stderr
@@ -2,7 +2,9 @@ error[E0748]: unterminated raw string
   --> $DIR/raw-byte-string-eof.rs:2:5
    |
 LL |     br##"a"#;
-   |     ^ unterminated raw string
+   |     ^      - help: consider terminating the string here: `##`
+   |     |
+   |     unterminated raw string
    |
    = note: this raw string should be terminated with `"##`
 
diff --git a/src/test/ui/parser/raw-byte-string-literals.rs b/src/test/ui/parser/raw/raw-byte-string-literals.rs
index 163c8ac66b0..163c8ac66b0 100644
--- a/src/test/ui/parser/raw-byte-string-literals.rs
+++ b/src/test/ui/parser/raw/raw-byte-string-literals.rs
diff --git a/src/test/ui/parser/raw-byte-string-literals.stderr b/src/test/ui/parser/raw/raw-byte-string-literals.stderr
index 4076fe334e6..4076fe334e6 100644
--- a/src/test/ui/parser/raw-byte-string-literals.stderr
+++ b/src/test/ui/parser/raw/raw-byte-string-literals.stderr
diff --git a/src/test/ui/parser/raw-str-delim.rs b/src/test/ui/parser/raw/raw-str-delim.rs
index 2f13893cecd..2f13893cecd 100644
--- a/src/test/ui/parser/raw-str-delim.rs
+++ b/src/test/ui/parser/raw/raw-str-delim.rs
diff --git a/src/test/ui/parser/raw-str-delim.stderr b/src/test/ui/parser/raw/raw-str-delim.stderr
index 8a04f99a126..8a04f99a126 100644
--- a/src/test/ui/parser/raw-str-delim.stderr
+++ b/src/test/ui/parser/raw/raw-str-delim.stderr
diff --git a/src/test/ui/parser/raw/raw-str-in-macro-call.rs b/src/test/ui/parser/raw/raw-str-in-macro-call.rs
new file mode 100644
index 00000000000..462c2279f5c
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-str-in-macro-call.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+macro_rules! m1 {
+    ($tt:tt #) => ()
+}
+
+macro_rules! m2 {
+    ($tt:tt) => ()
+}
+
+fn main() {
+    m1!(r#"abc"##);
+    m2!(r#"abc"#);
+}
diff --git a/src/test/ui/parser/raw/raw-str-unbalanced.rs b/src/test/ui/parser/raw/raw-str-unbalanced.rs
new file mode 100644
index 00000000000..35f118f5ce6
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-str-unbalanced.rs
@@ -0,0 +1,4 @@
+static s: &'static str =
+    r#"
+      "## //~ too many `#` when terminating raw string
+;
diff --git a/src/test/ui/parser/raw/raw-str-unbalanced.stderr b/src/test/ui/parser/raw/raw-str-unbalanced.stderr
new file mode 100644
index 00000000000..bf8f3a7a5a4
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-str-unbalanced.stderr
@@ -0,0 +1,10 @@
+error: too many `#` when terminating raw string
+  --> $DIR/raw-str-unbalanced.rs:3:9
+   |
+LL |       "##
+   |         ^ help: remove the extra `#`
+   |
+   = note: the raw string started with 1 `#`s
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/raw-str-unterminated.rs b/src/test/ui/parser/raw/raw-str-unterminated.rs
index fd317295561..fd317295561 100644
--- a/src/test/ui/parser/raw-str-unterminated.rs
+++ b/src/test/ui/parser/raw/raw-str-unterminated.rs
diff --git a/src/test/ui/parser/raw-str-unterminated.stderr b/src/test/ui/parser/raw/raw-str-unterminated.stderr
index 077f763f154..077f763f154 100644
--- a/src/test/ui/parser/raw-str-unterminated.stderr
+++ b/src/test/ui/parser/raw/raw-str-unterminated.stderr
diff --git a/src/test/ui/parser/raw/raw-string-2.rs b/src/test/ui/parser/raw/raw-string-2.rs
new file mode 100644
index 00000000000..067332d2819
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-string-2.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let x = r###"here's a long string"# "# "##;
+    //~^ ERROR unterminated raw string
+}
diff --git a/src/test/ui/parser/raw/raw-string-2.stderr b/src/test/ui/parser/raw/raw-string-2.stderr
new file mode 100644
index 00000000000..8bbac9d7bd0
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-string-2.stderr
@@ -0,0 +1,11 @@
+error[E0748]: unterminated raw string
+  --> $DIR/raw-string-2.rs:2:13
+   |
+LL |     let x = r###"here's a long string"# "# "##;
+   |             ^ unterminated raw string       -- help: consider terminating the string here: `###`
+   |
+   = note: this raw string should be terminated with `"###`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0748`.
diff --git a/src/test/ui/parser/raw/raw_string.rs b/src/test/ui/parser/raw/raw-string.rs
index 84f07c4a941..84f07c4a941 100644
--- a/src/test/ui/parser/raw/raw_string.rs
+++ b/src/test/ui/parser/raw/raw-string.rs
diff --git a/src/test/ui/parser/raw/raw_string.stderr b/src/test/ui/parser/raw/raw-string.stderr
index 0f1d7e4651d..b2b853a89e7 100644
--- a/src/test/ui/parser/raw/raw_string.stderr
+++ b/src/test/ui/parser/raw/raw-string.stderr
@@ -1,8 +1,10 @@
 error[E0748]: unterminated raw string
-  --> $DIR/raw_string.rs:2:13
+  --> $DIR/raw-string.rs:2:13
    |
 LL |     let x = r##"lol"#;
-   |             ^ unterminated raw string
+   |             ^       - help: consider terminating the string here: `##`
+   |             |
+   |             unterminated raw string
    |
    = note: this raw string should be terminated with `"##`
 
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 00000000000..25af8772ced
--- /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 00000000000..7012096b644
--- /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 728d4a64495..4c5f2d35649 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 09b92fc92f3..3d329e2e6ef 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 @@ LL |     match (true, false) {
    = 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 @@ LL |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
    = 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 c7cde468bb9..315eb03d165 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 62e6e662fa7..50a4674def7 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 59f7bb892c6..9947989dc12 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 358ecf2f2d0..436a293b6ce 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 @@ LL |     match x { T::B => { } }
    = 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 @@ LL |     match true {
    = 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 @@ LL |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
    = 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 @@ LL |     match (2, 3, 4) {
    = 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 @@ LL |     match (T::A, T::A) {
    = 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 @@ LL |     match T::A {
    = 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 @@ LL |     match *vec {
    = 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/phantom-oibit.stderr b/src/test/ui/phantom-oibit.stderr
index 7b6b105eb03..f8fe6947852 100644
--- a/src/test/ui/phantom-oibit.stderr
+++ b/src/test/ui/phantom-oibit.stderr
@@ -8,14 +8,13 @@ LL |     is_zen(x)
    |            ^ `T` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `T`
-help: consider restricting this type parameter with `T: std::marker::Sync`
-  --> $DIR/phantom-oibit.rs:20:13
-   |
-LL | fn not_sync<T>(x: Guard<T>) {
-   |             ^
    = note: required because of the requirements on the impl of `Zen` for `&T`
    = note: required because it appears within the type `std::marker::PhantomData<&T>`
    = note: required because it appears within the type `Guard<'_, T>`
+help: consider restricting type parameter `T`
+   |
+LL | fn not_sync<T: std::marker::Sync>(x: Guard<T>) {
+   |              ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `T` cannot be shared between threads safely
   --> $DIR/phantom-oibit.rs:26:12
@@ -27,15 +26,14 @@ LL |     is_zen(x)
    |            ^ `T` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `T`
-help: consider restricting this type parameter with `T: std::marker::Sync`
-  --> $DIR/phantom-oibit.rs:25:20
-   |
-LL | fn nested_not_sync<T>(x: Nested<Guard<T>>) {
-   |                    ^
    = note: required because of the requirements on the impl of `Zen` for `&T`
    = note: required because it appears within the type `std::marker::PhantomData<&T>`
    = note: required because it appears within the type `Guard<'_, T>`
    = note: required because it appears within the type `Nested<Guard<'_, T>>`
+help: consider restricting type parameter `T`
+   |
+LL | fn nested_not_sync<T: std::marker::Sync>(x: Nested<Guard<T>>) {
+   |                     ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/proc-macro/parent-source-spans.rs b/src/test/ui/proc-macro/parent-source-spans.rs
index 95a3f969512..7b2ffefb05b 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 254f87751fd..c7d15b43e89 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 @@ LL |     one!("hello", "world");
    = 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 @@ LL |     one!("hello", "world");
    = 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 @@ LL |     one!("hello", "world");
    = 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 @@ LL |     one!("hello", "world");
    = 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 @@ LL |     two!("yay", "rust");
    = 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 @@ LL |     two!("yay", "rust");
    = 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 @@ LL |     Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
    = 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 @@ LL |     Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
    = 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 8ff36ff0a26..ad8a5bbb0f9 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 15a1d6d9479..fc189828ad1 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 @@ LL | pub fn empty(_: TokenStream) -> TokenStream {
    | ------------------------------------------- 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 @@ LL |     attr_proc_macra!();
    |     ^^^^^^^^^^^^^^^ 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 @@ LL |     FooWithLongNama!();
    |     ^^^^^^^^^^^^^^^ 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 @@ LL | pub fn derive_clonea(input: TokenStream) -> TokenStream {
    | ------------------------------------------------------- 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 @@ LL | pub fn derive_clonea(input: TokenStream) -> TokenStream {
    | ------------------------------------------------------- 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 @@ LL | pub macro Clone($item:item) {
    | --------------------------- 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 @@ LL | pub macro Clone($item:item) {
    | --------------------------- 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 @@ LL | pub fn empty_attr(_: TokenStream, _: TokenStream) -> TokenStream {
    | ---------------------------------------------------------------- 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 @@ LL | pub fn derive_foo(input: TokenStream) -> TokenStream {
    | ---------------------------------------------------- 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/range.rs b/src/test/ui/range.rs
index 82983e37ea1..f3f7508d124 100644
--- a/src/test/ui/range.rs
+++ b/src/test/ui/range.rs
@@ -1,5 +1,5 @@
 // run-pass
-
+#![allow(unused_braces)]
 #![allow(unused_comparisons)]
 #![allow(dead_code)]
 #![allow(unused_mut)]
diff --git a/src/test/ui/range_inclusive.rs b/src/test/ui/range_inclusive.rs
index 68d9bf7d26b..540b35e0392 100644
--- a/src/test/ui/range_inclusive.rs
+++ b/src/test/ui/range_inclusive.rs
@@ -1,7 +1,7 @@
 // run-pass
 // Test inclusive range syntax.
-
 #![feature(range_is_empty)]
+#![allow(unused_braces)]
 #![allow(unused_comparisons)]
 
 use std::ops::RangeToInclusive;
diff --git a/src/test/ui/realloc-16687.rs b/src/test/ui/realloc-16687.rs
index eb6224ad1bb..0687a9ce454 100644
--- a/src/test/ui/realloc-16687.rs
+++ b/src/test/ui/realloc-16687.rs
@@ -6,7 +6,7 @@
 
 #![feature(allocator_api)]
 
-use std::alloc::{Global, AllocRef, Layout, handle_alloc_error};
+use std::alloc::{handle_alloc_error, AllocInit, AllocRef, Global, Layout, ReallocPlacement};
 use std::ptr::{self, NonNull};
 
 fn main() {
@@ -16,17 +16,17 @@ fn main() {
 }
 
 unsafe fn test_triangle() -> bool {
-    static COUNT : usize = 16;
+    static COUNT: usize = 16;
     let mut ascend = vec![ptr::null_mut(); COUNT];
     let ascend = &mut *ascend;
-    static ALIGN : usize = 1;
+    static ALIGN: usize = 1;
 
     // Checks that `ascend` forms triangle of ascending size formed
     // from pairs of rows (where each pair of rows is equally sized),
     // and the elements of the triangle match their row-pair index.
     unsafe fn sanity_check(ascend: &[*mut u8]) {
         for i in 0..COUNT / 2 {
-            let (p0, p1, size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
+            let (p0, p1, size) = (ascend[2 * i], ascend[2 * i + 1], idx_to_size(i));
             for j in 0..size {
                 assert_eq!(*p0.add(j), i as u8);
                 assert_eq!(*p1.add(j), i as u8);
@@ -34,20 +34,22 @@ unsafe fn test_triangle() -> bool {
         }
     }
 
-    static PRINT : bool = false;
+    static PRINT: bool = false;
 
     unsafe fn allocate(layout: Layout) -> *mut u8 {
         if PRINT {
             println!("allocate({:?})", layout);
         }
 
-        let (ptr, _) = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout));
+        let memory = Global
+            .alloc(layout, AllocInit::Uninitialized)
+            .unwrap_or_else(|_| handle_alloc_error(layout));
 
         if PRINT {
-            println!("allocate({:?}) = {:?}", layout, ptr);
+            println!("allocate({:?}) = {:?}", layout, memory.ptr);
         }
 
-        ptr.cast().as_ptr()
+        memory.ptr.cast().as_ptr()
     }
 
     unsafe fn deallocate(ptr: *mut u8, layout: Layout) {
@@ -63,19 +65,31 @@ unsafe fn test_triangle() -> bool {
             println!("reallocate({:?}, old={:?}, new={:?})", ptr, old, new);
         }
 
-        let (ptr, _) = Global.realloc(NonNull::new_unchecked(ptr), old, new.size())
-            .unwrap_or_else(|_| handle_alloc_error(
-                Layout::from_size_align_unchecked(new.size(), old.align())
-            ));
+        let memory = if new.size() > old.size() {
+            Global.grow(
+                NonNull::new_unchecked(ptr),
+                old,
+                new.size(),
+                ReallocPlacement::MayMove,
+                AllocInit::Uninitialized,
+            )
+        } else {
+            Global.shrink(NonNull::new_unchecked(ptr), old, new.size(), ReallocPlacement::MayMove)
+        };
+
+        let memory = memory.unwrap_or_else(|_| {
+            handle_alloc_error(Layout::from_size_align_unchecked(new.size(), old.align()))
+        });
 
         if PRINT {
-            println!("reallocate({:?}, old={:?}, new={:?}) = {:?}",
-                     ptr, old, new, ptr);
+            println!("reallocate({:?}, old={:?}, new={:?}) = {:?}", ptr, old, new, memory.ptr);
         }
-        ptr.cast().as_ptr()
+        memory.ptr.cast().as_ptr()
     }
 
-    fn idx_to_size(i: usize) -> usize { (i+1) * 10 }
+    fn idx_to_size(i: usize) -> usize {
+        (i + 1) * 10
+    }
 
     // Allocate pairs of rows that form a triangle shape.  (Hope is
     // that at least two rows will be allocated near each other, so
@@ -83,13 +97,13 @@ unsafe fn test_triangle() -> bool {
     // way.)
     for i in 0..COUNT / 2 {
         let size = idx_to_size(i);
-        ascend[2*i]   = allocate(Layout::from_size_align(size, ALIGN).unwrap());
-        ascend[2*i+1] = allocate(Layout::from_size_align(size, ALIGN).unwrap());
+        ascend[2 * i] = allocate(Layout::from_size_align(size, ALIGN).unwrap());
+        ascend[2 * i + 1] = allocate(Layout::from_size_align(size, ALIGN).unwrap());
     }
 
     // Initialize each pair of rows to distinct value.
     for i in 0..COUNT / 2 {
-        let (p0, p1, size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
+        let (p0, p1, size) = (ascend[2 * i], ascend[2 * i + 1], idx_to_size(i));
         for j in 0..size {
             *p0.add(j) = i as u8;
             *p1.add(j) = i as u8;
@@ -104,8 +118,8 @@ unsafe fn test_triangle() -> bool {
 
     for i in 0..COUNT / 2 {
         let size = idx_to_size(i);
-        deallocate(ascend[2*i], Layout::from_size_align(size, ALIGN).unwrap());
-        deallocate(ascend[2*i+1], Layout::from_size_align(size, ALIGN).unwrap());
+        deallocate(ascend[2 * i], Layout::from_size_align(size, ALIGN).unwrap());
+        deallocate(ascend[2 * i + 1], Layout::from_size_align(size, ALIGN).unwrap());
     }
 
     return true;
@@ -115,68 +129,68 @@ unsafe fn test_triangle() -> bool {
     // realloc'ing each row from top to bottom, and checking all the
     // rows as we go.
     unsafe fn test_1(ascend: &mut [*mut u8]) {
-        let new_size = idx_to_size(COUNT-1);
+        let new_size = idx_to_size(COUNT - 1);
         let new = Layout::from_size_align(new_size, ALIGN).unwrap();
         for i in 0..COUNT / 2 {
-            let (p0, p1, old_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
+            let (p0, p1, old_size) = (ascend[2 * i], ascend[2 * i + 1], idx_to_size(i));
             assert!(old_size < new_size);
             let old = Layout::from_size_align(old_size, ALIGN).unwrap();
 
-            ascend[2*i] = reallocate(p0, old.clone(), new.clone());
+            ascend[2 * i] = reallocate(p0, old.clone(), new.clone());
             sanity_check(&*ascend);
 
-            ascend[2*i+1] = reallocate(p1, old.clone(), new.clone());
+            ascend[2 * i + 1] = reallocate(p1, old.clone(), new.clone());
             sanity_check(&*ascend);
         }
     }
 
     // Test 2: turn the square back into a triangle, top to bottom.
     unsafe fn test_2(ascend: &mut [*mut u8]) {
-        let old_size = idx_to_size(COUNT-1);
+        let old_size = idx_to_size(COUNT - 1);
         let old = Layout::from_size_align(old_size, ALIGN).unwrap();
         for i in 0..COUNT / 2 {
-            let (p0, p1, new_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
+            let (p0, p1, new_size) = (ascend[2 * i], ascend[2 * i + 1], idx_to_size(i));
             assert!(new_size < old_size);
             let new = Layout::from_size_align(new_size, ALIGN).unwrap();
 
-            ascend[2*i] = reallocate(p0, old.clone(), new.clone());
+            ascend[2 * i] = reallocate(p0, old.clone(), new.clone());
             sanity_check(&*ascend);
 
-            ascend[2*i+1] = reallocate(p1, old.clone(), new.clone());
+            ascend[2 * i + 1] = reallocate(p1, old.clone(), new.clone());
             sanity_check(&*ascend);
         }
     }
 
     // Test 3: turn triangle into a square, bottom to top.
     unsafe fn test_3(ascend: &mut [*mut u8]) {
-        let new_size = idx_to_size(COUNT-1);
+        let new_size = idx_to_size(COUNT - 1);
         let new = Layout::from_size_align(new_size, ALIGN).unwrap();
         for i in (0..COUNT / 2).rev() {
-            let (p0, p1, old_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
+            let (p0, p1, old_size) = (ascend[2 * i], ascend[2 * i + 1], idx_to_size(i));
             assert!(old_size < new_size);
             let old = Layout::from_size_align(old_size, ALIGN).unwrap();
 
-            ascend[2*i+1] = reallocate(p1, old.clone(), new.clone());
+            ascend[2 * i + 1] = reallocate(p1, old.clone(), new.clone());
             sanity_check(&*ascend);
 
-            ascend[2*i] = reallocate(p0, old.clone(), new.clone());
+            ascend[2 * i] = reallocate(p0, old.clone(), new.clone());
             sanity_check(&*ascend);
         }
     }
 
     // Test 4: turn the square back into a triangle, bottom to top.
     unsafe fn test_4(ascend: &mut [*mut u8]) {
-        let old_size = idx_to_size(COUNT-1);
+        let old_size = idx_to_size(COUNT - 1);
         let old = Layout::from_size_align(old_size, ALIGN).unwrap();
         for i in (0..COUNT / 2).rev() {
-            let (p0, p1, new_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
+            let (p0, p1, new_size) = (ascend[2 * i], ascend[2 * i + 1], idx_to_size(i));
             assert!(new_size < old_size);
             let new = Layout::from_size_align(new_size, ALIGN).unwrap();
 
-            ascend[2*i+1] = reallocate(p1, old.clone(), new.clone());
+            ascend[2 * i + 1] = reallocate(p1, old.clone(), new.clone());
             sanity_check(&*ascend);
 
-            ascend[2*i] = reallocate(p0, old.clone(), new.clone());
+            ascend[2 * i] = reallocate(p0, old.clone(), new.clone());
             sanity_check(&*ascend);
         }
     }
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 5be426eb382..44893036383 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 d3e05498a4a..75e8ae264e7 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/regions/region-bounds-on-objects-and-type-parameters.stderr b/src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr
index 184cead2123..ea9be77a3e8 100644
--- a/src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr
+++ b/src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr
@@ -31,5 +31,5 @@ LL | struct Foo<'a,'b,'c> {
 
 error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0392, E0478.
-For more information about an error, try `rustc --explain E0392`.
+Some errors have detailed explanations: E0226, E0392, E0478.
+For more information about an error, try `rustc --explain E0226`.
diff --git a/src/test/ui/regions/regions-mock-codegen.rs b/src/test/ui/regions/regions-mock-codegen.rs
index fe3a864fe4b..380310190be 100644
--- a/src/test/ui/regions/regions-mock-codegen.rs
+++ b/src/test/ui/regions/regions-mock-codegen.rs
@@ -1,34 +1,34 @@
 // run-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
-
 // pretty-expanded FIXME #23616
-
 #![feature(allocator_api)]
 
-use std::alloc::{AllocRef, Global, Layout, handle_alloc_error};
+use std::alloc::{handle_alloc_error, AllocInit, AllocRef, Global, Layout};
 use std::ptr::NonNull;
 
 struct arena(());
 
 struct Bcx<'a> {
-    fcx: &'a Fcx<'a>
+    fcx: &'a Fcx<'a>,
 }
 
 struct Fcx<'a> {
     arena: &'a arena,
-    ccx: &'a Ccx
+    ccx: &'a Ccx,
 }
 
 struct Ccx {
-    x: isize
+    x: isize,
 }
 
 fn alloc(_bcx: &arena) -> &Bcx<'_> {
     unsafe {
         let layout = Layout::new::<Bcx>();
-        let (ptr, _) = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout));
-        &*(ptr.as_ptr() as *const _)
+        let memory = Global
+            .alloc(layout, AllocInit::Uninitialized)
+            .unwrap_or_else(|_| handle_alloc_error(layout));
+        &*(memory.ptr.as_ptr() as *const _)
     }
 }
 
diff --git a/src/test/ui/resolve/levenshtein.rs b/src/test/ui/resolve/levenshtein.rs
index 6a98782a9ba..a6f47162568 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 ecdec3c24a1..68e0cf08ffa 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 @@ LL | type A = Baz; // Misspelled type name.
    |          ^^^ 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 @@ LL | pub enum Option<T> {
    | ------------------ 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 @@ LL |     let v = [0u32; MAXITEM]; // Misspelled constant name.
    |                    ^^^^^^^ 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 @@ LL |     foobar(); // Misspelled function name.
    |     ^^^^^^ 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 @@ LL |     let b: m::first = m::second; // Misspelled item in module.
    |               ^^^^^ 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 519fb75be55..193a523aed2 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 d4bd760770d..1c47aafec6b 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/specialization/defaultimpl/specialization-wfcheck.stderr b/src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr
index ee7c002b16d..4e4cad62475 100644
--- a/src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr
+++ b/src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr
@@ -4,11 +4,10 @@ error[E0277]: the trait bound `U: std::cmp::Eq` is not satisfied
 LL | default impl<U> Foo<'static, U> for () {}
    |                 ^^^^^^^^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `U`
    |
-help: consider restricting this type parameter with `U: std::cmp::Eq`
-  --> $DIR/specialization-wfcheck.rs:7:14
+help: consider restricting type parameter `U`
    |
-LL | default impl<U> Foo<'static, U> for () {}
-   |              ^
+LL | default impl<U: std::cmp::Eq> Foo<'static, U> for () {}
+   |               ^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/specialization/issue-70442.rs b/src/test/ui/specialization/issue-70442.rs
new file mode 100644
index 00000000000..4371dd2e167
--- /dev/null
+++ b/src/test/ui/specialization/issue-70442.rs
@@ -0,0 +1,23 @@
+#![feature(specialization)]
+
+// check-pass
+
+trait Trait {
+    type Assoc;
+}
+
+impl<T> Trait for T {
+    default type Assoc = bool;
+}
+
+// This impl inherits the `Assoc` definition from above and "locks it in", or finalizes it, making
+// child impls unable to further specialize it. However, since the specialization graph didn't
+// correctly track this, we would refuse to project `Assoc` from this impl, even though that should
+// happen for items that are final.
+impl Trait for () {}
+
+fn foo<X: Trait<Assoc=bool>>() {}
+
+fn main() {
+    foo::<()>();  // `<() as Trait>::Assoc` is normalized to `bool` correctly
+}
diff --git a/src/test/ui/stability-in-private-module.rs b/src/test/ui/stability-in-private-module.rs
index 1815897f17a..f12e9198b0d 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 35a09b21995..8a7588c80d7 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/structs-enums/empty-tag.rs b/src/test/ui/structs-enums/empty-tag.rs
index 56a438200c0..271ab72c74f 100644
--- a/src/test/ui/structs-enums/empty-tag.rs
+++ b/src/test/ui/structs-enums/empty-tag.rs
@@ -1,4 +1,5 @@
 // run-pass
+#![allow(unused_braces)]
 #![allow(non_camel_case_types)]
 
 #[derive(Copy, Clone, Debug)]
diff --git a/src/test/ui/structs-enums/rec-align-u64.rs b/src/test/ui/structs-enums/rec-align-u64.rs
index 680a690ba34..b06e204d31b 100644
--- a/src/test/ui/structs-enums/rec-align-u64.rs
+++ b/src/test/ui/structs-enums/rec-align-u64.rs
@@ -67,13 +67,6 @@ mod m {
 
 #[cfg(target_os = "windows")]
 mod m {
-    #[cfg(target_arch = "x86")]
-    pub mod m {
-        pub fn align() -> usize { 8 }
-        pub fn size() -> usize { 16 }
-    }
-
-    #[cfg(target_arch = "x86_64")]
     pub mod m {
         pub fn align() -> usize { 8 }
         pub fn size() -> usize { 16 }
diff --git a/src/test/ui/suggestions/attribute-typos.rs b/src/test/ui/suggestions/attribute-typos.rs
index e1e3317093a..7c8231bbb24 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 1c307f0e2c1..152700a0798 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 @@ LL |     pub macro test($item:item) {
    |     -------------------------- 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 6b79697e983..b931a04c286 100644
--- a/src/test/ui/suggestions/const-no-type.rs
+++ b/src/test/ui/suggestions/const-no-type.rs
@@ -35,6 +35,11 @@ const C = 42;
 //~| 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 a7b5aa5e5b1..874c1bac10b 100644
--- a/src/test/ui/suggestions/const-no-type.stderr
+++ b/src/test/ui/suggestions/const-no-type.stderr
@@ -4,14 +4,20 @@ error: missing type for `const` item
 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 @@ error: missing type for `static mut` item
 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 241dde9fec1..288d6c699f5 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 c5fe6ddb8a9..37c20535229 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 49a37498fd9..f8b86377187 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 e4234cfcd51..57a389cbb49 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 @@ LL |     let fp = BufWriter::new(fp);
    = 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 @@ LL |     let fp = BufWriter::new(fp);
    = 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 @@ LL |     let fp = BufWriter::new(fp);
    = 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/restrict-type-argument.stderr b/src/test/ui/suggestions/restrict-type-argument.stderr
index 4d5cb8907e8..a98cb76a683 100644
--- a/src/test/ui/suggestions/restrict-type-argument.stderr
+++ b/src/test/ui/suggestions/restrict-type-argument.stderr
@@ -8,11 +8,10 @@ LL |     is_send(val);
    |             ^^^ `impl Sync` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `impl Sync`
-help: consider further restricting this bound with `+ std::marker::Send`
-  --> $DIR/restrict-type-argument.rs:3:23
+help: consider further restricting this bound
    |
-LL | fn use_impl_sync(val: impl Sync) {
-   |                       ^^^^^^^^^
+LL | fn use_impl_sync(val: impl Sync + std::marker::Send) {
+   |                                 ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `S` cannot be sent between threads safely
   --> $DIR/restrict-type-argument.rs:8:13
@@ -24,11 +23,10 @@ LL |     is_send(val);
    |             ^^^ `S` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `S`
-help: consider further restricting this bound with `+ std::marker::Send`
-  --> $DIR/restrict-type-argument.rs:7:31
+help: consider further restricting this bound
    |
-LL | fn use_where<S>(val: S) where S: Sync {
-   |                               ^^^^^^^
+LL | fn use_where<S>(val: S) where S: Sync + std::marker::Send {
+   |                                       ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `S` cannot be sent between threads safely
   --> $DIR/restrict-type-argument.rs:12:13
@@ -40,11 +38,10 @@ LL |     is_send(val);
    |             ^^^ `S` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `S`
-help: consider further restricting this bound with `+ std::marker::Send`
-  --> $DIR/restrict-type-argument.rs:11:17
+help: consider further restricting this bound
    |
-LL | fn use_bound<S: Sync>(val: S) {
-   |                 ^^^^
+LL | fn use_bound<S: Sync + std::marker::Send>(val: S) {
+   |                      ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `S` cannot be sent between threads safely
   --> $DIR/restrict-type-argument.rs:20:13
@@ -56,11 +53,10 @@ LL |     is_send(val);
    |             ^^^ `S` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `S`
-help: consider further restricting this bound with `+ std::marker::Send`
-  --> $DIR/restrict-type-argument.rs:18:5
+help: consider further restricting this bound
    |
-LL |     Sync
-   |     ^^^^
+LL |     Sync + std::marker::Send
+   |          ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `S` cannot be sent between threads safely
   --> $DIR/restrict-type-argument.rs:24:13
@@ -72,11 +68,10 @@ LL |     is_send(val);
    |             ^^^ `S` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `S`
-help: consider further restricting this bound with `+ std::marker::Send`
-  --> $DIR/restrict-type-argument.rs:23:47
+help: consider further restricting this bound
    |
-LL | fn use_bound_and_where<S: Sync>(val: S) where S: std::fmt::Debug {
-   |                                               ^^^^^^^^^^^^^^^^^^
+LL | fn use_bound_and_where<S: Sync>(val: S) where S: std::fmt::Debug + std::marker::Send {
+   |                                                                  ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `S` cannot be sent between threads safely
   --> $DIR/restrict-type-argument.rs:28:13
@@ -88,11 +83,10 @@ LL |     is_send(val);
    |             ^^^ `S` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `S`
-help: consider restricting this type parameter with `S: std::marker::Send`
-  --> $DIR/restrict-type-argument.rs:27:16
+help: consider restricting type parameter `S`
    |
-LL | fn use_unbound<S>(val: S) {
-   |                ^
+LL | fn use_unbound<S: std::marker::Send>(val: S) {
+   |                 ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 6 previous errors
 
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 00000000000..c3325fd80ca
--- /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 3be8db8663a..d62fd7e59c9 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 21818097bd6..56ecb7256f8 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 @@ LL | pub trait Eq: PartialEq<Self> {
    |               --------------- 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-alias/trait-alias-wf.stderr b/src/test/ui/traits/trait-alias/trait-alias-wf.stderr
index e7ed16a02a3..ca4980ca305 100644
--- a/src/test/ui/traits/trait-alias/trait-alias-wf.stderr
+++ b/src/test/ui/traits/trait-alias/trait-alias-wf.stderr
@@ -6,11 +6,10 @@ LL | trait A<T: Foo> {}
 LL | trait B<T> = A<T>;
    |              ^^^^ the trait `Foo` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: Foo`
-  --> $DIR/trait-alias-wf.rs:5:9
+help: consider restricting type parameter `T`
    |
-LL | trait B<T> = A<T>;
-   |         ^
+LL | trait B<T: Foo> = A<T>;
+   |          ^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/trait-bounds-on-structs-and-enums.stderr b/src/test/ui/traits/trait-bounds-on-structs-and-enums.stderr
index 56a9e3ff54e..9e8e5e08145 100644
--- a/src/test/ui/traits/trait-bounds-on-structs-and-enums.stderr
+++ b/src/test/ui/traits/trait-bounds-on-structs-and-enums.stderr
@@ -7,11 +7,10 @@ LL | struct Foo<T:Trait> {
 LL | impl<T> Foo<T> {
    |         ^^^^^^ the trait `Trait` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: Trait`
-  --> $DIR/trait-bounds-on-structs-and-enums.rs:13:6
+help: consider restricting type parameter `T`
    |
-LL | impl<T> Foo<T> {
-   |      ^
+LL | impl<T: Trait> Foo<T> {
+   |       ^^^^^^^
 
 error[E0277]: the trait bound `isize: Trait` is not satisfied
   --> $DIR/trait-bounds-on-structs-and-enums.rs:19:5
@@ -40,11 +39,10 @@ LL | struct Foo<T:Trait> {
 LL |     b: Foo<U>,
    |     ^^^^^^^^^ the trait `Trait` is not implemented for `U`
    |
-help: consider restricting this type parameter with `U: Trait`
-  --> $DIR/trait-bounds-on-structs-and-enums.rs:26:16
+help: consider restricting type parameter `U`
    |
-LL | struct Badness<U> {
-   |                ^
+LL | struct Badness<U: Trait> {
+   |                 ^^^^^^^
 
 error[E0277]: the trait bound `V: Trait` is not satisfied
   --> $DIR/trait-bounds-on-structs-and-enums.rs:31:21
@@ -55,11 +53,10 @@ LL | enum Bar<T:Trait> {
 LL |     EvenMoreBadness(Bar<V>),
    |                     ^^^^^^ the trait `Trait` is not implemented for `V`
    |
-help: consider restricting this type parameter with `V: Trait`
-  --> $DIR/trait-bounds-on-structs-and-enums.rs:30:18
+help: consider restricting type parameter `V`
    |
-LL | enum MoreBadness<V> {
-   |                  ^
+LL | enum MoreBadness<V: Trait> {
+   |                   ^^^^^^^
 
 error[E0277]: the trait bound `i32: Trait` is not satisfied
   --> $DIR/trait-bounds-on-structs-and-enums.rs:35:5
diff --git a/src/test/ui/traits/trait-suggest-where-clause.rs b/src/test/ui/traits/trait-suggest-where-clause.rs
index 5b34ed09190..8405e5ff62e 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 9680d58b8c0..4dddcd68f26 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 @@ LL | pub const fn size_of<T>() -> usize {
    = 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 @@ LL | pub const fn size_of<T>() -> usize {
    = 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 @@ LL |     <u64 as From<T>>::from;
    = 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 @@ LL |     <u64 as From<<T as Iterator>::Item>>::from;
    = 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 @@ LL |     <Misc<_> as From<T>>::from;
    = 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 @@ LL | pub const fn size_of<T>() -> usize {
    = 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/traits/traits-repeated-supertrait-ambig.stderr b/src/test/ui/traits/traits-repeated-supertrait-ambig.stderr
index 5b7f32ba1e0..4107c49bd80 100644
--- a/src/test/ui/traits/traits-repeated-supertrait-ambig.stderr
+++ b/src/test/ui/traits/traits-repeated-supertrait-ambig.stderr
@@ -10,11 +10,10 @@ error[E0277]: the trait bound `C: CompareTo<i32>` is not satisfied
 LL |     c.same_as(22)
    |       ^^^^^^^ the trait `CompareTo<i32>` is not implemented for `C`
    |
-help: consider further restricting this bound with `+ CompareTo<i32>`
-  --> $DIR/traits-repeated-supertrait-ambig.rs:29:17
+help: consider further restricting this bound
    |
-LL | fn with_trait<C:CompareToInts>(c: &C) -> bool {
-   |                 ^^^^^^^^^^^^^
+LL | fn with_trait<C:CompareToInts + CompareTo<i32>>(c: &C) -> bool {
+   |                               ^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `dyn CompareToInts: CompareTo<i32>` is not satisfied
   --> $DIR/traits-repeated-supertrait-ambig.rs:34:5
@@ -34,11 +33,10 @@ LL |     fn same_as(&self, t: T) -> bool;
 LL |     CompareTo::same_as(c, 22)
    |     ^^^^^^^^^^^^^^^^^^ the trait `CompareTo<i32>` is not implemented for `C`
    |
-help: consider further restricting this bound with `+ CompareTo<i32>`
-  --> $DIR/traits-repeated-supertrait-ambig.rs:37:17
+help: consider further restricting this bound
    |
-LL | fn with_ufcs2<C:CompareToInts>(c: &C) -> bool {
-   |                 ^^^^^^^^^^^^^
+LL | fn with_ufcs2<C:CompareToInts + CompareTo<i32>>(c: &C) -> bool {
+   |                               ^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `i64: CompareTo<i32>` is not satisfied
   --> $DIR/traits-repeated-supertrait-ambig.rs:42:23
diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-const.rs b/src/test/ui/type-alias-impl-trait/assoc-type-const.rs
index 2907c21c620..7f3f86e4df0 100644
--- a/src/test/ui/type-alias-impl-trait/assoc-type-const.rs
+++ b/src/test/ui/type-alias-impl-trait/assoc-type-const.rs
@@ -18,16 +18,16 @@ trait MyTrait<'a, const C: usize> {
     const MY_CONST: usize;
 }
 
-impl<'a, const C: usize> MyTrait<'a, { C }> for MyStruct<{ C }> {
+impl<'a, const C: usize> MyTrait<'a, C> for MyStruct<C> {
     type MyItem = u8;
     const MY_CONST: usize = C;
 }
 
-impl<'a, I, const C: usize> UnwrapItemsExt<'a, { C }> for I {
-    type Iter = impl MyTrait<'a, { C }>;
+impl<'a, I, const C: usize> UnwrapItemsExt<'a, C> for I {
+    type Iter = impl MyTrait<'a, C>;
 
     fn unwrap_items(self) -> Self::Iter {
-        MyStruct::<{ C }> {}
+        MyStruct::<C> {}
     }
 }
 
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 74b858105b9..aff558569ea 100644
--- a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr
+++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr
@@ -4,11 +4,10 @@ error[E0277]: the trait bound `T: TraitWithAssoc` is not satisfied
 LL | type Foo<V> = impl Trait<V>;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TraitWithAssoc` is not implemented for `T`
    |
-help: consider further restricting this bound with `+ TraitWithAssoc`
-  --> $DIR/bound_reduction2.rs:18:21
+help: consider further restricting this bound
    |
-LL | fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
-   |                     ^^^^^^^^^^^^^^
+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
diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr
index 299c7eae8d3..f7a04263259 100644
--- a/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr
@@ -10,12 +10,11 @@ error[E0277]: the trait bound `T: Trait` is not satisfied
 LL | type Underconstrained<T: Trait> = impl 'static;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: Trait`
-  --> $DIR/generic_underconstrained.rs:10:19
-   |
-LL | fn underconstrain<T>(_: T) -> Underconstrained<T> {
-   |                   ^
    = note: the return type of a function must have a statically known size
+help: consider restricting type parameter `T`
+   |
+LL | fn underconstrain<T: Trait>(_: T) -> Underconstrained<T> {
+   |                    ^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr
index 56966a32b43..ad160abcbd5 100644
--- a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr
@@ -20,12 +20,11 @@ LL |     5u32
    |     ---- this returned value is of type `u32`
    |
    = help: the trait `std::fmt::Debug` is not implemented for `U`
-help: consider restricting this type parameter with `U: std::fmt::Debug`
-  --> $DIR/generic_underconstrained2.rs:10:21
-   |
-LL | fn underconstrained<U>(_: U) -> Underconstrained<U> {
-   |                     ^
    = note: the return type of a function must have a statically known size
+help: consider restricting type parameter `U`
+   |
+LL | fn underconstrained<U: std::fmt::Debug>(_: U) -> Underconstrained<U> {
+   |                      ^^^^^^^^^^^^^^^^^
 
 error[E0277]: `V` doesn't implement `std::fmt::Debug`
   --> $DIR/generic_underconstrained2.rs:14:1
@@ -37,12 +36,11 @@ LL |     5u32
    |     ---- this returned value is of type `u32`
    |
    = help: the trait `std::fmt::Debug` is not implemented for `V`
-help: consider restricting this type parameter with `V: std::fmt::Debug`
-  --> $DIR/generic_underconstrained2.rs:19:25
-   |
-LL | fn underconstrained2<U, V>(_: U, _: V) -> Underconstrained2<V> {
-   |                         ^
    = note: the return type of a function must have a statically known size
+help: consider restricting type parameter `V`
+   |
+LL | fn underconstrained2<U, V: std::fmt::Debug>(_: U, _: V) -> Underconstrained2<V> {
+   |                          ^^^^^^^^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/type/type-check-defaults.stderr b/src/test/ui/type/type-check-defaults.stderr
index 31ee15e0745..ca9b85bacba 100644
--- a/src/test/ui/type/type-check-defaults.stderr
+++ b/src/test/ui/type/type-check-defaults.stderr
@@ -54,11 +54,10 @@ LL | trait Super<T: Copy> { }
 LL | trait Base<T = String>: Super<T> { }
    |                         ^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/type-check-defaults.rs:21:12
+help: consider further restricting type parameter `T`
    |
-LL | trait Base<T = String>: Super<T> { }
-   |            ^
+LL | trait Base<T = String>: Super<T>, T: std::marker::Copy { }
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: cannot add `u8` to `i32`
   --> $DIR/type-check-defaults.rs:24:66
diff --git a/src/test/ui/type_length_limit.rs b/src/test/ui/type_length_limit.rs
index 0ecd5cf5faf..1f1c8ad9626 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/typeck/typeck-default-trait-impl-send-param.stderr b/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr
index 45c9d8be85e..c8411017b3c 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr
@@ -8,11 +8,10 @@ LL | fn is_send<T:Send>() {
    |    -------   ---- required by this bound in `is_send`
    |
    = help: the trait `std::marker::Send` is not implemented for `T`
-help: consider restricting this type parameter with `T: std::marker::Send`
-  --> $DIR/typeck-default-trait-impl-send-param.rs:4:8
+help: consider restricting type parameter `T`
    |
-LL | fn foo<T>() {
-   |        ^
+LL | fn foo<T: std::marker::Send>() {
+   |         ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs
index a959aaae055..e804afcf9ed 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 bfe37b5029c..c7bf6710d06 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 @@ LL |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
    = 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 @@ LL |     let _ = match x {};
    = 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 @@ LL |     let _ = match x {};
    = 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 @@ LL |     let _ = match x {};
    = 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 @@ LL |     let _ = match x {
    = 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 @@ LL |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
    = 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 4b92475f1e4..4a106cc940a 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 d0a82a96c16..66437611872 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 @@ LL | #[derive(Clone)]
    = 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 bedaf27c2dd..dd38a7190aa 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 2e81e7cf832..161e25bb8c5 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 091b8a43862..4c30450c704 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 06c4b95baef..38c110c04c4 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/test/ui/unop-move-semantics.stderr b/src/test/ui/unop-move-semantics.stderr
index ab641c40dfe..e0499cfe95c 100644
--- a/src/test/ui/unop-move-semantics.stderr
+++ b/src/test/ui/unop-move-semantics.stderr
@@ -9,11 +9,10 @@ LL |
 LL |     x.clone();
    |     ^ value borrowed here after move
    |
-help: consider further restricting this bound with `+ Copy`
-  --> $DIR/unop-move-semantics.rs:5:24
+help: consider further restricting this bound
    |
-LL | fn move_then_borrow<T: Not<Output=T> + Clone>(x: T) {
-   |                        ^^^^^^^^^^^^^^^^^^^^^
+LL | fn move_then_borrow<T: Not<Output=T> + Clone + Copy>(x: T) {
+   |                                              ^^^^^^
 
 error[E0505]: cannot move out of `x` because it is borrowed
   --> $DIR/unop-move-semantics.rs:15:6
diff --git a/src/test/ui/unsized-locals/unsized-exprs-rpass.rs b/src/test/ui/unsized-locals/unsized-exprs-rpass.rs
index bc64fcdec2e..24c2758a0a2 100644
--- a/src/test/ui/unsized-locals/unsized-exprs-rpass.rs
+++ b/src/test/ui/unsized-locals/unsized-exprs-rpass.rs
@@ -1,5 +1,5 @@
 // run-pass
-
+#![allow(unused_braces, unused_parens)]
 #![feature(unsized_tuple_coercion, unsized_locals)]
 
 struct A<X: ?Sized>(X);
@@ -30,7 +30,6 @@ fn main() {
         *foo()
     });
     udrop::<[u8]>({*foo()});
-    #[allow(unused_parens)]
     udrop::<[u8]>((*foo()));
     udrop::<[u8]>((*tfoo()).1);
     *afoo() + 42;
diff --git a/src/test/ui/weird-exprs.rs b/src/test/ui/weird-exprs.rs
index ca68a5af0dd..d812bbd011e 100644
--- a/src/test/ui/weird-exprs.rs
+++ b/src/test/ui/weird-exprs.rs
@@ -5,7 +5,7 @@
 #![allow(non_camel_case_types)]
 #![allow(dead_code)]
 #![allow(unreachable_code)]
-#![allow(unused_parens)]
+#![allow(unused_braces, unused_parens)]
 
 #![recursion_limit = "256"]
 
diff --git a/src/test/ui/wf/wf-enum-bound.stderr b/src/test/ui/wf/wf-enum-bound.stderr
index be64ddb9759..f70f67d414f 100644
--- a/src/test/ui/wf/wf-enum-bound.stderr
+++ b/src/test/ui/wf/wf-enum-bound.stderr
@@ -7,11 +7,10 @@ LL | trait ExtraCopy<T:Copy> { }
 LL |     where T: ExtraCopy<U>
    |              ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `U`
    |
-help: consider restricting this type parameter with `where U: std::marker::Copy`
-  --> $DIR/wf-enum-bound.rs:9:17
+help: consider further restricting type parameter `U`
    |
-LL | enum SomeEnum<T,U>
-   |                 ^
+LL |     where T: ExtraCopy<U>, U: std::marker::Copy
+   |                          ^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-enum-fields-struct-variant.stderr b/src/test/ui/wf/wf-enum-fields-struct-variant.stderr
index 40454b33b7b..8634b7dba5c 100644
--- a/src/test/ui/wf/wf-enum-fields-struct-variant.stderr
+++ b/src/test/ui/wf/wf-enum-fields-struct-variant.stderr
@@ -7,11 +7,10 @@ LL | struct IsCopy<T:Copy> {
 LL |         f: IsCopy<A>
    |         ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `A`
    |
-help: consider restricting this type parameter with `A: std::marker::Copy`
-  --> $DIR/wf-enum-fields-struct-variant.rs:11:18
+help: consider restricting type parameter `A`
    |
-LL | enum AnotherEnum<A> {
-   |                  ^
+LL | enum AnotherEnum<A: std::marker::Copy> {
+   |                   ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-enum-fields.stderr b/src/test/ui/wf/wf-enum-fields.stderr
index e2612add776..a22b2d11a91 100644
--- a/src/test/ui/wf/wf-enum-fields.stderr
+++ b/src/test/ui/wf/wf-enum-fields.stderr
@@ -7,11 +7,10 @@ LL | struct IsCopy<T:Copy> {
 LL |     SomeVariant(IsCopy<A>)
    |                 ^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `A`
    |
-help: consider restricting this type parameter with `A: std::marker::Copy`
-  --> $DIR/wf-enum-fields.rs:11:15
+help: consider restricting type parameter `A`
    |
-LL | enum SomeEnum<A> {
-   |               ^
+LL | enum SomeEnum<A: std::marker::Copy> {
+   |                ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-fn-where-clause.stderr b/src/test/ui/wf/wf-fn-where-clause.stderr
index 2a4f2df5a89..cf1aeac7e3e 100644
--- a/src/test/ui/wf/wf-fn-where-clause.stderr
+++ b/src/test/ui/wf/wf-fn-where-clause.stderr
@@ -7,11 +7,10 @@ LL |
 LL | fn foo<T,U>() where T: ExtraCopy<U>
    |                        ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `U`
    |
-help: consider restricting this type parameter with `where U: std::marker::Copy`
-  --> $DIR/wf-fn-where-clause.rs:8:10
+help: consider further restricting type parameter `U`
    |
-LL | fn foo<T,U>() where T: ExtraCopy<U>
-   |          ^
+LL | fn foo<T,U>() where T: ExtraCopy<U>, U: std::marker::Copy
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the size for values of type `(dyn std::marker::Copy + 'static)` cannot be known at compilation time
   --> $DIR/wf-fn-where-clause.rs:12:16
diff --git a/src/test/ui/wf/wf-impl-associated-type-trait.stderr b/src/test/ui/wf/wf-impl-associated-type-trait.stderr
index 7774299b393..d44a6f01a47 100644
--- a/src/test/ui/wf/wf-impl-associated-type-trait.stderr
+++ b/src/test/ui/wf/wf-impl-associated-type-trait.stderr
@@ -7,11 +7,10 @@ LL | pub struct MySet<T:MyHash> {
 LL |     type Bar = MySet<T>;
    |     ^^^^^^^^^^^^^^^^^^^^ the trait `MyHash` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: MyHash`
-  --> $DIR/wf-impl-associated-type-trait.rs:16:6
+help: consider restricting type parameter `T`
    |
-LL | impl<T> Foo for T {
-   |      ^
+LL | impl<T: MyHash> Foo for T {
+   |       ^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-in-fn-arg.stderr b/src/test/ui/wf/wf-in-fn-arg.stderr
index c1a6657e63b..907701440aa 100644
--- a/src/test/ui/wf/wf-in-fn-arg.stderr
+++ b/src/test/ui/wf/wf-in-fn-arg.stderr
@@ -7,11 +7,10 @@ LL | struct MustBeCopy<T:Copy> {
 LL | fn bar<T>(_: &MustBeCopy<T>)
    |              ^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/wf-in-fn-arg.rs:10:8
+help: consider restricting type parameter `T`
    |
-LL | fn bar<T>(_: &MustBeCopy<T>)
-   |        ^
+LL | fn bar<T: std::marker::Copy>(_: &MustBeCopy<T>)
+   |         ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-in-fn-ret.stderr b/src/test/ui/wf/wf-in-fn-ret.stderr
index 754d64df019..2ed4eecefe1 100644
--- a/src/test/ui/wf/wf-in-fn-ret.stderr
+++ b/src/test/ui/wf/wf-in-fn-ret.stderr
@@ -7,11 +7,10 @@ LL | struct MustBeCopy<T:Copy> {
 LL | fn bar<T>() -> MustBeCopy<T>
    |                ^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/wf-in-fn-ret.rs:10:8
+help: consider restricting type parameter `T`
    |
-LL | fn bar<T>() -> MustBeCopy<T>
-   |        ^
+LL | fn bar<T: std::marker::Copy>() -> MustBeCopy<T>
+   |         ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-in-fn-type-arg.stderr b/src/test/ui/wf/wf-in-fn-type-arg.stderr
index 97a5c0fd913..0c699838abd 100644
--- a/src/test/ui/wf/wf-in-fn-type-arg.stderr
+++ b/src/test/ui/wf/wf-in-fn-type-arg.stderr
@@ -7,11 +7,10 @@ LL | struct MustBeCopy<T:Copy> {
 LL |     x: fn(MustBeCopy<T>)
    |     ^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/wf-in-fn-type-arg.rs:7:12
+help: consider restricting type parameter `T`
    |
-LL | struct Bar<T> {
-   |            ^
+LL | struct Bar<T: std::marker::Copy> {
+   |             ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-in-fn-type-ret.stderr b/src/test/ui/wf/wf-in-fn-type-ret.stderr
index 527b000edf8..3429ab89ffb 100644
--- a/src/test/ui/wf/wf-in-fn-type-ret.stderr
+++ b/src/test/ui/wf/wf-in-fn-type-ret.stderr
@@ -7,11 +7,10 @@ LL | struct MustBeCopy<T:Copy> {
 LL |     x: fn() -> MustBeCopy<T>
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/wf-in-fn-type-ret.rs:7:12
+help: consider restricting type parameter `T`
    |
-LL | struct Foo<T> {
-   |            ^
+LL | struct Foo<T: std::marker::Copy> {
+   |             ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-in-fn-where-clause.stderr b/src/test/ui/wf/wf-in-fn-where-clause.stderr
index 62c672a21e8..d33749d795c 100644
--- a/src/test/ui/wf/wf-in-fn-where-clause.stderr
+++ b/src/test/ui/wf/wf-in-fn-where-clause.stderr
@@ -7,11 +7,10 @@ LL | trait MustBeCopy<T:Copy> {
 LL |     where T: MustBeCopy<U>
    |              ^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `U`
    |
-help: consider restricting this type parameter with `where U: std::marker::Copy`
-  --> $DIR/wf-in-fn-where-clause.rs:9:10
+help: consider further restricting type parameter `U`
    |
-LL | fn bar<T,U>()
-   |          ^
+LL |     where T: MustBeCopy<U>, U: std::marker::Copy
+   |                           ^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-in-obj-type-trait.stderr b/src/test/ui/wf/wf-in-obj-type-trait.stderr
index 1b6438cdc24..605dc497849 100644
--- a/src/test/ui/wf/wf-in-obj-type-trait.stderr
+++ b/src/test/ui/wf/wf-in-obj-type-trait.stderr
@@ -7,11 +7,10 @@ LL | struct MustBeCopy<T:Copy> {
 LL |     x: dyn Object<MustBeCopy<T>>
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/wf-in-obj-type-trait.rs:9:12
+help: consider restricting type parameter `T`
    |
-LL | struct Bar<T> {
-   |            ^
+LL | struct Bar<T: std::marker::Copy> {
+   |             ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr b/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr
index 70337ee40ea..da2f8085a8a 100644
--- a/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr
+++ b/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr
@@ -7,11 +7,10 @@ LL | trait ExtraCopy<T:Copy> { }
 LL |     fn foo(self) where T: ExtraCopy<U>
    |                           ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `U`
    |
-help: consider restricting this type parameter with `U: std::marker::Copy`
-  --> $DIR/wf-inherent-impl-method-where-clause.rs:11:8
+help: consider restricting type parameter `U`
    |
-LL | impl<T,U> Foo<T,U> {
-   |        ^
+LL | impl<T,U: std::marker::Copy> Foo<T,U> {
+   |         ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-inherent-impl-where-clause.stderr b/src/test/ui/wf/wf-inherent-impl-where-clause.stderr
index c26d0ef7871..28d5bc62556 100644
--- a/src/test/ui/wf/wf-inherent-impl-where-clause.stderr
+++ b/src/test/ui/wf/wf-inherent-impl-where-clause.stderr
@@ -7,11 +7,10 @@ LL | trait ExtraCopy<T:Copy> { }
 LL | impl<T,U> Foo<T,U> where T: ExtraCopy<U>
    |                             ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `U`
    |
-help: consider restricting this type parameter with `where U: std::marker::Copy`
-  --> $DIR/wf-inherent-impl-where-clause.rs:11:8
+help: consider further restricting type parameter `U`
    |
-LL | impl<T,U> Foo<T,U> where T: ExtraCopy<U>
-   |        ^
+LL | impl<T,U> Foo<T,U> where T: ExtraCopy<U>, U: std::marker::Copy
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-struct-bound.stderr b/src/test/ui/wf/wf-struct-bound.stderr
index 545e4f87095..07e569ddac1 100644
--- a/src/test/ui/wf/wf-struct-bound.stderr
+++ b/src/test/ui/wf/wf-struct-bound.stderr
@@ -7,11 +7,10 @@ LL | trait ExtraCopy<T:Copy> { }
 LL |     where T: ExtraCopy<U>
    |              ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `U`
    |
-help: consider restricting this type parameter with `where U: std::marker::Copy`
-  --> $DIR/wf-struct-bound.rs:9:21
+help: consider further restricting type parameter `U`
    |
-LL | struct SomeStruct<T,U>
-   |                     ^
+LL |     where T: ExtraCopy<U>, U: std::marker::Copy
+   |                          ^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-struct-field.stderr b/src/test/ui/wf/wf-struct-field.stderr
index f0ebdfba2ff..f3bce24eace 100644
--- a/src/test/ui/wf/wf-struct-field.stderr
+++ b/src/test/ui/wf/wf-struct-field.stderr
@@ -7,11 +7,10 @@ LL | struct IsCopy<T:Copy> {
 LL |     data: IsCopy<A>
    |     ^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `A`
    |
-help: consider restricting this type parameter with `A: std::marker::Copy`
-  --> $DIR/wf-struct-field.rs:11:19
+help: consider restricting type parameter `A`
    |
-LL | struct SomeStruct<A> {
-   |                   ^
+LL | struct SomeStruct<A: std::marker::Copy> {
+   |                    ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-trait-associated-type-bound.stderr b/src/test/ui/wf/wf-trait-associated-type-bound.stderr
index dfccd486568..6cf7f2069b6 100644
--- a/src/test/ui/wf/wf-trait-associated-type-bound.stderr
+++ b/src/test/ui/wf/wf-trait-associated-type-bound.stderr
@@ -7,11 +7,10 @@ LL | trait ExtraCopy<T:Copy> { }
 LL |     type Type1: ExtraCopy<T>;
    |                 ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/wf-trait-associated-type-bound.rs:9:17
+help: consider restricting type parameter `T`
    |
-LL | trait SomeTrait<T> {
-   |                 ^
+LL | trait SomeTrait<T: std::marker::Copy> {
+   |                  ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-trait-bound.stderr b/src/test/ui/wf/wf-trait-bound.stderr
index 31faa14426a..b8ffad6d180 100644
--- a/src/test/ui/wf/wf-trait-bound.stderr
+++ b/src/test/ui/wf/wf-trait-bound.stderr
@@ -7,11 +7,10 @@ LL | trait ExtraCopy<T:Copy> { }
 LL |     where T: ExtraCopy<U>
    |              ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `U`
    |
-help: consider restricting this type parameter with `where U: std::marker::Copy`
-  --> $DIR/wf-trait-bound.rs:9:19
+help: consider further restricting type parameter `U`
    |
-LL | trait SomeTrait<T,U>
-   |                   ^
+LL |     where T: ExtraCopy<U>, U: std::marker::Copy
+   |                          ^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-trait-superbound.stderr b/src/test/ui/wf/wf-trait-superbound.stderr
index 372a5f8ba5d..88b4bec0451 100644
--- a/src/test/ui/wf/wf-trait-superbound.stderr
+++ b/src/test/ui/wf/wf-trait-superbound.stderr
@@ -7,11 +7,10 @@ LL |
 LL | trait SomeTrait<T>: ExtraCopy<T> {
    |                     ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/wf-trait-superbound.rs:9:17
+help: consider restricting type parameter `T`
    |
-LL | trait SomeTrait<T>: ExtraCopy<T> {
-   |                 ^
+LL | trait SomeTrait<T: std::marker::Copy>: ExtraCopy<T> {
+   |                  ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr
index c6f12e7753c..fb1471e95bb 100644
--- a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr
+++ b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr
@@ -7,11 +7,10 @@ LL | fn require_copy<T: Copy>(x: T) {}
 LL |         require_copy(self.x);
    |                      ^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/where-clause-constraints-are-local-for-inherent-impl.rs:6:6
+help: consider restricting type parameter `T`
    |
-LL | impl<T> Foo<T> {
-   |      ^
+LL | impl<T: std::marker::Copy> Foo<T> {
+   |       ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr
index 95688d6f2e4..6c1516d8ac9 100644
--- a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr
+++ b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr
@@ -7,11 +7,10 @@ LL | fn require_copy<T: Copy>(x: T) {}
 LL |         require_copy(self.x);
    |                      ^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-help: consider restricting this type parameter with `T: std::marker::Copy`
-  --> $DIR/where-clause-constraints-are-local-for-trait-impl.rs:11:6
+help: consider restricting type parameter `T`
    |
-LL | impl<T> Foo<T> for Bar<T> {
-   |      ^
+LL | impl<T: std::marker::Copy> Foo<T> for Bar<T> {
+   |       ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/zero-sized/zero-sized-tuple-struct.rs b/src/test/ui/zero-sized/zero-sized-tuple-struct.rs
index 6c438720e5d..2208590f7d6 100644
--- a/src/test/ui/zero-sized/zero-sized-tuple-struct.rs
+++ b/src/test/ui/zero-sized/zero-sized-tuple-struct.rs
@@ -1,4 +1,5 @@
 // run-pass
+#![allow(unused_braces)]
 #![allow(unused_assignments)]
 
 // Make sure that the constructor args are codegened for zero-sized tuple structs
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 98e9fe7a8b2..f075d3e22d6 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -56,6 +56,8 @@ static TARGETS: &[&str] = &[
     "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
-Subproject 8a0d4d9c9abc74fd670353094387d62028b40ae
+Subproject 6e07d2dfb7fc87b1c9489de41da4dafa239daf0
diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs
index cf00cb1ab8a..6968822c1b8 100644
--- a/src/tools/cargotest/main.rs
+++ b/src/tools/cargotest/main.rs
@@ -58,13 +58,6 @@ const TEST_REPOS: &'static [Test] = &[
         // This takes much less time to build than all of Servo and supports stable Rust.
         packages: &["selectors"],
     },
-    Test {
-        name: "webrender",
-        repo: "https://github.com/servo/webrender",
-        sha: "a3d6e6894c5a601fa547c6273eb963ca1321c2bb",
-        lock: None,
-        packages: &[],
-    },
 ];
 
 fn main() {
diff --git a/src/tools/clippy b/src/tools/clippy
-Subproject 70b93aab6ec576c3665f38fd485bb5e0154a88f
+Subproject 326b22048a6305d7c918b748be1c081468917ac
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 0ee016f33dd..04d34fd0d4a 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -180,29 +180,25 @@ pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Misma
 }
 
 fn print_diff(expected: &str, actual: &str, context_size: usize) {
-    write_diff(expected, actual, context_size, std::io::stdout());
-}
-
-fn write_diff(expected: &str, actual: &str, context_size: usize, mut dest: impl io::Write) {
     let diff_results = make_diff(expected, actual, context_size);
     for result in diff_results {
         let mut line_number = result.line_number;
         for line in result.lines {
             match line {
                 DiffLine::Expected(e) => {
-                    writeln!(dest, "-\t{}", e).unwrap();
+                    println!("-\t{}", e);
                     line_number += 1;
                 }
                 DiffLine::Context(c) => {
-                    writeln!(dest, "{}\t{}", line_number, c).unwrap();
+                    println!("{}\t{}", line_number, c);
                     line_number += 1;
                 }
                 DiffLine::Resulting(r) => {
-                    writeln!(dest, "+\t{}", r).unwrap();
+                    println!("+\t{}", r);
                 }
             }
         }
-        writeln!(dest).unwrap();
+        println!();
     }
 }
 
@@ -2517,7 +2513,7 @@ impl<'test> TestCx<'test> {
                     .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()
                         }
@@ -2567,6 +2563,16 @@ impl<'test> TestCx<'test> {
 
             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
-Subproject 0d0a457c8b1750e82f19527b18b313f3514633f
+Subproject 147ea8f400de3ca529abcb5eb7b65f84a4896ae
diff --git a/src/tools/rustdoc-js-common/lib.js b/src/tools/rustdoc-js-common/lib.js
new file mode 100644
index 00000000000..81e64aec491
--- /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 08930ff1227..6f730b0fdbb 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 @@ function findFile(dir, name, extension) {
             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 @@ function readFileMatching(dir, name, extension) {
     if (f === null) {
         return "";
     }
-    return readFile(dir + f);
+    return tools.readFile(dir + f);
 }
 
 function main(argv) {
@@ -253,88 +57,16 @@ function main(argv) {
     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 143e1a7480d..2e8901d56d0 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 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 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 loaded = loadContent(finalJS);
-    return [loaded, loaded.buildIndex(searchIndex.searchIndex)];
+    return tools.loadMainJsAndIndex(mainJs, aliases, searchIndex, crate);
 }
 
 function main(argv) {
@@ -279,54 +37,7 @@ function main(argv) {
         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/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 1ffc415fb24..a221184fab0 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -57,7 +57,7 @@ const EXCEPTIONS: &[(&str, &str)] = &[
 const RUNTIME_CRATES: &[&str] = &["std", "core", "alloc", "test", "panic_abort", "panic_unwind"];
 
 /// Which crates to check against the whitelist?
-const WHITELIST_CRATES: &[&str] = &["rustc", "rustc_codegen_llvm"];
+const WHITELIST_CRATES: &[&str] = &["rustc_middle", "rustc_codegen_llvm"];
 
 /// Whitelist of crates rustc is allowed to depend on. Avoid adding to the list if possible.
 ///