about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock12
-rw-r--r--Cargo.toml3
-rw-r--r--README.md21
-rw-r--r--RELEASES.md2
-rw-r--r--compiler/rustc/Cargo.toml (renamed from src/rustc/Cargo.toml)8
-rw-r--r--compiler/rustc/src/main.rs (renamed from src/rustc/rustc.rs)0
-rw-r--r--compiler/rustc_apfloat/Cargo.toml (renamed from src/librustc_apfloat/Cargo.toml)4
-rw-r--r--compiler/rustc_apfloat/src/ieee.rs (renamed from src/librustc_apfloat/ieee.rs)0
-rw-r--r--compiler/rustc_apfloat/src/lib.rs (renamed from src/librustc_apfloat/lib.rs)0
-rw-r--r--compiler/rustc_apfloat/src/ppc.rs (renamed from src/librustc_apfloat/ppc.rs)0
-rw-r--r--compiler/rustc_apfloat/tests/ieee.rs (renamed from src/librustc_apfloat/tests/ieee.rs)0
-rw-r--r--compiler/rustc_apfloat/tests/ppc.rs (renamed from src/librustc_apfloat/tests/ppc.rs)0
-rw-r--r--compiler/rustc_arena/Cargo.toml (renamed from src/librustc_arena/Cargo.toml)6
-rw-r--r--compiler/rustc_arena/src/lib.rs (renamed from src/librustc_arena/lib.rs)0
-rw-r--r--compiler/rustc_arena/src/tests.rs (renamed from src/librustc_arena/tests.rs)0
-rw-r--r--compiler/rustc_ast/Cargo.toml19
-rw-r--r--compiler/rustc_ast/README.md (renamed from src/librustc_ast/README.md)0
-rw-r--r--compiler/rustc_ast/src/ast.rs (renamed from src/librustc_ast/ast.rs)19
-rw-r--r--compiler/rustc_ast/src/ast/tests.rs (renamed from src/librustc_ast/ast/tests.rs)0
-rw-r--r--compiler/rustc_ast/src/attr/mod.rs (renamed from src/librustc_ast/attr/mod.rs)9
-rw-r--r--compiler/rustc_ast/src/crate_disambiguator.rs (renamed from src/librustc_ast/crate_disambiguator.rs)0
-rw-r--r--compiler/rustc_ast/src/entry.rs (renamed from src/librustc_ast/entry.rs)0
-rw-r--r--compiler/rustc_ast/src/expand/allocator.rs (renamed from src/librustc_ast/expand/allocator.rs)0
-rw-r--r--compiler/rustc_ast/src/expand/mod.rs (renamed from src/librustc_ast/expand/mod.rs)0
-rw-r--r--compiler/rustc_ast/src/lib.rs (renamed from src/librustc_ast/lib.rs)0
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs (renamed from src/librustc_ast/mut_visit.rs)2
-rw-r--r--compiler/rustc_ast/src/node_id.rs (renamed from src/librustc_ast/node_id.rs)0
-rw-r--r--compiler/rustc_ast/src/ptr.rs (renamed from src/librustc_ast/ptr.rs)0
-rw-r--r--compiler/rustc_ast/src/token.rs (renamed from src/librustc_ast/token.rs)18
-rw-r--r--compiler/rustc_ast/src/tokenstream.rs (renamed from src/librustc_ast/tokenstream.rs)0
-rw-r--r--compiler/rustc_ast/src/util/classify.rs (renamed from src/librustc_ast/util/classify.rs)0
-rw-r--r--compiler/rustc_ast/src/util/comments.rs (renamed from src/librustc_ast/util/comments.rs)0
-rw-r--r--compiler/rustc_ast/src/util/comments/tests.rs (renamed from src/librustc_ast/util/comments/tests.rs)0
-rw-r--r--compiler/rustc_ast/src/util/lev_distance.rs (renamed from src/librustc_ast/util/lev_distance.rs)0
-rw-r--r--compiler/rustc_ast/src/util/lev_distance/tests.rs (renamed from src/librustc_ast/util/lev_distance/tests.rs)0
-rw-r--r--compiler/rustc_ast/src/util/literal.rs (renamed from src/librustc_ast/util/literal.rs)0
-rw-r--r--compiler/rustc_ast/src/util/parser.rs (renamed from src/librustc_ast/util/parser.rs)0
-rw-r--r--compiler/rustc_ast/src/visit.rs (renamed from src/librustc_ast/visit.rs)2
-rw-r--r--compiler/rustc_ast_lowering/Cargo.toml22
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs (renamed from src/librustc_ast_lowering/expr.rs)0
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs (renamed from src/librustc_ast_lowering/item.rs)0
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs (renamed from src/librustc_ast_lowering/lib.rs)0
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs (renamed from src/librustc_ast_lowering/pat.rs)0
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs (renamed from src/librustc_ast_lowering/path.rs)0
-rw-r--r--compiler/rustc_ast_passes/Cargo.toml18
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs (renamed from src/librustc_ast_passes/ast_validation.rs)0
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs (renamed from src/librustc_ast_passes/feature_gate.rs)0
-rw-r--r--compiler/rustc_ast_passes/src/lib.rs (renamed from src/librustc_ast_passes/lib.rs)0
-rw-r--r--compiler/rustc_ast_passes/src/node_count.rs (renamed from src/librustc_ast_passes/node_count.rs)0
-rw-r--r--compiler/rustc_ast_passes/src/show_span.rs (renamed from src/librustc_ast_passes/show_span.rs)0
-rw-r--r--compiler/rustc_ast_pretty/Cargo.toml14
-rw-r--r--compiler/rustc_ast_pretty/src/helpers.rs (renamed from src/librustc_ast_pretty/helpers.rs)0
-rw-r--r--compiler/rustc_ast_pretty/src/lib.rs (renamed from src/librustc_ast_pretty/lib.rs)0
-rw-r--r--compiler/rustc_ast_pretty/src/pp.rs (renamed from src/librustc_ast_pretty/pp.rs)0
-rw-r--r--compiler/rustc_ast_pretty/src/pprust.rs (renamed from src/librustc_ast_pretty/pprust.rs)11
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/tests.rs (renamed from src/librustc_ast_pretty/pprust/tests.rs)0
-rw-r--r--compiler/rustc_attr/Cargo.toml21
-rw-r--r--compiler/rustc_attr/src/builtin.rs (renamed from src/librustc_attr/builtin.rs)0
-rw-r--r--compiler/rustc_attr/src/lib.rs (renamed from src/librustc_attr/lib.rs)0
-rw-r--r--compiler/rustc_builtin_macros/Cargo.toml24
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs (renamed from src/librustc_builtin_macros/asm.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/assert.rs (renamed from src/librustc_builtin_macros/assert.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/cfg.rs (renamed from src/librustc_builtin_macros/cfg.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/cfg_accessible.rs (renamed from src/librustc_builtin_macros/cfg_accessible.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/cmdline_attrs.rs (renamed from src/librustc_builtin_macros/cmdline_attrs.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/compile_error.rs (renamed from src/librustc_builtin_macros/compile_error.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/concat.rs (renamed from src/librustc_builtin_macros/concat.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/concat_idents.rs (renamed from src/librustc_builtin_macros/concat_idents.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/bounds.rs (renamed from src/librustc_builtin_macros/deriving/bounds.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/clone.rs (renamed from src/librustc_builtin_macros/deriving/clone.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs (renamed from src/librustc_builtin_macros/deriving/cmp/eq.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs (renamed from src/librustc_builtin_macros/deriving/cmp/ord.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs (renamed from src/librustc_builtin_macros/deriving/cmp/partial_eq.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs (renamed from src/librustc_builtin_macros/deriving/cmp/partial_ord.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/debug.rs (renamed from src/librustc_builtin_macros/deriving/debug.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/decodable.rs (renamed from src/librustc_builtin_macros/deriving/decodable.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/default.rs (renamed from src/librustc_builtin_macros/deriving/default.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/encodable.rs (renamed from src/librustc_builtin_macros/deriving/encodable.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs (renamed from src/librustc_builtin_macros/deriving/generic/mod.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/ty.rs (renamed from src/librustc_builtin_macros/deriving/generic/ty.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/hash.rs (renamed from src/librustc_builtin_macros/deriving/hash.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/mod.rs (renamed from src/librustc_builtin_macros/deriving/mod.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/env.rs (renamed from src/librustc_builtin_macros/env.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs (renamed from src/librustc_builtin_macros/format.rs)49
-rw-r--r--compiler/rustc_builtin_macros/src/format_foreign.rs (renamed from src/librustc_builtin_macros/format_foreign.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/format_foreign/printf/tests.rs (renamed from src/librustc_builtin_macros/format_foreign/printf/tests.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/format_foreign/shell/tests.rs (renamed from src/librustc_builtin_macros/format_foreign/shell/tests.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/global_allocator.rs (renamed from src/librustc_builtin_macros/global_allocator.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/global_asm.rs (renamed from src/librustc_builtin_macros/global_asm.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs (renamed from src/librustc_builtin_macros/lib.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/llvm_asm.rs (renamed from src/librustc_builtin_macros/llvm_asm.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/log_syntax.rs (renamed from src/librustc_builtin_macros/log_syntax.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/proc_macro_harness.rs (renamed from src/librustc_builtin_macros/proc_macro_harness.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/source_util.rs (renamed from src/librustc_builtin_macros/source_util.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/standard_library_imports.rs (renamed from src/librustc_builtin_macros/standard_library_imports.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/test.rs (renamed from src/librustc_builtin_macros/test.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/test_harness.rs (renamed from src/librustc_builtin_macros/test_harness.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/trace_macros.rs (renamed from src/librustc_builtin_macros/trace_macros.rs)0
-rw-r--r--compiler/rustc_builtin_macros/src/util.rs (renamed from src/librustc_builtin_macros/util.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/Cargo.toml34
-rw-r--r--compiler/rustc_codegen_llvm/README.md (renamed from src/librustc_codegen_llvm/README.md)0
-rw-r--r--compiler/rustc_codegen_llvm/src/abi.rs (renamed from src/librustc_codegen_llvm/abi.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/allocator.rs (renamed from src/librustc_codegen_llvm/allocator.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs (renamed from src/librustc_codegen_llvm/asm.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs (renamed from src/librustc_codegen_llvm/attributes.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/back/archive.rs (renamed from src/librustc_codegen_llvm/back/archive.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs (renamed from src/librustc_codegen_llvm/back/lto.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/back/profiling.rs (renamed from src/librustc_codegen_llvm/back/profiling.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs (renamed from src/librustc_codegen_llvm/back/write.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/base.rs (renamed from src/librustc_codegen_llvm/base.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs (renamed from src/librustc_codegen_llvm/builder.rs)19
-rw-r--r--compiler/rustc_codegen_llvm/src/callee.rs (renamed from src/librustc_codegen_llvm/callee.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/common.rs (renamed from src/librustc_codegen_llvm/common.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs (renamed from src/librustc_codegen_llvm/consts.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs (renamed from src/librustc_codegen_llvm/context.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs (renamed from src/librustc_codegen_llvm/coverageinfo/mapgen.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs (renamed from src/librustc_codegen_llvm/coverageinfo/mod.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs (renamed from src/librustc_codegen_llvm/debuginfo/create_scope_map.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/doc.rs (renamed from src/librustc_codegen_llvm/debuginfo/doc.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs (renamed from src/librustc_codegen_llvm/debuginfo/gdb.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs (renamed from src/librustc_codegen_llvm/debuginfo/metadata.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs (renamed from src/librustc_codegen_llvm/debuginfo/mod.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs (renamed from src/librustc_codegen_llvm/debuginfo/namespace.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/source_loc.rs (renamed from src/librustc_codegen_llvm/debuginfo/source_loc.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/utils.rs (renamed from src/librustc_codegen_llvm/debuginfo/utils.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/declare.rs (renamed from src/librustc_codegen_llvm/declare.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs (renamed from src/librustc_codegen_llvm/intrinsic.rs)4
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs (renamed from src/librustc_codegen_llvm/lib.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs (renamed from src/librustc_codegen_llvm/llvm/archive_ro.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs (renamed from src/librustc_codegen_llvm/llvm/diagnostic.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs (renamed from src/librustc_codegen_llvm/llvm/ffi.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/mod.rs (renamed from src/librustc_codegen_llvm/llvm/mod.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs (renamed from src/librustc_codegen_llvm/llvm_util.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/metadata.rs (renamed from src/librustc_codegen_llvm/metadata.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/mono_item.rs (renamed from src/librustc_codegen_llvm/mono_item.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/type_.rs (renamed from src/librustc_codegen_llvm/type_.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/type_of.rs (renamed from src/librustc_codegen_llvm/type_of.rs)29
-rw-r--r--compiler/rustc_codegen_llvm/src/va_arg.rs (renamed from src/librustc_codegen_llvm/va_arg.rs)0
-rw-r--r--compiler/rustc_codegen_llvm/src/value.rs (renamed from src/librustc_codegen_llvm/value.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/Cargo.toml36
-rw-r--r--compiler/rustc_codegen_ssa/README.md (renamed from src/librustc_codegen_ssa/README.md)0
-rw-r--r--compiler/rustc_codegen_ssa/src/back/archive.rs (renamed from src/librustc_codegen_ssa/back/archive.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/back/command.rs (renamed from src/librustc_codegen_ssa/back/command.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs (renamed from src/librustc_codegen_ssa/back/link.rs)121
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs (renamed from src/librustc_codegen_ssa/back/linker.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/back/lto.rs (renamed from src/librustc_codegen_ssa/back/lto.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/back/mod.rs (renamed from src/librustc_codegen_ssa/back/mod.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/back/rpath.rs (renamed from src/librustc_codegen_ssa/back/rpath.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/back/rpath/tests.rs (renamed from src/librustc_codegen_ssa/back/rpath/tests.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs (renamed from src/librustc_codegen_ssa/back/symbol_export.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs (renamed from src/librustc_codegen_ssa/back/write.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs (renamed from src/librustc_codegen_ssa/base.rs)33
-rw-r--r--compiler/rustc_codegen_ssa/src/common.rs (renamed from src/librustc_codegen_ssa/common.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs (renamed from src/librustc_codegen_ssa/coverageinfo/ffi.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/coverageinfo/map.rs (renamed from src/librustc_codegen_ssa/coverageinfo/map.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/coverageinfo/mod.rs (renamed from src/librustc_codegen_ssa/coverageinfo/mod.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/mod.rs (renamed from src/librustc_codegen_ssa/debuginfo/mod.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs (renamed from src/librustc_codegen_ssa/debuginfo/type_names.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/glue.rs (renamed from src/librustc_codegen_ssa/glue.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs (renamed from src/librustc_codegen_ssa/lib.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/meth.rs (renamed from src/librustc_codegen_ssa/meth.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/analyze.rs (renamed from src/librustc_codegen_ssa/mir/analyze.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs (renamed from src/librustc_codegen_ssa/mir/block.rs)2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/constant.rs (renamed from src/librustc_codegen_ssa/mir/constant.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs (renamed from src/librustc_codegen_ssa/mir/coverageinfo.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs (renamed from src/librustc_codegen_ssa/mir/debuginfo.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs (renamed from src/librustc_codegen_ssa/mir/mod.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs (renamed from src/librustc_codegen_ssa/mir/operand.rs)50
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs (renamed from src/librustc_codegen_ssa/mir/place.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs (renamed from src/librustc_codegen_ssa/mir/rvalue.rs)28
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/statement.rs (renamed from src/librustc_codegen_ssa/mir/statement.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/mono_item.rs (renamed from src/librustc_codegen_ssa/mono_item.rs)8
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/abi.rs (renamed from src/librustc_codegen_ssa/traits/abi.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/asm.rs (renamed from src/librustc_codegen_ssa/traits/asm.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/backend.rs (renamed from src/librustc_codegen_ssa/traits/backend.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/builder.rs (renamed from src/librustc_codegen_ssa/traits/builder.rs)14
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/consts.rs (renamed from src/librustc_codegen_ssa/traits/consts.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs (renamed from src/librustc_codegen_ssa/traits/coverageinfo.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/debuginfo.rs (renamed from src/librustc_codegen_ssa/traits/debuginfo.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/declare.rs (renamed from src/librustc_codegen_ssa/traits/declare.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/intrinsic.rs (renamed from src/librustc_codegen_ssa/traits/intrinsic.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/misc.rs (renamed from src/librustc_codegen_ssa/traits/misc.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/mod.rs (renamed from src/librustc_codegen_ssa/traits/mod.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/statics.rs (renamed from src/librustc_codegen_ssa/traits/statics.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/type_.rs (renamed from src/librustc_codegen_ssa/traits/type_.rs)0
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/write.rs (renamed from src/librustc_codegen_ssa/traits/write.rs)0
-rw-r--r--compiler/rustc_data_structures/Cargo.toml (renamed from src/librustc_data_structures/Cargo.toml)12
-rw-r--r--compiler/rustc_data_structures/src/atomic_ref.rs (renamed from src/librustc_data_structures/atomic_ref.rs)0
-rw-r--r--compiler/rustc_data_structures/src/base_n.rs (renamed from src/librustc_data_structures/base_n.rs)0
-rw-r--r--compiler/rustc_data_structures/src/base_n/tests.rs (renamed from src/librustc_data_structures/base_n/tests.rs)0
-rw-r--r--compiler/rustc_data_structures/src/binary_search_util/mod.rs (renamed from src/librustc_data_structures/binary_search_util/mod.rs)0
-rw-r--r--compiler/rustc_data_structures/src/binary_search_util/tests.rs (renamed from src/librustc_data_structures/binary_search_util/tests.rs)0
-rw-r--r--compiler/rustc_data_structures/src/box_region.rs (renamed from src/librustc_data_structures/box_region.rs)0
-rw-r--r--compiler/rustc_data_structures/src/captures.rs (renamed from src/librustc_data_structures/captures.rs)0
-rw-r--r--compiler/rustc_data_structures/src/const_cstr.rs (renamed from src/librustc_data_structures/const_cstr.rs)0
-rw-r--r--compiler/rustc_data_structures/src/fingerprint.rs (renamed from src/librustc_data_structures/fingerprint.rs)30
-rw-r--r--compiler/rustc_data_structures/src/flock.rs (renamed from src/librustc_data_structures/flock.rs)0
-rw-r--r--compiler/rustc_data_structures/src/frozen.rs (renamed from src/librustc_data_structures/frozen.rs)0
-rw-r--r--compiler/rustc_data_structures/src/fx.rs (renamed from src/librustc_data_structures/fx.rs)0
-rw-r--r--compiler/rustc_data_structures/src/graph/dominators/mod.rs (renamed from src/librustc_data_structures/graph/dominators/mod.rs)0
-rw-r--r--compiler/rustc_data_structures/src/graph/dominators/tests.rs (renamed from src/librustc_data_structures/graph/dominators/tests.rs)0
-rw-r--r--compiler/rustc_data_structures/src/graph/implementation/mod.rs (renamed from src/librustc_data_structures/graph/implementation/mod.rs)0
-rw-r--r--compiler/rustc_data_structures/src/graph/implementation/tests.rs (renamed from src/librustc_data_structures/graph/implementation/tests.rs)0
-rw-r--r--compiler/rustc_data_structures/src/graph/iterate/mod.rs (renamed from src/librustc_data_structures/graph/iterate/mod.rs)0
-rw-r--r--compiler/rustc_data_structures/src/graph/iterate/tests.rs (renamed from src/librustc_data_structures/graph/iterate/tests.rs)0
-rw-r--r--compiler/rustc_data_structures/src/graph/mod.rs (renamed from src/librustc_data_structures/graph/mod.rs)0
-rw-r--r--compiler/rustc_data_structures/src/graph/reference.rs (renamed from src/librustc_data_structures/graph/reference.rs)0
-rw-r--r--compiler/rustc_data_structures/src/graph/scc/mod.rs (renamed from src/librustc_data_structures/graph/scc/mod.rs)0
-rw-r--r--compiler/rustc_data_structures/src/graph/scc/tests.rs (renamed from src/librustc_data_structures/graph/scc/tests.rs)0
-rw-r--r--compiler/rustc_data_structures/src/graph/tests.rs (renamed from src/librustc_data_structures/graph/tests.rs)0
-rw-r--r--compiler/rustc_data_structures/src/graph/vec_graph/mod.rs (renamed from src/librustc_data_structures/graph/vec_graph/mod.rs)0
-rw-r--r--compiler/rustc_data_structures/src/graph/vec_graph/tests.rs (renamed from src/librustc_data_structures/graph/vec_graph/tests.rs)0
-rw-r--r--compiler/rustc_data_structures/src/jobserver.rs40
-rw-r--r--compiler/rustc_data_structures/src/lib.rs (renamed from src/librustc_data_structures/lib.rs)2
-rw-r--r--compiler/rustc_data_structures/src/macros.rs (renamed from src/librustc_data_structures/macros.rs)0
-rw-r--r--compiler/rustc_data_structures/src/map_in_place.rs (renamed from src/librustc_data_structures/map_in_place.rs)0
-rw-r--r--compiler/rustc_data_structures/src/obligation_forest/graphviz.rs (renamed from src/librustc_data_structures/obligation_forest/graphviz.rs)0
-rw-r--r--compiler/rustc_data_structures/src/obligation_forest/mod.rs (renamed from src/librustc_data_structures/obligation_forest/mod.rs)0
-rw-r--r--compiler/rustc_data_structures/src/obligation_forest/tests.rs (renamed from src/librustc_data_structures/obligation_forest/tests.rs)0
-rw-r--r--compiler/rustc_data_structures/src/owning_ref/LICENSE (renamed from src/librustc_data_structures/owning_ref/LICENSE)0
-rw-r--r--compiler/rustc_data_structures/src/owning_ref/mod.rs (renamed from src/librustc_data_structures/owning_ref/mod.rs)0
-rw-r--r--compiler/rustc_data_structures/src/owning_ref/tests.rs (renamed from src/librustc_data_structures/owning_ref/tests.rs)0
-rw-r--r--compiler/rustc_data_structures/src/profiling.rs (renamed from src/librustc_data_structures/profiling.rs)0
-rw-r--r--compiler/rustc_data_structures/src/ptr_key.rs (renamed from src/librustc_data_structures/ptr_key.rs)0
-rw-r--r--compiler/rustc_data_structures/src/sharded.rs (renamed from src/librustc_data_structures/sharded.rs)0
-rw-r--r--compiler/rustc_data_structures/src/sip128.rs (renamed from src/librustc_data_structures/sip128.rs)0
-rw-r--r--compiler/rustc_data_structures/src/sip128/tests.rs (renamed from src/librustc_data_structures/sip128/tests.rs)0
-rw-r--r--compiler/rustc_data_structures/src/small_c_str.rs (renamed from src/librustc_data_structures/small_c_str.rs)0
-rw-r--r--compiler/rustc_data_structures/src/small_c_str/tests.rs (renamed from src/librustc_data_structures/small_c_str/tests.rs)0
-rw-r--r--compiler/rustc_data_structures/src/snapshot_map/mod.rs (renamed from src/librustc_data_structures/snapshot_map/mod.rs)0
-rw-r--r--compiler/rustc_data_structures/src/snapshot_map/tests.rs (renamed from src/librustc_data_structures/snapshot_map/tests.rs)0
-rw-r--r--compiler/rustc_data_structures/src/sorted_map.rs (renamed from src/librustc_data_structures/sorted_map.rs)0
-rw-r--r--compiler/rustc_data_structures/src/sorted_map/index_map.rs (renamed from src/librustc_data_structures/sorted_map/index_map.rs)0
-rw-r--r--compiler/rustc_data_structures/src/sorted_map/tests.rs (renamed from src/librustc_data_structures/sorted_map/tests.rs)0
-rw-r--r--compiler/rustc_data_structures/src/stable_hasher.rs (renamed from src/librustc_data_structures/stable_hasher.rs)0
-rw-r--r--compiler/rustc_data_structures/src/stable_map.rs (renamed from src/librustc_data_structures/stable_map.rs)0
-rw-r--r--compiler/rustc_data_structures/src/stable_set.rs (renamed from src/librustc_data_structures/stable_set.rs)0
-rw-r--r--compiler/rustc_data_structures/src/stack.rs (renamed from src/librustc_data_structures/stack.rs)0
-rw-r--r--compiler/rustc_data_structures/src/svh.rs (renamed from src/librustc_data_structures/svh.rs)0
-rw-r--r--compiler/rustc_data_structures/src/sync.rs (renamed from src/librustc_data_structures/sync.rs)4
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr.rs (renamed from src/librustc_data_structures/tagged_ptr.rs)0
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr/copy.rs (renamed from src/librustc_data_structures/tagged_ptr/copy.rs)0
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr/drop.rs (renamed from src/librustc_data_structures/tagged_ptr/drop.rs)0
-rw-r--r--compiler/rustc_data_structures/src/temp_dir.rs (renamed from src/librustc_data_structures/temp_dir.rs)0
-rw-r--r--compiler/rustc_data_structures/src/thin_vec.rs (renamed from src/librustc_data_structures/thin_vec.rs)0
-rw-r--r--compiler/rustc_data_structures/src/tiny_list.rs (renamed from src/librustc_data_structures/tiny_list.rs)0
-rw-r--r--compiler/rustc_data_structures/src/tiny_list/tests.rs (renamed from src/librustc_data_structures/tiny_list/tests.rs)0
-rw-r--r--compiler/rustc_data_structures/src/transitive_relation.rs (renamed from src/librustc_data_structures/transitive_relation.rs)0
-rw-r--r--compiler/rustc_data_structures/src/transitive_relation/tests.rs (renamed from src/librustc_data_structures/transitive_relation/tests.rs)0
-rw-r--r--compiler/rustc_data_structures/src/unhash.rs29
-rw-r--r--compiler/rustc_data_structures/src/vec_linked_list.rs (renamed from src/librustc_data_structures/vec_linked_list.rs)0
-rw-r--r--compiler/rustc_data_structures/src/work_queue.rs (renamed from src/librustc_data_structures/work_queue.rs)0
-rw-r--r--compiler/rustc_driver/Cargo.toml40
-rw-r--r--compiler/rustc_driver/README.md (renamed from src/librustc_driver/README.md)0
-rw-r--r--compiler/rustc_driver/src/args.rs (renamed from src/librustc_driver/args.rs)0
-rw-r--r--compiler/rustc_driver/src/lib.rs (renamed from src/librustc_driver/lib.rs)13
-rw-r--r--compiler/rustc_driver/src/pretty.rs (renamed from src/librustc_driver/pretty.rs)0
-rw-r--r--compiler/rustc_error_codes/Cargo.toml (renamed from src/librustc_error_codes/Cargo.toml)4
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs (renamed from src/librustc_error_codes/error_codes.rs)1
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0001.md (renamed from src/librustc_error_codes/error_codes/E0001.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0002.md (renamed from src/librustc_error_codes/error_codes/E0002.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0004.md (renamed from src/librustc_error_codes/error_codes/E0004.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0005.md (renamed from src/librustc_error_codes/error_codes/E0005.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0007.md (renamed from src/librustc_error_codes/error_codes/E0007.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0009.md (renamed from src/librustc_error_codes/error_codes/E0009.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0010.md (renamed from src/librustc_error_codes/error_codes/E0010.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0013.md (renamed from src/librustc_error_codes/error_codes/E0013.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0014.md (renamed from src/librustc_error_codes/error_codes/E0014.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0015.md (renamed from src/librustc_error_codes/error_codes/E0015.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0019.md (renamed from src/librustc_error_codes/error_codes/E0019.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0023.md (renamed from src/librustc_error_codes/error_codes/E0023.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0025.md (renamed from src/librustc_error_codes/error_codes/E0025.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0026.md (renamed from src/librustc_error_codes/error_codes/E0026.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0027.md (renamed from src/librustc_error_codes/error_codes/E0027.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0029.md (renamed from src/librustc_error_codes/error_codes/E0029.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0030.md (renamed from src/librustc_error_codes/error_codes/E0030.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0033.md (renamed from src/librustc_error_codes/error_codes/E0033.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0034.md (renamed from src/librustc_error_codes/error_codes/E0034.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0038.md (renamed from src/librustc_error_codes/error_codes/E0038.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0040.md (renamed from src/librustc_error_codes/error_codes/E0040.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0044.md (renamed from src/librustc_error_codes/error_codes/E0044.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0045.md (renamed from src/librustc_error_codes/error_codes/E0045.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0046.md (renamed from src/librustc_error_codes/error_codes/E0046.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0049.md (renamed from src/librustc_error_codes/error_codes/E0049.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0050.md (renamed from src/librustc_error_codes/error_codes/E0050.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0053.md (renamed from src/librustc_error_codes/error_codes/E0053.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0054.md (renamed from src/librustc_error_codes/error_codes/E0054.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0055.md (renamed from src/librustc_error_codes/error_codes/E0055.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0057.md (renamed from src/librustc_error_codes/error_codes/E0057.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0059.md (renamed from src/librustc_error_codes/error_codes/E0059.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0060.md (renamed from src/librustc_error_codes/error_codes/E0060.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0061.md (renamed from src/librustc_error_codes/error_codes/E0061.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0062.md (renamed from src/librustc_error_codes/error_codes/E0062.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0063.md (renamed from src/librustc_error_codes/error_codes/E0063.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0067.md (renamed from src/librustc_error_codes/error_codes/E0067.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0069.md (renamed from src/librustc_error_codes/error_codes/E0069.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0070.md (renamed from src/librustc_error_codes/error_codes/E0070.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0071.md (renamed from src/librustc_error_codes/error_codes/E0071.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0072.md (renamed from src/librustc_error_codes/error_codes/E0072.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0073.md (renamed from src/librustc_error_codes/error_codes/E0073.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0074.md (renamed from src/librustc_error_codes/error_codes/E0074.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0075.md (renamed from src/librustc_error_codes/error_codes/E0075.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0076.md (renamed from src/librustc_error_codes/error_codes/E0076.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0077.md (renamed from src/librustc_error_codes/error_codes/E0077.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0080.md (renamed from src/librustc_error_codes/error_codes/E0080.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0081.md (renamed from src/librustc_error_codes/error_codes/E0081.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0084.md (renamed from src/librustc_error_codes/error_codes/E0084.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0087.md (renamed from src/librustc_error_codes/error_codes/E0087.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0088.md (renamed from src/librustc_error_codes/error_codes/E0088.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0089.md (renamed from src/librustc_error_codes/error_codes/E0089.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0090.md (renamed from src/librustc_error_codes/error_codes/E0090.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0091.md (renamed from src/librustc_error_codes/error_codes/E0091.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0092.md (renamed from src/librustc_error_codes/error_codes/E0092.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0093.md (renamed from src/librustc_error_codes/error_codes/E0093.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0094.md (renamed from src/librustc_error_codes/error_codes/E0094.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0106.md (renamed from src/librustc_error_codes/error_codes/E0106.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0107.md (renamed from src/librustc_error_codes/error_codes/E0107.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0109.md (renamed from src/librustc_error_codes/error_codes/E0109.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0110.md (renamed from src/librustc_error_codes/error_codes/E0110.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0116.md (renamed from src/librustc_error_codes/error_codes/E0116.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0117.md (renamed from src/librustc_error_codes/error_codes/E0117.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0118.md (renamed from src/librustc_error_codes/error_codes/E0118.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0119.md (renamed from src/librustc_error_codes/error_codes/E0119.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0120.md (renamed from src/librustc_error_codes/error_codes/E0120.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0121.md (renamed from src/librustc_error_codes/error_codes/E0121.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0124.md (renamed from src/librustc_error_codes/error_codes/E0124.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0128.md (renamed from src/librustc_error_codes/error_codes/E0128.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0130.md (renamed from src/librustc_error_codes/error_codes/E0130.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0131.md (renamed from src/librustc_error_codes/error_codes/E0131.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0132.md (renamed from src/librustc_error_codes/error_codes/E0132.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0133.md (renamed from src/librustc_error_codes/error_codes/E0133.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0136.md (renamed from src/librustc_error_codes/error_codes/E0136.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0137.md (renamed from src/librustc_error_codes/error_codes/E0137.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0138.md (renamed from src/librustc_error_codes/error_codes/E0138.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0139.md (renamed from src/librustc_error_codes/error_codes/E0139.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0152.md (renamed from src/librustc_error_codes/error_codes/E0152.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0154.md (renamed from src/librustc_error_codes/error_codes/E0154.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0158.md (renamed from src/librustc_error_codes/error_codes/E0158.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0161.md (renamed from src/librustc_error_codes/error_codes/E0161.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0162.md (renamed from src/librustc_error_codes/error_codes/E0162.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0164.md (renamed from src/librustc_error_codes/error_codes/E0164.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0165.md (renamed from src/librustc_error_codes/error_codes/E0165.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0170.md (renamed from src/librustc_error_codes/error_codes/E0170.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0178.md (renamed from src/librustc_error_codes/error_codes/E0178.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0184.md (renamed from src/librustc_error_codes/error_codes/E0184.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0185.md (renamed from src/librustc_error_codes/error_codes/E0185.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0186.md (renamed from src/librustc_error_codes/error_codes/E0186.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0191.md (renamed from src/librustc_error_codes/error_codes/E0191.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0192.md (renamed from src/librustc_error_codes/error_codes/E0192.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0193.md (renamed from src/librustc_error_codes/error_codes/E0193.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0195.md (renamed from src/librustc_error_codes/error_codes/E0195.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0197.md (renamed from src/librustc_error_codes/error_codes/E0197.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0198.md (renamed from src/librustc_error_codes/error_codes/E0198.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0199.md (renamed from src/librustc_error_codes/error_codes/E0199.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0200.md (renamed from src/librustc_error_codes/error_codes/E0200.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0201.md (renamed from src/librustc_error_codes/error_codes/E0201.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0202.md (renamed from src/librustc_error_codes/error_codes/E0202.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0203.md (renamed from src/librustc_error_codes/error_codes/E0203.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0204.md (renamed from src/librustc_error_codes/error_codes/E0204.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0205.md (renamed from src/librustc_error_codes/error_codes/E0205.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0206.md (renamed from src/librustc_error_codes/error_codes/E0206.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0207.md (renamed from src/librustc_error_codes/error_codes/E0207.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0210.md (renamed from src/librustc_error_codes/error_codes/E0210.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0211.md (renamed from src/librustc_error_codes/error_codes/E0211.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0214.md (renamed from src/librustc_error_codes/error_codes/E0214.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0220.md (renamed from src/librustc_error_codes/error_codes/E0220.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0221.md (renamed from src/librustc_error_codes/error_codes/E0221.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0222.md (renamed from src/librustc_error_codes/error_codes/E0222.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0223.md (renamed from src/librustc_error_codes/error_codes/E0223.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0224.md (renamed from src/librustc_error_codes/error_codes/E0224.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0225.md (renamed from src/librustc_error_codes/error_codes/E0225.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0226.md (renamed from src/librustc_error_codes/error_codes/E0226.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0228.md (renamed from src/librustc_error_codes/error_codes/E0228.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0229.md (renamed from src/librustc_error_codes/error_codes/E0229.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0230.md (renamed from src/librustc_error_codes/error_codes/E0230.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0231.md (renamed from src/librustc_error_codes/error_codes/E0231.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0232.md (renamed from src/librustc_error_codes/error_codes/E0232.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0243.md (renamed from src/librustc_error_codes/error_codes/E0243.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0244.md (renamed from src/librustc_error_codes/error_codes/E0244.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0251.md (renamed from src/librustc_error_codes/error_codes/E0251.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0252.md (renamed from src/librustc_error_codes/error_codes/E0252.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0253.md (renamed from src/librustc_error_codes/error_codes/E0253.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0254.md (renamed from src/librustc_error_codes/error_codes/E0254.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0255.md (renamed from src/librustc_error_codes/error_codes/E0255.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0256.md (renamed from src/librustc_error_codes/error_codes/E0256.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0259.md (renamed from src/librustc_error_codes/error_codes/E0259.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0260.md (renamed from src/librustc_error_codes/error_codes/E0260.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0261.md (renamed from src/librustc_error_codes/error_codes/E0261.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0262.md (renamed from src/librustc_error_codes/error_codes/E0262.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0263.md (renamed from src/librustc_error_codes/error_codes/E0263.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0264.md (renamed from src/librustc_error_codes/error_codes/E0264.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0267.md (renamed from src/librustc_error_codes/error_codes/E0267.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0268.md (renamed from src/librustc_error_codes/error_codes/E0268.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0271.md (renamed from src/librustc_error_codes/error_codes/E0271.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0275.md (renamed from src/librustc_error_codes/error_codes/E0275.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0276.md (renamed from src/librustc_error_codes/error_codes/E0276.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0277.md (renamed from src/librustc_error_codes/error_codes/E0277.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0281.md (renamed from src/librustc_error_codes/error_codes/E0281.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0282.md (renamed from src/librustc_error_codes/error_codes/E0282.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0283.md (renamed from src/librustc_error_codes/error_codes/E0283.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0284.md (renamed from src/librustc_error_codes/error_codes/E0284.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0297.md (renamed from src/librustc_error_codes/error_codes/E0297.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0301.md (renamed from src/librustc_error_codes/error_codes/E0301.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0302.md (renamed from src/librustc_error_codes/error_codes/E0302.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0303.md (renamed from src/librustc_error_codes/error_codes/E0303.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0307.md (renamed from src/librustc_error_codes/error_codes/E0307.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0308.md (renamed from src/librustc_error_codes/error_codes/E0308.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0309.md (renamed from src/librustc_error_codes/error_codes/E0309.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0310.md (renamed from src/librustc_error_codes/error_codes/E0310.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0312.md (renamed from src/librustc_error_codes/error_codes/E0312.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0317.md (renamed from src/librustc_error_codes/error_codes/E0317.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0321.md (renamed from src/librustc_error_codes/error_codes/E0321.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0322.md (renamed from src/librustc_error_codes/error_codes/E0322.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0323.md (renamed from src/librustc_error_codes/error_codes/E0323.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0324.md (renamed from src/librustc_error_codes/error_codes/E0324.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0325.md (renamed from src/librustc_error_codes/error_codes/E0325.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0326.md (renamed from src/librustc_error_codes/error_codes/E0326.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0328.md (renamed from src/librustc_error_codes/error_codes/E0328.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0329.md (renamed from src/librustc_error_codes/error_codes/E0329.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0364.md (renamed from src/librustc_error_codes/error_codes/E0364.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0365.md (renamed from src/librustc_error_codes/error_codes/E0365.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0366.md (renamed from src/librustc_error_codes/error_codes/E0366.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0367.md (renamed from src/librustc_error_codes/error_codes/E0367.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0368.md (renamed from src/librustc_error_codes/error_codes/E0368.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0369.md (renamed from src/librustc_error_codes/error_codes/E0369.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0370.md (renamed from src/librustc_error_codes/error_codes/E0370.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0371.md (renamed from src/librustc_error_codes/error_codes/E0371.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0373.md (renamed from src/librustc_error_codes/error_codes/E0373.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0374.md (renamed from src/librustc_error_codes/error_codes/E0374.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0375.md (renamed from src/librustc_error_codes/error_codes/E0375.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0376.md (renamed from src/librustc_error_codes/error_codes/E0376.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0378.md (renamed from src/librustc_error_codes/error_codes/E0378.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0379.md (renamed from src/librustc_error_codes/error_codes/E0379.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0380.md (renamed from src/librustc_error_codes/error_codes/E0380.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0381.md (renamed from src/librustc_error_codes/error_codes/E0381.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0382.md (renamed from src/librustc_error_codes/error_codes/E0382.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0383.md (renamed from src/librustc_error_codes/error_codes/E0383.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0384.md (renamed from src/librustc_error_codes/error_codes/E0384.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0386.md (renamed from src/librustc_error_codes/error_codes/E0386.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0387.md (renamed from src/librustc_error_codes/error_codes/E0387.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0388.md (renamed from src/librustc_error_codes/error_codes/E0388.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0389.md (renamed from src/librustc_error_codes/error_codes/E0389.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0390.md (renamed from src/librustc_error_codes/error_codes/E0390.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0391.md (renamed from src/librustc_error_codes/error_codes/E0391.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0392.md (renamed from src/librustc_error_codes/error_codes/E0392.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0393.md (renamed from src/librustc_error_codes/error_codes/E0393.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0398.md (renamed from src/librustc_error_codes/error_codes/E0398.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0399.md (renamed from src/librustc_error_codes/error_codes/E0399.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0401.md (renamed from src/librustc_error_codes/error_codes/E0401.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0403.md (renamed from src/librustc_error_codes/error_codes/E0403.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0404.md (renamed from src/librustc_error_codes/error_codes/E0404.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0405.md (renamed from src/librustc_error_codes/error_codes/E0405.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0407.md (renamed from src/librustc_error_codes/error_codes/E0407.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0408.md (renamed from src/librustc_error_codes/error_codes/E0408.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0409.md (renamed from src/librustc_error_codes/error_codes/E0409.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0411.md (renamed from src/librustc_error_codes/error_codes/E0411.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0412.md (renamed from src/librustc_error_codes/error_codes/E0412.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0415.md (renamed from src/librustc_error_codes/error_codes/E0415.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0416.md (renamed from src/librustc_error_codes/error_codes/E0416.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0422.md (renamed from src/librustc_error_codes/error_codes/E0422.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0423.md (renamed from src/librustc_error_codes/error_codes/E0423.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0424.md (renamed from src/librustc_error_codes/error_codes/E0424.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0425.md (renamed from src/librustc_error_codes/error_codes/E0425.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0426.md (renamed from src/librustc_error_codes/error_codes/E0426.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0428.md (renamed from src/librustc_error_codes/error_codes/E0428.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0429.md (renamed from src/librustc_error_codes/error_codes/E0429.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0430.md (renamed from src/librustc_error_codes/error_codes/E0430.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0431.md (renamed from src/librustc_error_codes/error_codes/E0431.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0432.md (renamed from src/librustc_error_codes/error_codes/E0432.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0433.md (renamed from src/librustc_error_codes/error_codes/E0433.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0434.md (renamed from src/librustc_error_codes/error_codes/E0434.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0435.md (renamed from src/librustc_error_codes/error_codes/E0435.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0436.md (renamed from src/librustc_error_codes/error_codes/E0436.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0437.md (renamed from src/librustc_error_codes/error_codes/E0437.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0438.md (renamed from src/librustc_error_codes/error_codes/E0438.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0439.md (renamed from src/librustc_error_codes/error_codes/E0439.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0445.md (renamed from src/librustc_error_codes/error_codes/E0445.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0446.md (renamed from src/librustc_error_codes/error_codes/E0446.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0447.md (renamed from src/librustc_error_codes/error_codes/E0447.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0448.md (renamed from src/librustc_error_codes/error_codes/E0448.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0449.md (renamed from src/librustc_error_codes/error_codes/E0449.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0451.md (renamed from src/librustc_error_codes/error_codes/E0451.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0452.md (renamed from src/librustc_error_codes/error_codes/E0452.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0453.md (renamed from src/librustc_error_codes/error_codes/E0453.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0454.md (renamed from src/librustc_error_codes/error_codes/E0454.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0455.md (renamed from src/librustc_error_codes/error_codes/E0455.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0458.md (renamed from src/librustc_error_codes/error_codes/E0458.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0459.md (renamed from src/librustc_error_codes/error_codes/E0459.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0463.md (renamed from src/librustc_error_codes/error_codes/E0463.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0466.md (renamed from src/librustc_error_codes/error_codes/E0466.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0468.md (renamed from src/librustc_error_codes/error_codes/E0468.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0469.md (renamed from src/librustc_error_codes/error_codes/E0469.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0477.md (renamed from src/librustc_error_codes/error_codes/E0477.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0478.md (renamed from src/librustc_error_codes/error_codes/E0478.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0491.md (renamed from src/librustc_error_codes/error_codes/E0491.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0492.md (renamed from src/librustc_error_codes/error_codes/E0492.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0493.md (renamed from src/librustc_error_codes/error_codes/E0493.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0495.md (renamed from src/librustc_error_codes/error_codes/E0495.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0496.md (renamed from src/librustc_error_codes/error_codes/E0496.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0497.md (renamed from src/librustc_error_codes/error_codes/E0497.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0499.md (renamed from src/librustc_error_codes/error_codes/E0499.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0500.md (renamed from src/librustc_error_codes/error_codes/E0500.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0501.md (renamed from src/librustc_error_codes/error_codes/E0501.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0502.md (renamed from src/librustc_error_codes/error_codes/E0502.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0503.md (renamed from src/librustc_error_codes/error_codes/E0503.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0504.md (renamed from src/librustc_error_codes/error_codes/E0504.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0505.md (renamed from src/librustc_error_codes/error_codes/E0505.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0506.md (renamed from src/librustc_error_codes/error_codes/E0506.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0507.md (renamed from src/librustc_error_codes/error_codes/E0507.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0508.md (renamed from src/librustc_error_codes/error_codes/E0508.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0509.md (renamed from src/librustc_error_codes/error_codes/E0509.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0510.md (renamed from src/librustc_error_codes/error_codes/E0510.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0511.md (renamed from src/librustc_error_codes/error_codes/E0511.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0512.md (renamed from src/librustc_error_codes/error_codes/E0512.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0515.md (renamed from src/librustc_error_codes/error_codes/E0515.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0516.md (renamed from src/librustc_error_codes/error_codes/E0516.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0517.md (renamed from src/librustc_error_codes/error_codes/E0517.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0518.md (renamed from src/librustc_error_codes/error_codes/E0518.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0520.md (renamed from src/librustc_error_codes/error_codes/E0520.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0522.md (renamed from src/librustc_error_codes/error_codes/E0522.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0524.md (renamed from src/librustc_error_codes/error_codes/E0524.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0525.md (renamed from src/librustc_error_codes/error_codes/E0525.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0527.md (renamed from src/librustc_error_codes/error_codes/E0527.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0528.md (renamed from src/librustc_error_codes/error_codes/E0528.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0529.md (renamed from src/librustc_error_codes/error_codes/E0529.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0530.md (renamed from src/librustc_error_codes/error_codes/E0530.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0531.md (renamed from src/librustc_error_codes/error_codes/E0531.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0532.md (renamed from src/librustc_error_codes/error_codes/E0532.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0533.md (renamed from src/librustc_error_codes/error_codes/E0533.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0534.md (renamed from src/librustc_error_codes/error_codes/E0534.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0535.md (renamed from src/librustc_error_codes/error_codes/E0535.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0536.md (renamed from src/librustc_error_codes/error_codes/E0536.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0537.md (renamed from src/librustc_error_codes/error_codes/E0537.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0538.md (renamed from src/librustc_error_codes/error_codes/E0538.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0539.md (renamed from src/librustc_error_codes/error_codes/E0539.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0541.md (renamed from src/librustc_error_codes/error_codes/E0541.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0550.md (renamed from src/librustc_error_codes/error_codes/E0550.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0551.md (renamed from src/librustc_error_codes/error_codes/E0551.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0552.md (renamed from src/librustc_error_codes/error_codes/E0552.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0554.md (renamed from src/librustc_error_codes/error_codes/E0554.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0556.md (renamed from src/librustc_error_codes/error_codes/E0556.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0557.md (renamed from src/librustc_error_codes/error_codes/E0557.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0559.md (renamed from src/librustc_error_codes/error_codes/E0559.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0560.md (renamed from src/librustc_error_codes/error_codes/E0560.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0561.md (renamed from src/librustc_error_codes/error_codes/E0561.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0562.md (renamed from src/librustc_error_codes/error_codes/E0562.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0565.md (renamed from src/librustc_error_codes/error_codes/E0565.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0566.md (renamed from src/librustc_error_codes/error_codes/E0566.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0567.md (renamed from src/librustc_error_codes/error_codes/E0567.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0568.md (renamed from src/librustc_error_codes/error_codes/E0568.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0569.md (renamed from src/librustc_error_codes/error_codes/E0569.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0570.md (renamed from src/librustc_error_codes/error_codes/E0570.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0571.md (renamed from src/librustc_error_codes/error_codes/E0571.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0572.md (renamed from src/librustc_error_codes/error_codes/E0572.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0573.md (renamed from src/librustc_error_codes/error_codes/E0573.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0574.md (renamed from src/librustc_error_codes/error_codes/E0574.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0575.md (renamed from src/librustc_error_codes/error_codes/E0575.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0576.md (renamed from src/librustc_error_codes/error_codes/E0576.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0577.md (renamed from src/librustc_error_codes/error_codes/E0577.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0578.md (renamed from src/librustc_error_codes/error_codes/E0578.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0579.md (renamed from src/librustc_error_codes/error_codes/E0579.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0580.md (renamed from src/librustc_error_codes/error_codes/E0580.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0581.md (renamed from src/librustc_error_codes/error_codes/E0581.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0582.md (renamed from src/librustc_error_codes/error_codes/E0582.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0583.md (renamed from src/librustc_error_codes/error_codes/E0583.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0584.md (renamed from src/librustc_error_codes/error_codes/E0584.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0585.md (renamed from src/librustc_error_codes/error_codes/E0585.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0586.md (renamed from src/librustc_error_codes/error_codes/E0586.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0587.md (renamed from src/librustc_error_codes/error_codes/E0587.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0588.md (renamed from src/librustc_error_codes/error_codes/E0588.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0589.md (renamed from src/librustc_error_codes/error_codes/E0589.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0590.md (renamed from src/librustc_error_codes/error_codes/E0590.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0591.md (renamed from src/librustc_error_codes/error_codes/E0591.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0592.md (renamed from src/librustc_error_codes/error_codes/E0592.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0593.md (renamed from src/librustc_error_codes/error_codes/E0593.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0594.md (renamed from src/librustc_error_codes/error_codes/E0594.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0595.md (renamed from src/librustc_error_codes/error_codes/E0595.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0596.md (renamed from src/librustc_error_codes/error_codes/E0596.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0597.md (renamed from src/librustc_error_codes/error_codes/E0597.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0599.md (renamed from src/librustc_error_codes/error_codes/E0599.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0600.md (renamed from src/librustc_error_codes/error_codes/E0600.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0601.md (renamed from src/librustc_error_codes/error_codes/E0601.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0602.md (renamed from src/librustc_error_codes/error_codes/E0602.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0603.md (renamed from src/librustc_error_codes/error_codes/E0603.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0604.md (renamed from src/librustc_error_codes/error_codes/E0604.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0605.md (renamed from src/librustc_error_codes/error_codes/E0605.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0606.md (renamed from src/librustc_error_codes/error_codes/E0606.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0607.md (renamed from src/librustc_error_codes/error_codes/E0607.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0608.md (renamed from src/librustc_error_codes/error_codes/E0608.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0609.md (renamed from src/librustc_error_codes/error_codes/E0609.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0610.md (renamed from src/librustc_error_codes/error_codes/E0610.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0614.md (renamed from src/librustc_error_codes/error_codes/E0614.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0615.md (renamed from src/librustc_error_codes/error_codes/E0615.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0616.md (renamed from src/librustc_error_codes/error_codes/E0616.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0617.md (renamed from src/librustc_error_codes/error_codes/E0617.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0618.md (renamed from src/librustc_error_codes/error_codes/E0618.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0619.md (renamed from src/librustc_error_codes/error_codes/E0619.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0620.md (renamed from src/librustc_error_codes/error_codes/E0620.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0621.md (renamed from src/librustc_error_codes/error_codes/E0621.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0622.md (renamed from src/librustc_error_codes/error_codes/E0622.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0623.md (renamed from src/librustc_error_codes/error_codes/E0623.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0624.md (renamed from src/librustc_error_codes/error_codes/E0624.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0626.md (renamed from src/librustc_error_codes/error_codes/E0626.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0627.md (renamed from src/librustc_error_codes/error_codes/E0627.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0628.md (renamed from src/librustc_error_codes/error_codes/E0628.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0631.md (renamed from src/librustc_error_codes/error_codes/E0631.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0633.md (renamed from src/librustc_error_codes/error_codes/E0633.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0634.md (renamed from src/librustc_error_codes/error_codes/E0634.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0635.md (renamed from src/librustc_error_codes/error_codes/E0635.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0636.md (renamed from src/librustc_error_codes/error_codes/E0636.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0637.md (renamed from src/librustc_error_codes/error_codes/E0637.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0638.md (renamed from src/librustc_error_codes/error_codes/E0638.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0639.md (renamed from src/librustc_error_codes/error_codes/E0639.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0641.md (renamed from src/librustc_error_codes/error_codes/E0641.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0642.md (renamed from src/librustc_error_codes/error_codes/E0642.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0643.md (renamed from src/librustc_error_codes/error_codes/E0643.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0644.md (renamed from src/librustc_error_codes/error_codes/E0644.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0646.md (renamed from src/librustc_error_codes/error_codes/E0646.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0647.md (renamed from src/librustc_error_codes/error_codes/E0647.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0648.md (renamed from src/librustc_error_codes/error_codes/E0648.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0657.md (renamed from src/librustc_error_codes/error_codes/E0657.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0658.md (renamed from src/librustc_error_codes/error_codes/E0658.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0659.md (renamed from src/librustc_error_codes/error_codes/E0659.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0660.md (renamed from src/librustc_error_codes/error_codes/E0660.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0661.md (renamed from src/librustc_error_codes/error_codes/E0661.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0662.md (renamed from src/librustc_error_codes/error_codes/E0662.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0663.md (renamed from src/librustc_error_codes/error_codes/E0663.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0664.md (renamed from src/librustc_error_codes/error_codes/E0664.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0665.md (renamed from src/librustc_error_codes/error_codes/E0665.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0666.md (renamed from src/librustc_error_codes/error_codes/E0666.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0668.md (renamed from src/librustc_error_codes/error_codes/E0668.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0669.md (renamed from src/librustc_error_codes/error_codes/E0669.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0670.md (renamed from src/librustc_error_codes/error_codes/E0670.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0671.md (renamed from src/librustc_error_codes/error_codes/E0671.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0687.md (renamed from src/librustc_error_codes/error_codes/E0687.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0688.md (renamed from src/librustc_error_codes/error_codes/E0688.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0689.md (renamed from src/librustc_error_codes/error_codes/E0689.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0690.md (renamed from src/librustc_error_codes/error_codes/E0690.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0691.md (renamed from src/librustc_error_codes/error_codes/E0691.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0692.md (renamed from src/librustc_error_codes/error_codes/E0692.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0693.md (renamed from src/librustc_error_codes/error_codes/E0693.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0695.md (renamed from src/librustc_error_codes/error_codes/E0695.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0696.md (renamed from src/librustc_error_codes/error_codes/E0696.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0697.md (renamed from src/librustc_error_codes/error_codes/E0697.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0698.md (renamed from src/librustc_error_codes/error_codes/E0698.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0699.md (renamed from src/librustc_error_codes/error_codes/E0699.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0700.md (renamed from src/librustc_error_codes/error_codes/E0700.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0701.md (renamed from src/librustc_error_codes/error_codes/E0701.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0703.md (renamed from src/librustc_error_codes/error_codes/E0703.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0704.md (renamed from src/librustc_error_codes/error_codes/E0704.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0705.md (renamed from src/librustc_error_codes/error_codes/E0705.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0706.md (renamed from src/librustc_error_codes/error_codes/E0706.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0708.md (renamed from src/librustc_error_codes/error_codes/E0708.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0710.md (renamed from src/librustc_error_codes/error_codes/E0710.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0712.md (renamed from src/librustc_error_codes/error_codes/E0712.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0713.md (renamed from src/librustc_error_codes/error_codes/E0713.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0714.md (renamed from src/librustc_error_codes/error_codes/E0714.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0715.md (renamed from src/librustc_error_codes/error_codes/E0715.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0716.md (renamed from src/librustc_error_codes/error_codes/E0716.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0718.md (renamed from src/librustc_error_codes/error_codes/E0718.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0719.md (renamed from src/librustc_error_codes/error_codes/E0719.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0720.md (renamed from src/librustc_error_codes/error_codes/E0720.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0723.md (renamed from src/librustc_error_codes/error_codes/E0723.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0724.md (renamed from src/librustc_error_codes/error_codes/E0724.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0725.md (renamed from src/librustc_error_codes/error_codes/E0725.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0727.md (renamed from src/librustc_error_codes/error_codes/E0727.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0728.md (renamed from src/librustc_error_codes/error_codes/E0728.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0729.md (renamed from src/librustc_error_codes/error_codes/E0729.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0730.md (renamed from src/librustc_error_codes/error_codes/E0730.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0731.md (renamed from src/librustc_error_codes/error_codes/E0731.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0732.md (renamed from src/librustc_error_codes/error_codes/E0732.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0733.md (renamed from src/librustc_error_codes/error_codes/E0733.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0734.md (renamed from src/librustc_error_codes/error_codes/E0734.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0735.md (renamed from src/librustc_error_codes/error_codes/E0735.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0736.md (renamed from src/librustc_error_codes/error_codes/E0736.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0737.md (renamed from src/librustc_error_codes/error_codes/E0737.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0739.md (renamed from src/librustc_error_codes/error_codes/E0739.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0740.md (renamed from src/librustc_error_codes/error_codes/E0740.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0741.md (renamed from src/librustc_error_codes/error_codes/E0741.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0742.md (renamed from src/librustc_error_codes/error_codes/E0742.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0743.md (renamed from src/librustc_error_codes/error_codes/E0743.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0744.md (renamed from src/librustc_error_codes/error_codes/E0744.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0745.md (renamed from src/librustc_error_codes/error_codes/E0745.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0746.md (renamed from src/librustc_error_codes/error_codes/E0746.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0747.md (renamed from src/librustc_error_codes/error_codes/E0747.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0748.md (renamed from src/librustc_error_codes/error_codes/E0748.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0749.md (renamed from src/librustc_error_codes/error_codes/E0749.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0750.md (renamed from src/librustc_error_codes/error_codes/E0750.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0751.md (renamed from src/librustc_error_codes/error_codes/E0751.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0752.md (renamed from src/librustc_error_codes/error_codes/E0752.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0753.md (renamed from src/librustc_error_codes/error_codes/E0753.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0754.md (renamed from src/librustc_error_codes/error_codes/E0754.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0758.md (renamed from src/librustc_error_codes/error_codes/E0758.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0759.md (renamed from src/librustc_error_codes/error_codes/E0759.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0760.md (renamed from src/librustc_error_codes/error_codes/E0760.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0761.md (renamed from src/librustc_error_codes/error_codes/E0761.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0762.md (renamed from src/librustc_error_codes/error_codes/E0762.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0763.md (renamed from src/librustc_error_codes/error_codes/E0763.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0764.md (renamed from src/librustc_error_codes/error_codes/E0764.md)22
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0765.md (renamed from src/librustc_error_codes/error_codes/E0765.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0766.md (renamed from src/librustc_error_codes/error_codes/E0766.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0767.md (renamed from src/librustc_error_codes/error_codes/E0767.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0768.md (renamed from src/librustc_error_codes/error_codes/E0768.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0769.md (renamed from src/librustc_error_codes/error_codes/E0769.md)22
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0770.md (renamed from src/librustc_error_codes/error_codes/E0770.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0771.md (renamed from src/librustc_error_codes/error_codes/E0771.md)0
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0773.md38
-rw-r--r--compiler/rustc_error_codes/src/lib.rs (renamed from src/librustc_error_codes/lib.rs)0
-rw-r--r--compiler/rustc_errors/Cargo.toml (renamed from src/librustc_errors/Cargo.toml)10
-rw-r--r--compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs (renamed from src/librustc_errors/annotate_snippet_emitter_writer.rs)0
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs (renamed from src/librustc_errors/diagnostic.rs)0
-rw-r--r--compiler/rustc_errors/src/diagnostic_builder.rs (renamed from src/librustc_errors/diagnostic_builder.rs)0
-rw-r--r--compiler/rustc_errors/src/emitter.rs (renamed from src/librustc_errors/emitter.rs)0
-rw-r--r--compiler/rustc_errors/src/json.rs (renamed from src/librustc_errors/json.rs)0
-rw-r--r--compiler/rustc_errors/src/json/tests.rs (renamed from src/librustc_errors/json/tests.rs)0
-rw-r--r--compiler/rustc_errors/src/lib.rs (renamed from src/librustc_errors/lib.rs)0
-rw-r--r--compiler/rustc_errors/src/lock.rs (renamed from src/librustc_errors/lock.rs)0
-rw-r--r--compiler/rustc_errors/src/registry.rs (renamed from src/librustc_errors/registry.rs)0
-rw-r--r--compiler/rustc_errors/src/snippet.rs (renamed from src/librustc_errors/snippet.rs)0
-rw-r--r--compiler/rustc_errors/src/styled_buffer.rs (renamed from src/librustc_errors/styled_buffer.rs)0
-rw-r--r--compiler/rustc_expand/Cargo.toml26
-rw-r--r--compiler/rustc_expand/src/base.rs (renamed from src/librustc_expand/base.rs)0
-rw-r--r--compiler/rustc_expand/src/build.rs (renamed from src/librustc_expand/build.rs)0
-rw-r--r--compiler/rustc_expand/src/config.rs (renamed from src/librustc_expand/config.rs)11
-rw-r--r--compiler/rustc_expand/src/expand.rs (renamed from src/librustc_expand/expand.rs)6
-rw-r--r--compiler/rustc_expand/src/lib.rs (renamed from src/librustc_expand/lib.rs)5
-rw-r--r--compiler/rustc_expand/src/mbe.rs (renamed from src/librustc_expand/mbe.rs)0
-rw-r--r--compiler/rustc_expand/src/mbe/macro_check.rs (renamed from src/librustc_expand/mbe/macro_check.rs)0
-rw-r--r--compiler/rustc_expand/src/mbe/macro_parser.rs (renamed from src/librustc_expand/mbe/macro_parser.rs)0
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs (renamed from src/librustc_expand/mbe/macro_rules.rs)0
-rw-r--r--compiler/rustc_expand/src/mbe/quoted.rs (renamed from src/librustc_expand/mbe/quoted.rs)0
-rw-r--r--compiler/rustc_expand/src/mbe/transcribe.rs (renamed from src/librustc_expand/mbe/transcribe.rs)0
-rw-r--r--compiler/rustc_expand/src/module.rs (renamed from src/librustc_expand/module.rs)0
-rw-r--r--compiler/rustc_expand/src/mut_visit/tests.rs (renamed from src/librustc_expand/mut_visit/tests.rs)0
-rw-r--r--compiler/rustc_expand/src/parse/tests.rs (renamed from src/librustc_expand/parse/tests.rs)0
-rw-r--r--compiler/rustc_expand/src/placeholders.rs (renamed from src/librustc_expand/placeholders.rs)8
-rw-r--r--compiler/rustc_expand/src/proc_macro.rs (renamed from src/librustc_expand/proc_macro.rs)41
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs (renamed from src/librustc_expand/proc_macro_server.rs)2
-rw-r--r--compiler/rustc_expand/src/tests.rs (renamed from src/librustc_expand/tests.rs)0
-rw-r--r--compiler/rustc_expand/src/tokenstream/tests.rs (renamed from src/librustc_expand/tokenstream/tests.rs)0
-rw-r--r--compiler/rustc_feature/Cargo.toml12
-rw-r--r--compiler/rustc_feature/src/accepted.rs (renamed from src/librustc_feature/accepted.rs)0
-rw-r--r--compiler/rustc_feature/src/active.rs (renamed from src/librustc_feature/active.rs)0
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs (renamed from src/librustc_feature/builtin_attrs.rs)10
-rw-r--r--compiler/rustc_feature/src/lib.rs (renamed from src/librustc_feature/lib.rs)2
-rw-r--r--compiler/rustc_feature/src/removed.rs (renamed from src/librustc_feature/removed.rs)0
-rw-r--r--compiler/rustc_fs_util/Cargo.toml (renamed from src/librustc_fs_util/Cargo.toml)6
-rw-r--r--compiler/rustc_fs_util/src/lib.rs (renamed from src/librustc_fs_util/lib.rs)0
-rw-r--r--compiler/rustc_graphviz/Cargo.toml (renamed from src/librustc_graphviz/Cargo.toml)4
-rw-r--r--compiler/rustc_graphviz/src/lib.rs (renamed from src/librustc_graphviz/lib.rs)0
-rw-r--r--compiler/rustc_graphviz/src/tests.rs (renamed from src/librustc_graphviz/tests.rs)0
-rw-r--r--compiler/rustc_hir/Cargo.toml19
-rw-r--r--compiler/rustc_hir/src/arena.rs (renamed from src/librustc_hir/arena.rs)0
-rw-r--r--compiler/rustc_hir/src/def.rs (renamed from src/librustc_hir/def.rs)0
-rw-r--r--compiler/rustc_hir/src/definitions.rs (renamed from src/librustc_hir/definitions.rs)0
-rw-r--r--compiler/rustc_hir/src/hir.rs (renamed from src/librustc_hir/hir.rs)0
-rw-r--r--compiler/rustc_hir/src/hir_id.rs (renamed from src/librustc_hir/hir_id.rs)0
-rw-r--r--compiler/rustc_hir/src/intravisit.rs (renamed from src/librustc_hir/intravisit.rs)0
-rw-r--r--compiler/rustc_hir/src/itemlikevisit.rs (renamed from src/librustc_hir/itemlikevisit.rs)0
-rw-r--r--compiler/rustc_hir/src/lang_items.rs (renamed from src/librustc_hir/lang_items.rs)16
-rw-r--r--compiler/rustc_hir/src/lib.rs (renamed from src/librustc_hir/lib.rs)1
-rw-r--r--compiler/rustc_hir/src/pat_util.rs (renamed from src/librustc_hir/pat_util.rs)0
-rw-r--r--compiler/rustc_hir/src/stable_hash_impls.rs (renamed from src/librustc_hir/stable_hash_impls.rs)0
-rw-r--r--compiler/rustc_hir/src/target.rs (renamed from src/librustc_hir/target.rs)0
-rw-r--r--compiler/rustc_hir/src/weak_lang_items.rs (renamed from src/librustc_hir/weak_lang_items.rs)14
-rw-r--r--compiler/rustc_hir_pretty/Cargo.toml15
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs (renamed from src/librustc_hir_pretty/lib.rs)0
-rw-r--r--compiler/rustc_incremental/Cargo.toml22
-rw-r--r--compiler/rustc_incremental/src/assert_dep_graph.rs (renamed from src/librustc_incremental/assert_dep_graph.rs)0
-rw-r--r--compiler/rustc_incremental/src/assert_module_sources.rs (renamed from src/librustc_incremental/assert_module_sources.rs)0
-rw-r--r--compiler/rustc_incremental/src/lib.rs (renamed from src/librustc_incremental/lib.rs)0
-rw-r--r--compiler/rustc_incremental/src/persist/README.md (renamed from src/librustc_incremental/persist/README.md)0
-rw-r--r--compiler/rustc_incremental/src/persist/data.rs (renamed from src/librustc_incremental/persist/data.rs)0
-rw-r--r--compiler/rustc_incremental/src/persist/dirty_clean.rs (renamed from src/librustc_incremental/persist/dirty_clean.rs)0
-rw-r--r--compiler/rustc_incremental/src/persist/file_format.rs (renamed from src/librustc_incremental/persist/file_format.rs)0
-rw-r--r--compiler/rustc_incremental/src/persist/fs.rs (renamed from src/librustc_incremental/persist/fs.rs)0
-rw-r--r--compiler/rustc_incremental/src/persist/fs/tests.rs (renamed from src/librustc_incremental/persist/fs/tests.rs)0
-rw-r--r--compiler/rustc_incremental/src/persist/load.rs (renamed from src/librustc_incremental/persist/load.rs)0
-rw-r--r--compiler/rustc_incremental/src/persist/mod.rs (renamed from src/librustc_incremental/persist/mod.rs)0
-rw-r--r--compiler/rustc_incremental/src/persist/save.rs (renamed from src/librustc_incremental/persist/save.rs)0
-rw-r--r--compiler/rustc_incremental/src/persist/work_product.rs (renamed from src/librustc_incremental/persist/work_product.rs)0
-rw-r--r--compiler/rustc_index/Cargo.toml (renamed from src/librustc_index/Cargo.toml)6
-rw-r--r--compiler/rustc_index/src/bit_set.rs (renamed from src/librustc_index/bit_set.rs)0
-rw-r--r--compiler/rustc_index/src/bit_set/tests.rs (renamed from src/librustc_index/bit_set/tests.rs)0
-rw-r--r--compiler/rustc_index/src/lib.rs (renamed from src/librustc_index/lib.rs)0
-rw-r--r--compiler/rustc_index/src/vec.rs (renamed from src/librustc_index/vec.rs)0
-rw-r--r--compiler/rustc_index/src/vec/tests.rs (renamed from src/librustc_index/vec/tests.rs)0
-rw-r--r--compiler/rustc_infer/Cargo.toml24
-rw-r--r--compiler/rustc_infer/src/infer/at.rs (renamed from src/librustc_infer/infer/at.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs (renamed from src/librustc_infer/infer/canonical/canonicalizer.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/canonical/mod.rs (renamed from src/librustc_infer/infer/canonical/mod.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/canonical/query_response.rs (renamed from src/librustc_infer/infer/canonical/query_response.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/canonical/substitute.rs (renamed from src/librustc_infer/infer/canonical/substitute.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/combine.rs (renamed from src/librustc_infer/infer/combine.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/equate.rs (renamed from src/librustc_infer/infer/equate.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs (renamed from src/librustc_infer/infer/error_reporting/mod.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs (renamed from src/librustc_infer/infer/error_reporting/need_type_info.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs (renamed from src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs (renamed from src/librustc_infer/infer/error_reporting/nice_region_error/find_anon_type.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs (renamed from src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs (renamed from src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs (renamed from src/librustc_infer/infer/error_reporting/nice_region_error/placeholder_error.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs (renamed from src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs (renamed from src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs (renamed from src/librustc_infer/infer/error_reporting/nice_region_error/util.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note.rs (renamed from src/librustc_infer/infer/error_reporting/note.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/free_regions.rs (renamed from src/librustc_infer/infer/free_regions.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/freshen.rs (renamed from src/librustc_infer/infer/freshen.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/fudge.rs (renamed from src/librustc_infer/infer/fudge.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/glb.rs (renamed from src/librustc_infer/infer/glb.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/higher_ranked/README.md (renamed from src/librustc_infer/infer/higher_ranked/README.md)0
-rw-r--r--compiler/rustc_infer/src/infer/higher_ranked/mod.rs (renamed from src/librustc_infer/infer/higher_ranked/mod.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/lattice.rs (renamed from src/librustc_infer/infer/lattice.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/README.md (renamed from src/librustc_infer/infer/lexical_region_resolve/README.md)0
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs (renamed from src/librustc_infer/infer/lexical_region_resolve/mod.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/lub.rs (renamed from src/librustc_infer/infer/lub.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs (renamed from src/librustc_infer/infer/mod.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/nll_relate/mod.rs (renamed from src/librustc_infer/infer/nll_relate/mod.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/outlives/env.rs (renamed from src/librustc_infer/infer/outlives/env.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/outlives/mod.rs (renamed from src/librustc_infer/infer/outlives/mod.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs (renamed from src/librustc_infer/infer/outlives/obligations.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/outlives/verify.rs (renamed from src/librustc_infer/infer/outlives/verify.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/README.md (renamed from src/librustc_infer/infer/region_constraints/README.md)0
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/leak_check.rs (renamed from src/librustc_infer/infer/region_constraints/leak_check.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/mod.rs (renamed from src/librustc_infer/infer/region_constraints/mod.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/resolve.rs (renamed from src/librustc_infer/infer/resolve.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/sub.rs (renamed from src/librustc_infer/infer/sub.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/type_variable.rs (renamed from src/librustc_infer/infer/type_variable.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/undo_log.rs (renamed from src/librustc_infer/infer/undo_log.rs)0
-rw-r--r--compiler/rustc_infer/src/lib.rs (renamed from src/librustc_infer/lib.rs)0
-rw-r--r--compiler/rustc_infer/src/traits/engine.rs (renamed from src/librustc_infer/traits/engine.rs)0
-rw-r--r--compiler/rustc_infer/src/traits/error_reporting/mod.rs (renamed from src/librustc_infer/traits/error_reporting/mod.rs)0
-rw-r--r--compiler/rustc_infer/src/traits/mod.rs (renamed from src/librustc_infer/traits/mod.rs)0
-rw-r--r--compiler/rustc_infer/src/traits/project.rs (renamed from src/librustc_infer/traits/project.rs)0
-rw-r--r--compiler/rustc_infer/src/traits/structural_impls.rs (renamed from src/librustc_infer/traits/structural_impls.rs)0
-rw-r--r--compiler/rustc_infer/src/traits/util.rs (renamed from src/librustc_infer/traits/util.rs)0
-rw-r--r--compiler/rustc_interface/Cargo.toml54
-rw-r--r--compiler/rustc_interface/src/callbacks.rs (renamed from src/librustc_interface/callbacks.rs)0
-rw-r--r--compiler/rustc_interface/src/interface.rs (renamed from src/librustc_interface/interface.rs)0
-rw-r--r--compiler/rustc_interface/src/lib.rs (renamed from src/librustc_interface/lib.rs)1
-rw-r--r--compiler/rustc_interface/src/passes.rs (renamed from src/librustc_interface/passes.rs)7
-rw-r--r--compiler/rustc_interface/src/proc_macro_decls.rs (renamed from src/librustc_interface/proc_macro_decls.rs)0
-rw-r--r--compiler/rustc_interface/src/queries.rs (renamed from src/librustc_interface/queries.rs)0
-rw-r--r--compiler/rustc_interface/src/tests.rs (renamed from src/librustc_interface/tests.rs)2
-rw-r--r--compiler/rustc_interface/src/util.rs (renamed from src/librustc_interface/util.rs)4
-rw-r--r--compiler/rustc_lexer/Cargo.toml (renamed from src/librustc_lexer/Cargo.toml)3
-rw-r--r--compiler/rustc_lexer/src/cursor.rs (renamed from src/librustc_lexer/src/cursor.rs)0
-rw-r--r--compiler/rustc_lexer/src/lib.rs (renamed from src/librustc_lexer/src/lib.rs)14
-rw-r--r--compiler/rustc_lexer/src/tests.rs287
-rw-r--r--compiler/rustc_lexer/src/unescape.rs (renamed from src/librustc_lexer/src/unescape.rs)0
-rw-r--r--compiler/rustc_lexer/src/unescape/tests.rs (renamed from src/librustc_lexer/src/unescape/tests.rs)0
-rw-r--r--compiler/rustc_lint/Cargo.toml22
-rw-r--r--compiler/rustc_lint/src/array_into_iter.rs (renamed from src/librustc_lint/array_into_iter.rs)0
-rw-r--r--compiler/rustc_lint/src/builtin.rs (renamed from src/librustc_lint/builtin.rs)0
-rw-r--r--compiler/rustc_lint/src/context.rs (renamed from src/librustc_lint/context.rs)0
-rw-r--r--compiler/rustc_lint/src/early.rs (renamed from src/librustc_lint/early.rs)0
-rw-r--r--compiler/rustc_lint/src/internal.rs (renamed from src/librustc_lint/internal.rs)0
-rw-r--r--compiler/rustc_lint/src/late.rs (renamed from src/librustc_lint/late.rs)0
-rw-r--r--compiler/rustc_lint/src/levels.rs (renamed from src/librustc_lint/levels.rs)0
-rw-r--r--compiler/rustc_lint/src/lib.rs (renamed from src/librustc_lint/lib.rs)0
-rw-r--r--compiler/rustc_lint/src/non_ascii_idents.rs (renamed from src/librustc_lint/non_ascii_idents.rs)0
-rw-r--r--compiler/rustc_lint/src/nonstandard_style.rs (renamed from src/librustc_lint/nonstandard_style.rs)0
-rw-r--r--compiler/rustc_lint/src/nonstandard_style/tests.rs (renamed from src/librustc_lint/nonstandard_style/tests.rs)0
-rw-r--r--compiler/rustc_lint/src/passes.rs (renamed from src/librustc_lint/passes.rs)0
-rw-r--r--compiler/rustc_lint/src/redundant_semicolon.rs (renamed from src/librustc_lint/redundant_semicolon.rs)0
-rw-r--r--compiler/rustc_lint/src/types.rs (renamed from src/librustc_lint/types.rs)0
-rw-r--r--compiler/rustc_lint/src/unused.rs (renamed from src/librustc_lint/unused.rs)0
-rw-r--r--compiler/rustc_macros/Cargo.toml (renamed from src/librustc_macros/Cargo.toml)0
-rw-r--r--compiler/rustc_macros/src/hash_stable.rs (renamed from src/librustc_macros/src/hash_stable.rs)0
-rw-r--r--compiler/rustc_macros/src/lib.rs (renamed from src/librustc_macros/src/lib.rs)0
-rw-r--r--compiler/rustc_macros/src/lift.rs (renamed from src/librustc_macros/src/lift.rs)0
-rw-r--r--compiler/rustc_macros/src/query.rs (renamed from src/librustc_macros/src/query.rs)0
-rw-r--r--compiler/rustc_macros/src/serialize.rs (renamed from src/librustc_macros/src/serialize.rs)0
-rw-r--r--compiler/rustc_macros/src/symbols.rs (renamed from src/librustc_macros/src/symbols.rs)0
-rw-r--r--compiler/rustc_macros/src/type_foldable.rs (renamed from src/librustc_macros/src/type_foldable.rs)0
-rw-r--r--compiler/rustc_metadata/Cargo.toml33
-rw-r--r--compiler/rustc_metadata/src/creader.rs (renamed from src/librustc_metadata/creader.rs)0
-rw-r--r--compiler/rustc_metadata/src/dependency_format.rs (renamed from src/librustc_metadata/dependency_format.rs)0
-rw-r--r--compiler/rustc_metadata/src/dynamic_lib.rs (renamed from src/librustc_metadata/dynamic_lib.rs)0
-rw-r--r--compiler/rustc_metadata/src/dynamic_lib/tests.rs (renamed from src/librustc_metadata/dynamic_lib/tests.rs)0
-rw-r--r--compiler/rustc_metadata/src/foreign_modules.rs (renamed from src/librustc_metadata/foreign_modules.rs)0
-rw-r--r--compiler/rustc_metadata/src/lib.rs (renamed from src/librustc_metadata/lib.rs)0
-rw-r--r--compiler/rustc_metadata/src/link_args.rs (renamed from src/librustc_metadata/link_args.rs)0
-rw-r--r--compiler/rustc_metadata/src/locator.rs (renamed from src/librustc_metadata/locator.rs)0
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs (renamed from src/librustc_metadata/native_libs.rs)0
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs (renamed from src/librustc_metadata/rmeta/decoder.rs)0
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs (renamed from src/librustc_metadata/rmeta/decoder/cstore_impl.rs)0
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs (renamed from src/librustc_metadata/rmeta/encoder.rs)0
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs (renamed from src/librustc_metadata/rmeta/mod.rs)0
-rw-r--r--compiler/rustc_metadata/src/rmeta/table.rs (renamed from src/librustc_metadata/rmeta/table.rs)0
-rw-r--r--compiler/rustc_middle/Cargo.toml33
-rw-r--r--compiler/rustc_middle/README.md (renamed from src/librustc_middle/README.md)0
-rw-r--r--compiler/rustc_middle/benches/lib.rs (renamed from src/librustc_middle/benches/lib.rs)0
-rw-r--r--compiler/rustc_middle/src/arena.rs (renamed from src/librustc_middle/arena.rs)0
-rw-r--r--compiler/rustc_middle/src/dep_graph/dep_node.rs (renamed from src/librustc_middle/dep_graph/dep_node.rs)0
-rw-r--r--compiler/rustc_middle/src/dep_graph/mod.rs (renamed from src/librustc_middle/dep_graph/mod.rs)0
-rw-r--r--compiler/rustc_middle/src/hir/exports.rs (renamed from src/librustc_middle/hir/exports.rs)0
-rw-r--r--compiler/rustc_middle/src/hir/map/blocks.rs (renamed from src/librustc_middle/hir/map/blocks.rs)0
-rw-r--r--compiler/rustc_middle/src/hir/map/collector.rs (renamed from src/librustc_middle/hir/map/collector.rs)0
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs (renamed from src/librustc_middle/hir/map/mod.rs)0
-rw-r--r--compiler/rustc_middle/src/hir/mod.rs (renamed from src/librustc_middle/hir/mod.rs)0
-rw-r--r--compiler/rustc_middle/src/hir/place.rs (renamed from src/librustc_middle/hir/place.rs)0
-rw-r--r--compiler/rustc_middle/src/ich/hcx.rs (renamed from src/librustc_middle/ich/hcx.rs)0
-rw-r--r--compiler/rustc_middle/src/ich/impls_hir.rs (renamed from src/librustc_middle/ich/impls_hir.rs)0
-rw-r--r--compiler/rustc_middle/src/ich/impls_syntax.rs (renamed from src/librustc_middle/ich/impls_syntax.rs)0
-rw-r--r--compiler/rustc_middle/src/ich/impls_ty.rs (renamed from src/librustc_middle/ich/impls_ty.rs)0
-rw-r--r--compiler/rustc_middle/src/ich/mod.rs (renamed from src/librustc_middle/ich/mod.rs)0
-rw-r--r--compiler/rustc_middle/src/infer/canonical.rs (renamed from src/librustc_middle/infer/canonical.rs)0
-rw-r--r--compiler/rustc_middle/src/infer/mod.rs (renamed from src/librustc_middle/infer/mod.rs)0
-rw-r--r--compiler/rustc_middle/src/infer/unify_key.rs (renamed from src/librustc_middle/infer/unify_key.rs)0
-rw-r--r--compiler/rustc_middle/src/lib.rs (renamed from src/librustc_middle/lib.rs)1
-rw-r--r--compiler/rustc_middle/src/lint.rs (renamed from src/librustc_middle/lint.rs)0
-rw-r--r--compiler/rustc_middle/src/macros.rs (renamed from src/librustc_middle/macros.rs)0
-rw-r--r--compiler/rustc_middle/src/middle/codegen_fn_attrs.rs (renamed from src/librustc_middle/middle/codegen_fn_attrs.rs)0
-rw-r--r--compiler/rustc_middle/src/middle/cstore.rs (renamed from src/librustc_middle/middle/cstore.rs)0
-rw-r--r--compiler/rustc_middle/src/middle/dependency_format.rs (renamed from src/librustc_middle/middle/dependency_format.rs)0
-rw-r--r--compiler/rustc_middle/src/middle/exported_symbols.rs (renamed from src/librustc_middle/middle/exported_symbols.rs)0
-rw-r--r--compiler/rustc_middle/src/middle/lang_items.rs (renamed from src/librustc_middle/middle/lang_items.rs)0
-rw-r--r--compiler/rustc_middle/src/middle/limits.rs (renamed from src/librustc_middle/middle/limits.rs)0
-rw-r--r--compiler/rustc_middle/src/middle/mod.rs (renamed from src/librustc_middle/middle/mod.rs)0
-rw-r--r--compiler/rustc_middle/src/middle/privacy.rs (renamed from src/librustc_middle/middle/privacy.rs)0
-rw-r--r--compiler/rustc_middle/src/middle/region.rs (renamed from src/librustc_middle/middle/region.rs)0
-rw-r--r--compiler/rustc_middle/src/middle/resolve_lifetime.rs (renamed from src/librustc_middle/middle/resolve_lifetime.rs)0
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs (renamed from src/librustc_middle/middle/stability.rs)0
-rw-r--r--compiler/rustc_middle/src/mir/coverage/mod.rs (renamed from src/librustc_middle/mir/coverage/mod.rs)0
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs (renamed from src/librustc_middle/mir/interpret/allocation.rs)0
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs (renamed from src/librustc_middle/mir/interpret/error.rs)0
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs (renamed from src/librustc_middle/mir/interpret/mod.rs)0
-rw-r--r--compiler/rustc_middle/src/mir/interpret/pointer.rs (renamed from src/librustc_middle/mir/interpret/pointer.rs)0
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs (renamed from src/librustc_middle/mir/interpret/queries.rs)0
-rw-r--r--compiler/rustc_middle/src/mir/interpret/value.rs (renamed from src/librustc_middle/mir/interpret/value.rs)0
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs (renamed from src/librustc_middle/mir/mod.rs)0
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs (renamed from src/librustc_middle/mir/mono.rs)39
-rw-r--r--compiler/rustc_middle/src/mir/predecessors.rs (renamed from src/librustc_middle/mir/predecessors.rs)0
-rw-r--r--compiler/rustc_middle/src/mir/query.rs (renamed from src/librustc_middle/mir/query.rs)0
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs (renamed from src/librustc_middle/mir/tcx.rs)0
-rw-r--r--compiler/rustc_middle/src/mir/terminator/mod.rs (renamed from src/librustc_middle/mir/terminator/mod.rs)0
-rw-r--r--compiler/rustc_middle/src/mir/traversal.rs (renamed from src/librustc_middle/mir/traversal.rs)0
-rw-r--r--compiler/rustc_middle/src/mir/type_foldable.rs (renamed from src/librustc_middle/mir/type_foldable.rs)0
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs (renamed from src/librustc_middle/mir/visit.rs)0
-rw-r--r--compiler/rustc_middle/src/query/mod.rs (renamed from src/librustc_middle/query/mod.rs)0
-rw-r--r--compiler/rustc_middle/src/tests.rs (renamed from src/librustc_middle/tests.rs)0
-rw-r--r--compiler/rustc_middle/src/traits/chalk.rs (renamed from src/librustc_middle/traits/chalk.rs)0
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs (renamed from src/librustc_middle/traits/mod.rs)0
-rw-r--r--compiler/rustc_middle/src/traits/query.rs (renamed from src/librustc_middle/traits/query.rs)0
-rw-r--r--compiler/rustc_middle/src/traits/select.rs (renamed from src/librustc_middle/traits/select.rs)0
-rw-r--r--compiler/rustc_middle/src/traits/specialization_graph.rs (renamed from src/librustc_middle/traits/specialization_graph.rs)0
-rw-r--r--compiler/rustc_middle/src/traits/structural_impls.rs (renamed from src/librustc_middle/traits/structural_impls.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/_match.rs (renamed from src/librustc_middle/ty/_match.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/adjustment.rs (renamed from src/librustc_middle/ty/adjustment.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/binding.rs (renamed from src/librustc_middle/ty/binding.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/cast.rs (renamed from src/librustc_middle/ty/cast.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs (renamed from src/librustc_middle/ty/codec.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs (renamed from src/librustc_middle/ty/consts.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/consts/int.rs (renamed from src/librustc_middle/ty/consts/int.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/consts/kind.rs (renamed from src/librustc_middle/ty/consts/kind.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/context.rs (renamed from src/librustc_middle/ty/context.rs)5
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs (renamed from src/librustc_middle/ty/diagnostics.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/erase_regions.rs (renamed from src/librustc_middle/ty/erase_regions.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/error.rs (renamed from src/librustc_middle/ty/error.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/fast_reject.rs (renamed from src/librustc_middle/ty/fast_reject.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs (renamed from src/librustc_middle/ty/flags.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/fold.rs (renamed from src/librustc_middle/ty/fold.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/def_id_forest.rs (renamed from src/librustc_middle/ty/inhabitedness/def_id_forest.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/mod.rs (renamed from src/librustc_middle/ty/inhabitedness/mod.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs (renamed from src/librustc_middle/ty/instance.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs (renamed from src/librustc_middle/ty/layout.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/list.rs (renamed from src/librustc_middle/ty/list.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs (renamed from src/librustc_middle/ty/mod.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/normalize_erasing_regions.rs (renamed from src/librustc_middle/ty/normalize_erasing_regions.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/outlives.rs (renamed from src/librustc_middle/ty/outlives.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/print/mod.rs (renamed from src/librustc_middle/ty/print/mod.rs)2
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs (renamed from src/librustc_middle/ty/print/pretty.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/query/README.md (renamed from src/librustc_middle/ty/query/README.md)0
-rw-r--r--compiler/rustc_middle/src/ty/query/job.rs (renamed from src/librustc_middle/ty/query/job.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/query/keys.rs (renamed from src/librustc_middle/ty/query/keys.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/query/mod.rs (renamed from src/librustc_middle/ty/query/mod.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/query/on_disk_cache.rs (renamed from src/librustc_middle/ty/query/on_disk_cache.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/query/plumbing.rs (renamed from src/librustc_middle/ty/query/plumbing.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/query/profiling_support.rs (renamed from src/librustc_middle/ty/query/profiling_support.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/query/stats.rs (renamed from src/librustc_middle/ty/query/stats.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/query/values.rs (renamed from src/librustc_middle/ty/query/values.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs (renamed from src/librustc_middle/ty/relate.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/steal.rs (renamed from src/librustc_middle/ty/steal.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs (renamed from src/librustc_middle/ty/structural_impls.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs (renamed from src/librustc_middle/ty/sty.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/subst.rs (renamed from src/librustc_middle/ty/subst.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/trait_def.rs (renamed from src/librustc_middle/ty/trait_def.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/util.rs (renamed from src/librustc_middle/ty/util.rs)0
-rw-r--r--compiler/rustc_middle/src/ty/walk.rs (renamed from src/librustc_middle/ty/walk.rs)4
-rw-r--r--compiler/rustc_middle/src/util/bug.rs (renamed from src/librustc_middle/util/bug.rs)0
-rw-r--r--compiler/rustc_middle/src/util/common.rs (renamed from src/librustc_middle/util/common.rs)0
-rw-r--r--compiler/rustc_middle/src/util/common/tests.rs (renamed from src/librustc_middle/util/common/tests.rs)0
-rw-r--r--compiler/rustc_mir/Cargo.toml33
-rw-r--r--compiler/rustc_mir/src/borrow_check/borrow_set.rs (renamed from src/librustc_mir/borrow_check/borrow_set.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/constraint_generation.rs (renamed from src/librustc_mir/borrow_check/constraint_generation.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/constraints/graph.rs (renamed from src/librustc_mir/borrow_check/constraints/graph.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/constraints/mod.rs (renamed from src/librustc_mir/borrow_check/constraints/mod.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/def_use.rs (renamed from src/librustc_mir/borrow_check/def_use.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs (renamed from src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs (renamed from src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/find_use.rs (renamed from src/librustc_mir/borrow_check/diagnostics/find_use.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs (renamed from src/librustc_mir/borrow_check/diagnostics/mod.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs (renamed from src/librustc_mir/borrow_check/diagnostics/move_errors.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs (renamed from src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/outlives_suggestion.rs (renamed from src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs (renamed from src/librustc_mir/borrow_check/diagnostics/region_errors.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs (renamed from src/librustc_mir/borrow_check/diagnostics/region_name.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/var_name.rs (renamed from src/librustc_mir/borrow_check/diagnostics/var_name.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/facts.rs (renamed from src/librustc_mir/borrow_check/facts.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/invalidation.rs (renamed from src/librustc_mir/borrow_check/invalidation.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/location.rs (renamed from src/librustc_mir/borrow_check/location.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/member_constraints.rs (renamed from src/librustc_mir/borrow_check/member_constraints.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/mod.rs (renamed from src/librustc_mir/borrow_check/mod.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/nll.rs (renamed from src/librustc_mir/borrow_check/nll.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/path_utils.rs (renamed from src/librustc_mir/borrow_check/path_utils.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/place_ext.rs (renamed from src/librustc_mir/borrow_check/place_ext.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/places_conflict.rs (renamed from src/librustc_mir/borrow_check/places_conflict.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/prefixes.rs (renamed from src/librustc_mir/borrow_check/prefixes.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/region_infer/dump_mir.rs (renamed from src/librustc_mir/borrow_check/region_infer/dump_mir.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/region_infer/graphviz.rs (renamed from src/librustc_mir/borrow_check/region_infer/graphviz.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/region_infer/mod.rs (renamed from src/librustc_mir/borrow_check/region_infer/mod.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/region_infer/opaque_types.rs (renamed from src/librustc_mir/borrow_check/region_infer/opaque_types.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/region_infer/reverse_sccs.rs (renamed from src/librustc_mir/borrow_check/region_infer/reverse_sccs.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/region_infer/values.rs (renamed from src/librustc_mir/borrow_check/region_infer/values.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/renumber.rs (renamed from src/librustc_mir/borrow_check/renumber.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/type_check/constraint_conversion.rs (renamed from src/librustc_mir/borrow_check/type_check/constraint_conversion.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/type_check/free_region_relations.rs (renamed from src/librustc_mir/borrow_check/type_check/free_region_relations.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/type_check/input_output.rs (renamed from src/librustc_mir/borrow_check/type_check/input_output.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/type_check/liveness/local_use_map.rs (renamed from src/librustc_mir/borrow_check/type_check/liveness/local_use_map.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/type_check/liveness/mod.rs (renamed from src/librustc_mir/borrow_check/type_check/liveness/mod.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/type_check/liveness/polonius.rs (renamed from src/librustc_mir/borrow_check/type_check/liveness/polonius.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/type_check/liveness/trace.rs (renamed from src/librustc_mir/borrow_check/type_check/liveness/trace.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/type_check/mod.rs (renamed from src/librustc_mir/borrow_check/type_check/mod.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/type_check/relate_tys.rs (renamed from src/librustc_mir/borrow_check/type_check/relate_tys.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/universal_regions.rs (renamed from src/librustc_mir/borrow_check/universal_regions.rs)0
-rw-r--r--compiler/rustc_mir/src/borrow_check/used_muts.rs (renamed from src/librustc_mir/borrow_check/used_muts.rs)0
-rw-r--r--compiler/rustc_mir/src/const_eval/error.rs (renamed from src/librustc_mir/const_eval/error.rs)0
-rw-r--r--compiler/rustc_mir/src/const_eval/eval_queries.rs (renamed from src/librustc_mir/const_eval/eval_queries.rs)0
-rw-r--r--compiler/rustc_mir/src/const_eval/fn_queries.rs (renamed from src/librustc_mir/const_eval/fn_queries.rs)0
-rw-r--r--compiler/rustc_mir/src/const_eval/machine.rs (renamed from src/librustc_mir/const_eval/machine.rs)0
-rw-r--r--compiler/rustc_mir/src/const_eval/mod.rs (renamed from src/librustc_mir/const_eval/mod.rs)0
-rw-r--r--compiler/rustc_mir/src/dataflow/drop_flag_effects.rs (renamed from src/librustc_mir/dataflow/drop_flag_effects.rs)0
-rw-r--r--compiler/rustc_mir/src/dataflow/framework/cursor.rs (renamed from src/librustc_mir/dataflow/framework/cursor.rs)0
-rw-r--r--compiler/rustc_mir/src/dataflow/framework/direction.rs (renamed from src/librustc_mir/dataflow/framework/direction.rs)0
-rw-r--r--compiler/rustc_mir/src/dataflow/framework/engine.rs (renamed from src/librustc_mir/dataflow/framework/engine.rs)0
-rw-r--r--compiler/rustc_mir/src/dataflow/framework/graphviz.rs (renamed from src/librustc_mir/dataflow/framework/graphviz.rs)0
-rw-r--r--compiler/rustc_mir/src/dataflow/framework/mod.rs (renamed from src/librustc_mir/dataflow/framework/mod.rs)0
-rw-r--r--compiler/rustc_mir/src/dataflow/framework/tests.rs (renamed from src/librustc_mir/dataflow/framework/tests.rs)0
-rw-r--r--compiler/rustc_mir/src/dataflow/framework/visitor.rs (renamed from src/librustc_mir/dataflow/framework/visitor.rs)0
-rw-r--r--compiler/rustc_mir/src/dataflow/impls/borrowed_locals.rs (renamed from src/librustc_mir/dataflow/impls/borrowed_locals.rs)0
-rw-r--r--compiler/rustc_mir/src/dataflow/impls/borrows.rs (renamed from src/librustc_mir/dataflow/impls/borrows.rs)0
-rw-r--r--compiler/rustc_mir/src/dataflow/impls/init_locals.rs (renamed from src/librustc_mir/dataflow/impls/init_locals.rs)0
-rw-r--r--compiler/rustc_mir/src/dataflow/impls/liveness.rs (renamed from src/librustc_mir/dataflow/impls/liveness.rs)0
-rw-r--r--compiler/rustc_mir/src/dataflow/impls/mod.rs (renamed from src/librustc_mir/dataflow/impls/mod.rs)0
-rw-r--r--compiler/rustc_mir/src/dataflow/impls/storage_liveness.rs (renamed from src/librustc_mir/dataflow/impls/storage_liveness.rs)0
-rw-r--r--compiler/rustc_mir/src/dataflow/mod.rs (renamed from src/librustc_mir/dataflow/mod.rs)0
-rw-r--r--compiler/rustc_mir/src/dataflow/move_paths/abs_domain.rs (renamed from src/librustc_mir/dataflow/move_paths/abs_domain.rs)0
-rw-r--r--compiler/rustc_mir/src/dataflow/move_paths/builder.rs (renamed from src/librustc_mir/dataflow/move_paths/builder.rs)0
-rw-r--r--compiler/rustc_mir/src/dataflow/move_paths/mod.rs (renamed from src/librustc_mir/dataflow/move_paths/mod.rs)0
-rw-r--r--compiler/rustc_mir/src/interpret/cast.rs (renamed from src/librustc_mir/interpret/cast.rs)0
-rw-r--r--compiler/rustc_mir/src/interpret/eval_context.rs (renamed from src/librustc_mir/interpret/eval_context.rs)0
-rw-r--r--compiler/rustc_mir/src/interpret/intern.rs (renamed from src/librustc_mir/interpret/intern.rs)0
-rw-r--r--compiler/rustc_mir/src/interpret/intrinsics.rs (renamed from src/librustc_mir/interpret/intrinsics.rs)0
-rw-r--r--compiler/rustc_mir/src/interpret/intrinsics/caller_location.rs (renamed from src/librustc_mir/interpret/intrinsics/caller_location.rs)0
-rw-r--r--compiler/rustc_mir/src/interpret/intrinsics/type_name.rs (renamed from src/librustc_mir/interpret/intrinsics/type_name.rs)0
-rw-r--r--compiler/rustc_mir/src/interpret/machine.rs (renamed from src/librustc_mir/interpret/machine.rs)0
-rw-r--r--compiler/rustc_mir/src/interpret/memory.rs (renamed from src/librustc_mir/interpret/memory.rs)0
-rw-r--r--compiler/rustc_mir/src/interpret/mod.rs (renamed from src/librustc_mir/interpret/mod.rs)0
-rw-r--r--compiler/rustc_mir/src/interpret/operand.rs (renamed from src/librustc_mir/interpret/operand.rs)0
-rw-r--r--compiler/rustc_mir/src/interpret/operator.rs (renamed from src/librustc_mir/interpret/operator.rs)0
-rw-r--r--compiler/rustc_mir/src/interpret/place.rs (renamed from src/librustc_mir/interpret/place.rs)0
-rw-r--r--compiler/rustc_mir/src/interpret/step.rs (renamed from src/librustc_mir/interpret/step.rs)0
-rw-r--r--compiler/rustc_mir/src/interpret/terminator.rs (renamed from src/librustc_mir/interpret/terminator.rs)0
-rw-r--r--compiler/rustc_mir/src/interpret/traits.rs (renamed from src/librustc_mir/interpret/traits.rs)0
-rw-r--r--compiler/rustc_mir/src/interpret/util.rs (renamed from src/librustc_mir/interpret/util.rs)0
-rw-r--r--compiler/rustc_mir/src/interpret/validity.rs (renamed from src/librustc_mir/interpret/validity.rs)0
-rw-r--r--compiler/rustc_mir/src/interpret/visitor.rs (renamed from src/librustc_mir/interpret/visitor.rs)0
-rw-r--r--compiler/rustc_mir/src/lib.rs (renamed from src/librustc_mir/lib.rs)0
-rw-r--r--compiler/rustc_mir/src/monomorphize/collector.rs (renamed from src/librustc_mir/monomorphize/collector.rs)24
-rw-r--r--compiler/rustc_mir/src/monomorphize/mod.rs (renamed from src/librustc_mir/monomorphize/mod.rs)0
-rw-r--r--compiler/rustc_mir/src/monomorphize/partitioning/default.rs (renamed from src/librustc_mir/monomorphize/partitioning/default.rs)0
-rw-r--r--compiler/rustc_mir/src/monomorphize/partitioning/merging.rs (renamed from src/librustc_mir/monomorphize/partitioning/merging.rs)0
-rw-r--r--compiler/rustc_mir/src/monomorphize/partitioning/mod.rs (renamed from src/librustc_mir/monomorphize/partitioning/mod.rs)8
-rw-r--r--compiler/rustc_mir/src/monomorphize/polymorphize.rs (renamed from src/librustc_mir/monomorphize/polymorphize.rs)0
-rw-r--r--compiler/rustc_mir/src/shim.rs (renamed from src/librustc_mir/shim.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/add_call_guards.rs (renamed from src/librustc_mir/transform/add_call_guards.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/add_moves_for_packed_drops.rs (renamed from src/librustc_mir/transform/add_moves_for_packed_drops.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/add_retag.rs (renamed from src/librustc_mir/transform/add_retag.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/mod.rs (renamed from src/librustc_mir/transform/check_consts/mod.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/ops.rs (renamed from src/librustc_mir/transform/check_consts/ops.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/post_drop_elaboration.rs (renamed from src/librustc_mir/transform/check_consts/post_drop_elaboration.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/qualifs.rs (renamed from src/librustc_mir/transform/check_consts/qualifs.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/resolver.rs (renamed from src/librustc_mir/transform/check_consts/resolver.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/validation.rs (renamed from src/librustc_mir/transform/check_consts/validation.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/check_packed_ref.rs (renamed from src/librustc_mir/transform/check_packed_ref.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/check_unsafety.rs (renamed from src/librustc_mir/transform/check_unsafety.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/cleanup_post_borrowck.rs (renamed from src/librustc_mir/transform/cleanup_post_borrowck.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/const_prop.rs (renamed from src/librustc_mir/transform/const_prop.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/copy_prop.rs (renamed from src/librustc_mir/transform/copy_prop.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/deaggregator.rs (renamed from src/librustc_mir/transform/deaggregator.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/dump_mir.rs (renamed from src/librustc_mir/transform/dump_mir.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/elaborate_drops.rs (renamed from src/librustc_mir/transform/elaborate_drops.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/generator.rs (renamed from src/librustc_mir/transform/generator.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/inline.rs (renamed from src/librustc_mir/transform/inline.rs)10
-rw-r--r--compiler/rustc_mir/src/transform/instcombine.rs (renamed from src/librustc_mir/transform/instcombine.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/instrument_coverage.rs (renamed from src/librustc_mir/transform/instrument_coverage.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/match_branches.rs (renamed from src/librustc_mir/transform/match_branches.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/mod.rs (renamed from src/librustc_mir/transform/mod.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/no_landing_pads.rs (renamed from src/librustc_mir/transform/no_landing_pads.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/nrvo.rs (renamed from src/librustc_mir/transform/nrvo.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/promote_consts.rs (renamed from src/librustc_mir/transform/promote_consts.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/qualify_min_const_fn.rs (renamed from src/librustc_mir/transform/qualify_min_const_fn.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/remove_noop_landing_pads.rs (renamed from src/librustc_mir/transform/remove_noop_landing_pads.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/required_consts.rs (renamed from src/librustc_mir/transform/required_consts.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/rustc_peek.rs (renamed from src/librustc_mir/transform/rustc_peek.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/simplify.rs (renamed from src/librustc_mir/transform/simplify.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/simplify_branches.rs (renamed from src/librustc_mir/transform/simplify_branches.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/simplify_comparison_integral.rs (renamed from src/librustc_mir/transform/simplify_comparison_integral.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/simplify_try.rs (renamed from src/librustc_mir/transform/simplify_try.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/uninhabited_enum_branching.rs (renamed from src/librustc_mir/transform/uninhabited_enum_branching.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/unreachable_prop.rs (renamed from src/librustc_mir/transform/unreachable_prop.rs)0
-rw-r--r--compiler/rustc_mir/src/transform/validate.rs (renamed from src/librustc_mir/transform/validate.rs)0
-rw-r--r--compiler/rustc_mir/src/util/aggregate.rs (renamed from src/librustc_mir/util/aggregate.rs)0
-rw-r--r--compiler/rustc_mir/src/util/alignment.rs (renamed from src/librustc_mir/util/alignment.rs)0
-rw-r--r--compiler/rustc_mir/src/util/borrowck_errors.rs (renamed from src/librustc_mir/util/borrowck_errors.rs)0
-rw-r--r--compiler/rustc_mir/src/util/collect_writes.rs (renamed from src/librustc_mir/util/collect_writes.rs)0
-rw-r--r--compiler/rustc_mir/src/util/def_use.rs (renamed from src/librustc_mir/util/def_use.rs)0
-rw-r--r--compiler/rustc_mir/src/util/elaborate_drops.rs (renamed from src/librustc_mir/util/elaborate_drops.rs)0
-rw-r--r--compiler/rustc_mir/src/util/graphviz.rs (renamed from src/librustc_mir/util/graphviz.rs)0
-rw-r--r--compiler/rustc_mir/src/util/mod.rs (renamed from src/librustc_mir/util/mod.rs)1
-rw-r--r--compiler/rustc_mir/src/util/patch.rs (renamed from src/librustc_mir/util/patch.rs)0
-rw-r--r--compiler/rustc_mir/src/util/pretty.rs (renamed from src/librustc_mir/util/pretty.rs)11
-rw-r--r--compiler/rustc_mir/src/util/spanview.rs461
-rw-r--r--compiler/rustc_mir/src/util/storage.rs (renamed from src/librustc_mir/util/storage.rs)0
-rw-r--r--compiler/rustc_mir_build/Cargo.toml27
-rw-r--r--compiler/rustc_mir_build/src/build/block.rs (renamed from src/librustc_mir_build/build/block.rs)0
-rw-r--r--compiler/rustc_mir_build/src/build/cfg.rs (renamed from src/librustc_mir_build/build/cfg.rs)0
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_constant.rs (renamed from src/librustc_mir_build/build/expr/as_constant.rs)0
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_operand.rs (renamed from src/librustc_mir_build/build/expr/as_operand.rs)0
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs (renamed from src/librustc_mir_build/build/expr/as_place.rs)0
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs (renamed from src/librustc_mir_build/build/expr/as_rvalue.rs)0
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_temp.rs (renamed from src/librustc_mir_build/build/expr/as_temp.rs)0
-rw-r--r--compiler/rustc_mir_build/src/build/expr/category.rs (renamed from src/librustc_mir_build/build/expr/category.rs)0
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs (renamed from src/librustc_mir_build/build/expr/into.rs)0
-rw-r--r--compiler/rustc_mir_build/src/build/expr/mod.rs (renamed from src/librustc_mir_build/build/expr/mod.rs)0
-rw-r--r--compiler/rustc_mir_build/src/build/expr/stmt.rs (renamed from src/librustc_mir_build/build/expr/stmt.rs)0
-rw-r--r--compiler/rustc_mir_build/src/build/into.rs (renamed from src/librustc_mir_build/build/into.rs)0
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs (renamed from src/librustc_mir_build/build/matches/mod.rs)0
-rw-r--r--compiler/rustc_mir_build/src/build/matches/simplify.rs (renamed from src/librustc_mir_build/build/matches/simplify.rs)0
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs (renamed from src/librustc_mir_build/build/matches/test.rs)0
-rw-r--r--compiler/rustc_mir_build/src/build/matches/util.rs (renamed from src/librustc_mir_build/build/matches/util.rs)0
-rw-r--r--compiler/rustc_mir_build/src/build/misc.rs (renamed from src/librustc_mir_build/build/misc.rs)0
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs (renamed from src/librustc_mir_build/build/mod.rs)0
-rw-r--r--compiler/rustc_mir_build/src/build/scope.rs (renamed from src/librustc_mir_build/build/scope.rs)0
-rw-r--r--compiler/rustc_mir_build/src/lib.rs (renamed from src/librustc_mir_build/lib.rs)0
-rw-r--r--compiler/rustc_mir_build/src/lints.rs (renamed from src/librustc_mir_build/lints.rs)0
-rw-r--r--compiler/rustc_mir_build/src/thir/constant.rs (renamed from src/librustc_mir_build/thir/constant.rs)0
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/block.rs (renamed from src/librustc_mir_build/thir/cx/block.rs)0
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs (renamed from src/librustc_mir_build/thir/cx/expr.rs)0
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/mod.rs (renamed from src/librustc_mir_build/thir/cx/mod.rs)0
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/to_ref.rs (renamed from src/librustc_mir_build/thir/cx/to_ref.rs)0
-rw-r--r--compiler/rustc_mir_build/src/thir/mod.rs (renamed from src/librustc_mir_build/thir/mod.rs)0
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/_match.rs (renamed from src/librustc_mir_build/thir/pattern/_match.rs)0
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs (renamed from src/librustc_mir_build/thir/pattern/check_match.rs)0
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs (renamed from src/librustc_mir_build/thir/pattern/const_to_pat.rs)0
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs (renamed from src/librustc_mir_build/thir/pattern/mod.rs)0
-rw-r--r--compiler/rustc_mir_build/src/thir/util.rs (renamed from src/librustc_mir_build/thir/util.rs)0
-rw-r--r--compiler/rustc_parse/Cargo.toml22
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs (renamed from src/librustc_parse/lexer/mod.rs)121
-rw-r--r--compiler/rustc_parse/src/lexer/tokentrees.rs (renamed from src/librustc_parse/lexer/tokentrees.rs)36
-rw-r--r--compiler/rustc_parse/src/lexer/unescape_error_reporting.rs (renamed from src/librustc_parse/lexer/unescape_error_reporting.rs)0
-rw-r--r--compiler/rustc_parse/src/lexer/unicode_chars.rs (renamed from src/librustc_parse/lexer/unicode_chars.rs)2
-rw-r--r--compiler/rustc_parse/src/lib.rs (renamed from src/librustc_parse/lib.rs)7
-rw-r--r--compiler/rustc_parse/src/parser/attr.rs (renamed from src/librustc_parse/parser/attr.rs)0
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs (renamed from src/librustc_parse/parser/diagnostics.rs)0
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs (renamed from src/librustc_parse/parser/expr.rs)2
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs (renamed from src/librustc_parse/parser/generics.rs)0
-rw-r--r--compiler/rustc_parse/src/parser/item.rs (renamed from src/librustc_parse/parser/item.rs)0
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs (renamed from src/librustc_parse/parser/mod.rs)7
-rw-r--r--compiler/rustc_parse/src/parser/nonterminal.rs (renamed from src/librustc_parse/parser/nonterminal.rs)0
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs (renamed from src/librustc_parse/parser/pat.rs)0
-rw-r--r--compiler/rustc_parse/src/parser/path.rs (renamed from src/librustc_parse/parser/path.rs)0
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs (renamed from src/librustc_parse/parser/stmt.rs)7
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs (renamed from src/librustc_parse/parser/ty.rs)0
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs (renamed from src/librustc_parse/validate_attr.rs)0
-rw-r--r--compiler/rustc_parse_format/Cargo.toml9
-rw-r--r--compiler/rustc_parse_format/src/lib.rs (renamed from src/librustc_parse_format/lib.rs)0
-rw-r--r--compiler/rustc_parse_format/src/tests.rs (renamed from src/librustc_parse_format/tests.rs)0
-rw-r--r--compiler/rustc_passes/Cargo.toml19
-rw-r--r--compiler/rustc_passes/src/check_attr.rs (renamed from src/librustc_passes/check_attr.rs)0
-rw-r--r--compiler/rustc_passes/src/check_const.rs (renamed from src/librustc_passes/check_const.rs)0
-rw-r--r--compiler/rustc_passes/src/dead.rs (renamed from src/librustc_passes/dead.rs)0
-rw-r--r--compiler/rustc_passes/src/diagnostic_items.rs (renamed from src/librustc_passes/diagnostic_items.rs)0
-rw-r--r--compiler/rustc_passes/src/entry.rs (renamed from src/librustc_passes/entry.rs)0
-rw-r--r--compiler/rustc_passes/src/hir_id_validator.rs (renamed from src/librustc_passes/hir_id_validator.rs)0
-rw-r--r--compiler/rustc_passes/src/hir_stats.rs (renamed from src/librustc_passes/hir_stats.rs)0
-rw-r--r--compiler/rustc_passes/src/intrinsicck.rs (renamed from src/librustc_passes/intrinsicck.rs)0
-rw-r--r--compiler/rustc_passes/src/lang_items.rs (renamed from src/librustc_passes/lang_items.rs)0
-rw-r--r--compiler/rustc_passes/src/layout_test.rs (renamed from src/librustc_passes/layout_test.rs)0
-rw-r--r--compiler/rustc_passes/src/lib.rs (renamed from src/librustc_passes/lib.rs)0
-rw-r--r--compiler/rustc_passes/src/lib_features.rs (renamed from src/librustc_passes/lib_features.rs)0
-rw-r--r--compiler/rustc_passes/src/liveness.rs (renamed from src/librustc_passes/liveness.rs)0
-rw-r--r--compiler/rustc_passes/src/loops.rs (renamed from src/librustc_passes/loops.rs)0
-rw-r--r--compiler/rustc_passes/src/reachable.rs (renamed from src/librustc_passes/reachable.rs)0
-rw-r--r--compiler/rustc_passes/src/region.rs (renamed from src/librustc_passes/region.rs)0
-rw-r--r--compiler/rustc_passes/src/stability.rs (renamed from src/librustc_passes/stability.rs)0
-rw-r--r--compiler/rustc_passes/src/upvars.rs (renamed from src/librustc_passes/upvars.rs)0
-rw-r--r--compiler/rustc_passes/src/weak_lang_items.rs (renamed from src/librustc_passes/weak_lang_items.rs)0
-rw-r--r--compiler/rustc_plugin_impl/Cargo.toml19
-rw-r--r--compiler/rustc_plugin_impl/src/build.rs (renamed from src/librustc_plugin_impl/build.rs)0
-rw-r--r--compiler/rustc_plugin_impl/src/lib.rs (renamed from src/librustc_plugin_impl/lib.rs)0
-rw-r--r--compiler/rustc_plugin_impl/src/load.rs (renamed from src/librustc_plugin_impl/load.rs)0
-rw-r--r--compiler/rustc_privacy/Cargo.toml16
-rw-r--r--compiler/rustc_privacy/src/lib.rs (renamed from src/librustc_privacy/lib.rs)0
-rw-r--r--compiler/rustc_query_system/Cargo.toml21
-rw-r--r--compiler/rustc_query_system/src/cache.rs (renamed from src/librustc_query_system/cache.rs)0
-rw-r--r--compiler/rustc_query_system/src/dep_graph/README.md (renamed from src/librustc_query_system/dep_graph/README.md)0
-rw-r--r--compiler/rustc_query_system/src/dep_graph/debug.rs (renamed from src/librustc_query_system/dep_graph/debug.rs)0
-rw-r--r--compiler/rustc_query_system/src/dep_graph/dep_node.rs (renamed from src/librustc_query_system/dep_graph/dep_node.rs)0
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs (renamed from src/librustc_query_system/dep_graph/graph.rs)0
-rw-r--r--compiler/rustc_query_system/src/dep_graph/mod.rs (renamed from src/librustc_query_system/dep_graph/mod.rs)0
-rw-r--r--compiler/rustc_query_system/src/dep_graph/prev.rs (renamed from src/librustc_query_system/dep_graph/prev.rs)0
-rw-r--r--compiler/rustc_query_system/src/dep_graph/query.rs (renamed from src/librustc_query_system/dep_graph/query.rs)0
-rw-r--r--compiler/rustc_query_system/src/dep_graph/serialized.rs (renamed from src/librustc_query_system/dep_graph/serialized.rs)0
-rw-r--r--compiler/rustc_query_system/src/lib.rs (renamed from src/librustc_query_system/lib.rs)0
-rw-r--r--compiler/rustc_query_system/src/query/README.md (renamed from src/librustc_query_system/query/README.md)0
-rw-r--r--compiler/rustc_query_system/src/query/caches.rs (renamed from src/librustc_query_system/query/caches.rs)0
-rw-r--r--compiler/rustc_query_system/src/query/config.rs (renamed from src/librustc_query_system/query/config.rs)0
-rw-r--r--compiler/rustc_query_system/src/query/job.rs (renamed from src/librustc_query_system/query/job.rs)0
-rw-r--r--compiler/rustc_query_system/src/query/mod.rs (renamed from src/librustc_query_system/query/mod.rs)0
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs (renamed from src/librustc_query_system/query/plumbing.rs)0
-rw-r--r--compiler/rustc_resolve/Cargo.toml29
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs (renamed from src/librustc_resolve/build_reduced_graph.rs)0
-rw-r--r--compiler/rustc_resolve/src/check_unused.rs (renamed from src/librustc_resolve/check_unused.rs)0
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs (renamed from src/librustc_resolve/def_collector.rs)0
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs (renamed from src/librustc_resolve/diagnostics.rs)0
-rw-r--r--compiler/rustc_resolve/src/imports.rs (renamed from src/librustc_resolve/imports.rs)0
-rw-r--r--compiler/rustc_resolve/src/late.rs (renamed from src/librustc_resolve/late.rs)7
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs (renamed from src/librustc_resolve/late/diagnostics.rs)13
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs (renamed from src/librustc_resolve/late/lifetimes.rs)0
-rw-r--r--compiler/rustc_resolve/src/lib.rs (renamed from src/librustc_resolve/lib.rs)8
-rw-r--r--compiler/rustc_resolve/src/macros.rs (renamed from src/librustc_resolve/macros.rs)22
-rw-r--r--compiler/rustc_save_analysis/Cargo.toml20
-rw-r--r--compiler/rustc_save_analysis/src/dump_visitor.rs (renamed from src/librustc_save_analysis/dump_visitor.rs)0
-rw-r--r--compiler/rustc_save_analysis/src/dumper.rs (renamed from src/librustc_save_analysis/dumper.rs)0
-rw-r--r--compiler/rustc_save_analysis/src/lib.rs (renamed from src/librustc_save_analysis/lib.rs)0
-rw-r--r--compiler/rustc_save_analysis/src/sig.rs (renamed from src/librustc_save_analysis/sig.rs)0
-rw-r--r--compiler/rustc_save_analysis/src/span_utils.rs (renamed from src/librustc_save_analysis/span_utils.rs)0
-rw-r--r--compiler/rustc_serialize/Cargo.toml (renamed from src/librustc_serialize/Cargo.toml)6
-rw-r--r--compiler/rustc_serialize/src/collection_impls.rs (renamed from src/librustc_serialize/collection_impls.rs)0
-rw-r--r--compiler/rustc_serialize/src/json.rs (renamed from src/librustc_serialize/json.rs)0
-rw-r--r--compiler/rustc_serialize/src/json/tests.rs (renamed from src/librustc_serialize/json/tests.rs)0
-rw-r--r--compiler/rustc_serialize/src/leb128.rs (renamed from src/librustc_serialize/leb128.rs)0
-rw-r--r--compiler/rustc_serialize/src/lib.rs (renamed from src/librustc_serialize/lib.rs)0
-rw-r--r--compiler/rustc_serialize/src/opaque.rs (renamed from src/librustc_serialize/opaque.rs)0
-rw-r--r--compiler/rustc_serialize/src/serialize.rs (renamed from src/librustc_serialize/serialize.rs)0
-rw-r--r--compiler/rustc_serialize/tests/json.rs (renamed from src/librustc_serialize/tests/json.rs)0
-rw-r--r--compiler/rustc_serialize/tests/leb128.rs (renamed from src/librustc_serialize/tests/leb128.rs)0
-rw-r--r--compiler/rustc_serialize/tests/opaque.rs (renamed from src/librustc_serialize/tests/opaque.rs)0
-rw-r--r--compiler/rustc_session/Cargo.toml20
-rw-r--r--compiler/rustc_session/src/cgu_reuse_tracker.rs (renamed from src/librustc_session/cgu_reuse_tracker.rs)0
-rw-r--r--compiler/rustc_session/src/code_stats.rs (renamed from src/librustc_session/code_stats.rs)0
-rw-r--r--compiler/rustc_session/src/config.rs (renamed from src/librustc_session/config.rs)32
-rw-r--r--compiler/rustc_session/src/filesearch.rs (renamed from src/librustc_session/filesearch.rs)0
-rw-r--r--compiler/rustc_session/src/lib.rs (renamed from src/librustc_session/lib.rs)1
-rw-r--r--compiler/rustc_session/src/lint.rs (renamed from src/librustc_session/lint.rs)0
-rw-r--r--compiler/rustc_session/src/lint/builtin.rs (renamed from src/librustc_session/lint/builtin.rs)0
-rw-r--r--compiler/rustc_session/src/options.rs (renamed from src/librustc_session/options.rs)50
-rw-r--r--compiler/rustc_session/src/output.rs (renamed from src/librustc_session/output.rs)0
-rw-r--r--compiler/rustc_session/src/parse.rs (renamed from src/librustc_session/parse.rs)0
-rw-r--r--compiler/rustc_session/src/search_paths.rs (renamed from src/librustc_session/search_paths.rs)0
-rw-r--r--compiler/rustc_session/src/session.rs (renamed from src/librustc_session/session.rs)52
-rw-r--r--compiler/rustc_session/src/utils.rs (renamed from src/librustc_session/utils.rs)0
-rw-r--r--compiler/rustc_span/Cargo.toml21
-rw-r--r--compiler/rustc_span/src/analyze_source_file.rs (renamed from src/librustc_span/analyze_source_file.rs)0
-rw-r--r--compiler/rustc_span/src/analyze_source_file/tests.rs (renamed from src/librustc_span/analyze_source_file/tests.rs)0
-rw-r--r--compiler/rustc_span/src/caching_source_map_view.rs (renamed from src/librustc_span/caching_source_map_view.rs)0
-rw-r--r--compiler/rustc_span/src/def_id.rs (renamed from src/librustc_span/def_id.rs)0
-rw-r--r--compiler/rustc_span/src/edition.rs (renamed from src/librustc_span/edition.rs)0
-rw-r--r--compiler/rustc_span/src/fatal_error.rs (renamed from src/librustc_span/fatal_error.rs)0
-rw-r--r--compiler/rustc_span/src/hygiene.rs (renamed from src/librustc_span/hygiene.rs)0
-rw-r--r--compiler/rustc_span/src/lib.rs (renamed from src/librustc_span/lib.rs)7
-rw-r--r--compiler/rustc_span/src/source_map.rs (renamed from src/librustc_span/source_map.rs)9
-rw-r--r--compiler/rustc_span/src/source_map/tests.rs (renamed from src/librustc_span/source_map/tests.rs)0
-rw-r--r--compiler/rustc_span/src/span_encoding.rs (renamed from src/librustc_span/span_encoding.rs)0
-rw-r--r--compiler/rustc_span/src/symbol.rs (renamed from src/librustc_span/symbol.rs)0
-rw-r--r--compiler/rustc_span/src/symbol/tests.rs (renamed from src/librustc_span/symbol/tests.rs)0
-rw-r--r--compiler/rustc_span/src/tests.rs (renamed from src/librustc_span/tests.rs)0
-rw-r--r--compiler/rustc_symbol_mangling/Cargo.toml21
-rw-r--r--compiler/rustc_symbol_mangling/src/legacy.rs (renamed from src/librustc_symbol_mangling/legacy.rs)0
-rw-r--r--compiler/rustc_symbol_mangling/src/lib.rs (renamed from src/librustc_symbol_mangling/lib.rs)0
-rw-r--r--compiler/rustc_symbol_mangling/src/test.rs (renamed from src/librustc_symbol_mangling/test.rs)0
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs (renamed from src/librustc_symbol_mangling/v0.rs)0
-rw-r--r--compiler/rustc_target/Cargo.toml14
-rw-r--r--compiler/rustc_target/README.md (renamed from src/librustc_target/README.md)0
-rw-r--r--compiler/rustc_target/src/abi/call/aarch64.rs (renamed from src/librustc_target/abi/call/aarch64.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/amdgpu.rs (renamed from src/librustc_target/abi/call/amdgpu.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/arm.rs (renamed from src/librustc_target/abi/call/arm.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/avr.rs (renamed from src/librustc_target/abi/call/avr.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/hexagon.rs (renamed from src/librustc_target/abi/call/hexagon.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/mips.rs (renamed from src/librustc_target/abi/call/mips.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/mips64.rs (renamed from src/librustc_target/abi/call/mips64.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs (renamed from src/librustc_target/abi/call/mod.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/msp430.rs (renamed from src/librustc_target/abi/call/msp430.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/nvptx.rs (renamed from src/librustc_target/abi/call/nvptx.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/nvptx64.rs (renamed from src/librustc_target/abi/call/nvptx64.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/powerpc.rs (renamed from src/librustc_target/abi/call/powerpc.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/powerpc64.rs (renamed from src/librustc_target/abi/call/powerpc64.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/riscv.rs (renamed from src/librustc_target/abi/call/riscv.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/s390x.rs (renamed from src/librustc_target/abi/call/s390x.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/sparc.rs (renamed from src/librustc_target/abi/call/sparc.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/sparc64.rs (renamed from src/librustc_target/abi/call/sparc64.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/wasm32.rs (renamed from src/librustc_target/abi/call/wasm32.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/wasm32_bindgen_compat.rs (renamed from src/librustc_target/abi/call/wasm32_bindgen_compat.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/x86.rs (renamed from src/librustc_target/abi/call/x86.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/x86_64.rs (renamed from src/librustc_target/abi/call/x86_64.rs)0
-rw-r--r--compiler/rustc_target/src/abi/call/x86_win64.rs (renamed from src/librustc_target/abi/call/x86_win64.rs)0
-rw-r--r--compiler/rustc_target/src/abi/mod.rs (renamed from src/librustc_target/abi/mod.rs)0
-rw-r--r--compiler/rustc_target/src/asm/aarch64.rs (renamed from src/librustc_target/asm/aarch64.rs)0
-rw-r--r--compiler/rustc_target/src/asm/arm.rs (renamed from src/librustc_target/asm/arm.rs)0
-rw-r--r--compiler/rustc_target/src/asm/hexagon.rs (renamed from src/librustc_target/asm/hexagon.rs)0
-rw-r--r--compiler/rustc_target/src/asm/mod.rs (renamed from src/librustc_target/asm/mod.rs)0
-rw-r--r--compiler/rustc_target/src/asm/nvptx.rs (renamed from src/librustc_target/asm/nvptx.rs)0
-rw-r--r--compiler/rustc_target/src/asm/riscv.rs (renamed from src/librustc_target/asm/riscv.rs)0
-rw-r--r--compiler/rustc_target/src/asm/x86.rs (renamed from src/librustc_target/asm/x86.rs)0
-rw-r--r--compiler/rustc_target/src/lib.rs (renamed from src/librustc_target/lib.rs)0
-rw-r--r--compiler/rustc_target/src/spec/aarch64_apple_darwin.rs (renamed from src/librustc_target/spec/aarch64_apple_darwin.rs)0
-rw-r--r--compiler/rustc_target/src/spec/aarch64_apple_ios.rs (renamed from src/librustc_target/spec/aarch64_apple_ios.rs)0
-rw-r--r--compiler/rustc_target/src/spec/aarch64_apple_tvos.rs (renamed from src/librustc_target/spec/aarch64_apple_tvos.rs)0
-rw-r--r--compiler/rustc_target/src/spec/aarch64_fuchsia.rs (renamed from src/librustc_target/spec/aarch64_fuchsia.rs)0
-rw-r--r--compiler/rustc_target/src/spec/aarch64_linux_android.rs (renamed from src/librustc_target/spec/aarch64_linux_android.rs)0
-rw-r--r--compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs (renamed from src/librustc_target/spec/aarch64_pc_windows_msvc.rs)0
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_cloudabi.rs (renamed from src/librustc_target/spec/aarch64_unknown_cloudabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs (renamed from src/librustc_target/spec/aarch64_unknown_freebsd.rs)0
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_hermit.rs (renamed from src/librustc_target/spec/aarch64_unknown_hermit.rs)0
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/aarch64_unknown_linux_gnu.rs)0
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs (renamed from src/librustc_target/spec/aarch64_unknown_linux_musl.rs)0
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_netbsd.rs (renamed from src/librustc_target/spec/aarch64_unknown_netbsd.rs)0
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_none.rs (renamed from src/librustc_target/spec/aarch64_unknown_none.rs)0
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs (renamed from src/librustc_target/spec/aarch64_unknown_none_softfloat.rs)0
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_openbsd.rs (renamed from src/librustc_target/spec/aarch64_unknown_openbsd.rs)0
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_redox.rs (renamed from src/librustc_target/spec/aarch64_unknown_redox.rs)0
-rw-r--r--compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs (renamed from src/librustc_target/spec/aarch64_uwp_windows_msvc.rs)0
-rw-r--r--compiler/rustc_target/src/spec/aarch64_wrs_vxworks.rs (renamed from src/librustc_target/spec/aarch64_wrs_vxworks.rs)0
-rw-r--r--compiler/rustc_target/src/spec/abi.rs (renamed from src/librustc_target/spec/abi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/abi/tests.rs (renamed from src/librustc_target/spec/abi/tests.rs)0
-rw-r--r--compiler/rustc_target/src/spec/android_base.rs (renamed from src/librustc_target/spec/android_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/apple_base.rs (renamed from src/librustc_target/spec/apple_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/apple_sdk_base.rs (renamed from src/librustc_target/spec/apple_sdk_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/arm_base.rs (renamed from src/librustc_target/spec/arm_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/arm_linux_androideabi.rs (renamed from src/librustc_target/spec/arm_linux_androideabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs (renamed from src/librustc_target/spec/arm_unknown_linux_gnueabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs (renamed from src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs (renamed from src/librustc_target/spec/arm_unknown_linux_musleabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs (renamed from src/librustc_target/spec/arm_unknown_linux_musleabihf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armebv7r_none_eabi.rs (renamed from src/librustc_target/spec/armebv7r_none_eabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs (renamed from src/librustc_target/spec/armebv7r_none_eabihf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs (renamed from src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs (renamed from src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs (renamed from src/librustc_target/spec/armv5te_unknown_linux_musleabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs (renamed from src/librustc_target/spec/armv6_unknown_freebsd.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs (renamed from src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv7_apple_ios.rs (renamed from src/librustc_target/spec/armv7_apple_ios.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv7_linux_androideabi.rs (renamed from src/librustc_target/spec/armv7_linux_androideabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_cloudabi_eabihf.rs (renamed from src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs (renamed from src/librustc_target/spec/armv7_unknown_freebsd.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs (renamed from src/librustc_target/spec/armv7_unknown_linux_gnueabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs (renamed from src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs (renamed from src/librustc_target/spec/armv7_unknown_linux_musleabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs (renamed from src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs (renamed from src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs (renamed from src/librustc_target/spec/armv7_wrs_vxworks_eabihf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv7a_none_eabi.rs (renamed from src/librustc_target/spec/armv7a_none_eabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv7a_none_eabihf.rs (renamed from src/librustc_target/spec/armv7a_none_eabihf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv7r_none_eabi.rs (renamed from src/librustc_target/spec/armv7r_none_eabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv7r_none_eabihf.rs (renamed from src/librustc_target/spec/armv7r_none_eabihf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/armv7s_apple_ios.rs (renamed from src/librustc_target/spec/armv7s_apple_ios.rs)0
-rw-r--r--compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs (renamed from src/librustc_target/spec/asmjs_unknown_emscripten.rs)0
-rw-r--r--compiler/rustc_target/src/spec/avr_gnu_base.rs (renamed from src/librustc_target/spec/avr_gnu_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/avr_unknown_gnu_atmega328.rs (renamed from src/librustc_target/spec/avr_unknown_gnu_atmega328.rs)0
-rw-r--r--compiler/rustc_target/src/spec/cloudabi_base.rs (renamed from src/librustc_target/spec/cloudabi_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/crt_objects.rs (renamed from src/librustc_target/spec/crt_objects.rs)0
-rw-r--r--compiler/rustc_target/src/spec/dragonfly_base.rs (renamed from src/librustc_target/spec/dragonfly_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/freebsd_base.rs (renamed from src/librustc_target/spec/freebsd_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/fuchsia_base.rs (renamed from src/librustc_target/spec/fuchsia_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/haiku_base.rs (renamed from src/librustc_target/spec/haiku_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/hermit_base.rs (renamed from src/librustc_target/spec/hermit_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/hermit_kernel_base.rs (renamed from src/librustc_target/spec/hermit_kernel_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs (renamed from src/librustc_target/spec/hexagon_unknown_linux_musl.rs)0
-rw-r--r--compiler/rustc_target/src/spec/i386_apple_ios.rs (renamed from src/librustc_target/spec/i386_apple_ios.rs)0
-rw-r--r--compiler/rustc_target/src/spec/i586_pc_windows_msvc.rs (renamed from src/librustc_target/spec/i586_pc_windows_msvc.rs)0
-rw-r--r--compiler/rustc_target/src/spec/i586_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/i586_unknown_linux_gnu.rs)0
-rw-r--r--compiler/rustc_target/src/spec/i586_unknown_linux_musl.rs (renamed from src/librustc_target/spec/i586_unknown_linux_musl.rs)0
-rw-r--r--compiler/rustc_target/src/spec/i686_apple_darwin.rs (renamed from src/librustc_target/spec/i686_apple_darwin.rs)0
-rw-r--r--compiler/rustc_target/src/spec/i686_linux_android.rs (renamed from src/librustc_target/spec/i686_linux_android.rs)0
-rw-r--r--compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs (renamed from src/librustc_target/spec/i686_pc_windows_gnu.rs)0
-rw-r--r--compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs (renamed from src/librustc_target/spec/i686_pc_windows_msvc.rs)0
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_cloudabi.rs (renamed from src/librustc_target/spec/i686_unknown_cloudabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_freebsd.rs (renamed from src/librustc_target/spec/i686_unknown_freebsd.rs)0
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_haiku.rs (renamed from src/librustc_target/spec/i686_unknown_haiku.rs)0
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/i686_unknown_linux_gnu.rs)0
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs (renamed from src/librustc_target/spec/i686_unknown_linux_musl.rs)0
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_netbsd.rs (renamed from src/librustc_target/spec/i686_unknown_netbsd.rs)0
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_openbsd.rs (renamed from src/librustc_target/spec/i686_unknown_openbsd.rs)0
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_uefi.rs (renamed from src/librustc_target/spec/i686_unknown_uefi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs (renamed from src/librustc_target/spec/i686_uwp_windows_gnu.rs)0
-rw-r--r--compiler/rustc_target/src/spec/i686_uwp_windows_msvc.rs (renamed from src/librustc_target/spec/i686_uwp_windows_msvc.rs)0
-rw-r--r--compiler/rustc_target/src/spec/i686_wrs_vxworks.rs (renamed from src/librustc_target/spec/i686_wrs_vxworks.rs)0
-rw-r--r--compiler/rustc_target/src/spec/illumos_base.rs (renamed from src/librustc_target/spec/illumos_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/l4re_base.rs (renamed from src/librustc_target/spec/l4re_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/linux_base.rs (renamed from src/librustc_target/spec/linux_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/linux_kernel_base.rs (renamed from src/librustc_target/spec/linux_kernel_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/linux_musl_base.rs (renamed from src/librustc_target/spec/linux_musl_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs (renamed from src/librustc_target/spec/mips64_unknown_linux_gnuabi64.rs)0
-rw-r--r--compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs (renamed from src/librustc_target/spec/mips64_unknown_linux_muslabi64.rs)0
-rw-r--r--compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs (renamed from src/librustc_target/spec/mips64el_unknown_linux_gnuabi64.rs)0
-rw-r--r--compiler/rustc_target/src/spec/mips64el_unknown_linux_muslabi64.rs (renamed from src/librustc_target/spec/mips64el_unknown_linux_muslabi64.rs)0
-rw-r--r--compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/mips_unknown_linux_gnu.rs)0
-rw-r--r--compiler/rustc_target/src/spec/mips_unknown_linux_musl.rs (renamed from src/librustc_target/spec/mips_unknown_linux_musl.rs)0
-rw-r--r--compiler/rustc_target/src/spec/mips_unknown_linux_uclibc.rs (renamed from src/librustc_target/spec/mips_unknown_linux_uclibc.rs)0
-rw-r--r--compiler/rustc_target/src/spec/mipsel_sony_psp.rs (renamed from src/librustc_target/spec/mipsel_sony_psp.rs)0
-rw-r--r--compiler/rustc_target/src/spec/mipsel_sony_psp_linker_script.ld (renamed from src/librustc_target/spec/mipsel_sony_psp_linker_script.ld)0
-rw-r--r--compiler/rustc_target/src/spec/mipsel_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/mipsel_unknown_linux_gnu.rs)0
-rw-r--r--compiler/rustc_target/src/spec/mipsel_unknown_linux_musl.rs (renamed from src/librustc_target/spec/mipsel_unknown_linux_musl.rs)0
-rw-r--r--compiler/rustc_target/src/spec/mipsel_unknown_linux_uclibc.rs (renamed from src/librustc_target/spec/mipsel_unknown_linux_uclibc.rs)0
-rw-r--r--compiler/rustc_target/src/spec/mipsisa32r6_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs)0
-rw-r--r--compiler/rustc_target/src/spec/mipsisa32r6el_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs)0
-rw-r--r--compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs (renamed from src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs)0
-rw-r--r--compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs (renamed from src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs)0
-rw-r--r--compiler/rustc_target/src/spec/mod.rs (renamed from src/librustc_target/spec/mod.rs)0
-rw-r--r--compiler/rustc_target/src/spec/msp430_none_elf.rs (renamed from src/librustc_target/spec/msp430_none_elf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/msvc_base.rs (renamed from src/librustc_target/spec/msvc_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/netbsd_base.rs (renamed from src/librustc_target/spec/netbsd_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs (renamed from src/librustc_target/spec/nvptx64_nvidia_cuda.rs)0
-rw-r--r--compiler/rustc_target/src/spec/openbsd_base.rs (renamed from src/librustc_target/spec/openbsd_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs (renamed from src/librustc_target/spec/powerpc64_unknown_freebsd.rs)0
-rw-r--r--compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/powerpc64_unknown_linux_gnu.rs)0
-rw-r--r--compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs (renamed from src/librustc_target/spec/powerpc64_unknown_linux_musl.rs)0
-rw-r--r--compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs (renamed from src/librustc_target/spec/powerpc64_wrs_vxworks.rs)0
-rw-r--r--compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/powerpc64le_unknown_linux_gnu.rs)0
-rw-r--r--compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs (renamed from src/librustc_target/spec/powerpc64le_unknown_linux_musl.rs)0
-rw-r--r--compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/powerpc_unknown_linux_gnu.rs)0
-rw-r--r--compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs (renamed from src/librustc_target/spec/powerpc_unknown_linux_gnuspe.rs)0
-rw-r--r--compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs (renamed from src/librustc_target/spec/powerpc_unknown_linux_musl.rs)0
-rw-r--r--compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs (renamed from src/librustc_target/spec/powerpc_unknown_netbsd.rs)0
-rw-r--r--compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs (renamed from src/librustc_target/spec/powerpc_wrs_vxworks.rs)0
-rw-r--r--compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs (renamed from src/librustc_target/spec/powerpc_wrs_vxworks_spe.rs)0
-rw-r--r--compiler/rustc_target/src/spec/redox_base.rs (renamed from src/librustc_target/spec/redox_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/riscv32i_unknown_none_elf.rs (renamed from src/librustc_target/spec/riscv32i_unknown_none_elf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/riscv32imac_unknown_none_elf.rs (renamed from src/librustc_target/spec/riscv32imac_unknown_none_elf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/riscv32imc_unknown_none_elf.rs (renamed from src/librustc_target/spec/riscv32imc_unknown_none_elf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/riscv64gc_unknown_linux_gnu.rs)0
-rw-r--r--compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs (renamed from src/librustc_target/spec/riscv64gc_unknown_none_elf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs (renamed from src/librustc_target/spec/riscv64imac_unknown_none_elf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/riscv_base.rs (renamed from src/librustc_target/spec/riscv_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/s390x_unknown_linux_gnu.rs)0
-rw-r--r--compiler/rustc_target/src/spec/solaris_base.rs (renamed from src/librustc_target/spec/solaris_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/sparc64_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/sparc64_unknown_linux_gnu.rs)0
-rw-r--r--compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs (renamed from src/librustc_target/spec/sparc64_unknown_netbsd.rs)0
-rw-r--r--compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs (renamed from src/librustc_target/spec/sparc64_unknown_openbsd.rs)0
-rw-r--r--compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/sparc_unknown_linux_gnu.rs)0
-rw-r--r--compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs (renamed from src/librustc_target/spec/sparcv9_sun_solaris.rs)0
-rw-r--r--compiler/rustc_target/src/spec/tests/tests_impl.rs (renamed from src/librustc_target/spec/tests/tests_impl.rs)0
-rw-r--r--compiler/rustc_target/src/spec/thumb_base.rs (renamed from src/librustc_target/spec/thumb_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs (renamed from src/librustc_target/spec/thumbv4t_none_eabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs (renamed from src/librustc_target/spec/thumbv6m_none_eabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs (renamed from src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs)0
-rw-r--r--compiler/rustc_target/src/spec/thumbv7a_uwp_windows_msvc.rs (renamed from src/librustc_target/spec/thumbv7a_uwp_windows_msvc.rs)0
-rw-r--r--compiler/rustc_target/src/spec/thumbv7em_none_eabi.rs (renamed from src/librustc_target/spec/thumbv7em_none_eabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/thumbv7em_none_eabihf.rs (renamed from src/librustc_target/spec/thumbv7em_none_eabihf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/thumbv7m_none_eabi.rs (renamed from src/librustc_target/spec/thumbv7m_none_eabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs (renamed from src/librustc_target/spec/thumbv7neon_linux_androideabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs (renamed from src/librustc_target/spec/thumbv7neon_unknown_linux_gnueabihf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs (renamed from src/librustc_target/spec/thumbv7neon_unknown_linux_musleabihf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/thumbv8m_base_none_eabi.rs (renamed from src/librustc_target/spec/thumbv8m_base_none_eabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/thumbv8m_main_none_eabi.rs (renamed from src/librustc_target/spec/thumbv8m_main_none_eabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/thumbv8m_main_none_eabihf.rs (renamed from src/librustc_target/spec/thumbv8m_main_none_eabihf.rs)0
-rw-r--r--compiler/rustc_target/src/spec/uefi_msvc_base.rs (renamed from src/librustc_target/spec/uefi_msvc_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/vxworks_base.rs (renamed from src/librustc_target/spec/vxworks_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/wasm32_base.rs (renamed from src/librustc_target/spec/wasm32_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs (renamed from src/librustc_target/spec/wasm32_unknown_emscripten.rs)0
-rw-r--r--compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs (renamed from src/librustc_target/spec/wasm32_unknown_unknown.rs)0
-rw-r--r--compiler/rustc_target/src/spec/wasm32_wasi.rs (renamed from src/librustc_target/spec/wasm32_wasi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/windows_gnu_base.rs (renamed from src/librustc_target/spec/windows_gnu_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/windows_msvc_base.rs (renamed from src/librustc_target/spec/windows_msvc_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs (renamed from src/librustc_target/spec/windows_uwp_gnu_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs (renamed from src/librustc_target/spec/windows_uwp_msvc_base.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_darwin.rs (renamed from src/librustc_target/spec/x86_64_apple_darwin.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_ios.rs (renamed from src/librustc_target/spec/x86_64_apple_ios.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs (renamed from src/librustc_target/spec/x86_64_apple_ios_macabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_tvos.rs (renamed from src/librustc_target/spec/x86_64_apple_tvos.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs (renamed from src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_fuchsia.rs (renamed from src/librustc_target/spec/x86_64_fuchsia.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_linux_android.rs (renamed from src/librustc_target/spec/x86_64_linux_android.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_linux_kernel.rs (renamed from src/librustc_target/spec/x86_64_linux_kernel.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs (renamed from src/librustc_target/spec/x86_64_pc_windows_gnu.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_pc_windows_msvc.rs (renamed from src/librustc_target/spec/x86_64_pc_windows_msvc.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_rumprun_netbsd.rs (renamed from src/librustc_target/spec/x86_64_rumprun_netbsd.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_sun_solaris.rs (renamed from src/librustc_target/spec/x86_64_sun_solaris.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_cloudabi.rs (renamed from src/librustc_target/spec/x86_64_unknown_cloudabi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs (renamed from src/librustc_target/spec/x86_64_unknown_dragonfly.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs (renamed from src/librustc_target/spec/x86_64_unknown_freebsd.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs (renamed from src/librustc_target/spec/x86_64_unknown_haiku.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs (renamed from src/librustc_target/spec/x86_64_unknown_hermit.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_hermit_kernel.rs (renamed from src/librustc_target/spec/x86_64_unknown_hermit_kernel.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs (renamed from src/librustc_target/spec/x86_64_unknown_illumos.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs (renamed from src/librustc_target/spec/x86_64_unknown_l4re_uclibc.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/x86_64_unknown_linux_gnu.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs (renamed from src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs (renamed from src/librustc_target/spec/x86_64_unknown_linux_musl.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs (renamed from src/librustc_target/spec/x86_64_unknown_netbsd.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs (renamed from src/librustc_target/spec/x86_64_unknown_openbsd.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_redox.rs (renamed from src/librustc_target/spec/x86_64_unknown_redox.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs (renamed from src/librustc_target/spec/x86_64_unknown_uefi.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs (renamed from src/librustc_target/spec/x86_64_uwp_windows_gnu.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_uwp_windows_msvc.rs (renamed from src/librustc_target/spec/x86_64_uwp_windows_msvc.rs)0
-rw-r--r--compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs (renamed from src/librustc_target/spec/x86_64_wrs_vxworks.rs)0
-rw-r--r--compiler/rustc_trait_selection/Cargo.toml25
-rw-r--r--compiler/rustc_trait_selection/src/autoderef.rs (renamed from src/librustc_trait_selection/autoderef.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/infer.rs (renamed from src/librustc_trait_selection/infer.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs (renamed from src/librustc_trait_selection/lib.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/opaque_types.rs (renamed from src/librustc_trait_selection/opaque_types.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs (renamed from src/librustc_trait_selection/traits/auto_trait.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs (renamed from src/librustc_trait_selection/traits/chalk_fulfill.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/codegen/mod.rs (renamed from src/librustc_trait_selection/traits/codegen/mod.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs (renamed from src/librustc_trait_selection/traits/coherence.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/engine.rs (renamed from src/librustc_trait_selection/traits/engine.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs (renamed from src/librustc_trait_selection/traits/error_reporting/mod.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs (renamed from src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs (renamed from src/librustc_trait_selection/traits/error_reporting/suggestions.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs (renamed from src/librustc_trait_selection/traits/fulfill.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/misc.rs (renamed from src/librustc_trait_selection/traits/misc.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs (renamed from src/librustc_trait_selection/traits/mod.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs (renamed from src/librustc_trait_selection/traits/object_safety.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/on_unimplemented.rs (renamed from src/librustc_trait_selection/traits/on_unimplemented.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs (renamed from src/librustc_trait_selection/traits/project.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs (renamed from src/librustc_trait_selection/traits/query/dropck_outlives.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs (renamed from src/librustc_trait_selection/traits/query/evaluate_obligation.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/method_autoderef.rs (renamed from src/librustc_trait_selection/traits/query/method_autoderef.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/mod.rs (renamed from src/librustc_trait_selection/traits/query/mod.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs (renamed from src/librustc_trait_selection/traits/query/normalize.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/outlives_bounds.rs (renamed from src/librustc_trait_selection/traits/query/outlives_bounds.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs (renamed from src/librustc_trait_selection/traits/query/type_op/ascribe_user_type.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs (renamed from src/librustc_trait_selection/traits/query/type_op/custom.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs (renamed from src/librustc_trait_selection/traits/query/type_op/eq.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs (renamed from src/librustc_trait_selection/traits/query/type_op/implied_outlives_bounds.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs (renamed from src/librustc_trait_selection/traits/query/type_op/mod.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs (renamed from src/librustc_trait_selection/traits/query/type_op/normalize.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs (renamed from src/librustc_trait_selection/traits/query/type_op/outlives.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs (renamed from src/librustc_trait_selection/traits/query/type_op/prove_predicate.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs (renamed from src/librustc_trait_selection/traits/query/type_op/subtype.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs (renamed from src/librustc_trait_selection/traits/select/candidate_assembly.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs (renamed from src/librustc_trait_selection/traits/select/confirmation.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs (renamed from src/librustc_trait_selection/traits/select/mod.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs (renamed from src/librustc_trait_selection/traits/specialize/mod.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs (renamed from src/librustc_trait_selection/traits/specialize/specialization_graph.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/structural_match.rs (renamed from src/librustc_trait_selection/traits/structural_match.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs (renamed from src/librustc_trait_selection/traits/util.rs)0
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs (renamed from src/librustc_trait_selection/traits/wf.rs)0
-rw-r--r--compiler/rustc_traits/Cargo.toml19
-rw-r--r--compiler/rustc_traits/src/chalk/db.rs (renamed from src/librustc_traits/chalk/db.rs)0
-rw-r--r--compiler/rustc_traits/src/chalk/lowering.rs (renamed from src/librustc_traits/chalk/lowering.rs)0
-rw-r--r--compiler/rustc_traits/src/chalk/mod.rs (renamed from src/librustc_traits/chalk/mod.rs)0
-rw-r--r--compiler/rustc_traits/src/dropck_outlives.rs (renamed from src/librustc_traits/dropck_outlives.rs)0
-rw-r--r--compiler/rustc_traits/src/evaluate_obligation.rs (renamed from src/librustc_traits/evaluate_obligation.rs)0
-rw-r--r--compiler/rustc_traits/src/implied_outlives_bounds.rs (renamed from src/librustc_traits/implied_outlives_bounds.rs)0
-rw-r--r--compiler/rustc_traits/src/lib.rs (renamed from src/librustc_traits/lib.rs)0
-rw-r--r--compiler/rustc_traits/src/normalize_erasing_regions.rs (renamed from src/librustc_traits/normalize_erasing_regions.rs)0
-rw-r--r--compiler/rustc_traits/src/normalize_projection_ty.rs (renamed from src/librustc_traits/normalize_projection_ty.rs)0
-rw-r--r--compiler/rustc_traits/src/type_op.rs (renamed from src/librustc_traits/type_op.rs)0
-rw-r--r--compiler/rustc_ty/Cargo.toml17
-rw-r--r--compiler/rustc_ty/src/common_traits.rs (renamed from src/librustc_ty/common_traits.rs)0
-rw-r--r--compiler/rustc_ty/src/instance.rs (renamed from src/librustc_ty/instance.rs)0
-rw-r--r--compiler/rustc_ty/src/lib.rs (renamed from src/librustc_ty/lib.rs)0
-rw-r--r--compiler/rustc_ty/src/needs_drop.rs (renamed from src/librustc_ty/needs_drop.rs)0
-rw-r--r--compiler/rustc_ty/src/ty.rs (renamed from src/librustc_ty/ty.rs)0
-rw-r--r--compiler/rustc_typeck/Cargo.toml27
-rw-r--r--compiler/rustc_typeck/README.md (renamed from src/librustc_typeck/README.md)0
-rw-r--r--compiler/rustc_typeck/src/astconv/errors.rs (renamed from src/librustc_typeck/astconv/errors.rs)0
-rw-r--r--compiler/rustc_typeck/src/astconv/generics.rs (renamed from src/librustc_typeck/astconv/generics.rs)0
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs (renamed from src/librustc_typeck/astconv/mod.rs)0
-rw-r--r--compiler/rustc_typeck/src/bounds.rs (renamed from src/librustc_typeck/bounds.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/_match.rs (renamed from src/librustc_typeck/check/_match.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/autoderef.rs (renamed from src/librustc_typeck/check/autoderef.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/callee.rs (renamed from src/librustc_typeck/check/callee.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/cast.rs (renamed from src/librustc_typeck/check/cast.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/closure.rs (renamed from src/librustc_typeck/check/closure.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/coercion.rs (renamed from src/librustc_typeck/check/coercion.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/compare_method.rs (renamed from src/librustc_typeck/check/compare_method.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/demand.rs (renamed from src/librustc_typeck/check/demand.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/dropck.rs (renamed from src/librustc_typeck/check/dropck.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs (renamed from src/librustc_typeck/check/expr.rs)55
-rw-r--r--compiler/rustc_typeck/src/check/generator_interior.rs (renamed from src/librustc_typeck/check/generator_interior.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/intrinsic.rs (renamed from src/librustc_typeck/check/intrinsic.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/method/confirm.rs (renamed from src/librustc_typeck/check/method/confirm.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/method/mod.rs (renamed from src/librustc_typeck/check/method/mod.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/method/probe.rs (renamed from src/librustc_typeck/check/method/probe.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/method/suggest.rs (renamed from src/librustc_typeck/check/method/suggest.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/mod.rs (renamed from src/librustc_typeck/check/mod.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/op.rs (renamed from src/librustc_typeck/check/op.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/pat.rs (renamed from src/librustc_typeck/check/pat.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/place_op.rs (renamed from src/librustc_typeck/check/place_op.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/regionck.rs (renamed from src/librustc_typeck/check/regionck.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/upvar.rs (renamed from src/librustc_typeck/check/upvar.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/wfcheck.rs (renamed from src/librustc_typeck/check/wfcheck.rs)0
-rw-r--r--compiler/rustc_typeck/src/check/writeback.rs (renamed from src/librustc_typeck/check/writeback.rs)0
-rw-r--r--compiler/rustc_typeck/src/check_unused.rs (renamed from src/librustc_typeck/check_unused.rs)0
-rw-r--r--compiler/rustc_typeck/src/coherence/builtin.rs (renamed from src/librustc_typeck/coherence/builtin.rs)0
-rw-r--r--compiler/rustc_typeck/src/coherence/inherent_impls.rs (renamed from src/librustc_typeck/coherence/inherent_impls.rs)0
-rw-r--r--compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs (renamed from src/librustc_typeck/coherence/inherent_impls_overlap.rs)0
-rw-r--r--compiler/rustc_typeck/src/coherence/mod.rs (renamed from src/librustc_typeck/coherence/mod.rs)0
-rw-r--r--compiler/rustc_typeck/src/coherence/orphan.rs (renamed from src/librustc_typeck/coherence/orphan.rs)0
-rw-r--r--compiler/rustc_typeck/src/coherence/unsafety.rs (renamed from src/librustc_typeck/coherence/unsafety.rs)0
-rw-r--r--compiler/rustc_typeck/src/collect.rs (renamed from src/librustc_typeck/collect.rs)0
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs (renamed from src/librustc_typeck/collect/type_of.rs)0
-rw-r--r--compiler/rustc_typeck/src/constrained_generic_params.rs (renamed from src/librustc_typeck/constrained_generic_params.rs)0
-rw-r--r--compiler/rustc_typeck/src/expr_use_visitor.rs (renamed from src/librustc_typeck/expr_use_visitor.rs)0
-rw-r--r--compiler/rustc_typeck/src/impl_wf_check.rs (renamed from src/librustc_typeck/impl_wf_check.rs)0
-rw-r--r--compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs (renamed from src/librustc_typeck/impl_wf_check/min_specialization.rs)0
-rw-r--r--compiler/rustc_typeck/src/lib.rs (renamed from src/librustc_typeck/lib.rs)0
-rw-r--r--compiler/rustc_typeck/src/mem_categorization.rs (renamed from src/librustc_typeck/mem_categorization.rs)0
-rw-r--r--compiler/rustc_typeck/src/outlives/explicit.rs (renamed from src/librustc_typeck/outlives/explicit.rs)0
-rw-r--r--compiler/rustc_typeck/src/outlives/implicit_infer.rs (renamed from src/librustc_typeck/outlives/implicit_infer.rs)0
-rw-r--r--compiler/rustc_typeck/src/outlives/mod.rs (renamed from src/librustc_typeck/outlives/mod.rs)0
-rw-r--r--compiler/rustc_typeck/src/outlives/test.rs (renamed from src/librustc_typeck/outlives/test.rs)0
-rw-r--r--compiler/rustc_typeck/src/outlives/utils.rs (renamed from src/librustc_typeck/outlives/utils.rs)0
-rw-r--r--compiler/rustc_typeck/src/structured_errors.rs (renamed from src/librustc_typeck/structured_errors.rs)0
-rw-r--r--compiler/rustc_typeck/src/variance/constraints.rs (renamed from src/librustc_typeck/variance/constraints.rs)0
-rw-r--r--compiler/rustc_typeck/src/variance/mod.rs (renamed from src/librustc_typeck/variance/mod.rs)0
-rw-r--r--compiler/rustc_typeck/src/variance/solve.rs (renamed from src/librustc_typeck/variance/solve.rs)0
-rw-r--r--compiler/rustc_typeck/src/variance/terms.rs (renamed from src/librustc_typeck/variance/terms.rs)0
-rw-r--r--compiler/rustc_typeck/src/variance/test.rs (renamed from src/librustc_typeck/variance/test.rs)0
-rw-r--r--compiler/rustc_typeck/src/variance/xform.rs (renamed from src/librustc_typeck/variance/xform.rs)0
-rw-r--r--library/alloc/src/borrow.rs4
-rw-r--r--library/alloc/src/boxed.rs8
-rw-r--r--library/alloc/src/collections/vec_deque.rs17
-rw-r--r--library/alloc/src/rc.rs8
-rw-r--r--library/alloc/src/sync.rs6
-rw-r--r--library/alloc/src/vec.rs22
-rw-r--r--library/core/benches/num/flt2dec/strategy/dragon.rs49
-rw-r--r--library/core/benches/num/flt2dec/strategy/grisu.rs49
-rw-r--r--library/core/src/array/mod.rs13
-rw-r--r--library/core/src/clone.rs13
-rw-r--r--library/core/src/convert/mod.rs52
-rw-r--r--library/core/src/fmt/float.rs116
-rw-r--r--library/core/src/iter/adapters/mod.rs38
-rw-r--r--library/core/src/iter/mod.rs80
-rw-r--r--library/core/src/iter/traits/double_ended.rs7
-rw-r--r--library/core/src/iter/traits/iterator.rs124
-rw-r--r--library/core/src/macros/mod.rs2
-rw-r--r--library/core/src/marker.rs59
-rw-r--r--library/core/src/mem/maybe_uninit.rs38
-rw-r--r--library/core/src/num/flt2dec/mod.rs226
-rw-r--r--library/core/src/num/flt2dec/strategy/dragon.rs41
-rw-r--r--library/core/src/num/flt2dec/strategy/grisu.rs97
-rw-r--r--library/core/src/ops/control_flow.rs67
-rw-r--r--library/core/src/ops/mod.rs4
-rw-r--r--library/core/src/panic.rs9
-rw-r--r--library/core/src/pin.rs6
-rw-r--r--library/core/src/slice/mod.rs173
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/core/tests/num/flt2dec/mod.rs71
-rw-r--r--library/core/tests/num/flt2dec/random.rs31
-rw-r--r--library/core/tests/option.rs1
-rw-r--r--library/core/tests/result.rs1
-rw-r--r--library/proc_macro/src/bridge/client.rs10
-rw-r--r--library/proc_macro/src/bridge/mod.rs3
-rw-r--r--library/proc_macro/src/bridge/server.rs34
-rw-r--r--library/std/src/ascii.rs2
-rw-r--r--library/std/src/backtrace.rs55
-rw-r--r--library/std/src/backtrace/tests.rs53
-rw-r--r--library/std/src/collections/hash/map.rs933
-rw-r--r--library/std/src/collections/hash/map/tests.rs926
-rw-r--r--library/std/src/collections/hash/set.rs422
-rw-r--r--library/std/src/collections/hash/set/tests.rs415
-rw-r--r--library/std/src/env.rs163
-rw-r--r--library/std/src/env/tests.rs102
-rw-r--r--library/std/src/error.rs44
-rw-r--r--library/std/src/error/tests.rs37
-rw-r--r--library/std/src/f32.rs766
-rw-r--r--library/std/src/f32/tests.rs759
-rw-r--r--library/std/src/f64.rs762
-rw-r--r--library/std/src/f64/tests.rs755
-rw-r--r--library/std/src/ffi/c_str.rs203
-rw-r--r--library/std/src/ffi/c_str/tests.rs195
-rw-r--r--library/std/src/ffi/os_str.rs172
-rw-r--r--library/std/src/ffi/os_str/tests.rs165
-rw-r--r--library/std/src/fs.rs1381
-rw-r--r--library/std/src/fs/tests.rs1339
-rw-r--r--library/std/src/io/buffered.rs923
-rw-r--r--library/std/src/io/buffered/tests.rs916
-rw-r--r--library/std/src/io/cursor.rs531
-rw-r--r--library/std/src/io/cursor/tests.rs516
-rw-r--r--library/std/src/io/error.rs60
-rw-r--r--library/std/src/io/error/tests.rs53
-rw-r--r--library/std/src/io/impls.rs64
-rw-r--r--library/std/src/io/impls/tests.rs57
-rw-r--r--library/std/src/io/mod.rs501
-rw-r--r--library/std/src/io/stdio.rs54
-rw-r--r--library/std/src/io/stdio/tests.rs47
-rw-r--r--library/std/src/io/tests.rs494
-rw-r--r--library/std/src/io/util.rs71
-rw-r--r--library/std/src/io/util/tests.rs45
-rw-r--r--library/std/src/keyword_docs.rs26
-rw-r--r--library/std/src/lazy.rs337
-rw-r--r--library/std/src/lazy/tests.rs323
-rw-r--r--library/std/src/lib.rs2
-rw-r--r--library/std/src/memchr.rs90
-rw-r--r--library/std/src/memchr/tests.rs86
-rw-r--r--library/std/src/net/addr.rs240
-rw-r--r--library/std/src/net/addr/tests.rs229
-rw-r--r--library/std/src/net/ip.rs1010
-rw-r--r--library/std/src/net/ip/tests.rs811
-rw-r--r--library/std/src/net/parser.rs146
-rw-r--r--library/std/src/net/parser/tests.rs139
-rw-r--r--library/std/src/net/tcp.rs870
-rw-r--r--library/std/src/net/tcp/tests.rs862
-rw-r--r--library/std/src/net/udp.rs380
-rw-r--r--library/std/src/net/udp/tests.rs372
-rw-r--r--library/std/src/num.rs253
-rw-r--r--library/std/src/num/benches.rs9
-rw-r--r--library/std/src/num/tests.rs230
-rw-r--r--library/std/src/os/raw/mod.rs25
-rw-r--r--library/std/src/os/raw/tests.rs16
-rw-r--r--library/std/src/path.rs1403
-rw-r--r--library/std/src/path/tests.rs1394
-rw-r--r--library/std/src/prelude/mod.rs2
-rw-r--r--library/std/src/primitive_docs.rs49
-rw-r--r--library/std/src/process.rs411
-rw-r--r--library/std/src/process/tests.rs401
-rw-r--r--library/std/src/sync/barrier.rs42
-rw-r--r--library/std/src/sync/barrier/tests.rs35
-rw-r--r--library/std/src/sync/condvar.rs218
-rw-r--r--library/std/src/sync/condvar/tests.rs211
-rw-r--r--library/std/src/sync/mpsc/mod.rs1367
-rw-r--r--library/std/src/sync/mpsc/mpsc_queue.rs54
-rw-r--r--library/std/src/sync/mpsc/mpsc_queue/tests.rs47
-rw-r--r--library/std/src/sync/mpsc/spsc_queue.rs108
-rw-r--r--library/std/src/sync/mpsc/spsc_queue/tests.rs101
-rw-r--r--library/std/src/sync/mpsc/sync_tests.rs647
-rw-r--r--library/std/src/sync/mpsc/tests.rs706
-rw-r--r--library/std/src/sync/mutex.rs245
-rw-r--r--library/std/src/sync/mutex/tests.rs238
-rw-r--r--library/std/src/sync/once.rs123
-rw-r--r--library/std/src/sync/once/tests.rs116
-rw-r--r--library/std/src/sync/rwlock.rs254
-rw-r--r--library/std/src/sync/rwlock/tests.rs247
-rw-r--r--library/std/src/sys/sgx/abi/tls.rs116
-rw-r--r--library/std/src/sys/sgx/abi/tls/sync_bitset.rs85
-rw-r--r--library/std/src/sys/sgx/abi/tls/sync_bitset/tests.rs25
-rw-r--r--library/std/src/sys/sgx/rwlock.rs50
-rw-r--r--library/std/src/sys/sgx/rwlock/tests.rs43
-rw-r--r--library/std/src/sys/sgx/waitqueue.rs398
-rw-r--r--library/std/src/sys/sgx/waitqueue/spin_mutex.rs76
-rw-r--r--library/std/src/sys/sgx/waitqueue/spin_mutex/tests.rs23
-rw-r--r--library/std/src/sys/sgx/waitqueue/tests.rs20
-rw-r--r--library/std/src/sys/sgx/waitqueue/unsafe_list.rs146
-rw-r--r--library/std/src/sys/sgx/waitqueue/unsafe_list/tests.rs103
-rw-r--r--library/std/src/sys/unix/ext/fs.rs7
-rw-r--r--library/std/src/sys/unix/ext/net.rs382
-rw-r--r--library/std/src/sys/unix/ext/net/tests.rs374
-rw-r--r--library/std/src/sys/unix/fd.rs16
-rw-r--r--library/std/src/sys/unix/fd/tests.rs9
-rw-r--r--library/std/src/sys/unix/os.rs30
-rw-r--r--library/std/src/sys/unix/os/tests.rs23
-rw-r--r--library/std/src/sys/unix/process/process_common.rs71
-rw-r--r--library/std/src/sys/unix/process/process_common/tests.rs64
-rw-r--r--library/std/src/sys/vxworks/net.rs30
-rw-r--r--library/std/src/sys/vxworks/net/tests.rs23
-rw-r--r--library/std/src/sys/wasi/alloc.rs43
-rw-r--r--library/std/src/sys/wasi/args.rs2
-rw-r--r--library/std/src/sys/wasi/ext/fs.rs1
-rw-r--r--library/std/src/sys/wasi/ext/io.rs1
-rw-r--r--library/std/src/sys/wasi/ext/mod.rs2
-rw-r--r--library/std/src/sys/wasi/fd.rs1
-rw-r--r--library/std/src/sys/wasi/fs.rs2
-rw-r--r--library/std/src/sys/wasi/io.rs2
-rw-r--r--library/std/src/sys/wasi/net.rs2
-rw-r--r--library/std/src/sys/wasi/os.rs2
-rw-r--r--library/std/src/sys/wasi/pipe.rs2
-rw-r--r--library/std/src/sys/wasi/process.rs2
-rw-r--r--library/std/src/sys/wasi/stdio.rs2
-rw-r--r--library/std/src/sys/wasi/thread.rs2
-rw-r--r--library/std/src/sys/wasi/time.rs2
-rw-r--r--library/std/src/sys/windows/args.rs69
-rw-r--r--library/std/src/sys/windows/args/tests.rs61
-rw-r--r--library/std/src/sys/windows/os.rs20
-rw-r--r--library/std/src/sys/windows/os/tests.rs13
-rw-r--r--library/std/src/sys/windows/process.rs41
-rw-r--r--library/std/src/sys/windows/process/tests.rs31
-rw-r--r--library/std/src/sys_common/bytestring.rs26
-rw-r--r--library/std/src/sys_common/bytestring/tests.rs19
-rw-r--r--library/std/src/sys_common/mod.rs8
-rw-r--r--library/std/src/sys_common/net.rs26
-rw-r--r--library/std/src/sys_common/net/tests.rs19
-rw-r--r--library/std/src/sys_common/remutex.rs79
-rw-r--r--library/std/src/sys_common/remutex/tests.rs72
-rw-r--r--library/std/src/sys_common/tests.rs6
-rw-r--r--library/std/src/sys_common/thread_local_key.rs41
-rw-r--r--library/std/src/sys_common/thread_local_key/tests.rs34
-rw-r--r--library/std/src/sys_common/wtf8.rs407
-rw-r--r--library/std/src/sys_common/wtf8/tests.rs397
-rw-r--r--library/std/src/thread/local.rs206
-rw-r--r--library/std/src/thread/local/dynamic_tests.rs40
-rw-r--r--library/std/src/thread/local/tests.rs154
-rw-r--r--library/std/src/thread/mod.rs273
-rw-r--r--library/std/src/thread/tests.rs262
-rw-r--r--library/std/src/time.rs172
-rw-r--r--library/std/src/time/tests.rs165
-rw-r--r--src/README.md2
-rw-r--r--src/bootstrap/Cargo.toml1
-rw-r--r--src/bootstrap/README.md2
-rw-r--r--src/bootstrap/builder.rs8
-rw-r--r--src/bootstrap/builder/tests.rs4
-rw-r--r--src/bootstrap/compile.rs6
-rw-r--r--src/bootstrap/config.rs7
-rw-r--r--src/bootstrap/dist.rs2
-rw-r--r--src/bootstrap/doc.rs1
-rw-r--r--src/bootstrap/flags.rs2
-rw-r--r--src/bootstrap/lib.rs39
-rw-r--r--src/bootstrap/native.rs8
-rw-r--r--src/bootstrap/sanity.rs40
-rw-r--r--src/bootstrap/test.rs2
-rw-r--r--src/build_helper/Cargo.toml1
m---------src/doc/book0
m---------src/doc/edition-guide0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
-rw-r--r--src/doc/rustc/src/codegen-options/index.md20
-rw-r--r--src/doc/rustdoc/src/lints.md2
-rw-r--r--src/librustc_ast/Cargo.toml21
-rw-r--r--src/librustc_ast_lowering/Cargo.toml24
-rw-r--r--src/librustc_ast_passes/Cargo.toml22
-rw-r--r--src/librustc_ast_pretty/Cargo.toml16
-rw-r--r--src/librustc_attr/Cargo.toml23
-rw-r--r--src/librustc_builtin_macros/Cargo.toml26
-rw-r--r--src/librustc_codegen_llvm/Cargo.toml36
-rw-r--r--src/librustc_codegen_ssa/Cargo.toml38
-rw-r--r--src/librustc_data_structures/jobserver.rs42
-rw-r--r--src/librustc_driver/Cargo.toml43
-rw-r--r--src/librustc_expand/Cargo.toml28
-rw-r--r--src/librustc_expand/parse/lexer/tests.rs252
-rw-r--r--src/librustc_feature/Cargo.toml15
-rw-r--r--src/librustc_hir/Cargo.toml22
-rw-r--r--src/librustc_hir_pretty/Cargo.toml17
-rw-r--r--src/librustc_incremental/Cargo.toml24
-rw-r--r--src/librustc_infer/Cargo.toml26
-rw-r--r--src/librustc_interface/Cargo.toml57
-rw-r--r--src/librustc_lexer/src/tests.rs167
-rw-r--r--src/librustc_lint/Cargo.toml26
-rw-r--r--src/librustc_llvm/Cargo.toml1
-rw-r--r--src/librustc_metadata/Cargo.toml35
-rw-r--r--src/librustc_middle/Cargo.toml35
-rw-r--r--src/librustc_middle/ty/print/obsolete.rs251
-rw-r--r--src/librustc_mir/Cargo.toml35
-rw-r--r--src/librustc_mir_build/Cargo.toml29
-rw-r--r--src/librustc_parse/Cargo.toml24
-rw-r--r--src/librustc_parse_format/Cargo.toml13
-rw-r--r--src/librustc_passes/Cargo.toml23
-rw-r--r--src/librustc_plugin_impl/Cargo.toml21
-rw-r--r--src/librustc_privacy/Cargo.toml20
-rw-r--r--src/librustc_query_system/Cargo.toml23
-rw-r--r--src/librustc_resolve/Cargo.toml31
-rw-r--r--src/librustc_save_analysis/Cargo.toml24
-rw-r--r--src/librustc_session/Cargo.toml24
-rw-r--r--src/librustc_span/Cargo.toml23
-rw-r--r--src/librustc_symbol_mangling/Cargo.toml23
-rw-r--r--src/librustc_target/Cargo.toml18
-rw-r--r--src/librustc_trait_selection/Cargo.toml27
-rw-r--r--src/librustc_traits/Cargo.toml23
-rw-r--r--src/librustc_ty/Cargo.toml21
-rw-r--r--src/librustc_typeck/Cargo.toml29
-rw-r--r--src/librustdoc/Cargo.toml3
-rw-r--r--src/librustdoc/clean/blanket_impl.rs3
-rw-r--r--src/librustdoc/clean/cfg/tests.rs13
-rw-r--r--src/librustdoc/clean/utils.rs5
-rw-r--r--src/librustdoc/config.rs6
-rw-r--r--src/librustdoc/core.rs7
-rw-r--r--src/librustdoc/html/format.rs2
-rw-r--r--src/librustdoc/html/highlight.rs2
-rw-r--r--src/librustdoc/html/highlight/tests.rs2
-rw-r--r--src/librustdoc/html/layout.rs4
-rw-r--r--src/librustdoc/html/markdown.rs3
-rw-r--r--src/librustdoc/html/markdown/tests.rs35
-rw-r--r--src/librustdoc/html/render/mod.rs172
-rw-r--r--src/librustdoc/html/sources.rs2
-rw-r--r--src/librustdoc/html/static/main.js12
-rw-r--r--src/librustdoc/html/static/themes/ayu.css3
-rw-r--r--src/librustdoc/lib.rs22
-rw-r--r--src/librustdoc/passes/check_code_block_syntax.rs75
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs2
-rw-r--r--src/librustdoc/passes/mod.rs3
-rw-r--r--src/librustdoc/passes/strip_private.rs2
-rw-r--r--src/test/codegen-units/item-collection/cross-crate-generic-functions.rs10
-rw-r--r--src/test/codegen-units/item-collection/cross-crate-trait-method.rs22
-rw-r--r--src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs14
-rw-r--r--src/test/codegen-units/item-collection/function-as-argument.rs23
-rw-r--r--src/test/codegen-units/item-collection/generic-drop-glue.rs24
-rw-r--r--src/test/codegen-units/item-collection/generic-functions.rs28
-rw-r--r--src/test/codegen-units/item-collection/generic-impl.rs36
-rw-r--r--src/test/codegen-units/item-collection/impl-in-non-instantiated-generic.rs4
-rw-r--r--src/test/codegen-units/item-collection/instantiation-through-vtable.rs14
-rw-r--r--src/test/codegen-units/item-collection/items-within-generic-items.rs12
-rw-r--r--src/test/codegen-units/item-collection/non-generic-drop-glue.rs10
-rw-r--r--src/test/codegen-units/item-collection/non-generic-functions.rs24
-rw-r--r--src/test/codegen-units/item-collection/overloaded-operators.rs12
-rw-r--r--src/test/codegen-units/item-collection/static-init.rs6
-rw-r--r--src/test/codegen-units/item-collection/statics-and-consts.rs12
-rw-r--r--src/test/codegen-units/item-collection/trait-implementations.rs22
-rw-r--r--src/test/codegen-units/item-collection/trait-method-as-argument.rs31
-rw-r--r--src/test/codegen-units/item-collection/trait-method-default-impl.rs18
-rw-r--r--src/test/codegen-units/item-collection/transitive-drop-glue.rs26
-rw-r--r--src/test/codegen-units/item-collection/tuple-drop-glue.rs12
-rw-r--r--src/test/codegen-units/item-collection/unreferenced-const-fn.rs2
-rw-r--r--src/test/codegen-units/item-collection/unsizing.rs18
-rw-r--r--src/test/codegen-units/item-collection/unused-traits-and-generics.rs2
-rw-r--r--src/test/codegen-units/partitioning/extern-drop-glue.rs10
-rw-r--r--src/test/codegen-units/partitioning/extern-generic.rs14
-rw-r--r--src/test/codegen-units/partitioning/incremental-merging.rs9
-rw-r--r--src/test/codegen-units/partitioning/inlining-from-extern-crate.rs10
-rw-r--r--src/test/codegen-units/partitioning/local-drop-glue.rs14
-rw-r--r--src/test/codegen-units/partitioning/local-generic.rs17
-rw-r--r--src/test/codegen-units/partitioning/local-inlining-but-not-all.rs8
-rw-r--r--src/test/codegen-units/partitioning/local-inlining.rs8
-rw-r--r--src/test/codegen-units/partitioning/local-transitive-inlining.rs8
-rw-r--r--src/test/codegen-units/partitioning/regular-modules.rs43
-rw-r--r--src/test/codegen-units/partitioning/shared-generics.rs4
-rw-r--r--src/test/codegen-units/partitioning/statics.rs20
-rw-r--r--src/test/codegen-units/partitioning/vtable-through-const.rs24
-rw-r--r--src/test/codegen-units/polymorphization/unused_type_parameters.rs147
-rw-r--r--src/test/codegen/enum-bounds-check-derived-idx.rs25
-rw-r--r--src/test/codegen/enum-bounds-check-issue-13926.rs19
-rw-r--r--src/test/codegen/enum-bounds-check.rs12
-rw-r--r--src/test/mir-opt/inline/inline-async.rs18
-rw-r--r--src/test/mir-opt/spanview-block.rs5
-rw-r--r--src/test/mir-opt/spanview-statement.rs5
-rw-r--r--src/test/mir-opt/spanview-terminator.rs5
-rw-r--r--src/test/mir-opt/spanview_block.main.mir_map.0.html67
-rw-r--r--src/test/mir-opt/spanview_statement.main.mir_map.0.html67
-rw-r--r--src/test/mir-opt/spanview_terminator.main.mir_map.0.html66
-rw-r--r--src/test/rustdoc/index-page.rs4
-rw-r--r--src/test/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-move-mut-base-ptr.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-mut-borrow-of-mut-base-ptr.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-swap-mut-base-ptr.rs2
-rw-r--r--src/test/ui/codemap_tests/bad-format-args.rs2
-rw-r--r--src/test/ui/codemap_tests/bad-format-args.stderr2
-rw-r--r--src/test/ui/const-generics/argument_order.full.stderr (renamed from src/test/ui/const-generics/argument_order.stderr)4
-rw-r--r--src/test/ui/const-generics/argument_order.min.stderr30
-rw-r--r--src/test/ui/const-generics/argument_order.rs8
-rw-r--r--src/test/ui/const-generics/array-wrapper-struct-ctor.rs7
-rw-r--r--src/test/ui/const-generics/array-wrapper-struct-ctor.stderr11
-rw-r--r--src/test/ui/const-generics/cannot-infer-type-for-const-param.rs6
-rw-r--r--src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr11
-rw-r--r--src/test/ui/const-generics/const-arg-type-arg-misordered.full.stderr (renamed from src/test/ui/const-generics/const-arg-type-arg-misordered.stderr)2
-rw-r--r--src/test/ui/const-generics/const-arg-type-arg-misordered.min.stderr12
-rw-r--r--src/test/ui/const-generics/const-arg-type-arg-misordered.rs9
-rw-r--r--src/test/ui/const-generics/const-param-before-other-params.full.stderr (renamed from src/test/ui/const-generics/const-param-before-other-params.stderr)2
-rw-r--r--src/test/ui/const-generics/const-param-before-other-params.min.stderr32
-rw-r--r--src/test/ui/const-generics/const-param-before-other-params.rs9
-rw-r--r--src/test/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr9
-rw-r--r--src/test/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr18
-rw-r--r--src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs7
-rw-r--r--src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr18
-rw-r--r--src/test/ui/const-generics/issues/issue-64494.full.stderr (renamed from src/test/ui/const-generics/issues/issue-64494.stderr)4
-rw-r--r--src/test/ui/const-generics/issues/issue-64494.min.stderr28
-rw-r--r--src/test/ui/const-generics/issues/issue-64494.rs13
-rw-r--r--src/test/ui/const-generics/issues/issue-64519.rs7
-rw-r--r--src/test/ui/const-generics/issues/issue-66205.full.stderr10
-rw-r--r--src/test/ui/const-generics/issues/issue-66205.min.stderr10
-rw-r--r--src/test/ui/const-generics/issues/issue-66205.rs9
-rw-r--r--src/test/ui/const-generics/issues/issue-66205.stderr19
-rw-r--r--src/test/ui/const-generics/issues/issue-66906.rs7
-rw-r--r--src/test/ui/const-generics/issues/issue-66906.stderr11
-rw-r--r--src/test/ui/const-generics/issues/issue-67185-1.rs7
-rw-r--r--src/test/ui/const-generics/issues/issue-67185-1.stderr11
-rw-r--r--src/test/ui/const-generics/issues/issue-68596.rs6
-rw-r--r--src/test/ui/const-generics/issues/issue-68615-adt.min.stderr11
-rw-r--r--src/test/ui/const-generics/issues/issue-68615-adt.rs9
-rw-r--r--src/test/ui/const-generics/issues/issue-68615-array.min.stderr11
-rw-r--r--src/test/ui/const-generics/issues/issue-68615-array.rs9
-rw-r--r--src/test/ui/const-generics/issues/issue-68977.full.stderr10
-rw-r--r--src/test/ui/const-generics/issues/issue-68977.min.stderr18
-rw-r--r--src/test/ui/const-generics/issues/issue-68977.rs10
-rw-r--r--src/test/ui/const-generics/issues/issue-68977.stderr19
-rw-r--r--src/test/ui/const-generics/issues/issue-70125-1.rs6
-rw-r--r--src/test/ui/const-generics/issues/issue-70125-1.stderr11
-rw-r--r--src/test/ui/const-generics/issues/issue-70125-2.rs7
-rw-r--r--src/test/ui/const-generics/issues/issue-70125-2.stderr11
-rw-r--r--src/test/ui/const-generics/issues/issue-70167.rs7
-rw-r--r--src/test/ui/const-generics/issues/issue-70167.stderr11
-rw-r--r--src/test/ui/const-generics/issues/issue-71169.full.stderr (renamed from src/test/ui/const-generics/issues/issue-71169.stderr)4
-rw-r--r--src/test/ui/const-generics/issues/issue-71169.min.stderr18
-rw-r--r--src/test/ui/const-generics/issues/issue-71169.rs9
-rw-r--r--src/test/ui/const-generics/issues/issue-71381.full.stderr (renamed from src/test/ui/const-generics/issues/issue-71381.stderr)8
-rw-r--r--src/test/ui/const-generics/issues/issue-71381.min.stderr27
-rw-r--r--src/test/ui/const-generics/issues/issue-71381.rs6
-rw-r--r--src/test/ui/const-generics/issues/issue-71382.full.stderr (renamed from src/test/ui/const-generics/issues/issue-71382.stderr)2
-rw-r--r--src/test/ui/const-generics/issues/issue-71382.min.stderr8
-rw-r--r--src/test/ui/const-generics/issues/issue-71382.rs6
-rw-r--r--src/test/ui/const-generics/issues/issue-71611.full.stderr (renamed from src/test/ui/const-generics/issues/issue-71611.stderr)4
-rw-r--r--src/test/ui/const-generics/issues/issue-71611.min.stderr15
-rw-r--r--src/test/ui/const-generics/issues/issue-71611.rs6
-rw-r--r--src/test/ui/const-generics/issues/issue-72352.full.stderr (renamed from src/test/ui/const-generics/issues/issue-72352.stderr)2
-rw-r--r--src/test/ui/const-generics/issues/issue-72352.min.stderr8
-rw-r--r--src/test/ui/const-generics/issues/issue-72352.rs6
-rw-r--r--src/test/ui/const-generics/issues/issue-73491.min.stderr11
-rw-r--r--src/test/ui/const-generics/issues/issue-73491.rs9
-rw-r--r--src/test/ui/const-generics/issues/issue-73508.full.stderr8
-rw-r--r--src/test/ui/const-generics/issues/issue-73508.min.stderr8
-rw-r--r--src/test/ui/const-generics/issues/issue-73508.rs5
-rw-r--r--src/test/ui/const-generics/issues/issue-73508.stderr17
-rw-r--r--src/test/ui/const-generics/issues/issue-74101.min.stderr20
-rw-r--r--src/test/ui/const-generics/issues/issue-74101.rs10
-rw-r--r--src/test/ui/const-generics/issues/issue-74255.min.stderr11
-rw-r--r--src/test/ui/const-generics/issues/issue-74255.rs9
-rw-r--r--src/test/ui/const-generics/issues/issue-75047.min.stderr11
-rw-r--r--src/test/ui/const-generics/issues/issue-75047.rs9
-rw-r--r--src/test/ui/const-generics/issues/issue70273-assoc-fn.rs7
-rw-r--r--src/test/ui/const-generics/issues/issue70273-assoc-fn.stderr11
-rw-r--r--src/test/ui/const-generics/std/const-generics-range.min.stderr56
-rw-r--r--src/test/ui/const-generics/std/const-generics-range.rs14
-rw-r--r--src/test/ui/const-generics/type-after-const-ok.min.stderr8
-rw-r--r--src/test/ui/const-generics/type-after-const-ok.rs10
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-61936.rs6
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-63695.rs6
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-67144-1.rs6
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-67144-2.rs6
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-69816.rs6
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-70217.rs7
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-70507.rs6
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-70586.rs6
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-71348.min.stderr20
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-71348.rs10
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-71382.full.stderr8
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-71382.min.stderr8
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-71382.rs6
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-71382.stderr17
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-71805.rs6
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-73730.rs6
-rw-r--r--src/test/ui/const-generics/type-dependent/non-local.rs6
-rw-r--r--src/test/ui/const-generics/type-dependent/qpath.rs6
-rw-r--r--src/test/ui/const-generics/type-dependent/simple.rs6
-rw-r--r--src/test/ui/const-generics/type-dependent/type-mismatch.full.stderr14
-rw-r--r--src/test/ui/const-generics/type-dependent/type-mismatch.min.stderr14
-rw-r--r--src/test/ui/const-generics/type-dependent/type-mismatch.rs6
-rw-r--r--src/test/ui/const-generics/type-dependent/type-mismatch.stderr23
-rw-r--r--src/test/ui/const-generics/types-mismatch-const-args.full.stderr (renamed from src/test/ui/const-generics/types-mismatch-const-args.stderr)15
-rw-r--r--src/test/ui/const-generics/types-mismatch-const-args.min.stderr25
-rw-r--r--src/test/ui/const-generics/types-mismatch-const-args.rs6
-rw-r--r--src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs7
-rw-r--r--src/test/ui/const-generics/uninferred-consts-during-codegen-1.stderr11
-rw-r--r--src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs7
-rw-r--r--src/test/ui/const-generics/uninferred-consts-during-codegen-2.stderr11
-rw-r--r--src/test/ui/consts/cow-is-borrowed.rs15
-rw-r--r--src/test/ui/consts/std/net/ipv4.rs58
-rw-r--r--src/test/ui/consts/std/net/ipv6.rs53
-rw-r--r--src/test/ui/error-codes/E0070.stderr12
-rw-r--r--src/test/ui/fmt/incorrect-separator.rs29
-rw-r--r--src/test/ui/fmt/incorrect-separator.stderr44
-rw-r--r--src/test/ui/issues/issue-13407.stderr12
-rw-r--r--src/test/ui/macros/duplicate-builtin.rs17
-rw-r--r--src/test/ui/macros/duplicate-builtin.stderr21
-rw-r--r--src/test/ui/macros/missing-comma.rs2
-rw-r--r--src/test/ui/macros/missing-comma.stderr2
-rw-r--r--src/test/ui/macros/unknown-builtin.rs4
-rw-r--r--src/test/ui/macros/unknown-builtin.stderr9
-rw-r--r--src/test/ui/parser/shebang/shebang-doc-comment.rs5
-rw-r--r--src/test/ui/parser/shebang/shebang-doc-comment.stderr8
-rw-r--r--src/test/ui/parser/unicode-quote-chars.rs2
-rw-r--r--src/test/ui/parser/unicode-quote-chars.stderr2
-rw-r--r--src/test/ui/pattern/const-pat-ice.stderr2
-rw-r--r--src/test/ui/proc-macro/issue-75930-derive-cfg.rs30
-rw-r--r--src/test/ui/proc-macro/issue-75930-derive-cfg.stdout221
-rw-r--r--src/test/ui/proc-macro/load-panic-backtrace.rs21
-rw-r--r--src/test/ui/proc-macro/load-panic-backtrace.stderr11
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr20
-rw-r--r--src/test/ui/suggestions/if-let-typo.rs9
-rw-r--r--src/test/ui/suggestions/if-let-typo.stderr60
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs2
-rw-r--r--src/test/ui/type/type-check/assignment-expected-bool.stderr114
-rw-r--r--src/test/ui/type/type-check/assignment-in-if.stderr64
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/ast_utils.rs2
-rw-r--r--src/tools/clippy/tests/ui/issue-3145.rs2
-rw-r--r--src/tools/clippy/tests/ui/issue-3145.stderr4
-rw-r--r--src/tools/error_index_generator/build.rs4
m---------src/tools/miri16
m---------src/tools/rust-analyzer38
-rw-r--r--src/tools/tidy/src/debug_artifacts.rs2
-rw-r--r--src/tools/tidy/src/edition.rs1
-rw-r--r--src/tools/tidy/src/features.rs20
-rw-r--r--src/tools/tidy/src/main.rs47
-rw-r--r--src/tools/tidy/src/pal.rs5
-rw-r--r--src/tools/tidy/src/unit_tests.rs14
-rw-r--r--src/tools/unstable-book-gen/src/main.rs10
2098 files changed, 22597 insertions, 20969 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ffc1f0dec1d..f94d95d2dc8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -278,7 +278,7 @@ checksum = "81a18687293a1546b67c246452202bbbf143d239cb43494cc163da14979082da"
 
 [[package]]
 name = "cargo"
-version = "0.48.0"
+version = "0.49.0"
 dependencies = [
  "anyhow",
  "atty",
@@ -998,9 +998,9 @@ dependencies = [
 
 [[package]]
 name = "expect-test"
-version = "0.1.0"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3e383741ea1982866572109d1a8c807bd36aad91fca701489fdca56ef92b3b8"
+checksum = "ceb96f3eaa0d4e8769c52dacfd4eb60183b817ed2f176171b3c691d5022b0f2e"
 dependencies = [
  "difference",
  "once_cell",
@@ -3417,10 +3417,8 @@ dependencies = [
  "ena",
  "indexmap",
  "jobserver",
- "lazy_static",
  "libc",
  "measureme",
- "once_cell",
  "parking_lot 0.10.2",
  "rustc-hash",
  "rustc-rayon",
@@ -3441,7 +3439,6 @@ dependencies = [
 name = "rustc_driver"
 version = "0.0.0"
 dependencies = [
- "lazy_static",
  "libc",
  "rustc_ast",
  "rustc_ast_pretty",
@@ -3515,7 +3512,6 @@ dependencies = [
 name = "rustc_feature"
 version = "0.0.0"
 dependencies = [
- "lazy_static",
  "rustc_data_structures",
  "rustc_span",
 ]
@@ -3532,7 +3528,6 @@ version = "0.0.0"
 name = "rustc_hir"
 version = "0.0.0"
 dependencies = [
- "lazy_static",
  "rustc_ast",
  "rustc_data_structures",
  "rustc_index",
@@ -3607,7 +3602,6 @@ name = "rustc_interface"
 version = "0.0.0"
 dependencies = [
  "libc",
- "once_cell",
  "rustc-rayon",
  "rustc_ast",
  "rustc_ast_lowering",
diff --git a/Cargo.toml b/Cargo.toml
index d8d9cc399c8..fde1cb5a35c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,8 +1,7 @@
 [workspace]
 members = [
   "src/bootstrap",
-  "src/rustc",
-  "src/librustc_codegen_llvm",
+  "compiler/rustc",
   "library/std",
   "library/test",
   "src/tools/cargotest",
diff --git a/README.md b/README.md
index fe9776bc5f8..a7e23d8ac2c 100644
--- a/README.md
+++ b/README.md
@@ -112,7 +112,7 @@ build.
    # Install build tools needed for Rust. If you're building a 32-bit compiler,
    # then replace "x86_64" below with "i686". If you've already got git, python,
    # or CMake installed and in PATH you can remove them from this list. Note
-   # that it is important that you do **not** use the 'python2' and 'cmake'
+   # that it is important that you do **not** use the 'python2', 'cmake' and 'ninja'
    # packages from the 'msys2' subsystem. The build has historically been known
    # to fail with these packages.
    $ pacman -S git \
@@ -121,7 +121,8 @@ build.
                tar \
                mingw-w64-x86_64-python \
                mingw-w64-x86_64-cmake \
-               mingw-w64-x86_64-gcc
+               mingw-w64-x86_64-gcc \
+               mingw-w64-x86_64-ninja
    ```
 
 4. Navigate to Rust's source code (or clone it), then build it:
@@ -210,11 +211,17 @@ fetch snapshots, and an OS that can execute the available snapshot binaries.
 
 Snapshot binaries are currently built and tested on several platforms:
 
-| Platform / Architecture    | x86 | x86_64 |
-|----------------------------|-----|--------|
-| Windows (7, 8, 10, ...)    | ✓   | ✓      |
-| Linux (2.6.18 or later)    | ✓   | ✓      |
-| macOS (10.7 Lion or later) | ✓   | ✓      |
+| Platform / Architecture                     | x86 | x86_64 |
+|---------------------------------------------|-----|--------|
+| Windows (7, 8, 10, ...)                     | ✓   | ✓      |
+| Linux (kernel 2.6.32, glibc 2.11 or later)  | ✓   | ✓      |
+| macOS (10.7 Lion or later)                  | (\*) | ✓      |
+
+(\*): Apple dropped support for running 32-bit binaries starting from macOS 10.15 and iOS 11.
+Due to this decision from Apple, the targets are no longer useful to our users.
+Please read [our blog post][macx32] for more info.
+
+[macx32]: https://blog.rust-lang.org/2020/01/03/reducing-support-for-32-bit-apple-targets.html
 
 You may find that other platforms work, but these are our officially
 supported build environments that are most likely to work.
diff --git a/RELEASES.md b/RELEASES.md
index 64fe2df3c49..0f59d72bd16 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -10,7 +10,7 @@ Language
   function's caller's location information for panic messages.][72445]
 - [Recursively indexing into tuples no longer needs parentheses.][71322] E.g.
   `x.0.0` over `(x.0).0`.
-- [`mem::transmute` can now be used in static and constants.][72920] **Note**
+- [`mem::transmute` can now be used in statics and constants.][72920] **Note**
   You currently can't use `mem::transmute` in constant functions.
 
 Compiler
diff --git a/src/rustc/Cargo.toml b/compiler/rustc/Cargo.toml
index 5e0f167bb38..cf011e63e02 100644
--- a/src/rustc/Cargo.toml
+++ b/compiler/rustc/Cargo.toml
@@ -4,16 +4,12 @@ name = "rustc-main"
 version = "0.0.0"
 edition = '2018'
 
-[[bin]]
-name = "rustc_binary"
-path = "rustc.rs"
-
 [dependencies]
-rustc_driver = { path = "../librustc_driver" }
+rustc_driver = { path = "../rustc_driver" }
 
 # Make sure rustc_codegen_ssa ends up in the sysroot, because this
 # crate is intended to be used by codegen backends, which may not be in-tree.
-rustc_codegen_ssa = { path = "../librustc_codegen_ssa" }
+rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
 
 [dependencies.jemalloc-sys]
 version = '0.3.0'
diff --git a/src/rustc/rustc.rs b/compiler/rustc/src/main.rs
index 6bc5aa6382c..6bc5aa6382c 100644
--- a/src/rustc/rustc.rs
+++ b/compiler/rustc/src/main.rs
diff --git a/src/librustc_apfloat/Cargo.toml b/compiler/rustc_apfloat/Cargo.toml
index 726965e1e71..306513f1a7e 100644
--- a/src/librustc_apfloat/Cargo.toml
+++ b/compiler/rustc_apfloat/Cargo.toml
@@ -4,10 +4,6 @@ name = "rustc_apfloat"
 version = "0.0.0"
 edition = "2018"
 
-[lib]
-name = "rustc_apfloat"
-path = "lib.rs"
-
 [dependencies]
 bitflags = "1.2.1"
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_apfloat/ieee.rs b/compiler/rustc_apfloat/src/ieee.rs
index e3d941cad7a..e3d941cad7a 100644
--- a/src/librustc_apfloat/ieee.rs
+++ b/compiler/rustc_apfloat/src/ieee.rs
diff --git a/src/librustc_apfloat/lib.rs b/compiler/rustc_apfloat/src/lib.rs
index ba3adc4a135..ba3adc4a135 100644
--- a/src/librustc_apfloat/lib.rs
+++ b/compiler/rustc_apfloat/src/lib.rs
diff --git a/src/librustc_apfloat/ppc.rs b/compiler/rustc_apfloat/src/ppc.rs
index 4ae8edf3157..4ae8edf3157 100644
--- a/src/librustc_apfloat/ppc.rs
+++ b/compiler/rustc_apfloat/src/ppc.rs
diff --git a/src/librustc_apfloat/tests/ieee.rs b/compiler/rustc_apfloat/tests/ieee.rs
index 2d8bb7d1e8e..2d8bb7d1e8e 100644
--- a/src/librustc_apfloat/tests/ieee.rs
+++ b/compiler/rustc_apfloat/tests/ieee.rs
diff --git a/src/librustc_apfloat/tests/ppc.rs b/compiler/rustc_apfloat/tests/ppc.rs
index 5a8de71cb34..5a8de71cb34 100644
--- a/src/librustc_apfloat/tests/ppc.rs
+++ b/compiler/rustc_apfloat/tests/ppc.rs
diff --git a/src/librustc_arena/Cargo.toml b/compiler/rustc_arena/Cargo.toml
index dfae956e2b6..41701f3255f 100644
--- a/src/librustc_arena/Cargo.toml
+++ b/compiler/rustc_arena/Cargo.toml
@@ -4,10 +4,6 @@ name = "rustc_arena"
 version = "0.0.0"
 edition = "2018"
 
-[lib]
-name = "rustc_arena"
-path = "lib.rs"
-
 [dependencies]
-rustc_data_structures = { path = "../librustc_data_structures" }
+rustc_data_structures = { path = "../rustc_data_structures" }
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_arena/lib.rs b/compiler/rustc_arena/src/lib.rs
index 5e6a0340d12..5e6a0340d12 100644
--- a/src/librustc_arena/lib.rs
+++ b/compiler/rustc_arena/src/lib.rs
diff --git a/src/librustc_arena/tests.rs b/compiler/rustc_arena/src/tests.rs
index 8e63bdf5458..8e63bdf5458 100644
--- a/src/librustc_arena/tests.rs
+++ b/compiler/rustc_arena/src/tests.rs
diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml
new file mode 100644
index 00000000000..13e17a807c4
--- /dev/null
+++ b/compiler/rustc_ast/Cargo.toml
@@ -0,0 +1,19 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_ast"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+rustc_serialize = { path = "../rustc_serialize" }
+tracing = "0.1"
+rustc_span = { path = "../rustc_span" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_index = { path = "../rustc_index" }
+rustc_lexer = { path = "../rustc_lexer" }
+rustc_macros = { path = "../rustc_macros" }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
+bitflags = "1.2.1"
diff --git a/src/librustc_ast/README.md b/compiler/rustc_ast/README.md
index dd407dba1f4..dd407dba1f4 100644
--- a/src/librustc_ast/README.md
+++ b/compiler/rustc_ast/README.md
diff --git a/src/librustc_ast/ast.rs b/compiler/rustc_ast/src/ast.rs
index 127a53cad2b..49aa1fc1735 100644
--- a/src/librustc_ast/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -922,9 +922,13 @@ impl Stmt {
     pub fn add_trailing_semicolon(mut self) -> Self {
         self.kind = match self.kind {
             StmtKind::Expr(expr) => StmtKind::Semi(expr),
-            StmtKind::MacCall(mac) => StmtKind::MacCall(
-                mac.map(|(mac, _style, attrs)| (mac, MacStmtStyle::Semicolon, attrs)),
-            ),
+            StmtKind::MacCall(mac) => {
+                StmtKind::MacCall(mac.map(|MacCallStmt { mac, style: _, attrs }| MacCallStmt {
+                    mac,
+                    style: MacStmtStyle::Semicolon,
+                    attrs,
+                }))
+            }
             kind => kind,
         };
         self
@@ -958,7 +962,14 @@ pub enum StmtKind {
     /// Just a trailing semi-colon.
     Empty,
     /// Macro.
-    MacCall(P<(MacCall, MacStmtStyle, AttrVec)>),
+    MacCall(P<MacCallStmt>),
+}
+
+#[derive(Clone, Encodable, Decodable, Debug)]
+pub struct MacCallStmt {
+    pub mac: MacCall,
+    pub style: MacStmtStyle,
+    pub attrs: AttrVec,
 }
 
 #[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
diff --git a/src/librustc_ast/ast/tests.rs b/compiler/rustc_ast/src/ast/tests.rs
index 8ba55bf037b..8ba55bf037b 100644
--- a/src/librustc_ast/ast/tests.rs
+++ b/compiler/rustc_ast/src/ast/tests.rs
diff --git a/src/librustc_ast/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index edcbce3e2cf..12d6f7cc33d 100644
--- a/src/librustc_ast/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -16,7 +16,6 @@ use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
 
 use std::iter;
-use std::ops::DerefMut;
 
 pub struct MarkedAttrs(GrowableBitSet<AttrId>);
 
@@ -634,10 +633,7 @@ impl HasAttrs for StmtKind {
             StmtKind::Local(ref local) => local.attrs(),
             StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => expr.attrs(),
             StmtKind::Empty | StmtKind::Item(..) => &[],
-            StmtKind::MacCall(ref mac) => {
-                let (_, _, ref attrs) = **mac;
-                attrs.attrs()
-            }
+            StmtKind::MacCall(ref mac) => mac.attrs.attrs(),
         }
     }
 
@@ -647,8 +643,7 @@ impl HasAttrs for StmtKind {
             StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.visit_attrs(f),
             StmtKind::Empty | StmtKind::Item(..) => {}
             StmtKind::MacCall(mac) => {
-                let (_mac, _style, attrs) = mac.deref_mut();
-                attrs.visit_attrs(f);
+                mac.attrs.visit_attrs(f);
             }
         }
     }
diff --git a/src/librustc_ast/crate_disambiguator.rs b/compiler/rustc_ast/src/crate_disambiguator.rs
index bd7d8516714..bd7d8516714 100644
--- a/src/librustc_ast/crate_disambiguator.rs
+++ b/compiler/rustc_ast/src/crate_disambiguator.rs
diff --git a/src/librustc_ast/entry.rs b/compiler/rustc_ast/src/entry.rs
index 290f6006de0..290f6006de0 100644
--- a/src/librustc_ast/entry.rs
+++ b/compiler/rustc_ast/src/entry.rs
diff --git a/src/librustc_ast/expand/allocator.rs b/compiler/rustc_ast/src/expand/allocator.rs
index cd27f958e46..cd27f958e46 100644
--- a/src/librustc_ast/expand/allocator.rs
+++ b/compiler/rustc_ast/src/expand/allocator.rs
diff --git a/src/librustc_ast/expand/mod.rs b/compiler/rustc_ast/src/expand/mod.rs
index eebfc38bdf4..eebfc38bdf4 100644
--- a/src/librustc_ast/expand/mod.rs
+++ b/compiler/rustc_ast/src/expand/mod.rs
diff --git a/src/librustc_ast/lib.rs b/compiler/rustc_ast/src/lib.rs
index b556c1a446b..b556c1a446b 100644
--- a/src/librustc_ast/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
diff --git a/src/librustc_ast/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 965571aaa54..3ef83ef3fc9 100644
--- a/src/librustc_ast/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -1305,7 +1305,7 @@ pub fn noop_flat_map_stmt_kind<T: MutVisitor>(
         StmtKind::Semi(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Semi).collect(),
         StmtKind::Empty => smallvec![StmtKind::Empty],
         StmtKind::MacCall(mut mac) => {
-            let (mac_, _semi, attrs) = mac.deref_mut();
+            let MacCallStmt { mac: mac_, style: _, attrs } = mac.deref_mut();
             vis.visit_mac(mac_);
             visit_thin_attrs(attrs, vis);
             smallvec![StmtKind::MacCall(mac)]
diff --git a/src/librustc_ast/node_id.rs b/compiler/rustc_ast/src/node_id.rs
index 1035e945538..1035e945538 100644
--- a/src/librustc_ast/node_id.rs
+++ b/compiler/rustc_ast/src/node_id.rs
diff --git a/src/librustc_ast/ptr.rs b/compiler/rustc_ast/src/ptr.rs
index e4a3cccb7ea..e4a3cccb7ea 100644
--- a/src/librustc_ast/ptr.rs
+++ b/compiler/rustc_ast/src/ptr.rs
diff --git a/src/librustc_ast/token.rs b/compiler/rustc_ast/src/token.rs
index 4a8bf6b4f19..c6cc890b47f 100644
--- a/src/librustc_ast/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -251,17 +251,6 @@ pub enum TokenKind {
     /// similarly to symbols in string literal tokens.
     DocComment(CommentKind, ast::AttrStyle, Symbol),
 
-    // Junk. These carry no data because we don't really care about the data
-    // they *would* carry, and don't really want to allocate a new ident for
-    // them. Instead, users could extract that from the associated span.
-    /// Whitespace.
-    Whitespace,
-    /// A comment.
-    Comment,
-    Shebang(Symbol),
-    /// A completely invalid token which should be skipped.
-    Unknown(Symbol),
-
     Eof,
 }
 
@@ -331,7 +320,7 @@ impl Token {
 
     /// Some token that will be thrown away later.
     pub fn dummy() -> Self {
-        Token::new(TokenKind::Whitespace, DUMMY_SP)
+        Token::new(TokenKind::Question, DUMMY_SP)
     }
 
     /// Recovers a `Token` from an `Ident`. This creates a raw identifier if necessary.
@@ -360,7 +349,7 @@ impl Token {
     pub fn is_op(&self) -> bool {
         match self.kind {
             OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) | Ident(..)
-            | Lifetime(..) | Interpolated(..) | Whitespace | Comment | Shebang(..) | Eof => false,
+            | Lifetime(..) | Interpolated(..) | Eof => false,
             _ => true,
         }
     }
@@ -676,8 +665,7 @@ impl Token {
             Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq(..) | At | DotDotDot
             | DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar
             | Question | OpenDelim(..) | CloseDelim(..) | Literal(..) | Ident(..)
-            | Lifetime(..) | Interpolated(..) | DocComment(..) | Whitespace | Comment
-            | Shebang(..) | Unknown(..) | Eof => return None,
+            | Lifetime(..) | Interpolated(..) | DocComment(..) | Eof => return None,
         };
 
         Some(Token::new(kind, self.span.to(joint.span)))
diff --git a/src/librustc_ast/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index 151acddae84..151acddae84 100644
--- a/src/librustc_ast/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
diff --git a/src/librustc_ast/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs
index 60422a2e573..60422a2e573 100644
--- a/src/librustc_ast/util/classify.rs
+++ b/compiler/rustc_ast/src/util/classify.rs
diff --git a/src/librustc_ast/util/comments.rs b/compiler/rustc_ast/src/util/comments.rs
index e97c8cc4562..e97c8cc4562 100644
--- a/src/librustc_ast/util/comments.rs
+++ b/compiler/rustc_ast/src/util/comments.rs
diff --git a/src/librustc_ast/util/comments/tests.rs b/compiler/rustc_ast/src/util/comments/tests.rs
index e19198f863b..e19198f863b 100644
--- a/src/librustc_ast/util/comments/tests.rs
+++ b/compiler/rustc_ast/src/util/comments/tests.rs
diff --git a/src/librustc_ast/util/lev_distance.rs b/compiler/rustc_ast/src/util/lev_distance.rs
index d4e0e3ba051..d4e0e3ba051 100644
--- a/src/librustc_ast/util/lev_distance.rs
+++ b/compiler/rustc_ast/src/util/lev_distance.rs
diff --git a/src/librustc_ast/util/lev_distance/tests.rs b/compiler/rustc_ast/src/util/lev_distance/tests.rs
index 7ebedbcb76a..7ebedbcb76a 100644
--- a/src/librustc_ast/util/lev_distance/tests.rs
+++ b/compiler/rustc_ast/src/util/lev_distance/tests.rs
diff --git a/src/librustc_ast/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs
index 597e5b437fc..597e5b437fc 100644
--- a/src/librustc_ast/util/literal.rs
+++ b/compiler/rustc_ast/src/util/literal.rs
diff --git a/src/librustc_ast/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs
index 2ee94965756..2ee94965756 100644
--- a/src/librustc_ast/util/parser.rs
+++ b/compiler/rustc_ast/src/util/parser.rs
diff --git a/src/librustc_ast/visit.rs b/compiler/rustc_ast/src/visit.rs
index b65a88cb90e..234ce280f97 100644
--- a/src/librustc_ast/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -692,7 +692,7 @@ pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) {
         StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => visitor.visit_expr(expr),
         StmtKind::Empty => {}
         StmtKind::MacCall(ref mac) => {
-            let (ref mac, _, ref attrs) = **mac;
+            let MacCallStmt { ref mac, style: _, ref attrs } = **mac;
             visitor.visit_mac(mac);
             for attr in attrs.iter() {
                 visitor.visit_attribute(attr);
diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml
new file mode 100644
index 00000000000..177a9066edf
--- /dev/null
+++ b/compiler/rustc_ast_lowering/Cargo.toml
@@ -0,0 +1,22 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_ast_lowering"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+rustc_arena = { path = "../rustc_arena" }
+tracing = "0.1"
+rustc_ast_pretty = { path = "../rustc_ast_pretty" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_target = { path = "../rustc_target" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_index = { path = "../rustc_index" }
+rustc_span = { path = "../rustc_span" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_session = { path = "../rustc_session" }
+rustc_ast = { path = "../rustc_ast" }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_ast_lowering/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index df452825bba..df452825bba 100644
--- a/src/librustc_ast_lowering/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
diff --git a/src/librustc_ast_lowering/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index f3309afec7d..f3309afec7d 100644
--- a/src/librustc_ast_lowering/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
diff --git a/src/librustc_ast_lowering/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 586355fe613..586355fe613 100644
--- a/src/librustc_ast_lowering/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
diff --git a/src/librustc_ast_lowering/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index cb7b7c0eb61..cb7b7c0eb61 100644
--- a/src/librustc_ast_lowering/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
diff --git a/src/librustc_ast_lowering/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index cf68dfb9ae1..cf68dfb9ae1 100644
--- a/src/librustc_ast_lowering/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml
new file mode 100644
index 00000000000..7cf3e752c92
--- /dev/null
+++ b/compiler/rustc_ast_passes/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_ast_passes"
+version = "0.0.0"
+edition = "2018"
+
+[dependencies]
+itertools = "0.8"
+tracing = "0.1"
+rustc_ast_pretty = { path = "../rustc_ast_pretty" }
+rustc_attr = { path = "../rustc_attr" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_feature = { path = "../rustc_feature" }
+rustc_parse = { path = "../rustc_parse" }
+rustc_session = { path = "../rustc_session" }
+rustc_span = { path = "../rustc_span" }
+rustc_ast = { path = "../rustc_ast" }
diff --git a/src/librustc_ast_passes/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index a01dd8c939c..a01dd8c939c 100644
--- a/src/librustc_ast_passes/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
diff --git a/src/librustc_ast_passes/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 0ee8ef55e61..0ee8ef55e61 100644
--- a/src/librustc_ast_passes/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
diff --git a/src/librustc_ast_passes/lib.rs b/compiler/rustc_ast_passes/src/lib.rs
index bfe30441980..bfe30441980 100644
--- a/src/librustc_ast_passes/lib.rs
+++ b/compiler/rustc_ast_passes/src/lib.rs
diff --git a/src/librustc_ast_passes/node_count.rs b/compiler/rustc_ast_passes/src/node_count.rs
index 706dca2b7f4..706dca2b7f4 100644
--- a/src/librustc_ast_passes/node_count.rs
+++ b/compiler/rustc_ast_passes/src/node_count.rs
diff --git a/src/librustc_ast_passes/show_span.rs b/compiler/rustc_ast_passes/src/show_span.rs
index 053aba86222..053aba86222 100644
--- a/src/librustc_ast_passes/show_span.rs
+++ b/compiler/rustc_ast_passes/src/show_span.rs
diff --git a/compiler/rustc_ast_pretty/Cargo.toml b/compiler/rustc_ast_pretty/Cargo.toml
new file mode 100644
index 00000000000..f447bc7f4ef
--- /dev/null
+++ b/compiler/rustc_ast_pretty/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_ast_pretty"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+tracing = "0.1"
+rustc_span = { path = "../rustc_span" }
+rustc_ast = { path = "../rustc_ast" }
+rustc_target = { path = "../rustc_target" }
diff --git a/src/librustc_ast_pretty/helpers.rs b/compiler/rustc_ast_pretty/src/helpers.rs
index dce856df9c6..dce856df9c6 100644
--- a/src/librustc_ast_pretty/helpers.rs
+++ b/compiler/rustc_ast_pretty/src/helpers.rs
diff --git a/src/librustc_ast_pretty/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs
index 9adc6c604e8..9adc6c604e8 100644
--- a/src/librustc_ast_pretty/lib.rs
+++ b/compiler/rustc_ast_pretty/src/lib.rs
diff --git a/src/librustc_ast_pretty/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs
index ca7f127ced6..ca7f127ced6 100644
--- a/src/librustc_ast_pretty/pp.rs
+++ b/compiler/rustc_ast_pretty/src/pp.rs
diff --git a/src/librustc_ast_pretty/pprust.rs b/compiler/rustc_ast_pretty/src/pprust.rs
index cb48deb5886..9743a000429 100644
--- a/src/librustc_ast_pretty/pprust.rs
+++ b/compiler/rustc_ast_pretty/src/pprust.rs
@@ -289,10 +289,6 @@ fn token_kind_to_string_ext(tok: &TokenKind, convert_dollar_crate: Option<Span>)
             doc_comment_to_string(comment_kind, attr_style, data)
         }
         token::Eof => "<eof>".to_string(),
-        token::Whitespace => " ".to_string(),
-        token::Comment => "/* */".to_string(),
-        token::Shebang(s) => format!("/* shebang: {}*/", s),
-        token::Unknown(s) => s.to_string(),
 
         token::Interpolated(ref nt) => nonterminal_to_string(nt),
     }
@@ -1507,11 +1503,10 @@ impl<'a> State<'a> {
                 self.s.word(";");
             }
             ast::StmtKind::MacCall(ref mac) => {
-                let (ref mac, style, ref attrs) = **mac;
                 self.space_if_not_bol();
-                self.print_outer_attributes(attrs);
-                self.print_mac(mac);
-                if style == ast::MacStmtStyle::Semicolon {
+                self.print_outer_attributes(&mac.attrs);
+                self.print_mac(&mac.mac);
+                if mac.style == ast::MacStmtStyle::Semicolon {
                     self.s.word(";");
                 }
             }
diff --git a/src/librustc_ast_pretty/pprust/tests.rs b/compiler/rustc_ast_pretty/src/pprust/tests.rs
index fdbf3feb900..fdbf3feb900 100644
--- a/src/librustc_ast_pretty/pprust/tests.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/tests.rs
diff --git a/compiler/rustc_attr/Cargo.toml b/compiler/rustc_attr/Cargo.toml
new file mode 100644
index 00000000000..5f941a0a650
--- /dev/null
+++ b/compiler/rustc_attr/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_attr"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+rustc_ast_pretty = { path = "../rustc_ast_pretty" }
+rustc_serialize = { path = "../rustc_serialize" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_span = { path = "../rustc_span" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_feature = { path = "../rustc_feature" }
+rustc_lexer = { path = "../rustc_lexer" }
+rustc_macros = { path = "../rustc_macros" }
+rustc_session = { path = "../rustc_session" }
+rustc_ast = { path = "../rustc_ast" }
+version_check = "0.9"
diff --git a/src/librustc_attr/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index b8929fe0889..b8929fe0889 100644
--- a/src/librustc_attr/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
diff --git a/src/librustc_attr/lib.rs b/compiler/rustc_attr/src/lib.rs
index 149a950f7d4..149a950f7d4 100644
--- a/src/librustc_attr/lib.rs
+++ b/compiler/rustc_attr/src/lib.rs
diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml
new file mode 100644
index 00000000000..c397a854126
--- /dev/null
+++ b/compiler/rustc_builtin_macros/Cargo.toml
@@ -0,0 +1,24 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_builtin_macros"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+rustc_parse_format = { path = "../rustc_parse_format" }
+tracing = "0.1"
+rustc_ast_pretty = { path = "../rustc_ast_pretty" }
+rustc_attr = { path = "../rustc_attr" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_feature = { path = "../rustc_feature" }
+rustc_parse = { path = "../rustc_parse" }
+rustc_target = { path = "../rustc_target" }
+rustc_session = { path = "../rustc_session" }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
+rustc_ast = { path = "../rustc_ast" }
+rustc_expand = { path = "../rustc_expand" }
+rustc_span = { path = "../rustc_span" }
diff --git a/src/librustc_builtin_macros/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 5dafd6b77ab..5dafd6b77ab 100644
--- a/src/librustc_builtin_macros/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
diff --git a/src/librustc_builtin_macros/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs
index 25181715540..25181715540 100644
--- a/src/librustc_builtin_macros/assert.rs
+++ b/compiler/rustc_builtin_macros/src/assert.rs
diff --git a/src/librustc_builtin_macros/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs
index 4c00162b556..4c00162b556 100644
--- a/src/librustc_builtin_macros/cfg.rs
+++ b/compiler/rustc_builtin_macros/src/cfg.rs
diff --git a/src/librustc_builtin_macros/cfg_accessible.rs b/compiler/rustc_builtin_macros/src/cfg_accessible.rs
index 75f4b077640..75f4b077640 100644
--- a/src/librustc_builtin_macros/cfg_accessible.rs
+++ b/compiler/rustc_builtin_macros/src/cfg_accessible.rs
diff --git a/src/librustc_builtin_macros/cmdline_attrs.rs b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
index 34e2accc615..34e2accc615 100644
--- a/src/librustc_builtin_macros/cmdline_attrs.rs
+++ b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
diff --git a/src/librustc_builtin_macros/compile_error.rs b/compiler/rustc_builtin_macros/src/compile_error.rs
index f5955604e5f..f5955604e5f 100644
--- a/src/librustc_builtin_macros/compile_error.rs
+++ b/compiler/rustc_builtin_macros/src/compile_error.rs
diff --git a/src/librustc_builtin_macros/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs
index e5077d93674..e5077d93674 100644
--- a/src/librustc_builtin_macros/concat.rs
+++ b/compiler/rustc_builtin_macros/src/concat.rs
diff --git a/src/librustc_builtin_macros/concat_idents.rs b/compiler/rustc_builtin_macros/src/concat_idents.rs
index 8223cdda072..8223cdda072 100644
--- a/src/librustc_builtin_macros/concat_idents.rs
+++ b/compiler/rustc_builtin_macros/src/concat_idents.rs
diff --git a/src/librustc_builtin_macros/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
index 12ef166b8b0..12ef166b8b0 100644
--- a/src/librustc_builtin_macros/deriving/bounds.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
diff --git a/src/librustc_builtin_macros/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs
index 957c8035399..957c8035399 100644
--- a/src/librustc_builtin_macros/deriving/clone.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs
diff --git a/src/librustc_builtin_macros/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
index 79f35ad5819..79f35ad5819 100644
--- a/src/librustc_builtin_macros/deriving/cmp/eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
diff --git a/src/librustc_builtin_macros/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
index c1473e24093..c1473e24093 100644
--- a/src/librustc_builtin_macros/deriving/cmp/ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
diff --git a/src/librustc_builtin_macros/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
index 8e9f15743cc..8e9f15743cc 100644
--- a/src/librustc_builtin_macros/deriving/cmp/partial_eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
diff --git a/src/librustc_builtin_macros/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
index 21174ca4c8b..21174ca4c8b 100644
--- a/src/librustc_builtin_macros/deriving/cmp/partial_ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
diff --git a/src/librustc_builtin_macros/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs
index 120e859f2b1..120e859f2b1 100644
--- a/src/librustc_builtin_macros/deriving/debug.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs
diff --git a/src/librustc_builtin_macros/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
index df69f6c90d8..df69f6c90d8 100644
--- a/src/librustc_builtin_macros/deriving/decodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
diff --git a/src/librustc_builtin_macros/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index 980be3a0050..980be3a0050 100644
--- a/src/librustc_builtin_macros/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
diff --git a/src/librustc_builtin_macros/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
index 62aa1cbfbf2..62aa1cbfbf2 100644
--- a/src/librustc_builtin_macros/deriving/encodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 849e8b136e1..849e8b136e1 100644
--- a/src/librustc_builtin_macros/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
diff --git a/src/librustc_builtin_macros/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
index 6b7d0e1f204..6b7d0e1f204 100644
--- a/src/librustc_builtin_macros/deriving/generic/ty.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
diff --git a/src/librustc_builtin_macros/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs
index 868f863b990..868f863b990 100644
--- a/src/librustc_builtin_macros/deriving/hash.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs
diff --git a/src/librustc_builtin_macros/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs
index 7e3fd131d44..7e3fd131d44 100644
--- a/src/librustc_builtin_macros/deriving/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs
diff --git a/src/librustc_builtin_macros/env.rs b/compiler/rustc_builtin_macros/src/env.rs
index 6de12acfb94..6de12acfb94 100644
--- a/src/librustc_builtin_macros/env.rs
+++ b/compiler/rustc_builtin_macros/src/env.rs
diff --git a/src/librustc_builtin_macros/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 373277f525d..5d6f791f137 100644
--- a/src/librustc_builtin_macros/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -135,21 +135,52 @@ fn parse_args<'a>(
         return Err(ecx.struct_span_err(sp, "requires at least a format string argument"));
     }
 
-    let fmtstr = p.parse_expr()?;
+    let first_token = &p.token;
+    let fmtstr = match first_token.kind {
+        token::TokenKind::Literal(token::Lit {
+            kind: token::LitKind::Str | token::LitKind::StrRaw(_),
+            ..
+        }) => {
+            // If the first token is a string literal, then a format expression
+            // is constructed from it.
+            //
+            // This allows us to properly handle cases when the first comma
+            // after the format string is mistakenly replaced with any operator,
+            // which cause the expression parser to eat too much tokens.
+            p.parse_literal_maybe_minus()?
+        }
+        _ => {
+            // Otherwise, we fall back to the expression parser.
+            p.parse_expr()?
+        }
+    };
+
     let mut first = true;
     let mut named = false;
 
     while p.token != token::Eof {
         if !p.eat(&token::Comma) {
             if first {
-                // After `format!(""` we always expect *only* a comma...
-                let mut err = ecx.struct_span_err(p.token.span, "expected token: `,`");
-                err.span_label(p.token.span, "expected `,`");
-                p.maybe_annotate_with_ascription(&mut err, false);
-                return Err(err);
-            } else {
-                // ...after that delegate to `expect` to also include the other expected tokens.
-                let _ = p.expect(&token::Comma)?;
+                p.clear_expected_tokens();
+            }
+
+            // `Parser::expect` tries to recover using the
+            // `Parser::unexpected_try_recover` function. This function is able
+            // to recover if the expected token is a closing delimiter.
+            //
+            // As `,` is not a closing delimiter, it will always return an `Err`
+            // variant.
+            let mut err = p.expect(&token::Comma).unwrap_err();
+
+            match token::TokenKind::Comma.similar_tokens() {
+                Some(tks) if tks.contains(&p.token.kind) => {
+                    // If a similar token is found, then it may be a typo. We
+                    // consider it as a comma, and continue parsing.
+                    err.emit();
+                    p.bump();
+                }
+                // Otherwise stop the parsing and return the error.
+                _ => return Err(err),
             }
         }
         first = false;
diff --git a/src/librustc_builtin_macros/format_foreign.rs b/compiler/rustc_builtin_macros/src/format_foreign.rs
index 85cf4c42e94..85cf4c42e94 100644
--- a/src/librustc_builtin_macros/format_foreign.rs
+++ b/compiler/rustc_builtin_macros/src/format_foreign.rs
diff --git a/src/librustc_builtin_macros/format_foreign/printf/tests.rs b/compiler/rustc_builtin_macros/src/format_foreign/printf/tests.rs
index 33c54c9cee0..33c54c9cee0 100644
--- a/src/librustc_builtin_macros/format_foreign/printf/tests.rs
+++ b/compiler/rustc_builtin_macros/src/format_foreign/printf/tests.rs
diff --git a/src/librustc_builtin_macros/format_foreign/shell/tests.rs b/compiler/rustc_builtin_macros/src/format_foreign/shell/tests.rs
index ed8fe81dfcd..ed8fe81dfcd 100644
--- a/src/librustc_builtin_macros/format_foreign/shell/tests.rs
+++ b/compiler/rustc_builtin_macros/src/format_foreign/shell/tests.rs
diff --git a/src/librustc_builtin_macros/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs
index 8478fcfbf09..8478fcfbf09 100644
--- a/src/librustc_builtin_macros/global_allocator.rs
+++ b/compiler/rustc_builtin_macros/src/global_allocator.rs
diff --git a/src/librustc_builtin_macros/global_asm.rs b/compiler/rustc_builtin_macros/src/global_asm.rs
index 2465f33622e..2465f33622e 100644
--- a/src/librustc_builtin_macros/global_asm.rs
+++ b/compiler/rustc_builtin_macros/src/global_asm.rs
diff --git a/src/librustc_builtin_macros/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 87be6d1743a..87be6d1743a 100644
--- a/src/librustc_builtin_macros/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
diff --git a/src/librustc_builtin_macros/llvm_asm.rs b/compiler/rustc_builtin_macros/src/llvm_asm.rs
index db73fdbe24f..db73fdbe24f 100644
--- a/src/librustc_builtin_macros/llvm_asm.rs
+++ b/compiler/rustc_builtin_macros/src/llvm_asm.rs
diff --git a/src/librustc_builtin_macros/log_syntax.rs b/compiler/rustc_builtin_macros/src/log_syntax.rs
index ede34a76125..ede34a76125 100644
--- a/src/librustc_builtin_macros/log_syntax.rs
+++ b/compiler/rustc_builtin_macros/src/log_syntax.rs
diff --git a/src/librustc_builtin_macros/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
index 0c6769906f3..0c6769906f3 100644
--- a/src/librustc_builtin_macros/proc_macro_harness.rs
+++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
diff --git a/src/librustc_builtin_macros/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs
index 70753208af3..70753208af3 100644
--- a/src/librustc_builtin_macros/source_util.rs
+++ b/compiler/rustc_builtin_macros/src/source_util.rs
diff --git a/src/librustc_builtin_macros/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs
index e801b5c7b0c..e801b5c7b0c 100644
--- a/src/librustc_builtin_macros/standard_library_imports.rs
+++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs
diff --git a/src/librustc_builtin_macros/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index 8e56e80bba2..8e56e80bba2 100644
--- a/src/librustc_builtin_macros/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
diff --git a/src/librustc_builtin_macros/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index 0ea60665d67..0ea60665d67 100644
--- a/src/librustc_builtin_macros/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
diff --git a/src/librustc_builtin_macros/trace_macros.rs b/compiler/rustc_builtin_macros/src/trace_macros.rs
index c17f2afe494..c17f2afe494 100644
--- a/src/librustc_builtin_macros/trace_macros.rs
+++ b/compiler/rustc_builtin_macros/src/trace_macros.rs
diff --git a/src/librustc_builtin_macros/util.rs b/compiler/rustc_builtin_macros/src/util.rs
index 01ea80c4c8a..01ea80c4c8a 100644
--- a/src/librustc_builtin_macros/util.rs
+++ b/compiler/rustc_builtin_macros/src/util.rs
diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml
new file mode 100644
index 00000000000..38f552558c8
--- /dev/null
+++ b/compiler/rustc_codegen_llvm/Cargo.toml
@@ -0,0 +1,34 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_codegen_llvm"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+test = false
+doctest = false
+
+[dependencies]
+bitflags = "1.0"
+libc = "0.2"
+measureme = "0.7.1"
+snap = "1"
+tracing = "0.1"
+rustc_middle = { path = "../rustc_middle" }
+rustc-demangle = "0.1"
+rustc_attr = { path = "../rustc_attr" }
+rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_feature = { path = "../rustc_feature" }
+rustc_fs_util = { path = "../rustc_fs_util" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_incremental = { path = "../rustc_incremental" }
+rustc_index = { path = "../rustc_index" }
+rustc_llvm = { path = "../../src/librustc_llvm" }
+rustc_session = { path = "../rustc_session" }
+rustc_serialize = { path = "../rustc_serialize" }
+rustc_target = { path = "../rustc_target" }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
+rustc_ast = { path = "../rustc_ast" }
+rustc_span = { path = "../rustc_span" }
diff --git a/src/librustc_codegen_llvm/README.md b/compiler/rustc_codegen_llvm/README.md
index afec60d017e..afec60d017e 100644
--- a/src/librustc_codegen_llvm/README.md
+++ b/compiler/rustc_codegen_llvm/README.md
diff --git a/src/librustc_codegen_llvm/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index 7857ccb613b..7857ccb613b 100644
--- a/src/librustc_codegen_llvm/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
diff --git a/src/librustc_codegen_llvm/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs
index bc1d9e1818c..bc1d9e1818c 100644
--- a/src/librustc_codegen_llvm/allocator.rs
+++ b/compiler/rustc_codegen_llvm/src/allocator.rs
diff --git a/src/librustc_codegen_llvm/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index a468d09c2d9..a468d09c2d9 100644
--- a/src/librustc_codegen_llvm/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
diff --git a/src/librustc_codegen_llvm/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index 227a87ff819..227a87ff819 100644
--- a/src/librustc_codegen_llvm/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
diff --git a/src/librustc_codegen_llvm/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs
index a115a1e9516..a115a1e9516 100644
--- a/src/librustc_codegen_llvm/back/archive.rs
+++ b/compiler/rustc_codegen_llvm/src/back/archive.rs
diff --git a/src/librustc_codegen_llvm/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index 7c710a1cb3d..7c710a1cb3d 100644
--- a/src/librustc_codegen_llvm/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
diff --git a/src/librustc_codegen_llvm/back/profiling.rs b/compiler/rustc_codegen_llvm/src/back/profiling.rs
index 2741f7d848e..2741f7d848e 100644
--- a/src/librustc_codegen_llvm/back/profiling.rs
+++ b/compiler/rustc_codegen_llvm/src/back/profiling.rs
diff --git a/src/librustc_codegen_llvm/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 6f386c1287c..6f386c1287c 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
diff --git a/src/librustc_codegen_llvm/base.rs b/compiler/rustc_codegen_llvm/src/base.rs
index 6a1b373ef07..6a1b373ef07 100644
--- a/src/librustc_codegen_llvm/base.rs
+++ b/compiler/rustc_codegen_llvm/src/base.rs
diff --git a/src/librustc_codegen_llvm/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 4ece08f6293..89c3e21632e 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -6,7 +6,6 @@ use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
 use libc::{c_char, c_uint};
-use rustc_codegen_ssa::base::to_immediate;
 use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, TypeKind};
 use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
 use rustc_codegen_ssa::mir::place::PlaceRef;
@@ -367,6 +366,20 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         (self.extract_value(res, 0), self.extract_value(res, 1))
     }
 
+    fn from_immediate(&mut self, val: Self::Value) -> Self::Value {
+        if self.cx().val_ty(val) == self.cx().type_i1() {
+            self.zext(val, self.cx().type_i8())
+        } else {
+            val
+        }
+    }
+    fn to_immediate_scalar(&mut self, val: Self::Value, scalar: &abi::Scalar) -> Self::Value {
+        if scalar.is_bool() {
+            return self.trunc(val, self.cx().type_i1());
+        }
+        val
+    }
+
     fn alloca(&mut self, ty: &'ll Type, align: Align) -> &'ll Value {
         let mut bx = Builder::with_cx(self.cx);
         bx.position_at_start(unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn()) });
@@ -471,7 +484,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
                 }
                 load
             });
-            OperandValue::Immediate(to_immediate(self, llval, place.layout))
+            OperandValue::Immediate(self.to_immediate(llval, place.layout))
         } 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);
 
@@ -479,7 +492,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
                 let llptr = self.struct_gep(place.llval, i as u64);
                 let load = self.load(llptr, align);
                 scalar_load_metadata(self, load, scalar);
-                if scalar.is_bool() { self.trunc(load, self.type_i1()) } else { load }
+                self.to_immediate_scalar(load, scalar)
             };
 
             OperandValue::Pair(
diff --git a/src/librustc_codegen_llvm/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs
index 4afd906fce7..4afd906fce7 100644
--- a/src/librustc_codegen_llvm/callee.rs
+++ b/compiler/rustc_codegen_llvm/src/callee.rs
diff --git a/src/librustc_codegen_llvm/common.rs b/compiler/rustc_codegen_llvm/src/common.rs
index 0b1cf03fa7e..0b1cf03fa7e 100644
--- a/src/librustc_codegen_llvm/common.rs
+++ b/compiler/rustc_codegen_llvm/src/common.rs
diff --git a/src/librustc_codegen_llvm/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index 86a5ec59254..86a5ec59254 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
diff --git a/src/librustc_codegen_llvm/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 1c51a9df5d8..1c51a9df5d8 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
diff --git a/src/librustc_codegen_llvm/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
index ec6c177614d..ec6c177614d 100644
--- a/src/librustc_codegen_llvm/coverageinfo/mapgen.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
diff --git a/src/librustc_codegen_llvm/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
index 2bd37bf9c4f..2bd37bf9c4f 100644
--- a/src/librustc_codegen_llvm/coverageinfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
diff --git a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
index 7f47b61de3f..7f47b61de3f 100644
--- a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
diff --git a/src/librustc_codegen_llvm/debuginfo/doc.rs b/compiler/rustc_codegen_llvm/src/debuginfo/doc.rs
index b3a8fa29887..b3a8fa29887 100644
--- a/src/librustc_codegen_llvm/debuginfo/doc.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/doc.rs
diff --git a/src/librustc_codegen_llvm/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
index 29edd66049c..29edd66049c 100644
--- a/src/librustc_codegen_llvm/debuginfo/gdb.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 9d92d53775c..9d92d53775c 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index b414426af8c..b414426af8c 100644
--- a/src/librustc_codegen_llvm/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
diff --git a/src/librustc_codegen_llvm/debuginfo/namespace.rs b/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs
index d1a55335c44..d1a55335c44 100644
--- a/src/librustc_codegen_llvm/debuginfo/namespace.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs
diff --git a/src/librustc_codegen_llvm/debuginfo/source_loc.rs b/compiler/rustc_codegen_llvm/src/debuginfo/source_loc.rs
index 66ae9d72c3e..66ae9d72c3e 100644
--- a/src/librustc_codegen_llvm/debuginfo/source_loc.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/source_loc.rs
diff --git a/src/librustc_codegen_llvm/debuginfo/utils.rs b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs
index ee188e69be1..ee188e69be1 100644
--- a/src/librustc_codegen_llvm/debuginfo/utils.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs
diff --git a/src/librustc_codegen_llvm/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs
index ec42bd4a039..ec42bd4a039 100644
--- a/src/librustc_codegen_llvm/declare.rs
+++ b/compiler/rustc_codegen_llvm/src/declare.rs
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index c1dfb83b135..951b9928cc9 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -8,7 +8,7 @@ use crate::va_arg::emit_va_arg;
 use crate::value::Value;
 
 use rustc_ast as ast;
-use rustc_codegen_ssa::base::{compare_simd_types, to_immediate, wants_msvc_seh};
+use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh};
 use rustc_codegen_ssa::common::span_invalid_monomorphization_error;
 use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
 use rustc_codegen_ssa::glue;
@@ -301,7 +301,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
                 unsafe {
                     llvm::LLVMSetAlignment(load, align);
                 }
-                to_immediate(self, load, self.layout_of(tp_ty))
+                self.to_immediate(load, self.layout_of(tp_ty))
             }
             sym::volatile_store => {
                 let dst = args[0].deref(self.cx());
diff --git a/src/librustc_codegen_llvm/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index 67d4b2642c0..67d4b2642c0 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
diff --git a/src/librustc_codegen_llvm/llvm/archive_ro.rs b/compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs
index 64db4f7462d..64db4f7462d 100644
--- a/src/librustc_codegen_llvm/llvm/archive_ro.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs
diff --git a/src/librustc_codegen_llvm/llvm/diagnostic.rs b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs
index 47f5c94e70c..47f5c94e70c 100644
--- a/src/librustc_codegen_llvm/llvm/diagnostic.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 32822eba930..32822eba930 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
index c09e3659f80..c09e3659f80 100644
--- a/src/librustc_codegen_llvm/llvm/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index f0b50459837..f0b50459837 100644
--- a/src/librustc_codegen_llvm/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
diff --git a/src/librustc_codegen_llvm/metadata.rs b/compiler/rustc_codegen_llvm/src/metadata.rs
index 9036428c04b..9036428c04b 100644
--- a/src/librustc_codegen_llvm/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/metadata.rs
diff --git a/src/librustc_codegen_llvm/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs
index 992e83d08fc..992e83d08fc 100644
--- a/src/librustc_codegen_llvm/mono_item.rs
+++ b/compiler/rustc_codegen_llvm/src/mono_item.rs
diff --git a/src/librustc_codegen_llvm/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs
index 3b53b4fe77b..3b53b4fe77b 100644
--- a/src/librustc_codegen_llvm/type_.rs
+++ b/compiler/rustc_codegen_llvm/src/type_.rs
diff --git a/src/librustc_codegen_llvm/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs
index 40870c66475..a02601eb43e 100644
--- a/src/librustc_codegen_llvm/type_of.rs
+++ b/compiler/rustc_codegen_llvm/src/type_of.rs
@@ -4,7 +4,6 @@ use crate::type_::Type;
 use rustc_codegen_ssa::traits::*;
 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, AddressSpace, Align, FieldsShape};
 use rustc_target::abi::{Int, Pointer, F32, F64};
@@ -52,32 +51,34 @@ fn uncached_llvm_type<'a, 'tcx>(
     }
 
     let name = match layout.ty.kind {
-        ty::Closure(..) |
-        ty::Generator(..) |
-        ty::Adt(..) |
         // FIXME(eddyb) producing readable type names for trait objects can result
         // in problematically distinct types due to HRTB and subtyping (see #47638).
         // ty::Dynamic(..) |
-        ty::Foreign(..) |
-        ty::Str => {
-            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, _), &Variants::Single { index })
-                 = (&layout.ty.kind, &layout.variants)
+        ty::Adt(..) | ty::Closure(..) | ty::Foreign(..) | ty::Generator(..) | ty::Str
+            if !cx.sess().fewer_names() =>
+        {
+            let mut name = layout.ty.to_string();
+            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(_, _, _), &Variants::Single { index })
-                 = (&layout.ty.kind, &layout.variants)
+            if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
+                (&layout.ty.kind, &layout.variants)
             {
                 write!(&mut name, "::{}", ty::GeneratorSubsts::variant_name(index)).unwrap();
             }
             Some(name)
         }
-        _ => None
+        ty::Adt(..) => {
+            // If `Some` is returned then a named struct is created in LLVM. Name collisions are
+            // avoided by LLVM (with increasing suffixes). If rustc doesn't generate names then that
+            // can improve perf.
+            Some(String::new())
+        }
+        _ => None,
     };
 
     match layout.fields {
diff --git a/src/librustc_codegen_llvm/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs
index 54efa05aee8..54efa05aee8 100644
--- a/src/librustc_codegen_llvm/va_arg.rs
+++ b/compiler/rustc_codegen_llvm/src/va_arg.rs
diff --git a/src/librustc_codegen_llvm/value.rs b/compiler/rustc_codegen_llvm/src/value.rs
index 1338a229566..1338a229566 100644
--- a/src/librustc_codegen_llvm/value.rs
+++ b/compiler/rustc_codegen_llvm/src/value.rs
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
new file mode 100644
index 00000000000..e5df0f60941
--- /dev/null
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -0,0 +1,36 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_codegen_ssa"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+test = false
+
+[dependencies]
+bitflags = "1.2.1"
+cc = "1.0.1"
+num_cpus = "1.0"
+memmap = "0.7"
+tracing = "0.1"
+libc = "0.2.50"
+jobserver = "0.1.11"
+tempfile = "3.1"
+pathdiff = "0.2.0"
+
+rustc_serialize = { path = "../rustc_serialize" }
+rustc_ast = { path = "../rustc_ast" }
+rustc_span = { path = "../rustc_span" }
+rustc_middle = { path = "../rustc_middle" }
+rustc_apfloat = { path = "../rustc_apfloat" }
+rustc_attr = { path = "../rustc_attr" }
+rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
+rustc_data_structures = { path = "../rustc_data_structures"}
+rustc_errors = { path = "../rustc_errors" }
+rustc_fs_util = { path = "../rustc_fs_util" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_incremental = { path = "../rustc_incremental" }
+rustc_index = { path = "../rustc_index" }
+rustc_macros = { path = "../rustc_macros" }
+rustc_target = { path = "../rustc_target" }
+rustc_session = { path = "../rustc_session" }
diff --git a/src/librustc_codegen_ssa/README.md b/compiler/rustc_codegen_ssa/README.md
index 7b770187b75..7b770187b75 100644
--- a/src/librustc_codegen_ssa/README.md
+++ b/compiler/rustc_codegen_ssa/README.md
diff --git a/src/librustc_codegen_ssa/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index f83b4b2b0c0..f83b4b2b0c0 100644
--- a/src/librustc_codegen_ssa/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
diff --git a/src/librustc_codegen_ssa/back/command.rs b/compiler/rustc_codegen_ssa/src/back/command.rs
index 0208bb73abd..0208bb73abd 100644
--- a/src/librustc_codegen_ssa/back/command.rs
+++ b/compiler/rustc_codegen_ssa/src/back/command.rs
diff --git a/src/librustc_codegen_ssa/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index bfcf979d125..c044020d930 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1014,86 +1014,7 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
     }
 }
 
-// Because windows-gnu target is meant to be self-contained for pure Rust code it bundles
-// own mingw-w64 libraries. These libraries are usually not compatible with mingw-w64
-// installed in the system. This breaks many cases where Rust is mixed with other languages
-// (e.g. *-sys crates).
-// We prefer system mingw-w64 libraries if they are available to avoid this issue.
-fn get_crt_libs_path(sess: &Session) -> Option<PathBuf> {
-    fn find_exe_in_path<P>(exe_name: P) -> Option<PathBuf>
-    where
-        P: AsRef<Path>,
-    {
-        for dir in env::split_paths(&env::var_os("PATH")?) {
-            let full_path = dir.join(&exe_name);
-            if full_path.is_file() {
-                return Some(fix_windows_verbatim_for_gcc(&full_path));
-            }
-        }
-        None
-    }
-
-    fn probe(sess: &Session) -> Option<PathBuf> {
-        if let (linker, LinkerFlavor::Gcc) = linker_and_flavor(&sess) {
-            let linker_path = if cfg!(windows) && linker.extension().is_none() {
-                linker.with_extension("exe")
-            } else {
-                linker
-            };
-            if let Some(linker_path) = find_exe_in_path(linker_path) {
-                let mingw_arch = match &sess.target.target.arch {
-                    x if x == "x86" => "i686",
-                    x => x,
-                };
-                let mingw_bits = &sess.target.target.target_pointer_width;
-                let mingw_dir = format!("{}-w64-mingw32", mingw_arch);
-                // Here we have path/bin/gcc but we need path/
-                let mut path = linker_path;
-                path.pop();
-                path.pop();
-                // Loosely based on Clang MinGW driver
-                let probe_paths = vec![
-                    path.join(&mingw_dir).join("lib"),                // Typical path
-                    path.join(&mingw_dir).join("sys-root/mingw/lib"), // Rare path
-                    path.join(format!(
-                        "lib/mingw/tools/install/mingw{}/{}/lib",
-                        &mingw_bits, &mingw_dir
-                    )), // Chocolatey is creative
-                ];
-                for probe_path in probe_paths {
-                    if probe_path.join("crt2.o").exists() {
-                        return Some(probe_path);
-                    };
-                }
-            };
-        };
-        None
-    }
-
-    let mut system_library_path = sess.system_library_path.borrow_mut();
-    match &*system_library_path {
-        Some(Some(compiler_libs_path)) => Some(compiler_libs_path.clone()),
-        Some(None) => None,
-        None => {
-            let path = probe(sess);
-            *system_library_path = Some(path.clone());
-            path
-        }
-    }
-}
-
 fn get_object_file_path(sess: &Session, name: &str, self_contained: bool) -> PathBuf {
-    // prefer system {,dll}crt2.o libs, see get_crt_libs_path comment for more details
-    if sess.opts.debugging_opts.link_self_contained.is_none()
-        && sess.target.target.llvm_target.contains("windows-gnu")
-    {
-        if let Some(compiler_libs_path) = get_crt_libs_path(sess) {
-            let file_path = compiler_libs_path.join(name);
-            if file_path.exists() {
-                return file_path;
-            }
-        }
-    }
     let fs = sess.target_filesearch(PathKind::Native);
     let file_path = fs.get_lib_path().join(name);
     if file_path.exists() {
@@ -1286,10 +1207,32 @@ fn link_output_kind(sess: &Session, crate_type: CrateType) -> LinkOutputKind {
     }
 }
 
+// Returns true if linker is located within sysroot
+fn detect_self_contained_mingw(sess: &Session) -> bool {
+    let (linker, _) = linker_and_flavor(&sess);
+    // Assume `-C linker=rust-lld` as self-contained mode
+    if linker == Path::new("rust-lld") {
+        return true;
+    }
+    let linker_with_extension = if cfg!(windows) && linker.extension().is_none() {
+        linker.with_extension("exe")
+    } else {
+        linker
+    };
+    for dir in env::split_paths(&env::var_os("PATH").unwrap_or_default()) {
+        let full_path = dir.join(&linker_with_extension);
+        // If linker comes from sysroot assume self-contained mode
+        if full_path.is_file() && !full_path.starts_with(&sess.sysroot) {
+            return false;
+        }
+    }
+    true
+}
+
 /// Whether we link to our own CRT objects instead of relying on gcc to pull them.
 /// We only provide such support for a very limited number of targets.
 fn crt_objects_fallback(sess: &Session, crate_type: CrateType) -> bool {
-    if let Some(self_contained) = sess.opts.debugging_opts.link_self_contained {
+    if let Some(self_contained) = sess.opts.cg.link_self_contained {
         return self_contained;
     }
 
@@ -1298,10 +1241,10 @@ fn crt_objects_fallback(sess: &Session, crate_type: CrateType) -> bool {
         // based on host and linker path, for example.
         // (https://github.com/rust-lang/rust/pull/71769#issuecomment-626330237).
         Some(CrtObjectsFallback::Musl) => sess.crt_static(Some(crate_type)),
-        // FIXME: Find some heuristic for "native mingw toolchain is available",
-        // likely based on `get_crt_libs_path` (https://github.com/rust-lang/rust/pull/67429).
         Some(CrtObjectsFallback::Mingw) => {
-            sess.host == sess.target.target && sess.target.target.target_vendor != "uwp"
+            sess.host == sess.target.target
+                && sess.target.target.target_vendor != "uwp"
+                && detect_self_contained_mingw(&sess)
         }
         // FIXME: Figure out cases in which WASM needs to link with a native toolchain.
         Some(CrtObjectsFallback::Wasm) => true,
@@ -1498,16 +1441,6 @@ fn link_local_crate_native_libs_and_dependent_crate_libs<'a, B: ArchiveBuilder<'
 
 /// Add sysroot and other globally set directories to the directory search list.
 fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session, self_contained: bool) {
-    // Prefer system mingw-w64 libs, see get_crt_libs_path comment for more details.
-    if sess.opts.debugging_opts.link_self_contained.is_none()
-        && cfg!(windows)
-        && sess.target.target.llvm_target.contains("windows-gnu")
-    {
-        if let Some(compiler_libs_path) = get_crt_libs_path(sess) {
-            cmd.include_path(&compiler_libs_path);
-        }
-    }
-
     // The default library location, we need this to find the runtime.
     // The location of crates will be determined as needed.
     let lib_path = sess.target_filesearch(PathKind::All).get_lib_path();
@@ -1668,7 +1601,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
     // FIXME: Order dependent, applies to the following objects. Where should it be placed?
     // Try to strip as much out of the generated object by removing unused
     // sections if possible. See more comments in linker.rs
-    if sess.opts.cg.link_dead_code != Some(true) {
+    if !sess.link_dead_code() {
         let keep_metadata = crate_type == CrateType::Dylib;
         cmd.gc_sections(keep_metadata);
     }
diff --git a/src/librustc_codegen_ssa/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 0ddf8bd316f..0ddf8bd316f 100644
--- a/src/librustc_codegen_ssa/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
diff --git a/src/librustc_codegen_ssa/back/lto.rs b/compiler/rustc_codegen_ssa/src/back/lto.rs
index 0d7f4447696..0d7f4447696 100644
--- a/src/librustc_codegen_ssa/back/lto.rs
+++ b/compiler/rustc_codegen_ssa/src/back/lto.rs
diff --git a/src/librustc_codegen_ssa/back/mod.rs b/compiler/rustc_codegen_ssa/src/back/mod.rs
index 20ca503d43f..20ca503d43f 100644
--- a/src/librustc_codegen_ssa/back/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/back/mod.rs
diff --git a/src/librustc_codegen_ssa/back/rpath.rs b/compiler/rustc_codegen_ssa/src/back/rpath.rs
index 005d2efdd3b..005d2efdd3b 100644
--- a/src/librustc_codegen_ssa/back/rpath.rs
+++ b/compiler/rustc_codegen_ssa/src/back/rpath.rs
diff --git a/src/librustc_codegen_ssa/back/rpath/tests.rs b/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs
index 35836ae719b..35836ae719b 100644
--- a/src/librustc_codegen_ssa/back/rpath/tests.rs
+++ b/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs
diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index 51cc1ada432..51cc1ada432 100644
--- a/src/librustc_codegen_ssa/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
diff --git a/src/librustc_codegen_ssa/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 7d69bb983dd..7d69bb983dd 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
diff --git a/src/librustc_codegen_ssa/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 77c12c410d5..e0b649d91c7 100644
--- a/src/librustc_codegen_ssa/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -38,7 +38,7 @@ 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::{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};
@@ -48,7 +48,7 @@ use rustc_session::utils::NativeLibKind;
 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 rustc_target::abi::{Align, LayoutOf, VariantIdx};
 
 use std::cmp;
 use std::ops::{Deref, DerefMut};
@@ -330,35 +330,6 @@ pub fn wants_msvc_seh(sess: &Session) -> bool {
     sess.target.target.options.is_like_msvc
 }
 
-pub fn from_immediate<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
-    bx: &mut Bx,
-    val: Bx::Value,
-) -> Bx::Value {
-    if bx.cx().val_ty(val) == bx.cx().type_i1() { bx.zext(val, bx.cx().type_i8()) } else { val }
-}
-
-pub fn to_immediate<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
-    bx: &mut Bx,
-    val: Bx::Value,
-    layout: layout::TyAndLayout<'_>,
-) -> Bx::Value {
-    if let Abi::Scalar(ref scalar) = layout.abi {
-        return to_immediate_scalar(bx, val, scalar);
-    }
-    val
-}
-
-pub fn to_immediate_scalar<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
-    bx: &mut Bx,
-    val: Bx::Value,
-    scalar: &Scalar,
-) -> Bx::Value {
-    if scalar.is_bool() {
-        return bx.trunc(val, bx.cx().type_i1());
-    }
-    val
-}
-
 pub fn memcpy_ty<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     bx: &mut Bx,
     dst: Bx::Value,
diff --git a/src/librustc_codegen_ssa/common.rs b/compiler/rustc_codegen_ssa/src/common.rs
index e04ed531bbf..e04ed531bbf 100644
--- a/src/librustc_codegen_ssa/common.rs
+++ b/compiler/rustc_codegen_ssa/src/common.rs
diff --git a/src/librustc_codegen_ssa/coverageinfo/ffi.rs b/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs
index a266d179a42..a266d179a42 100644
--- a/src/librustc_codegen_ssa/coverageinfo/ffi.rs
+++ b/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs
diff --git a/src/librustc_codegen_ssa/coverageinfo/map.rs b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs
index 814e43c5fa5..814e43c5fa5 100644
--- a/src/librustc_codegen_ssa/coverageinfo/map.rs
+++ b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs
diff --git a/src/librustc_codegen_ssa/coverageinfo/mod.rs b/compiler/rustc_codegen_ssa/src/coverageinfo/mod.rs
index 569fd3f1a51..569fd3f1a51 100644
--- a/src/librustc_codegen_ssa/coverageinfo/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/coverageinfo/mod.rs
diff --git a/src/librustc_codegen_ssa/debuginfo/mod.rs b/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs
index d1a0cf78d6a..d1a0cf78d6a 100644
--- a/src/librustc_codegen_ssa/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs
diff --git a/src/librustc_codegen_ssa/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index fb8f5a62989..fb8f5a62989 100644
--- a/src/librustc_codegen_ssa/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
diff --git a/src/librustc_codegen_ssa/glue.rs b/compiler/rustc_codegen_ssa/src/glue.rs
index 5b086bc43ff..5b086bc43ff 100644
--- a/src/librustc_codegen_ssa/glue.rs
+++ b/compiler/rustc_codegen_ssa/src/glue.rs
diff --git a/src/librustc_codegen_ssa/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 73e33369175..73e33369175 100644
--- a/src/librustc_codegen_ssa/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
diff --git a/src/librustc_codegen_ssa/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs
index bcc19c6a44b..bcc19c6a44b 100644
--- a/src/librustc_codegen_ssa/meth.rs
+++ b/compiler/rustc_codegen_ssa/src/meth.rs
diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index 2e386c1e594..2e386c1e594 100644
--- a/src/librustc_codegen_ssa/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 8048a569f79..6eb80157239 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -1143,7 +1143,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     }
                 }
                 // We store bools as `i8` so we need to truncate to `i1`.
-                llval = base::to_immediate(bx, llval, arg.layout);
+                llval = bx.to_immediate(llval, arg.layout);
             }
         }
 
diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs
index 4943e279c7e..4943e279c7e 100644
--- a/src/librustc_codegen_ssa/mir/constant.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs
diff --git a/src/librustc_codegen_ssa/mir/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs
index a2ad27b925c..a2ad27b925c 100644
--- a/src/librustc_codegen_ssa/mir/coverageinfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs
diff --git a/src/librustc_codegen_ssa/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index d8a530d98fa..d8a530d98fa 100644
--- a/src/librustc_codegen_ssa/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 26e6c354702..26e6c354702 100644
--- a/src/librustc_codegen_ssa/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index 937c7457c63..bbd004be875 100644
--- a/src/librustc_codegen_ssa/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -147,8 +147,8 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
             debug!("Operand::immediate_or_packed_pair: packing {:?} into {:?}", self, llty);
             // Reconstruct the immediate aggregate.
             let mut llpair = bx.cx().const_undef(llty);
-            let imm_a = base::from_immediate(bx, a);
-            let imm_b = base::from_immediate(bx, b);
+            let imm_a = bx.from_immediate(a);
+            let imm_b = bx.from_immediate(b);
             llpair = bx.insert_value(llpair, imm_a, 0);
             llpair = bx.insert_value(llpair, imm_b, 1);
             llpair
@@ -168,9 +168,9 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
 
             // Deconstruct the immediate aggregate.
             let a_llval = bx.extract_value(llval, 0);
-            let a_llval = base::to_immediate_scalar(bx, a_llval, a);
+            let a_llval = bx.to_immediate_scalar(a_llval, a);
             let b_llval = bx.extract_value(llval, 1);
-            let b_llval = base::to_immediate_scalar(bx, b_llval, b);
+            let b_llval = bx.to_immediate_scalar(b_llval, b);
             OperandValue::Pair(a_llval, b_llval)
         } else {
             OperandValue::Immediate(llval)
@@ -220,29 +220,23 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
             _ => bug!("OperandRef::extract_field({:?}): not applicable", self),
         };
 
-        // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
-        // Bools in union fields needs to be truncated.
-        let to_immediate_or_cast = |bx: &mut Bx, val, ty| {
-            if ty == bx.cx().type_i1() { bx.trunc(val, ty) } else { bx.bitcast(val, ty) }
-        };
-
-        match val {
-            OperandValue::Immediate(ref mut llval) => {
-                *llval = to_immediate_or_cast(bx, *llval, bx.cx().immediate_backend_type(field));
+        match (&mut val, &field.abi) {
+            (OperandValue::Immediate(llval), _) => {
+                // Bools in union fields needs to be truncated.
+                *llval = bx.to_immediate(*llval, field);
+                // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
+                *llval = bx.bitcast(*llval, bx.cx().immediate_backend_type(field));
             }
-            OperandValue::Pair(ref mut a, ref mut b) => {
-                *a = to_immediate_or_cast(
-                    bx,
-                    *a,
-                    bx.cx().scalar_pair_element_backend_type(field, 0, true),
-                );
-                *b = to_immediate_or_cast(
-                    bx,
-                    *b,
-                    bx.cx().scalar_pair_element_backend_type(field, 1, true),
-                );
+            (OperandValue::Pair(a, b), Abi::ScalarPair(a_abi, b_abi)) => {
+                // Bools in union fields needs to be truncated.
+                *a = bx.to_immediate_scalar(*a, a_abi);
+                *b = bx.to_immediate_scalar(*b, b_abi);
+                // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
+                *a = bx.bitcast(*a, bx.cx().scalar_pair_element_backend_type(field, 0, true));
+                *b = bx.bitcast(*b, bx.cx().scalar_pair_element_backend_type(field, 1, true));
             }
-            OperandValue::Ref(..) => bug!(),
+            (OperandValue::Pair(..), _) => bug!(),
+            (OperandValue::Ref(..), _) => bug!(),
         }
 
         OperandRef { val, layout: field }
@@ -302,7 +296,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
                 bug!("cannot directly store unsized values");
             }
             OperandValue::Immediate(s) => {
-                let val = base::from_immediate(bx, s);
+                let val = bx.from_immediate(s);
                 bx.store_with_flags(val, dest.llval, dest.align, flags);
             }
             OperandValue::Pair(a, b) => {
@@ -313,12 +307,12 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
                 let b_offset = a_scalar.value.size(bx).align_to(b_scalar.value.align(bx).abi);
 
                 let llptr = bx.struct_gep(dest.llval, 0);
-                let val = base::from_immediate(bx, a);
+                let val = bx.from_immediate(a);
                 let align = dest.align;
                 bx.store_with_flags(val, llptr, align, flags);
 
                 let llptr = bx.struct_gep(dest.llval, 1);
-                let val = base::from_immediate(bx, b);
+                let val = bx.from_immediate(b);
                 let align = dest.align.restrict_for_offset(b_offset);
                 bx.store_with_flags(val, llptr, align, flags);
             }
diff --git a/src/librustc_codegen_ssa/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index 05656774f0e..05656774f0e 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 71f924df119..c64fc9bfcf0 100644
--- a/src/librustc_codegen_ssa/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -98,7 +98,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     }
 
                     // Use llvm.memset.p0i8.* to initialize byte arrays
-                    let v = base::from_immediate(&mut bx, v);
+                    let v = bx.from_immediate(v);
                     if bx.cx().val_ty(v) == bx.cx().type_i8() {
                         bx.memset(start, v, size, dest.align, MemFlags::empty());
                         return bx;
@@ -327,13 +327,29 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                                 if er.end != er.start
                                     && scalar.valid_range.end() > scalar.valid_range.start()
                                 {
-                                    // We want `table[e as usize]` to not
+                                    // We want `table[e as usize ± k]` to not
                                     // have bound checks, and this is the most
-                                    // convenient place to put the `assume`.
-                                    let ll_t_in_const =
+                                    // convenient place to put the `assume`s.
+                                    if *scalar.valid_range.start() > 0 {
+                                        let enum_value_lower_bound = bx
+                                            .cx()
+                                            .const_uint_big(ll_t_in, *scalar.valid_range.start());
+                                        let cmp_start = bx.icmp(
+                                            IntPredicate::IntUGE,
+                                            llval,
+                                            enum_value_lower_bound,
+                                        );
+                                        bx.assume(cmp_start);
+                                    }
+
+                                    let enum_value_upper_bound =
                                         bx.cx().const_uint_big(ll_t_in, *scalar.valid_range.end());
-                                    let cmp = bx.icmp(IntPredicate::IntULE, llval, ll_t_in_const);
-                                    bx.assume(cmp);
+                                    let cmp_end = bx.icmp(
+                                        IntPredicate::IntULE,
+                                        llval,
+                                        enum_value_upper_bound,
+                                    );
+                                    bx.assume(cmp_end);
                                 }
                             }
                         }
diff --git a/src/librustc_codegen_ssa/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs
index 6f74ba77d4c..6f74ba77d4c 100644
--- a/src/librustc_codegen_ssa/mir/statement.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs
diff --git a/src/librustc_codegen_ssa/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs
index fc65149937f..607b5459673 100644
--- a/src/librustc_codegen_ssa/mono_item.rs
+++ b/compiler/rustc_codegen_ssa/src/mono_item.rs
@@ -21,7 +21,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
     fn define<Bx: BuilderMethods<'a, 'tcx>>(&self, cx: &'a Bx::CodegenCx) {
         debug!(
             "BEGIN IMPLEMENTING '{} ({})' in cgu {}",
-            self.to_string(cx.tcx(), true),
+            self,
             self.to_raw_string(),
             cx.codegen_unit().name()
         );
@@ -45,7 +45,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
 
         debug!(
             "END IMPLEMENTING '{} ({})' in cgu {}",
-            self.to_string(cx.tcx(), true),
+            self,
             self.to_raw_string(),
             cx.codegen_unit().name()
         );
@@ -59,7 +59,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
     ) {
         debug!(
             "BEGIN PREDEFINING '{} ({})' in cgu {}",
-            self.to_string(cx.tcx(), true),
+            self,
             self.to_raw_string(),
             cx.codegen_unit().name()
         );
@@ -80,7 +80,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
 
         debug!(
             "END PREDEFINING '{} ({})' in cgu {}",
-            self.to_string(cx.tcx(), true),
+            self,
             self.to_raw_string(),
             cx.codegen_unit().name()
         );
diff --git a/src/librustc_codegen_ssa/traits/abi.rs b/compiler/rustc_codegen_ssa/src/traits/abi.rs
index dd8495850bd..dd8495850bd 100644
--- a/src/librustc_codegen_ssa/traits/abi.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/abi.rs
diff --git a/src/librustc_codegen_ssa/traits/asm.rs b/compiler/rustc_codegen_ssa/src/traits/asm.rs
index 69931935c49..69931935c49 100644
--- a/src/librustc_codegen_ssa/traits/asm.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/asm.rs
diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs
index 3522ea01153..3522ea01153 100644
--- a/src/librustc_codegen_ssa/traits/backend.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs
diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs
index 5ffc83c5f99..5142922260a 100644
--- a/src/librustc_codegen_ssa/traits/builder.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs
@@ -13,9 +13,9 @@ use crate::mir::operand::OperandRef;
 use crate::mir::place::PlaceRef;
 use crate::MemFlags;
 
-use rustc_middle::ty::layout::HasParamEnv;
+use rustc_middle::ty::layout::{HasParamEnv, TyAndLayout};
 use rustc_middle::ty::Ty;
-use rustc_target::abi::{Align, Size};
+use rustc_target::abi::{Abi, Align, Scalar, Size};
 use rustc_target::spec::HasTargetSpec;
 
 use std::iter::TrustedLen;
@@ -115,6 +115,16 @@ pub trait BuilderMethods<'a, 'tcx>:
         rhs: Self::Value,
     ) -> (Self::Value, Self::Value);
 
+    fn from_immediate(&mut self, val: Self::Value) -> Self::Value;
+    fn to_immediate(&mut self, val: Self::Value, layout: TyAndLayout<'_>) -> Self::Value {
+        if let Abi::Scalar(ref scalar) = layout.abi {
+            self.to_immediate_scalar(val, scalar)
+        } else {
+            val
+        }
+    }
+    fn to_immediate_scalar(&mut self, val: Self::Value, scalar: &Scalar) -> Self::Value;
+
     fn alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value;
     fn dynamic_alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value;
     fn array_alloca(&mut self, ty: Self::Type, len: Self::Value, align: Align) -> Self::Value;
diff --git a/src/librustc_codegen_ssa/traits/consts.rs b/compiler/rustc_codegen_ssa/src/traits/consts.rs
index 6b58dea794b..6b58dea794b 100644
--- a/src/librustc_codegen_ssa/traits/consts.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/consts.rs
diff --git a/src/librustc_codegen_ssa/traits/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs
index b74e4e45901..b74e4e45901 100644
--- a/src/librustc_codegen_ssa/traits/coverageinfo.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs
diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
index 1ee0f489ffc..1ee0f489ffc 100644
--- a/src/librustc_codegen_ssa/traits/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
diff --git a/src/librustc_codegen_ssa/traits/declare.rs b/compiler/rustc_codegen_ssa/src/traits/declare.rs
index 690aacd2056..690aacd2056 100644
--- a/src/librustc_codegen_ssa/traits/declare.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/declare.rs
diff --git a/src/librustc_codegen_ssa/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
index 9d48e233de6..9d48e233de6 100644
--- a/src/librustc_codegen_ssa/traits/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
diff --git a/src/librustc_codegen_ssa/traits/misc.rs b/compiler/rustc_codegen_ssa/src/traits/misc.rs
index fc57a9a80b2..fc57a9a80b2 100644
--- a/src/librustc_codegen_ssa/traits/misc.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/misc.rs
diff --git a/src/librustc_codegen_ssa/traits/mod.rs b/compiler/rustc_codegen_ssa/src/traits/mod.rs
index 0ac519dd0b1..0ac519dd0b1 100644
--- a/src/librustc_codegen_ssa/traits/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/mod.rs
diff --git a/src/librustc_codegen_ssa/traits/statics.rs b/compiler/rustc_codegen_ssa/src/traits/statics.rs
index 817fc02d166..817fc02d166 100644
--- a/src/librustc_codegen_ssa/traits/statics.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/statics.rs
diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs
index 726d948cfd4..726d948cfd4 100644
--- a/src/librustc_codegen_ssa/traits/type_.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs
diff --git a/src/librustc_codegen_ssa/traits/write.rs b/compiler/rustc_codegen_ssa/src/traits/write.rs
index 27d52e9b9c5..27d52e9b9c5 100644
--- a/src/librustc_codegen_ssa/traits/write.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/write.rs
diff --git a/src/librustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml
index 988bb733f9f..fcae9b936ed 100644
--- a/src/librustc_data_structures/Cargo.toml
+++ b/compiler/rustc_data_structures/Cargo.toml
@@ -5,8 +5,6 @@ version = "0.0.0"
 edition = "2018"
 
 [lib]
-name = "rustc_data_structures"
-path = "lib.rs"
 doctest = false
 
 [dependencies]
@@ -14,11 +12,9 @@ ena = "0.14"
 indexmap = "1.5.1"
 tracing = "0.1"
 jobserver_crate = { version = "0.1.13", package = "jobserver" }
-lazy_static = "1"
-once_cell = { version = "1", features = ["parking_lot"] }
-rustc_serialize = { path = "../librustc_serialize" }
-rustc_macros = { path = "../librustc_macros" }
-rustc_graphviz = { path = "../librustc_graphviz" }
+rustc_serialize = { path = "../rustc_serialize" }
+rustc_macros = { path = "../rustc_macros" }
+rustc_graphviz = { path = "../rustc_graphviz" }
 cfg-if = "0.1.2"
 crossbeam-utils = { version = "0.7", features = ["nightly"] }
 stable_deref_trait = "1.0.0"
@@ -26,7 +22,7 @@ rayon = { version = "0.3.0", package = "rustc-rayon" }
 rayon-core = { version = "0.3.0", package = "rustc-rayon-core" }
 rustc-hash = "1.1.0"
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
-rustc_index = { path = "../librustc_index", package = "rustc_index" }
+rustc_index = { path = "../rustc_index", package = "rustc_index" }
 bitflags = "1.2.1"
 measureme = "0.7.1"
 libc = "0.2"
diff --git a/src/librustc_data_structures/atomic_ref.rs b/compiler/rustc_data_structures/src/atomic_ref.rs
index eeb1b309257..eeb1b309257 100644
--- a/src/librustc_data_structures/atomic_ref.rs
+++ b/compiler/rustc_data_structures/src/atomic_ref.rs
diff --git a/src/librustc_data_structures/base_n.rs b/compiler/rustc_data_structures/src/base_n.rs
index 3c7bea27124..3c7bea27124 100644
--- a/src/librustc_data_structures/base_n.rs
+++ b/compiler/rustc_data_structures/src/base_n.rs
diff --git a/src/librustc_data_structures/base_n/tests.rs b/compiler/rustc_data_structures/src/base_n/tests.rs
index b68ef1eb7f4..b68ef1eb7f4 100644
--- a/src/librustc_data_structures/base_n/tests.rs
+++ b/compiler/rustc_data_structures/src/base_n/tests.rs
diff --git a/src/librustc_data_structures/binary_search_util/mod.rs b/compiler/rustc_data_structures/src/binary_search_util/mod.rs
index ede5757a479..ede5757a479 100644
--- a/src/librustc_data_structures/binary_search_util/mod.rs
+++ b/compiler/rustc_data_structures/src/binary_search_util/mod.rs
diff --git a/src/librustc_data_structures/binary_search_util/tests.rs b/compiler/rustc_data_structures/src/binary_search_util/tests.rs
index d74febb5c0f..d74febb5c0f 100644
--- a/src/librustc_data_structures/binary_search_util/tests.rs
+++ b/compiler/rustc_data_structures/src/binary_search_util/tests.rs
diff --git a/src/librustc_data_structures/box_region.rs b/compiler/rustc_data_structures/src/box_region.rs
index eb6f4e8213e..eb6f4e8213e 100644
--- a/src/librustc_data_structures/box_region.rs
+++ b/compiler/rustc_data_structures/src/box_region.rs
diff --git a/src/librustc_data_structures/captures.rs b/compiler/rustc_data_structures/src/captures.rs
index 26b90ebfd5f..26b90ebfd5f 100644
--- a/src/librustc_data_structures/captures.rs
+++ b/compiler/rustc_data_structures/src/captures.rs
diff --git a/src/librustc_data_structures/const_cstr.rs b/compiler/rustc_data_structures/src/const_cstr.rs
index 1ebcb87818e..1ebcb87818e 100644
--- a/src/librustc_data_structures/const_cstr.rs
+++ b/compiler/rustc_data_structures/src/const_cstr.rs
diff --git a/src/librustc_data_structures/fingerprint.rs b/compiler/rustc_data_structures/src/fingerprint.rs
index f8d631ce01e..aba0bbbac80 100644
--- a/src/librustc_data_structures/fingerprint.rs
+++ b/compiler/rustc_data_structures/src/fingerprint.rs
@@ -3,9 +3,10 @@ use rustc_serialize::{
     opaque::{self, EncodeResult},
     Decodable, Encodable,
 };
+use std::hash::{Hash, Hasher};
 use std::mem;
 
-#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)]
+#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy)]
 pub struct Fingerprint(u64, u64);
 
 impl Fingerprint {
@@ -76,6 +77,33 @@ impl ::std::fmt::Display for Fingerprint {
     }
 }
 
+impl Hash for Fingerprint {
+    #[inline]
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        state.write_fingerprint(self);
+    }
+}
+
+trait FingerprintHasher {
+    fn write_fingerprint(&mut self, fingerprint: &Fingerprint);
+}
+
+impl<H: Hasher> FingerprintHasher for H {
+    #[inline]
+    default fn write_fingerprint(&mut self, fingerprint: &Fingerprint) {
+        self.write_u64(fingerprint.0);
+        self.write_u64(fingerprint.1);
+    }
+}
+
+impl FingerprintHasher for crate::unhash::Unhasher {
+    #[inline]
+    fn write_fingerprint(&mut self, fingerprint: &Fingerprint) {
+        // `Unhasher` only wants a single `u64`
+        self.write_u64(fingerprint.0);
+    }
+}
+
 impl stable_hasher::StableHasherResult for Fingerprint {
     #[inline]
     fn finish(hasher: stable_hasher::StableHasher) -> Self {
diff --git a/src/librustc_data_structures/flock.rs b/compiler/rustc_data_structures/src/flock.rs
index 9383be474fd..9383be474fd 100644
--- a/src/librustc_data_structures/flock.rs
+++ b/compiler/rustc_data_structures/src/flock.rs
diff --git a/src/librustc_data_structures/frozen.rs b/compiler/rustc_data_structures/src/frozen.rs
index 2daf5b04141..2daf5b04141 100644
--- a/src/librustc_data_structures/frozen.rs
+++ b/compiler/rustc_data_structures/src/frozen.rs
diff --git a/src/librustc_data_structures/fx.rs b/compiler/rustc_data_structures/src/fx.rs
index bbeb193dba3..bbeb193dba3 100644
--- a/src/librustc_data_structures/fx.rs
+++ b/compiler/rustc_data_structures/src/fx.rs
diff --git a/src/librustc_data_structures/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs
index 438a0d0c6ff..438a0d0c6ff 100644
--- a/src/librustc_data_structures/graph/dominators/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs
diff --git a/src/librustc_data_structures/graph/dominators/tests.rs b/compiler/rustc_data_structures/src/graph/dominators/tests.rs
index 1160df5186b..1160df5186b 100644
--- a/src/librustc_data_structures/graph/dominators/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/dominators/tests.rs
diff --git a/src/librustc_data_structures/graph/implementation/mod.rs b/compiler/rustc_data_structures/src/graph/implementation/mod.rs
index 1aa7ac024d9..1aa7ac024d9 100644
--- a/src/librustc_data_structures/graph/implementation/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/implementation/mod.rs
diff --git a/src/librustc_data_structures/graph/implementation/tests.rs b/compiler/rustc_data_structures/src/graph/implementation/tests.rs
index e4e4d0d44ba..e4e4d0d44ba 100644
--- a/src/librustc_data_structures/graph/implementation/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/implementation/tests.rs
diff --git a/src/librustc_data_structures/graph/iterate/mod.rs b/compiler/rustc_data_structures/src/graph/iterate/mod.rs
index 64ff6130ddf..64ff6130ddf 100644
--- a/src/librustc_data_structures/graph/iterate/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/iterate/mod.rs
diff --git a/src/librustc_data_structures/graph/iterate/tests.rs b/compiler/rustc_data_structures/src/graph/iterate/tests.rs
index 0e038e88b22..0e038e88b22 100644
--- a/src/librustc_data_structures/graph/iterate/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/iterate/tests.rs
diff --git a/src/librustc_data_structures/graph/mod.rs b/compiler/rustc_data_structures/src/graph/mod.rs
index e0903e43241..e0903e43241 100644
--- a/src/librustc_data_structures/graph/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/mod.rs
diff --git a/src/librustc_data_structures/graph/reference.rs b/compiler/rustc_data_structures/src/graph/reference.rs
index c259fe56c15..c259fe56c15 100644
--- a/src/librustc_data_structures/graph/reference.rs
+++ b/compiler/rustc_data_structures/src/graph/reference.rs
diff --git a/src/librustc_data_structures/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs
index 2db8e466e11..2db8e466e11 100644
--- a/src/librustc_data_structures/graph/scc/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs
diff --git a/src/librustc_data_structures/graph/scc/tests.rs b/compiler/rustc_data_structures/src/graph/scc/tests.rs
index 1d5f46ebab1..1d5f46ebab1 100644
--- a/src/librustc_data_structures/graph/scc/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/scc/tests.rs
diff --git a/src/librustc_data_structures/graph/tests.rs b/compiler/rustc_data_structures/src/graph/tests.rs
index 7f4ef906b36..7f4ef906b36 100644
--- a/src/librustc_data_structures/graph/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/tests.rs
diff --git a/src/librustc_data_structures/graph/vec_graph/mod.rs b/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs
index 064467174ca..064467174ca 100644
--- a/src/librustc_data_structures/graph/vec_graph/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs
diff --git a/src/librustc_data_structures/graph/vec_graph/tests.rs b/compiler/rustc_data_structures/src/graph/vec_graph/tests.rs
index c8f97926717..c8f97926717 100644
--- a/src/librustc_data_structures/graph/vec_graph/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/vec_graph/tests.rs
diff --git a/compiler/rustc_data_structures/src/jobserver.rs b/compiler/rustc_data_structures/src/jobserver.rs
new file mode 100644
index 00000000000..41605afb44e
--- /dev/null
+++ b/compiler/rustc_data_structures/src/jobserver.rs
@@ -0,0 +1,40 @@
+pub use jobserver_crate::Client;
+use std::lazy::SyncLazy;
+
+// We can only call `from_env` once per process
+
+// Note that this is unsafe because it may misinterpret file descriptors
+// on Unix as jobserver file descriptors. We hopefully execute this near
+// the beginning of the process though to ensure we don't get false
+// positives, or in other words we try to execute this before we open
+// any file descriptors ourselves.
+//
+// Pick a "reasonable maximum" if we don't otherwise have
+// a jobserver in our environment, capping out at 32 so we
+// don't take everything down by hogging the process run queue.
+// The fixed number is used to have deterministic compilation
+// across machines.
+//
+// Also note that we stick this in a global because there could be
+// multiple rustc instances in this process, and the jobserver is
+// per-process.
+static GLOBAL_CLIENT: SyncLazy<Client> = SyncLazy::new(|| unsafe {
+    Client::from_env().unwrap_or_else(|| {
+        let client = Client::new(32).expect("failed to create jobserver");
+        // Acquire a token for the main thread which we can release later
+        client.acquire_raw().ok();
+        client
+    })
+});
+
+pub fn client() -> Client {
+    GLOBAL_CLIENT.clone()
+}
+
+pub fn acquire_thread() {
+    GLOBAL_CLIENT.acquire_raw().ok();
+}
+
+pub fn release_thread() {
+    GLOBAL_CLIENT.release_raw().ok();
+}
diff --git a/src/librustc_data_structures/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index af4a7bd1881..de4e7a13424 100644
--- a/src/librustc_data_structures/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -26,6 +26,7 @@
 #![feature(extend_one)]
 #![feature(const_panic)]
 #![feature(const_generics)]
+#![feature(once_cell)]
 #![allow(rustc::default_hash_types)]
 
 #[macro_use]
@@ -102,6 +103,7 @@ pub use atomic_ref::AtomicRef;
 pub mod frozen;
 pub mod tagged_ptr;
 pub mod temp_dir;
+pub mod unhash;
 
 pub struct OnDrop<F: Fn()>(pub F);
 
diff --git a/src/librustc_data_structures/macros.rs b/compiler/rustc_data_structures/src/macros.rs
index 67fbe3058cd..67fbe3058cd 100644
--- a/src/librustc_data_structures/macros.rs
+++ b/compiler/rustc_data_structures/src/macros.rs
diff --git a/src/librustc_data_structures/map_in_place.rs b/compiler/rustc_data_structures/src/map_in_place.rs
index 5dd9fc6e8bc..5dd9fc6e8bc 100644
--- a/src/librustc_data_structures/map_in_place.rs
+++ b/compiler/rustc_data_structures/src/map_in_place.rs
diff --git a/src/librustc_data_structures/obligation_forest/graphviz.rs b/compiler/rustc_data_structures/src/obligation_forest/graphviz.rs
index 3a268e4b4f4..3a268e4b4f4 100644
--- a/src/librustc_data_structures/obligation_forest/graphviz.rs
+++ b/compiler/rustc_data_structures/src/obligation_forest/graphviz.rs
diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
index 7cf5202d919..7cf5202d919 100644
--- a/src/librustc_data_structures/obligation_forest/mod.rs
+++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
diff --git a/src/librustc_data_structures/obligation_forest/tests.rs b/compiler/rustc_data_structures/src/obligation_forest/tests.rs
index 01652465eea..01652465eea 100644
--- a/src/librustc_data_structures/obligation_forest/tests.rs
+++ b/compiler/rustc_data_structures/src/obligation_forest/tests.rs
diff --git a/src/librustc_data_structures/owning_ref/LICENSE b/compiler/rustc_data_structures/src/owning_ref/LICENSE
index dff72d1e432..dff72d1e432 100644
--- a/src/librustc_data_structures/owning_ref/LICENSE
+++ b/compiler/rustc_data_structures/src/owning_ref/LICENSE
diff --git a/src/librustc_data_structures/owning_ref/mod.rs b/compiler/rustc_data_structures/src/owning_ref/mod.rs
index ad4b79de236..ad4b79de236 100644
--- a/src/librustc_data_structures/owning_ref/mod.rs
+++ b/compiler/rustc_data_structures/src/owning_ref/mod.rs
diff --git a/src/librustc_data_structures/owning_ref/tests.rs b/compiler/rustc_data_structures/src/owning_ref/tests.rs
index 7b8179e90bd..7b8179e90bd 100644
--- a/src/librustc_data_structures/owning_ref/tests.rs
+++ b/compiler/rustc_data_structures/src/owning_ref/tests.rs
diff --git a/src/librustc_data_structures/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs
index 07d16c6483e..07d16c6483e 100644
--- a/src/librustc_data_structures/profiling.rs
+++ b/compiler/rustc_data_structures/src/profiling.rs
diff --git a/src/librustc_data_structures/ptr_key.rs b/compiler/rustc_data_structures/src/ptr_key.rs
index 440ccb05d86..440ccb05d86 100644
--- a/src/librustc_data_structures/ptr_key.rs
+++ b/compiler/rustc_data_structures/src/ptr_key.rs
diff --git a/src/librustc_data_structures/sharded.rs b/compiler/rustc_data_structures/src/sharded.rs
index 485719c5175..485719c5175 100644
--- a/src/librustc_data_structures/sharded.rs
+++ b/compiler/rustc_data_structures/src/sharded.rs
diff --git a/src/librustc_data_structures/sip128.rs b/compiler/rustc_data_structures/src/sip128.rs
index beb28dd0720..beb28dd0720 100644
--- a/src/librustc_data_structures/sip128.rs
+++ b/compiler/rustc_data_structures/src/sip128.rs
diff --git a/src/librustc_data_structures/sip128/tests.rs b/compiler/rustc_data_structures/src/sip128/tests.rs
index 80b7fc74756..80b7fc74756 100644
--- a/src/librustc_data_structures/sip128/tests.rs
+++ b/compiler/rustc_data_structures/src/sip128/tests.rs
diff --git a/src/librustc_data_structures/small_c_str.rs b/compiler/rustc_data_structures/src/small_c_str.rs
index 4a089398ce6..4a089398ce6 100644
--- a/src/librustc_data_structures/small_c_str.rs
+++ b/compiler/rustc_data_structures/src/small_c_str.rs
diff --git a/src/librustc_data_structures/small_c_str/tests.rs b/compiler/rustc_data_structures/src/small_c_str/tests.rs
index 47277604b2b..47277604b2b 100644
--- a/src/librustc_data_structures/small_c_str/tests.rs
+++ b/compiler/rustc_data_structures/src/small_c_str/tests.rs
diff --git a/src/librustc_data_structures/snapshot_map/mod.rs b/compiler/rustc_data_structures/src/snapshot_map/mod.rs
index b4cc85293f7..b4cc85293f7 100644
--- a/src/librustc_data_structures/snapshot_map/mod.rs
+++ b/compiler/rustc_data_structures/src/snapshot_map/mod.rs
diff --git a/src/librustc_data_structures/snapshot_map/tests.rs b/compiler/rustc_data_structures/src/snapshot_map/tests.rs
index 72ca53c2be9..72ca53c2be9 100644
--- a/src/librustc_data_structures/snapshot_map/tests.rs
+++ b/compiler/rustc_data_structures/src/snapshot_map/tests.rs
diff --git a/src/librustc_data_structures/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs
index 856eb73e629..856eb73e629 100644
--- a/src/librustc_data_structures/sorted_map.rs
+++ b/compiler/rustc_data_structures/src/sorted_map.rs
diff --git a/src/librustc_data_structures/sorted_map/index_map.rs b/compiler/rustc_data_structures/src/sorted_map/index_map.rs
index 2bb421a47ef..2bb421a47ef 100644
--- a/src/librustc_data_structures/sorted_map/index_map.rs
+++ b/compiler/rustc_data_structures/src/sorted_map/index_map.rs
diff --git a/src/librustc_data_structures/sorted_map/tests.rs b/compiler/rustc_data_structures/src/sorted_map/tests.rs
index 7d91e1fdcef..7d91e1fdcef 100644
--- a/src/librustc_data_structures/sorted_map/tests.rs
+++ b/compiler/rustc_data_structures/src/sorted_map/tests.rs
diff --git a/src/librustc_data_structures/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs
index c1c79b174f4..c1c79b174f4 100644
--- a/src/librustc_data_structures/stable_hasher.rs
+++ b/compiler/rustc_data_structures/src/stable_hasher.rs
diff --git a/src/librustc_data_structures/stable_map.rs b/compiler/rustc_data_structures/src/stable_map.rs
index 670452d0d8c..670452d0d8c 100644
--- a/src/librustc_data_structures/stable_map.rs
+++ b/compiler/rustc_data_structures/src/stable_map.rs
diff --git a/src/librustc_data_structures/stable_set.rs b/compiler/rustc_data_structures/src/stable_set.rs
index c7ca74f5fbd..c7ca74f5fbd 100644
--- a/src/librustc_data_structures/stable_set.rs
+++ b/compiler/rustc_data_structures/src/stable_set.rs
diff --git a/src/librustc_data_structures/stack.rs b/compiler/rustc_data_structures/src/stack.rs
index a4964b7aa0c..a4964b7aa0c 100644
--- a/src/librustc_data_structures/stack.rs
+++ b/compiler/rustc_data_structures/src/stack.rs
diff --git a/src/librustc_data_structures/svh.rs b/compiler/rustc_data_structures/src/svh.rs
index 02103de2e8d..02103de2e8d 100644
--- a/src/librustc_data_structures/svh.rs
+++ b/compiler/rustc_data_structures/src/svh.rs
diff --git a/src/librustc_data_structures/sync.rs b/compiler/rustc_data_structures/src/sync.rs
index 53d831749ce..d22f3adfb01 100644
--- a/src/librustc_data_structures/sync.rs
+++ b/compiler/rustc_data_structures/src/sync.rs
@@ -229,7 +229,7 @@ cfg_if! {
         pub use std::cell::RefMut as LockGuard;
         pub use std::cell::RefMut as MappedLockGuard;
 
-        pub use once_cell::unsync::OnceCell;
+        pub use std::lazy::OnceCell;
 
         use std::cell::RefCell as InnerRwLock;
         use std::cell::RefCell as InnerLock;
@@ -314,7 +314,7 @@ cfg_if! {
         pub use parking_lot::MutexGuard as LockGuard;
         pub use parking_lot::MappedMutexGuard as MappedLockGuard;
 
-        pub use once_cell::sync::OnceCell;
+        pub use std::lazy::SyncOnceCell as OnceCell;
 
         pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32, AtomicU64};
 
diff --git a/src/librustc_data_structures/tagged_ptr.rs b/compiler/rustc_data_structures/src/tagged_ptr.rs
index e3839d19365..e3839d19365 100644
--- a/src/librustc_data_structures/tagged_ptr.rs
+++ b/compiler/rustc_data_structures/src/tagged_ptr.rs
diff --git a/src/librustc_data_structures/tagged_ptr/copy.rs b/compiler/rustc_data_structures/src/tagged_ptr/copy.rs
index d39d146db31..d39d146db31 100644
--- a/src/librustc_data_structures/tagged_ptr/copy.rs
+++ b/compiler/rustc_data_structures/src/tagged_ptr/copy.rs
diff --git a/src/librustc_data_structures/tagged_ptr/drop.rs b/compiler/rustc_data_structures/src/tagged_ptr/drop.rs
index 63f64beae5a..63f64beae5a 100644
--- a/src/librustc_data_structures/tagged_ptr/drop.rs
+++ b/compiler/rustc_data_structures/src/tagged_ptr/drop.rs
diff --git a/src/librustc_data_structures/temp_dir.rs b/compiler/rustc_data_structures/src/temp_dir.rs
index 0d9b3e3ca25..0d9b3e3ca25 100644
--- a/src/librustc_data_structures/temp_dir.rs
+++ b/compiler/rustc_data_structures/src/temp_dir.rs
diff --git a/src/librustc_data_structures/thin_vec.rs b/compiler/rustc_data_structures/src/thin_vec.rs
index 4d673fd5cf9..4d673fd5cf9 100644
--- a/src/librustc_data_structures/thin_vec.rs
+++ b/compiler/rustc_data_structures/src/thin_vec.rs
diff --git a/src/librustc_data_structures/tiny_list.rs b/compiler/rustc_data_structures/src/tiny_list.rs
index e94a0c6eb59..e94a0c6eb59 100644
--- a/src/librustc_data_structures/tiny_list.rs
+++ b/compiler/rustc_data_structures/src/tiny_list.rs
diff --git a/src/librustc_data_structures/tiny_list/tests.rs b/compiler/rustc_data_structures/src/tiny_list/tests.rs
index a8ae2bc8727..a8ae2bc8727 100644
--- a/src/librustc_data_structures/tiny_list/tests.rs
+++ b/compiler/rustc_data_structures/src/tiny_list/tests.rs
diff --git a/src/librustc_data_structures/transitive_relation.rs b/compiler/rustc_data_structures/src/transitive_relation.rs
index fe60a99dde0..fe60a99dde0 100644
--- a/src/librustc_data_structures/transitive_relation.rs
+++ b/compiler/rustc_data_structures/src/transitive_relation.rs
diff --git a/src/librustc_data_structures/transitive_relation/tests.rs b/compiler/rustc_data_structures/src/transitive_relation/tests.rs
index ca90ba176ae..ca90ba176ae 100644
--- a/src/librustc_data_structures/transitive_relation/tests.rs
+++ b/compiler/rustc_data_structures/src/transitive_relation/tests.rs
diff --git a/compiler/rustc_data_structures/src/unhash.rs b/compiler/rustc_data_structures/src/unhash.rs
new file mode 100644
index 00000000000..48e21a9dab1
--- /dev/null
+++ b/compiler/rustc_data_structures/src/unhash.rs
@@ -0,0 +1,29 @@
+use std::collections::{HashMap, HashSet};
+use std::hash::{BuildHasherDefault, Hasher};
+
+pub type UnhashMap<K, V> = HashMap<K, V, BuildHasherDefault<Unhasher>>;
+pub type UnhashSet<V> = HashSet<V, BuildHasherDefault<Unhasher>>;
+
+/// This no-op hasher expects only a single `write_u64` call. It's intended for
+/// map keys that already have hash-like quality, like `Fingerprint`.
+#[derive(Default)]
+pub struct Unhasher {
+    value: u64,
+}
+
+impl Hasher for Unhasher {
+    #[inline]
+    fn finish(&self) -> u64 {
+        self.value
+    }
+
+    fn write(&mut self, _bytes: &[u8]) {
+        unimplemented!("use write_u64");
+    }
+
+    #[inline]
+    fn write_u64(&mut self, value: u64) {
+        debug_assert_eq!(0, self.value, "Unhasher doesn't mix values!");
+        self.value = value;
+    }
+}
diff --git a/src/librustc_data_structures/vec_linked_list.rs b/compiler/rustc_data_structures/src/vec_linked_list.rs
index 1cf030d852e..1cf030d852e 100644
--- a/src/librustc_data_structures/vec_linked_list.rs
+++ b/compiler/rustc_data_structures/src/vec_linked_list.rs
diff --git a/src/librustc_data_structures/work_queue.rs b/compiler/rustc_data_structures/src/work_queue.rs
index 0c848eb144d..0c848eb144d 100644
--- a/src/librustc_data_structures/work_queue.rs
+++ b/compiler/rustc_data_structures/src/work_queue.rs
diff --git a/compiler/rustc_driver/Cargo.toml b/compiler/rustc_driver/Cargo.toml
new file mode 100644
index 00000000000..0d9dcb262b2
--- /dev/null
+++ b/compiler/rustc_driver/Cargo.toml
@@ -0,0 +1,40 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_driver"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+crate-type = ["dylib"]
+
+[dependencies]
+libc = "0.2"
+tracing = { version = "0.1.18", features = ["release_max_level_info"]  }
+tracing-subscriber = { version = "0.2.10", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
+rustc_middle = { path = "../rustc_middle" }
+rustc_ast_pretty = { path = "../rustc_ast_pretty" }
+rustc_target = { path = "../rustc_target" }
+rustc_lint = { path = "../rustc_lint" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_feature = { path = "../rustc_feature" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_hir_pretty = { path = "../rustc_hir_pretty" }
+rustc_metadata = { path = "../rustc_metadata" }
+rustc_mir = { path = "../rustc_mir" }
+rustc_parse = { path = "../rustc_parse" }
+rustc_plugin_impl = { path = "../rustc_plugin_impl" }
+rustc_save_analysis = { path = "../rustc_save_analysis" }
+rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
+rustc_session = { path = "../rustc_session" }
+rustc_error_codes = { path = "../rustc_error_codes" }
+rustc_interface = { path = "../rustc_interface" }
+rustc_serialize = { path = "../rustc_serialize" }
+rustc_ast = { path = "../rustc_ast" }
+rustc_span = { path = "../rustc_span" }
+
+[target.'cfg(windows)'.dependencies]
+winapi = { version = "0.3", features = ["consoleapi", "debugapi", "processenv"] }
+
+[features]
+llvm = ['rustc_interface/llvm']
diff --git a/src/librustc_driver/README.md b/compiler/rustc_driver/README.md
index 37dc7f6ba5f..37dc7f6ba5f 100644
--- a/src/librustc_driver/README.md
+++ b/compiler/rustc_driver/README.md
diff --git a/src/librustc_driver/args.rs b/compiler/rustc_driver/src/args.rs
index 5686819c61b..5686819c61b 100644
--- a/src/librustc_driver/args.rs
+++ b/compiler/rustc_driver/src/args.rs
diff --git a/src/librustc_driver/lib.rs b/compiler/rustc_driver/src/lib.rs
index 09f5b22cc63..c277e314d0e 100644
--- a/src/librustc_driver/lib.rs
+++ b/compiler/rustc_driver/src/lib.rs
@@ -6,12 +6,11 @@
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
 #![feature(nll)]
+#![feature(once_cell)]
 #![recursion_limit = "256"]
 
 #[macro_use]
 extern crate tracing;
-#[macro_use]
-extern crate lazy_static;
 
 pub extern crate rustc_plugin_impl as plugin;
 
@@ -48,6 +47,7 @@ use std::env;
 use std::ffi::OsString;
 use std::fs;
 use std::io::{self, Read, Write};
+use std::lazy::SyncLazy;
 use std::mem;
 use std::panic::{self, catch_unwind};
 use std::path::PathBuf;
@@ -1141,13 +1141,12 @@ pub fn catch_with_exit_code(f: impl FnOnce() -> interface::Result<()>) -> i32 {
     }
 }
 
-lazy_static! {
-    static ref DEFAULT_HOOK: Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static> = {
+static DEFAULT_HOOK: SyncLazy<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static>> =
+    SyncLazy::new(|| {
         let hook = panic::take_hook();
         panic::set_hook(Box::new(|info| report_ice(info, BUG_REPORT_URL)));
         hook
-    };
-}
+    });
 
 /// Prints the ICE message, including backtrace and query stack.
 ///
@@ -1222,7 +1221,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
 ///
 /// A custom rustc driver can skip calling this to set up a custom ICE hook.
 pub fn install_ice_hook() {
-    lazy_static::initialize(&DEFAULT_HOOK);
+    SyncLazy::force(&DEFAULT_HOOK);
 }
 
 /// This allows tools to enable rust logging without having to magically match rustc's
diff --git a/src/librustc_driver/pretty.rs b/compiler/rustc_driver/src/pretty.rs
index b0fbf1e03f5..b0fbf1e03f5 100644
--- a/src/librustc_driver/pretty.rs
+++ b/compiler/rustc_driver/src/pretty.rs
diff --git a/src/librustc_error_codes/Cargo.toml b/compiler/rustc_error_codes/Cargo.toml
index 5def867ff11..b4c9cd94565 100644
--- a/src/librustc_error_codes/Cargo.toml
+++ b/compiler/rustc_error_codes/Cargo.toml
@@ -3,7 +3,3 @@ authors = ["The Rust Project Developers"]
 name = "rustc_error_codes"
 version = "0.0.0"
 edition = "2018"
-
-[lib]
-name = "rustc_error_codes"
-path = "lib.rs"
diff --git a/src/librustc_error_codes/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index 4e5e77f80c2..789a1fc35a6 100644
--- a/src/librustc_error_codes/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -454,6 +454,7 @@ E0768: include_str!("./error_codes/E0768.md"),
 E0769: include_str!("./error_codes/E0769.md"),
 E0770: include_str!("./error_codes/E0770.md"),
 E0771: include_str!("./error_codes/E0771.md"),
+E0773: include_str!("./error_codes/E0773.md"),
 ;
 //  E0006, // merged with E0005
 //  E0008, // cannot bind by-move into a pattern guard
diff --git a/src/librustc_error_codes/error_codes/E0001.md b/compiler/rustc_error_codes/src/error_codes/E0001.md
index 90756780d15..90756780d15 100644
--- a/src/librustc_error_codes/error_codes/E0001.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0001.md
diff --git a/src/librustc_error_codes/error_codes/E0002.md b/compiler/rustc_error_codes/src/error_codes/E0002.md
index 5cb59da10e0..5cb59da10e0 100644
--- a/src/librustc_error_codes/error_codes/E0002.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0002.md
diff --git a/src/librustc_error_codes/error_codes/E0004.md b/compiler/rustc_error_codes/src/error_codes/E0004.md
index b79ef5fd8cb..b79ef5fd8cb 100644
--- a/src/librustc_error_codes/error_codes/E0004.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0004.md
diff --git a/src/librustc_error_codes/error_codes/E0005.md b/compiler/rustc_error_codes/src/error_codes/E0005.md
index e2e7db5082d..e2e7db5082d 100644
--- a/src/librustc_error_codes/error_codes/E0005.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0005.md
diff --git a/src/librustc_error_codes/error_codes/E0007.md b/compiler/rustc_error_codes/src/error_codes/E0007.md
index 2be7870d5ae..2be7870d5ae 100644
--- a/src/librustc_error_codes/error_codes/E0007.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0007.md
diff --git a/src/librustc_error_codes/error_codes/E0009.md b/compiler/rustc_error_codes/src/error_codes/E0009.md
index aaabba04349..aaabba04349 100644
--- a/src/librustc_error_codes/error_codes/E0009.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0009.md
diff --git a/src/librustc_error_codes/error_codes/E0010.md b/compiler/rustc_error_codes/src/error_codes/E0010.md
index 71c790e102f..71c790e102f 100644
--- a/src/librustc_error_codes/error_codes/E0010.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0010.md
diff --git a/src/librustc_error_codes/error_codes/E0013.md b/compiler/rustc_error_codes/src/error_codes/E0013.md
index 8de177590ec..8de177590ec 100644
--- a/src/librustc_error_codes/error_codes/E0013.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0013.md
diff --git a/src/librustc_error_codes/error_codes/E0014.md b/compiler/rustc_error_codes/src/error_codes/E0014.md
index 2c69957e9f6..2c69957e9f6 100644
--- a/src/librustc_error_codes/error_codes/E0014.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0014.md
diff --git a/src/librustc_error_codes/error_codes/E0015.md b/compiler/rustc_error_codes/src/error_codes/E0015.md
index 021a0219d13..021a0219d13 100644
--- a/src/librustc_error_codes/error_codes/E0015.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0015.md
diff --git a/src/librustc_error_codes/error_codes/E0019.md b/compiler/rustc_error_codes/src/error_codes/E0019.md
index 7832468a539..7832468a539 100644
--- a/src/librustc_error_codes/error_codes/E0019.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0019.md
diff --git a/src/librustc_error_codes/error_codes/E0023.md b/compiler/rustc_error_codes/src/error_codes/E0023.md
index c1d85705da3..c1d85705da3 100644
--- a/src/librustc_error_codes/error_codes/E0023.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0023.md
diff --git a/src/librustc_error_codes/error_codes/E0025.md b/compiler/rustc_error_codes/src/error_codes/E0025.md
index a85dc8c1978..a85dc8c1978 100644
--- a/src/librustc_error_codes/error_codes/E0025.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0025.md
diff --git a/src/librustc_error_codes/error_codes/E0026.md b/compiler/rustc_error_codes/src/error_codes/E0026.md
index 72c575aabb6..72c575aabb6 100644
--- a/src/librustc_error_codes/error_codes/E0026.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0026.md
diff --git a/src/librustc_error_codes/error_codes/E0027.md b/compiler/rustc_error_codes/src/error_codes/E0027.md
index a8b1340ca0c..a8b1340ca0c 100644
--- a/src/librustc_error_codes/error_codes/E0027.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0027.md
diff --git a/src/librustc_error_codes/error_codes/E0029.md b/compiler/rustc_error_codes/src/error_codes/E0029.md
index d12d85b9b4c..d12d85b9b4c 100644
--- a/src/librustc_error_codes/error_codes/E0029.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0029.md
diff --git a/src/librustc_error_codes/error_codes/E0030.md b/compiler/rustc_error_codes/src/error_codes/E0030.md
index 67d496da5e4..67d496da5e4 100644
--- a/src/librustc_error_codes/error_codes/E0030.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0030.md
diff --git a/src/librustc_error_codes/error_codes/E0033.md b/compiler/rustc_error_codes/src/error_codes/E0033.md
index 735a2d1f3fe..735a2d1f3fe 100644
--- a/src/librustc_error_codes/error_codes/E0033.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0033.md
diff --git a/src/librustc_error_codes/error_codes/E0034.md b/compiler/rustc_error_codes/src/error_codes/E0034.md
index 2a21f3441c6..2a21f3441c6 100644
--- a/src/librustc_error_codes/error_codes/E0034.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0034.md
diff --git a/src/librustc_error_codes/error_codes/E0038.md b/compiler/rustc_error_codes/src/error_codes/E0038.md
index b2cc2a2273a..b2cc2a2273a 100644
--- a/src/librustc_error_codes/error_codes/E0038.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0038.md
diff --git a/src/librustc_error_codes/error_codes/E0040.md b/compiler/rustc_error_codes/src/error_codes/E0040.md
index 1373f8340d8..1373f8340d8 100644
--- a/src/librustc_error_codes/error_codes/E0040.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0040.md
diff --git a/src/librustc_error_codes/error_codes/E0044.md b/compiler/rustc_error_codes/src/error_codes/E0044.md
index 635ff953290..635ff953290 100644
--- a/src/librustc_error_codes/error_codes/E0044.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0044.md
diff --git a/src/librustc_error_codes/error_codes/E0045.md b/compiler/rustc_error_codes/src/error_codes/E0045.md
index 143c693bf7c..143c693bf7c 100644
--- a/src/librustc_error_codes/error_codes/E0045.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0045.md
diff --git a/src/librustc_error_codes/error_codes/E0046.md b/compiler/rustc_error_codes/src/error_codes/E0046.md
index d8f95330c36..d8f95330c36 100644
--- a/src/librustc_error_codes/error_codes/E0046.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0046.md
diff --git a/src/librustc_error_codes/error_codes/E0049.md b/compiler/rustc_error_codes/src/error_codes/E0049.md
index a2034a3428b..a2034a3428b 100644
--- a/src/librustc_error_codes/error_codes/E0049.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0049.md
diff --git a/src/librustc_error_codes/error_codes/E0050.md b/compiler/rustc_error_codes/src/error_codes/E0050.md
index 7b84c480073..7b84c480073 100644
--- a/src/librustc_error_codes/error_codes/E0050.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0050.md
diff --git a/src/librustc_error_codes/error_codes/E0053.md b/compiler/rustc_error_codes/src/error_codes/E0053.md
index cb2a8638a29..cb2a8638a29 100644
--- a/src/librustc_error_codes/error_codes/E0053.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0053.md
diff --git a/src/librustc_error_codes/error_codes/E0054.md b/compiler/rustc_error_codes/src/error_codes/E0054.md
index c3eb375fbcc..c3eb375fbcc 100644
--- a/src/librustc_error_codes/error_codes/E0054.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0054.md
diff --git a/src/librustc_error_codes/error_codes/E0055.md b/compiler/rustc_error_codes/src/error_codes/E0055.md
index 223ba400029..223ba400029 100644
--- a/src/librustc_error_codes/error_codes/E0055.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0055.md
diff --git a/src/librustc_error_codes/error_codes/E0057.md b/compiler/rustc_error_codes/src/error_codes/E0057.md
index bb5e4b48d2d..bb5e4b48d2d 100644
--- a/src/librustc_error_codes/error_codes/E0057.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0057.md
diff --git a/src/librustc_error_codes/error_codes/E0059.md b/compiler/rustc_error_codes/src/error_codes/E0059.md
index b22edead25e..b22edead25e 100644
--- a/src/librustc_error_codes/error_codes/E0059.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0059.md
diff --git a/src/librustc_error_codes/error_codes/E0060.md b/compiler/rustc_error_codes/src/error_codes/E0060.md
index e6906d72367..e6906d72367 100644
--- a/src/librustc_error_codes/error_codes/E0060.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0060.md
diff --git a/src/librustc_error_codes/error_codes/E0061.md b/compiler/rustc_error_codes/src/error_codes/E0061.md
index 143251c13b0..143251c13b0 100644
--- a/src/librustc_error_codes/error_codes/E0061.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0061.md
diff --git a/src/librustc_error_codes/error_codes/E0062.md b/compiler/rustc_error_codes/src/error_codes/E0062.md
index 64fc027b885..64fc027b885 100644
--- a/src/librustc_error_codes/error_codes/E0062.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0062.md
diff --git a/src/librustc_error_codes/error_codes/E0063.md b/compiler/rustc_error_codes/src/error_codes/E0063.md
index 0e611deac42..0e611deac42 100644
--- a/src/librustc_error_codes/error_codes/E0063.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0063.md
diff --git a/src/librustc_error_codes/error_codes/E0067.md b/compiler/rustc_error_codes/src/error_codes/E0067.md
index 11041bb53ee..11041bb53ee 100644
--- a/src/librustc_error_codes/error_codes/E0067.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0067.md
diff --git a/src/librustc_error_codes/error_codes/E0069.md b/compiler/rustc_error_codes/src/error_codes/E0069.md
index 7367a5c0922..7367a5c0922 100644
--- a/src/librustc_error_codes/error_codes/E0069.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0069.md
diff --git a/src/librustc_error_codes/error_codes/E0070.md b/compiler/rustc_error_codes/src/error_codes/E0070.md
index 97522af3da8..97522af3da8 100644
--- a/src/librustc_error_codes/error_codes/E0070.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0070.md
diff --git a/src/librustc_error_codes/error_codes/E0071.md b/compiler/rustc_error_codes/src/error_codes/E0071.md
index bc2c03a0220..bc2c03a0220 100644
--- a/src/librustc_error_codes/error_codes/E0071.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0071.md
diff --git a/src/librustc_error_codes/error_codes/E0072.md b/compiler/rustc_error_codes/src/error_codes/E0072.md
index 8f7749abab1..8f7749abab1 100644
--- a/src/librustc_error_codes/error_codes/E0072.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0072.md
diff --git a/src/librustc_error_codes/error_codes/E0073.md b/compiler/rustc_error_codes/src/error_codes/E0073.md
index a5aea86ff2d..a5aea86ff2d 100644
--- a/src/librustc_error_codes/error_codes/E0073.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0073.md
diff --git a/src/librustc_error_codes/error_codes/E0074.md b/compiler/rustc_error_codes/src/error_codes/E0074.md
index e25dec7681b..e25dec7681b 100644
--- a/src/librustc_error_codes/error_codes/E0074.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0074.md
diff --git a/src/librustc_error_codes/error_codes/E0075.md b/compiler/rustc_error_codes/src/error_codes/E0075.md
index 969c1ee7131..969c1ee7131 100644
--- a/src/librustc_error_codes/error_codes/E0075.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0075.md
diff --git a/src/librustc_error_codes/error_codes/E0076.md b/compiler/rustc_error_codes/src/error_codes/E0076.md
index f293a2a5772..f293a2a5772 100644
--- a/src/librustc_error_codes/error_codes/E0076.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0076.md
diff --git a/src/librustc_error_codes/error_codes/E0077.md b/compiler/rustc_error_codes/src/error_codes/E0077.md
index b14513c6ccf..b14513c6ccf 100644
--- a/src/librustc_error_codes/error_codes/E0077.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0077.md
diff --git a/src/librustc_error_codes/error_codes/E0080.md b/compiler/rustc_error_codes/src/error_codes/E0080.md
index 7b1bbde6140..7b1bbde6140 100644
--- a/src/librustc_error_codes/error_codes/E0080.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0080.md
diff --git a/src/librustc_error_codes/error_codes/E0081.md b/compiler/rustc_error_codes/src/error_codes/E0081.md
index b834a734cef..b834a734cef 100644
--- a/src/librustc_error_codes/error_codes/E0081.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0081.md
diff --git a/src/librustc_error_codes/error_codes/E0084.md b/compiler/rustc_error_codes/src/error_codes/E0084.md
index 38ce9b43d0a..38ce9b43d0a 100644
--- a/src/librustc_error_codes/error_codes/E0084.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0084.md
diff --git a/src/librustc_error_codes/error_codes/E0087.md b/compiler/rustc_error_codes/src/error_codes/E0087.md
index 9d292186f0f..9d292186f0f 100644
--- a/src/librustc_error_codes/error_codes/E0087.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0087.md
diff --git a/src/librustc_error_codes/error_codes/E0088.md b/compiler/rustc_error_codes/src/error_codes/E0088.md
index 7780ad5b56e..7780ad5b56e 100644
--- a/src/librustc_error_codes/error_codes/E0088.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0088.md
diff --git a/src/librustc_error_codes/error_codes/E0089.md b/compiler/rustc_error_codes/src/error_codes/E0089.md
index 504fbc7b96a..504fbc7b96a 100644
--- a/src/librustc_error_codes/error_codes/E0089.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0089.md
diff --git a/src/librustc_error_codes/error_codes/E0090.md b/compiler/rustc_error_codes/src/error_codes/E0090.md
index e091bb6c9f2..e091bb6c9f2 100644
--- a/src/librustc_error_codes/error_codes/E0090.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0090.md
diff --git a/src/librustc_error_codes/error_codes/E0091.md b/compiler/rustc_error_codes/src/error_codes/E0091.md
index 03cb3280371..03cb3280371 100644
--- a/src/librustc_error_codes/error_codes/E0091.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0091.md
diff --git a/src/librustc_error_codes/error_codes/E0092.md b/compiler/rustc_error_codes/src/error_codes/E0092.md
index e289534bf7a..e289534bf7a 100644
--- a/src/librustc_error_codes/error_codes/E0092.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0092.md
diff --git a/src/librustc_error_codes/error_codes/E0093.md b/compiler/rustc_error_codes/src/error_codes/E0093.md
index 8e7de1a9d37..8e7de1a9d37 100644
--- a/src/librustc_error_codes/error_codes/E0093.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0093.md
diff --git a/src/librustc_error_codes/error_codes/E0094.md b/compiler/rustc_error_codes/src/error_codes/E0094.md
index 42baa65bf9f..42baa65bf9f 100644
--- a/src/librustc_error_codes/error_codes/E0094.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0094.md
diff --git a/src/librustc_error_codes/error_codes/E0106.md b/compiler/rustc_error_codes/src/error_codes/E0106.md
index 60ca1ddc283..60ca1ddc283 100644
--- a/src/librustc_error_codes/error_codes/E0106.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0106.md
diff --git a/src/librustc_error_codes/error_codes/E0107.md b/compiler/rustc_error_codes/src/error_codes/E0107.md
index 4d22b17fe10..4d22b17fe10 100644
--- a/src/librustc_error_codes/error_codes/E0107.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0107.md
diff --git a/src/librustc_error_codes/error_codes/E0109.md b/compiler/rustc_error_codes/src/error_codes/E0109.md
index 2eab9725a6f..2eab9725a6f 100644
--- a/src/librustc_error_codes/error_codes/E0109.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0109.md
diff --git a/src/librustc_error_codes/error_codes/E0110.md b/compiler/rustc_error_codes/src/error_codes/E0110.md
index b9fe406ffb9..b9fe406ffb9 100644
--- a/src/librustc_error_codes/error_codes/E0110.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0110.md
diff --git a/src/librustc_error_codes/error_codes/E0116.md b/compiler/rustc_error_codes/src/error_codes/E0116.md
index ca849c2a128..ca849c2a128 100644
--- a/src/librustc_error_codes/error_codes/E0116.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0116.md
diff --git a/src/librustc_error_codes/error_codes/E0117.md b/compiler/rustc_error_codes/src/error_codes/E0117.md
index 0544667ccca..0544667ccca 100644
--- a/src/librustc_error_codes/error_codes/E0117.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0117.md
diff --git a/src/librustc_error_codes/error_codes/E0118.md b/compiler/rustc_error_codes/src/error_codes/E0118.md
index 5cb5f506e0a..5cb5f506e0a 100644
--- a/src/librustc_error_codes/error_codes/E0118.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0118.md
diff --git a/src/librustc_error_codes/error_codes/E0119.md b/compiler/rustc_error_codes/src/error_codes/E0119.md
index e596349e5e2..e596349e5e2 100644
--- a/src/librustc_error_codes/error_codes/E0119.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0119.md
diff --git a/src/librustc_error_codes/error_codes/E0120.md b/compiler/rustc_error_codes/src/error_codes/E0120.md
index dc7258d8731..dc7258d8731 100644
--- a/src/librustc_error_codes/error_codes/E0120.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0120.md
diff --git a/src/librustc_error_codes/error_codes/E0121.md b/compiler/rustc_error_codes/src/error_codes/E0121.md
index 06fe396d50d..06fe396d50d 100644
--- a/src/librustc_error_codes/error_codes/E0121.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0121.md
diff --git a/src/librustc_error_codes/error_codes/E0124.md b/compiler/rustc_error_codes/src/error_codes/E0124.md
index 8af7cb819cf..8af7cb819cf 100644
--- a/src/librustc_error_codes/error_codes/E0124.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0124.md
diff --git a/src/librustc_error_codes/error_codes/E0128.md b/compiler/rustc_error_codes/src/error_codes/E0128.md
index 6f8dfe3a73b..6f8dfe3a73b 100644
--- a/src/librustc_error_codes/error_codes/E0128.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0128.md
diff --git a/src/librustc_error_codes/error_codes/E0130.md b/compiler/rustc_error_codes/src/error_codes/E0130.md
index a270feaf58c..a270feaf58c 100644
--- a/src/librustc_error_codes/error_codes/E0130.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0130.md
diff --git a/src/librustc_error_codes/error_codes/E0131.md b/compiler/rustc_error_codes/src/error_codes/E0131.md
index ed798d4f881..ed798d4f881 100644
--- a/src/librustc_error_codes/error_codes/E0131.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0131.md
diff --git a/src/librustc_error_codes/error_codes/E0132.md b/compiler/rustc_error_codes/src/error_codes/E0132.md
index a23cc988bdb..a23cc988bdb 100644
--- a/src/librustc_error_codes/error_codes/E0132.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0132.md
diff --git a/src/librustc_error_codes/error_codes/E0133.md b/compiler/rustc_error_codes/src/error_codes/E0133.md
index 1adbcc31356..1adbcc31356 100644
--- a/src/librustc_error_codes/error_codes/E0133.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0133.md
diff --git a/src/librustc_error_codes/error_codes/E0136.md b/compiler/rustc_error_codes/src/error_codes/E0136.md
index b91b52c074c..b91b52c074c 100644
--- a/src/librustc_error_codes/error_codes/E0136.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0136.md
diff --git a/src/librustc_error_codes/error_codes/E0137.md b/compiler/rustc_error_codes/src/error_codes/E0137.md
index 0a02913d236..0a02913d236 100644
--- a/src/librustc_error_codes/error_codes/E0137.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0137.md
diff --git a/src/librustc_error_codes/error_codes/E0138.md b/compiler/rustc_error_codes/src/error_codes/E0138.md
index 3f5eaea9f98..3f5eaea9f98 100644
--- a/src/librustc_error_codes/error_codes/E0138.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0138.md
diff --git a/src/librustc_error_codes/error_codes/E0139.md b/compiler/rustc_error_codes/src/error_codes/E0139.md
index a116cf29395..a116cf29395 100644
--- a/src/librustc_error_codes/error_codes/E0139.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0139.md
diff --git a/src/librustc_error_codes/error_codes/E0152.md b/compiler/rustc_error_codes/src/error_codes/E0152.md
index 120c96b4211..120c96b4211 100644
--- a/src/librustc_error_codes/error_codes/E0152.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0152.md
diff --git a/src/librustc_error_codes/error_codes/E0154.md b/compiler/rustc_error_codes/src/error_codes/E0154.md
index e437a71897c..e437a71897c 100644
--- a/src/librustc_error_codes/error_codes/E0154.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0154.md
diff --git a/src/librustc_error_codes/error_codes/E0158.md b/compiler/rustc_error_codes/src/error_codes/E0158.md
index 0a9ef9c3938..0a9ef9c3938 100644
--- a/src/librustc_error_codes/error_codes/E0158.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0158.md
diff --git a/src/librustc_error_codes/error_codes/E0161.md b/compiler/rustc_error_codes/src/error_codes/E0161.md
index c2e2f0240f4..c2e2f0240f4 100644
--- a/src/librustc_error_codes/error_codes/E0161.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0161.md
diff --git a/src/librustc_error_codes/error_codes/E0162.md b/compiler/rustc_error_codes/src/error_codes/E0162.md
index 98146147f39..98146147f39 100644
--- a/src/librustc_error_codes/error_codes/E0162.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0162.md
diff --git a/src/librustc_error_codes/error_codes/E0164.md b/compiler/rustc_error_codes/src/error_codes/E0164.md
index 48bb6f4b382..48bb6f4b382 100644
--- a/src/librustc_error_codes/error_codes/E0164.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0164.md
diff --git a/src/librustc_error_codes/error_codes/E0165.md b/compiler/rustc_error_codes/src/error_codes/E0165.md
index 92243db4550..92243db4550 100644
--- a/src/librustc_error_codes/error_codes/E0165.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0165.md
diff --git a/src/librustc_error_codes/error_codes/E0170.md b/compiler/rustc_error_codes/src/error_codes/E0170.md
index 9678cd173b7..9678cd173b7 100644
--- a/src/librustc_error_codes/error_codes/E0170.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0170.md
diff --git a/src/librustc_error_codes/error_codes/E0178.md b/compiler/rustc_error_codes/src/error_codes/E0178.md
index 0c6f918632f..0c6f918632f 100644
--- a/src/librustc_error_codes/error_codes/E0178.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0178.md
diff --git a/src/librustc_error_codes/error_codes/E0184.md b/compiler/rustc_error_codes/src/error_codes/E0184.md
index 4624f9e5b85..4624f9e5b85 100644
--- a/src/librustc_error_codes/error_codes/E0184.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0184.md
diff --git a/src/librustc_error_codes/error_codes/E0185.md b/compiler/rustc_error_codes/src/error_codes/E0185.md
index 944a93ed14e..944a93ed14e 100644
--- a/src/librustc_error_codes/error_codes/E0185.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0185.md
diff --git a/src/librustc_error_codes/error_codes/E0186.md b/compiler/rustc_error_codes/src/error_codes/E0186.md
index 7db1e843323..7db1e843323 100644
--- a/src/librustc_error_codes/error_codes/E0186.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0186.md
diff --git a/src/librustc_error_codes/error_codes/E0191.md b/compiler/rustc_error_codes/src/error_codes/E0191.md
index 46b773bdc50..46b773bdc50 100644
--- a/src/librustc_error_codes/error_codes/E0191.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0191.md
diff --git a/src/librustc_error_codes/error_codes/E0192.md b/compiler/rustc_error_codes/src/error_codes/E0192.md
index 5fd951b2e86..5fd951b2e86 100644
--- a/src/librustc_error_codes/error_codes/E0192.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0192.md
diff --git a/src/librustc_error_codes/error_codes/E0193.md b/compiler/rustc_error_codes/src/error_codes/E0193.md
index e29a949ffba..e29a949ffba 100644
--- a/src/librustc_error_codes/error_codes/E0193.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0193.md
diff --git a/src/librustc_error_codes/error_codes/E0195.md b/compiler/rustc_error_codes/src/error_codes/E0195.md
index b8c313d412e..b8c313d412e 100644
--- a/src/librustc_error_codes/error_codes/E0195.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0195.md
diff --git a/src/librustc_error_codes/error_codes/E0197.md b/compiler/rustc_error_codes/src/error_codes/E0197.md
index c142b8f3664..c142b8f3664 100644
--- a/src/librustc_error_codes/error_codes/E0197.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0197.md
diff --git a/src/librustc_error_codes/error_codes/E0198.md b/compiler/rustc_error_codes/src/error_codes/E0198.md
index 90f1e542874..90f1e542874 100644
--- a/src/librustc_error_codes/error_codes/E0198.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0198.md
diff --git a/src/librustc_error_codes/error_codes/E0199.md b/compiler/rustc_error_codes/src/error_codes/E0199.md
index 88130e8e5e5..88130e8e5e5 100644
--- a/src/librustc_error_codes/error_codes/E0199.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0199.md
diff --git a/src/librustc_error_codes/error_codes/E0200.md b/compiler/rustc_error_codes/src/error_codes/E0200.md
index 7245bb59ce5..7245bb59ce5 100644
--- a/src/librustc_error_codes/error_codes/E0200.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0200.md
diff --git a/src/librustc_error_codes/error_codes/E0201.md b/compiler/rustc_error_codes/src/error_codes/E0201.md
index 0e1a7b7b7de..0e1a7b7b7de 100644
--- a/src/librustc_error_codes/error_codes/E0201.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0201.md
diff --git a/src/librustc_error_codes/error_codes/E0202.md b/compiler/rustc_error_codes/src/error_codes/E0202.md
index afc61ec2e48..afc61ec2e48 100644
--- a/src/librustc_error_codes/error_codes/E0202.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0202.md
diff --git a/src/librustc_error_codes/error_codes/E0203.md b/compiler/rustc_error_codes/src/error_codes/E0203.md
index 1edb519275f..1edb519275f 100644
--- a/src/librustc_error_codes/error_codes/E0203.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0203.md
diff --git a/src/librustc_error_codes/error_codes/E0204.md b/compiler/rustc_error_codes/src/error_codes/E0204.md
index 96e44758be4..96e44758be4 100644
--- a/src/librustc_error_codes/error_codes/E0204.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0204.md
diff --git a/src/librustc_error_codes/error_codes/E0205.md b/compiler/rustc_error_codes/src/error_codes/E0205.md
index 7916f53ad3b..7916f53ad3b 100644
--- a/src/librustc_error_codes/error_codes/E0205.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0205.md
diff --git a/src/librustc_error_codes/error_codes/E0206.md b/compiler/rustc_error_codes/src/error_codes/E0206.md
index da53b671ad0..da53b671ad0 100644
--- a/src/librustc_error_codes/error_codes/E0206.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0206.md
diff --git a/src/librustc_error_codes/error_codes/E0207.md b/compiler/rustc_error_codes/src/error_codes/E0207.md
index cb4f5d5157d..cb4f5d5157d 100644
--- a/src/librustc_error_codes/error_codes/E0207.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0207.md
diff --git a/src/librustc_error_codes/error_codes/E0210.md b/compiler/rustc_error_codes/src/error_codes/E0210.md
index dc2fd9b0ca0..dc2fd9b0ca0 100644
--- a/src/librustc_error_codes/error_codes/E0210.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0210.md
diff --git a/src/librustc_error_codes/error_codes/E0211.md b/compiler/rustc_error_codes/src/error_codes/E0211.md
index 77289f01900..77289f01900 100644
--- a/src/librustc_error_codes/error_codes/E0211.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0211.md
diff --git a/src/librustc_error_codes/error_codes/E0214.md b/compiler/rustc_error_codes/src/error_codes/E0214.md
index b64ee80e284..b64ee80e284 100644
--- a/src/librustc_error_codes/error_codes/E0214.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0214.md
diff --git a/src/librustc_error_codes/error_codes/E0220.md b/compiler/rustc_error_codes/src/error_codes/E0220.md
index ddc54007c8c..ddc54007c8c 100644
--- a/src/librustc_error_codes/error_codes/E0220.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0220.md
diff --git a/src/librustc_error_codes/error_codes/E0221.md b/compiler/rustc_error_codes/src/error_codes/E0221.md
index 26111ca4293..26111ca4293 100644
--- a/src/librustc_error_codes/error_codes/E0221.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0221.md
diff --git a/src/librustc_error_codes/error_codes/E0222.md b/compiler/rustc_error_codes/src/error_codes/E0222.md
index fbf1b8d7033..fbf1b8d7033 100644
--- a/src/librustc_error_codes/error_codes/E0222.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0222.md
diff --git a/src/librustc_error_codes/error_codes/E0223.md b/compiler/rustc_error_codes/src/error_codes/E0223.md
index 0d49f514ccf..0d49f514ccf 100644
--- a/src/librustc_error_codes/error_codes/E0223.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0223.md
diff --git a/src/librustc_error_codes/error_codes/E0224.md b/compiler/rustc_error_codes/src/error_codes/E0224.md
index fd89c1d5256..fd89c1d5256 100644
--- a/src/librustc_error_codes/error_codes/E0224.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0224.md
diff --git a/src/librustc_error_codes/error_codes/E0225.md b/compiler/rustc_error_codes/src/error_codes/E0225.md
index c306e710097..c306e710097 100644
--- a/src/librustc_error_codes/error_codes/E0225.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0225.md
diff --git a/src/librustc_error_codes/error_codes/E0226.md b/compiler/rustc_error_codes/src/error_codes/E0226.md
index 4e65132ff0d..4e65132ff0d 100644
--- a/src/librustc_error_codes/error_codes/E0226.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0226.md
diff --git a/src/librustc_error_codes/error_codes/E0228.md b/compiler/rustc_error_codes/src/error_codes/E0228.md
index 3443a5ae863..3443a5ae863 100644
--- a/src/librustc_error_codes/error_codes/E0228.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0228.md
diff --git a/src/librustc_error_codes/error_codes/E0229.md b/compiler/rustc_error_codes/src/error_codes/E0229.md
index a8fab057d43..a8fab057d43 100644
--- a/src/librustc_error_codes/error_codes/E0229.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0229.md
diff --git a/src/librustc_error_codes/error_codes/E0230.md b/compiler/rustc_error_codes/src/error_codes/E0230.md
index cfb72e74319..cfb72e74319 100644
--- a/src/librustc_error_codes/error_codes/E0230.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0230.md
diff --git a/src/librustc_error_codes/error_codes/E0231.md b/compiler/rustc_error_codes/src/error_codes/E0231.md
index 23a0a88ecdd..23a0a88ecdd 100644
--- a/src/librustc_error_codes/error_codes/E0231.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0231.md
diff --git a/src/librustc_error_codes/error_codes/E0232.md b/compiler/rustc_error_codes/src/error_codes/E0232.md
index b310caefa6e..b310caefa6e 100644
--- a/src/librustc_error_codes/error_codes/E0232.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0232.md
diff --git a/src/librustc_error_codes/error_codes/E0243.md b/compiler/rustc_error_codes/src/error_codes/E0243.md
index 5d3d1828bf5..5d3d1828bf5 100644
--- a/src/librustc_error_codes/error_codes/E0243.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0243.md
diff --git a/src/librustc_error_codes/error_codes/E0244.md b/compiler/rustc_error_codes/src/error_codes/E0244.md
index 5187b7b05d2..5187b7b05d2 100644
--- a/src/librustc_error_codes/error_codes/E0244.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0244.md
diff --git a/src/librustc_error_codes/error_codes/E0251.md b/compiler/rustc_error_codes/src/error_codes/E0251.md
index 4121dd27877..4121dd27877 100644
--- a/src/librustc_error_codes/error_codes/E0251.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0251.md
diff --git a/src/librustc_error_codes/error_codes/E0252.md b/compiler/rustc_error_codes/src/error_codes/E0252.md
index e678944650f..e678944650f 100644
--- a/src/librustc_error_codes/error_codes/E0252.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0252.md
diff --git a/src/librustc_error_codes/error_codes/E0253.md b/compiler/rustc_error_codes/src/error_codes/E0253.md
index aea51d40238..aea51d40238 100644
--- a/src/librustc_error_codes/error_codes/E0253.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0253.md
diff --git a/src/librustc_error_codes/error_codes/E0254.md b/compiler/rustc_error_codes/src/error_codes/E0254.md
index 44383ed6eab..44383ed6eab 100644
--- a/src/librustc_error_codes/error_codes/E0254.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0254.md
diff --git a/src/librustc_error_codes/error_codes/E0255.md b/compiler/rustc_error_codes/src/error_codes/E0255.md
index 83f5ec3dda4..83f5ec3dda4 100644
--- a/src/librustc_error_codes/error_codes/E0255.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0255.md
diff --git a/src/librustc_error_codes/error_codes/E0256.md b/compiler/rustc_error_codes/src/error_codes/E0256.md
index 385376cdade..385376cdade 100644
--- a/src/librustc_error_codes/error_codes/E0256.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0256.md
diff --git a/src/librustc_error_codes/error_codes/E0259.md b/compiler/rustc_error_codes/src/error_codes/E0259.md
index 8d8f93db30f..8d8f93db30f 100644
--- a/src/librustc_error_codes/error_codes/E0259.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0259.md
diff --git a/src/librustc_error_codes/error_codes/E0260.md b/compiler/rustc_error_codes/src/error_codes/E0260.md
index b8bdb81fcbf..b8bdb81fcbf 100644
--- a/src/librustc_error_codes/error_codes/E0260.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0260.md
diff --git a/src/librustc_error_codes/error_codes/E0261.md b/compiler/rustc_error_codes/src/error_codes/E0261.md
index e3268437396..e3268437396 100644
--- a/src/librustc_error_codes/error_codes/E0261.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0261.md
diff --git a/src/librustc_error_codes/error_codes/E0262.md b/compiler/rustc_error_codes/src/error_codes/E0262.md
index 67419d53ef9..67419d53ef9 100644
--- a/src/librustc_error_codes/error_codes/E0262.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0262.md
diff --git a/src/librustc_error_codes/error_codes/E0263.md b/compiler/rustc_error_codes/src/error_codes/E0263.md
index 37271ac692d..37271ac692d 100644
--- a/src/librustc_error_codes/error_codes/E0263.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0263.md
diff --git a/src/librustc_error_codes/error_codes/E0264.md b/compiler/rustc_error_codes/src/error_codes/E0264.md
index e2a27f7b106..e2a27f7b106 100644
--- a/src/librustc_error_codes/error_codes/E0264.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0264.md
diff --git a/src/librustc_error_codes/error_codes/E0267.md b/compiler/rustc_error_codes/src/error_codes/E0267.md
index 951490df874..951490df874 100644
--- a/src/librustc_error_codes/error_codes/E0267.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0267.md
diff --git a/src/librustc_error_codes/error_codes/E0268.md b/compiler/rustc_error_codes/src/error_codes/E0268.md
index 436aef79fe0..436aef79fe0 100644
--- a/src/librustc_error_codes/error_codes/E0268.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0268.md
diff --git a/src/librustc_error_codes/error_codes/E0271.md b/compiler/rustc_error_codes/src/error_codes/E0271.md
index ddd245b1a2b..ddd245b1a2b 100644
--- a/src/librustc_error_codes/error_codes/E0271.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0271.md
diff --git a/src/librustc_error_codes/error_codes/E0275.md b/compiler/rustc_error_codes/src/error_codes/E0275.md
index 2d12fcea4ca..2d12fcea4ca 100644
--- a/src/librustc_error_codes/error_codes/E0275.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0275.md
diff --git a/src/librustc_error_codes/error_codes/E0276.md b/compiler/rustc_error_codes/src/error_codes/E0276.md
index ad76968c589..ad76968c589 100644
--- a/src/librustc_error_codes/error_codes/E0276.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0276.md
diff --git a/src/librustc_error_codes/error_codes/E0277.md b/compiler/rustc_error_codes/src/error_codes/E0277.md
index 2e2cd5e01fb..2e2cd5e01fb 100644
--- a/src/librustc_error_codes/error_codes/E0277.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0277.md
diff --git a/src/librustc_error_codes/error_codes/E0281.md b/compiler/rustc_error_codes/src/error_codes/E0281.md
index 1d7904b67dd..1d7904b67dd 100644
--- a/src/librustc_error_codes/error_codes/E0281.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0281.md
diff --git a/src/librustc_error_codes/error_codes/E0282.md b/compiler/rustc_error_codes/src/error_codes/E0282.md
index 49d2205f92c..49d2205f92c 100644
--- a/src/librustc_error_codes/error_codes/E0282.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0282.md
diff --git a/src/librustc_error_codes/error_codes/E0283.md b/compiler/rustc_error_codes/src/error_codes/E0283.md
index 6885f9a486d..6885f9a486d 100644
--- a/src/librustc_error_codes/error_codes/E0283.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0283.md
diff --git a/src/librustc_error_codes/error_codes/E0284.md b/compiler/rustc_error_codes/src/error_codes/E0284.md
index a1ffa2bda00..a1ffa2bda00 100644
--- a/src/librustc_error_codes/error_codes/E0284.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0284.md
diff --git a/src/librustc_error_codes/error_codes/E0297.md b/compiler/rustc_error_codes/src/error_codes/E0297.md
index 66c31376d8b..66c31376d8b 100644
--- a/src/librustc_error_codes/error_codes/E0297.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0297.md
diff --git a/src/librustc_error_codes/error_codes/E0301.md b/compiler/rustc_error_codes/src/error_codes/E0301.md
index 485e19fbb8d..485e19fbb8d 100644
--- a/src/librustc_error_codes/error_codes/E0301.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0301.md
diff --git a/src/librustc_error_codes/error_codes/E0302.md b/compiler/rustc_error_codes/src/error_codes/E0302.md
index e6ac9d590c8..e6ac9d590c8 100644
--- a/src/librustc_error_codes/error_codes/E0302.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0302.md
diff --git a/src/librustc_error_codes/error_codes/E0303.md b/compiler/rustc_error_codes/src/error_codes/E0303.md
index 459906047cc..459906047cc 100644
--- a/src/librustc_error_codes/error_codes/E0303.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0303.md
diff --git a/src/librustc_error_codes/error_codes/E0307.md b/compiler/rustc_error_codes/src/error_codes/E0307.md
index 0d29d56ea1a..0d29d56ea1a 100644
--- a/src/librustc_error_codes/error_codes/E0307.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0307.md
diff --git a/src/librustc_error_codes/error_codes/E0308.md b/compiler/rustc_error_codes/src/error_codes/E0308.md
index e2c40f03019..e2c40f03019 100644
--- a/src/librustc_error_codes/error_codes/E0308.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0308.md
diff --git a/src/librustc_error_codes/error_codes/E0309.md b/compiler/rustc_error_codes/src/error_codes/E0309.md
index e719ee590ab..e719ee590ab 100644
--- a/src/librustc_error_codes/error_codes/E0309.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0309.md
diff --git a/src/librustc_error_codes/error_codes/E0310.md b/compiler/rustc_error_codes/src/error_codes/E0310.md
index 8d4311d018b..8d4311d018b 100644
--- a/src/librustc_error_codes/error_codes/E0310.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0310.md
diff --git a/src/librustc_error_codes/error_codes/E0312.md b/compiler/rustc_error_codes/src/error_codes/E0312.md
index cb090d01382..cb090d01382 100644
--- a/src/librustc_error_codes/error_codes/E0312.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0312.md
diff --git a/src/librustc_error_codes/error_codes/E0317.md b/compiler/rustc_error_codes/src/error_codes/E0317.md
index 230911c2086..230911c2086 100644
--- a/src/librustc_error_codes/error_codes/E0317.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0317.md
diff --git a/src/librustc_error_codes/error_codes/E0321.md b/compiler/rustc_error_codes/src/error_codes/E0321.md
index bfcdabfe9de..bfcdabfe9de 100644
--- a/src/librustc_error_codes/error_codes/E0321.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0321.md
diff --git a/src/librustc_error_codes/error_codes/E0322.md b/compiler/rustc_error_codes/src/error_codes/E0322.md
index ccef8681dd6..ccef8681dd6 100644
--- a/src/librustc_error_codes/error_codes/E0322.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0322.md
diff --git a/src/librustc_error_codes/error_codes/E0323.md b/compiler/rustc_error_codes/src/error_codes/E0323.md
index 0bf42d17ebc..0bf42d17ebc 100644
--- a/src/librustc_error_codes/error_codes/E0323.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0323.md
diff --git a/src/librustc_error_codes/error_codes/E0324.md b/compiler/rustc_error_codes/src/error_codes/E0324.md
index 1442cb77dd9..1442cb77dd9 100644
--- a/src/librustc_error_codes/error_codes/E0324.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0324.md
diff --git a/src/librustc_error_codes/error_codes/E0325.md b/compiler/rustc_error_codes/src/error_codes/E0325.md
index 656fd1ec82b..656fd1ec82b 100644
--- a/src/librustc_error_codes/error_codes/E0325.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0325.md
diff --git a/src/librustc_error_codes/error_codes/E0326.md b/compiler/rustc_error_codes/src/error_codes/E0326.md
index bc522e9cf40..bc522e9cf40 100644
--- a/src/librustc_error_codes/error_codes/E0326.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0326.md
diff --git a/src/librustc_error_codes/error_codes/E0328.md b/compiler/rustc_error_codes/src/error_codes/E0328.md
index 83909235455..83909235455 100644
--- a/src/librustc_error_codes/error_codes/E0328.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0328.md
diff --git a/src/librustc_error_codes/error_codes/E0329.md b/compiler/rustc_error_codes/src/error_codes/E0329.md
index 37d84a1a89b..37d84a1a89b 100644
--- a/src/librustc_error_codes/error_codes/E0329.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0329.md
diff --git a/src/librustc_error_codes/error_codes/E0364.md b/compiler/rustc_error_codes/src/error_codes/E0364.md
index d01fb0c9c42..d01fb0c9c42 100644
--- a/src/librustc_error_codes/error_codes/E0364.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0364.md
diff --git a/src/librustc_error_codes/error_codes/E0365.md b/compiler/rustc_error_codes/src/error_codes/E0365.md
index e3d417a7d01..e3d417a7d01 100644
--- a/src/librustc_error_codes/error_codes/E0365.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0365.md
diff --git a/src/librustc_error_codes/error_codes/E0366.md b/compiler/rustc_error_codes/src/error_codes/E0366.md
index e6f8e61893b..e6f8e61893b 100644
--- a/src/librustc_error_codes/error_codes/E0366.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0366.md
diff --git a/src/librustc_error_codes/error_codes/E0367.md b/compiler/rustc_error_codes/src/error_codes/E0367.md
index cfebeada272..cfebeada272 100644
--- a/src/librustc_error_codes/error_codes/E0367.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0367.md
diff --git a/src/librustc_error_codes/error_codes/E0368.md b/compiler/rustc_error_codes/src/error_codes/E0368.md
index 7b9d9334821..7b9d9334821 100644
--- a/src/librustc_error_codes/error_codes/E0368.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0368.md
diff --git a/src/librustc_error_codes/error_codes/E0369.md b/compiler/rustc_error_codes/src/error_codes/E0369.md
index ab0f4b40843..ab0f4b40843 100644
--- a/src/librustc_error_codes/error_codes/E0369.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0369.md
diff --git a/src/librustc_error_codes/error_codes/E0370.md b/compiler/rustc_error_codes/src/error_codes/E0370.md
index 14e954722a2..14e954722a2 100644
--- a/src/librustc_error_codes/error_codes/E0370.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0370.md
diff --git a/src/librustc_error_codes/error_codes/E0371.md b/compiler/rustc_error_codes/src/error_codes/E0371.md
index a44721346e2..a44721346e2 100644
--- a/src/librustc_error_codes/error_codes/E0371.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0371.md
diff --git a/src/librustc_error_codes/error_codes/E0373.md b/compiler/rustc_error_codes/src/error_codes/E0373.md
index fd969877931..fd969877931 100644
--- a/src/librustc_error_codes/error_codes/E0373.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0373.md
diff --git a/src/librustc_error_codes/error_codes/E0374.md b/compiler/rustc_error_codes/src/error_codes/E0374.md
index 6d7dc88823c..6d7dc88823c 100644
--- a/src/librustc_error_codes/error_codes/E0374.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0374.md
diff --git a/src/librustc_error_codes/error_codes/E0375.md b/compiler/rustc_error_codes/src/error_codes/E0375.md
index 71e53057165..71e53057165 100644
--- a/src/librustc_error_codes/error_codes/E0375.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0375.md
diff --git a/src/librustc_error_codes/error_codes/E0376.md b/compiler/rustc_error_codes/src/error_codes/E0376.md
index 50de15bd30f..50de15bd30f 100644
--- a/src/librustc_error_codes/error_codes/E0376.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0376.md
diff --git a/src/librustc_error_codes/error_codes/E0378.md b/compiler/rustc_error_codes/src/error_codes/E0378.md
index c6fe997f3dc..c6fe997f3dc 100644
--- a/src/librustc_error_codes/error_codes/E0378.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0378.md
diff --git a/src/librustc_error_codes/error_codes/E0379.md b/compiler/rustc_error_codes/src/error_codes/E0379.md
index 930204847ec..930204847ec 100644
--- a/src/librustc_error_codes/error_codes/E0379.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0379.md
diff --git a/src/librustc_error_codes/error_codes/E0380.md b/compiler/rustc_error_codes/src/error_codes/E0380.md
index 638f0c8ecc6..638f0c8ecc6 100644
--- a/src/librustc_error_codes/error_codes/E0380.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0380.md
diff --git a/src/librustc_error_codes/error_codes/E0381.md b/compiler/rustc_error_codes/src/error_codes/E0381.md
index 97678009925..97678009925 100644
--- a/src/librustc_error_codes/error_codes/E0381.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0381.md
diff --git a/src/librustc_error_codes/error_codes/E0382.md b/compiler/rustc_error_codes/src/error_codes/E0382.md
index d1408a06296..d1408a06296 100644
--- a/src/librustc_error_codes/error_codes/E0382.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0382.md
diff --git a/src/librustc_error_codes/error_codes/E0383.md b/compiler/rustc_error_codes/src/error_codes/E0383.md
index fd2b0b08fb0..fd2b0b08fb0 100644
--- a/src/librustc_error_codes/error_codes/E0383.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0383.md
diff --git a/src/librustc_error_codes/error_codes/E0384.md b/compiler/rustc_error_codes/src/error_codes/E0384.md
index e21fac0797c..e21fac0797c 100644
--- a/src/librustc_error_codes/error_codes/E0384.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0384.md
diff --git a/src/librustc_error_codes/error_codes/E0386.md b/compiler/rustc_error_codes/src/error_codes/E0386.md
index de3b468b6e4..de3b468b6e4 100644
--- a/src/librustc_error_codes/error_codes/E0386.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0386.md
diff --git a/src/librustc_error_codes/error_codes/E0387.md b/compiler/rustc_error_codes/src/error_codes/E0387.md
index 38ad19bd6aa..38ad19bd6aa 100644
--- a/src/librustc_error_codes/error_codes/E0387.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0387.md
diff --git a/src/librustc_error_codes/error_codes/E0388.md b/compiler/rustc_error_codes/src/error_codes/E0388.md
index 512fb42e6ec..512fb42e6ec 100644
--- a/src/librustc_error_codes/error_codes/E0388.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0388.md
diff --git a/src/librustc_error_codes/error_codes/E0389.md b/compiler/rustc_error_codes/src/error_codes/E0389.md
index 9f064e44c82..9f064e44c82 100644
--- a/src/librustc_error_codes/error_codes/E0389.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0389.md
diff --git a/src/librustc_error_codes/error_codes/E0390.md b/compiler/rustc_error_codes/src/error_codes/E0390.md
index ecc5b5568ad..ecc5b5568ad 100644
--- a/src/librustc_error_codes/error_codes/E0390.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0390.md
diff --git a/src/librustc_error_codes/error_codes/E0391.md b/compiler/rustc_error_codes/src/error_codes/E0391.md
index dff50ccaa0b..dff50ccaa0b 100644
--- a/src/librustc_error_codes/error_codes/E0391.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0391.md
diff --git a/src/librustc_error_codes/error_codes/E0392.md b/compiler/rustc_error_codes/src/error_codes/E0392.md
index f373d89456d..f373d89456d 100644
--- a/src/librustc_error_codes/error_codes/E0392.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0392.md
diff --git a/src/librustc_error_codes/error_codes/E0393.md b/compiler/rustc_error_codes/src/error_codes/E0393.md
index 3e853cf1b8a..3e853cf1b8a 100644
--- a/src/librustc_error_codes/error_codes/E0393.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0393.md
diff --git a/src/librustc_error_codes/error_codes/E0398.md b/compiler/rustc_error_codes/src/error_codes/E0398.md
index 75d86979e3c..75d86979e3c 100644
--- a/src/librustc_error_codes/error_codes/E0398.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0398.md
diff --git a/src/librustc_error_codes/error_codes/E0399.md b/compiler/rustc_error_codes/src/error_codes/E0399.md
index 6ea6054b417..6ea6054b417 100644
--- a/src/librustc_error_codes/error_codes/E0399.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0399.md
diff --git a/src/librustc_error_codes/error_codes/E0401.md b/compiler/rustc_error_codes/src/error_codes/E0401.md
index 4c93053d5f8..4c93053d5f8 100644
--- a/src/librustc_error_codes/error_codes/E0401.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0401.md
diff --git a/src/librustc_error_codes/error_codes/E0403.md b/compiler/rustc_error_codes/src/error_codes/E0403.md
index 5f4a40ce92e..5f4a40ce92e 100644
--- a/src/librustc_error_codes/error_codes/E0403.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0403.md
diff --git a/src/librustc_error_codes/error_codes/E0404.md b/compiler/rustc_error_codes/src/error_codes/E0404.md
index 1360cc99afc..1360cc99afc 100644
--- a/src/librustc_error_codes/error_codes/E0404.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0404.md
diff --git a/src/librustc_error_codes/error_codes/E0405.md b/compiler/rustc_error_codes/src/error_codes/E0405.md
index ff1e8c0be88..ff1e8c0be88 100644
--- a/src/librustc_error_codes/error_codes/E0405.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0405.md
diff --git a/src/librustc_error_codes/error_codes/E0407.md b/compiler/rustc_error_codes/src/error_codes/E0407.md
index fa26c77a1b0..fa26c77a1b0 100644
--- a/src/librustc_error_codes/error_codes/E0407.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0407.md
diff --git a/src/librustc_error_codes/error_codes/E0408.md b/compiler/rustc_error_codes/src/error_codes/E0408.md
index 3acdbb740a3..3acdbb740a3 100644
--- a/src/librustc_error_codes/error_codes/E0408.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0408.md
diff --git a/src/librustc_error_codes/error_codes/E0409.md b/compiler/rustc_error_codes/src/error_codes/E0409.md
index 53eb0fd0573..53eb0fd0573 100644
--- a/src/librustc_error_codes/error_codes/E0409.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0409.md
diff --git a/src/librustc_error_codes/error_codes/E0411.md b/compiler/rustc_error_codes/src/error_codes/E0411.md
index d82171533ae..d82171533ae 100644
--- a/src/librustc_error_codes/error_codes/E0411.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0411.md
diff --git a/src/librustc_error_codes/error_codes/E0412.md b/compiler/rustc_error_codes/src/error_codes/E0412.md
index d9ebc852bba..d9ebc852bba 100644
--- a/src/librustc_error_codes/error_codes/E0412.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0412.md
diff --git a/src/librustc_error_codes/error_codes/E0415.md b/compiler/rustc_error_codes/src/error_codes/E0415.md
index 97d733a7b2d..97d733a7b2d 100644
--- a/src/librustc_error_codes/error_codes/E0415.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0415.md
diff --git a/src/librustc_error_codes/error_codes/E0416.md b/compiler/rustc_error_codes/src/error_codes/E0416.md
index 7bc316dafc5..7bc316dafc5 100644
--- a/src/librustc_error_codes/error_codes/E0416.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0416.md
diff --git a/src/librustc_error_codes/error_codes/E0422.md b/compiler/rustc_error_codes/src/error_codes/E0422.md
index 828a52e7341..828a52e7341 100644
--- a/src/librustc_error_codes/error_codes/E0422.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0422.md
diff --git a/src/librustc_error_codes/error_codes/E0423.md b/compiler/rustc_error_codes/src/error_codes/E0423.md
index a98ada17a46..a98ada17a46 100644
--- a/src/librustc_error_codes/error_codes/E0423.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0423.md
diff --git a/src/librustc_error_codes/error_codes/E0424.md b/compiler/rustc_error_codes/src/error_codes/E0424.md
index a9f6f579b42..a9f6f579b42 100644
--- a/src/librustc_error_codes/error_codes/E0424.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0424.md
diff --git a/src/librustc_error_codes/error_codes/E0425.md b/compiler/rustc_error_codes/src/error_codes/E0425.md
index 13e71b85065..13e71b85065 100644
--- a/src/librustc_error_codes/error_codes/E0425.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0425.md
diff --git a/src/librustc_error_codes/error_codes/E0426.md b/compiler/rustc_error_codes/src/error_codes/E0426.md
index 275a83e606e..275a83e606e 100644
--- a/src/librustc_error_codes/error_codes/E0426.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0426.md
diff --git a/src/librustc_error_codes/error_codes/E0428.md b/compiler/rustc_error_codes/src/error_codes/E0428.md
index 38db0b4bcf9..38db0b4bcf9 100644
--- a/src/librustc_error_codes/error_codes/E0428.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0428.md
diff --git a/src/librustc_error_codes/error_codes/E0429.md b/compiler/rustc_error_codes/src/error_codes/E0429.md
index 8c5fd8624fd..8c5fd8624fd 100644
--- a/src/librustc_error_codes/error_codes/E0429.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0429.md
diff --git a/src/librustc_error_codes/error_codes/E0430.md b/compiler/rustc_error_codes/src/error_codes/E0430.md
index 8cca0f21e59..8cca0f21e59 100644
--- a/src/librustc_error_codes/error_codes/E0430.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0430.md
diff --git a/src/librustc_error_codes/error_codes/E0431.md b/compiler/rustc_error_codes/src/error_codes/E0431.md
index 1b70f5f1d7b..1b70f5f1d7b 100644
--- a/src/librustc_error_codes/error_codes/E0431.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0431.md
diff --git a/src/librustc_error_codes/error_codes/E0432.md b/compiler/rustc_error_codes/src/error_codes/E0432.md
index a6e2acac5d2..a6e2acac5d2 100644
--- a/src/librustc_error_codes/error_codes/E0432.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0432.md
diff --git a/src/librustc_error_codes/error_codes/E0433.md b/compiler/rustc_error_codes/src/error_codes/E0433.md
index f9e333e8ccd..f9e333e8ccd 100644
--- a/src/librustc_error_codes/error_codes/E0433.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0433.md
diff --git a/src/librustc_error_codes/error_codes/E0434.md b/compiler/rustc_error_codes/src/error_codes/E0434.md
index 8fd60412baf..8fd60412baf 100644
--- a/src/librustc_error_codes/error_codes/E0434.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0434.md
diff --git a/src/librustc_error_codes/error_codes/E0435.md b/compiler/rustc_error_codes/src/error_codes/E0435.md
index 424e5ce1e2e..424e5ce1e2e 100644
--- a/src/librustc_error_codes/error_codes/E0435.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0435.md
diff --git a/src/librustc_error_codes/error_codes/E0436.md b/compiler/rustc_error_codes/src/error_codes/E0436.md
index 48ecc49e92f..48ecc49e92f 100644
--- a/src/librustc_error_codes/error_codes/E0436.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0436.md
diff --git a/src/librustc_error_codes/error_codes/E0437.md b/compiler/rustc_error_codes/src/error_codes/E0437.md
index 0f924ba6920..0f924ba6920 100644
--- a/src/librustc_error_codes/error_codes/E0437.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0437.md
diff --git a/src/librustc_error_codes/error_codes/E0438.md b/compiler/rustc_error_codes/src/error_codes/E0438.md
index 13723bc3009..13723bc3009 100644
--- a/src/librustc_error_codes/error_codes/E0438.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0438.md
diff --git a/src/librustc_error_codes/error_codes/E0439.md b/compiler/rustc_error_codes/src/error_codes/E0439.md
index 3e663df866c..3e663df866c 100644
--- a/src/librustc_error_codes/error_codes/E0439.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0439.md
diff --git a/src/librustc_error_codes/error_codes/E0445.md b/compiler/rustc_error_codes/src/error_codes/E0445.md
index e6a28a9c2c4..e6a28a9c2c4 100644
--- a/src/librustc_error_codes/error_codes/E0445.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0445.md
diff --git a/src/librustc_error_codes/error_codes/E0446.md b/compiler/rustc_error_codes/src/error_codes/E0446.md
index 6ec47c4962c..6ec47c4962c 100644
--- a/src/librustc_error_codes/error_codes/E0446.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0446.md
diff --git a/src/librustc_error_codes/error_codes/E0447.md b/compiler/rustc_error_codes/src/error_codes/E0447.md
index af8cd8d6d52..af8cd8d6d52 100644
--- a/src/librustc_error_codes/error_codes/E0447.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0447.md
diff --git a/src/librustc_error_codes/error_codes/E0448.md b/compiler/rustc_error_codes/src/error_codes/E0448.md
index ba096f9e984..ba096f9e984 100644
--- a/src/librustc_error_codes/error_codes/E0448.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0448.md
diff --git a/src/librustc_error_codes/error_codes/E0449.md b/compiler/rustc_error_codes/src/error_codes/E0449.md
index 9afc67689bf..9afc67689bf 100644
--- a/src/librustc_error_codes/error_codes/E0449.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0449.md
diff --git a/src/librustc_error_codes/error_codes/E0451.md b/compiler/rustc_error_codes/src/error_codes/E0451.md
index 821073fe16e..821073fe16e 100644
--- a/src/librustc_error_codes/error_codes/E0451.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0451.md
diff --git a/src/librustc_error_codes/error_codes/E0452.md b/compiler/rustc_error_codes/src/error_codes/E0452.md
index 429813a7cdd..429813a7cdd 100644
--- a/src/librustc_error_codes/error_codes/E0452.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0452.md
diff --git a/src/librustc_error_codes/error_codes/E0453.md b/compiler/rustc_error_codes/src/error_codes/E0453.md
index 11789db8f36..11789db8f36 100644
--- a/src/librustc_error_codes/error_codes/E0453.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0453.md
diff --git a/src/librustc_error_codes/error_codes/E0454.md b/compiler/rustc_error_codes/src/error_codes/E0454.md
index 23ca6c7824d..23ca6c7824d 100644
--- a/src/librustc_error_codes/error_codes/E0454.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0454.md
diff --git a/src/librustc_error_codes/error_codes/E0455.md b/compiler/rustc_error_codes/src/error_codes/E0455.md
index 2f80c34b889..2f80c34b889 100644
--- a/src/librustc_error_codes/error_codes/E0455.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0455.md
diff --git a/src/librustc_error_codes/error_codes/E0458.md b/compiler/rustc_error_codes/src/error_codes/E0458.md
index 075226ac98b..075226ac98b 100644
--- a/src/librustc_error_codes/error_codes/E0458.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0458.md
diff --git a/src/librustc_error_codes/error_codes/E0459.md b/compiler/rustc_error_codes/src/error_codes/E0459.md
index 6f75f2a99a5..6f75f2a99a5 100644
--- a/src/librustc_error_codes/error_codes/E0459.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0459.md
diff --git a/src/librustc_error_codes/error_codes/E0463.md b/compiler/rustc_error_codes/src/error_codes/E0463.md
index e46938c607d..e46938c607d 100644
--- a/src/librustc_error_codes/error_codes/E0463.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0463.md
diff --git a/src/librustc_error_codes/error_codes/E0466.md b/compiler/rustc_error_codes/src/error_codes/E0466.md
index 7aefedbc087..7aefedbc087 100644
--- a/src/librustc_error_codes/error_codes/E0466.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0466.md
diff --git a/src/librustc_error_codes/error_codes/E0468.md b/compiler/rustc_error_codes/src/error_codes/E0468.md
index cf8664718fa..cf8664718fa 100644
--- a/src/librustc_error_codes/error_codes/E0468.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0468.md
diff --git a/src/librustc_error_codes/error_codes/E0469.md b/compiler/rustc_error_codes/src/error_codes/E0469.md
index 22db976aac2..22db976aac2 100644
--- a/src/librustc_error_codes/error_codes/E0469.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0469.md
diff --git a/src/librustc_error_codes/error_codes/E0477.md b/compiler/rustc_error_codes/src/error_codes/E0477.md
index 9cfefb1de63..9cfefb1de63 100644
--- a/src/librustc_error_codes/error_codes/E0477.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0477.md
diff --git a/src/librustc_error_codes/error_codes/E0478.md b/compiler/rustc_error_codes/src/error_codes/E0478.md
index 4bc5fde2e89..4bc5fde2e89 100644
--- a/src/librustc_error_codes/error_codes/E0478.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0478.md
diff --git a/src/librustc_error_codes/error_codes/E0491.md b/compiler/rustc_error_codes/src/error_codes/E0491.md
index d45663f3a53..d45663f3a53 100644
--- a/src/librustc_error_codes/error_codes/E0491.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0491.md
diff --git a/src/librustc_error_codes/error_codes/E0492.md b/compiler/rustc_error_codes/src/error_codes/E0492.md
index 1caa59999ae..1caa59999ae 100644
--- a/src/librustc_error_codes/error_codes/E0492.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0492.md
diff --git a/src/librustc_error_codes/error_codes/E0493.md b/compiler/rustc_error_codes/src/error_codes/E0493.md
index 0dcc3b62b4b..0dcc3b62b4b 100644
--- a/src/librustc_error_codes/error_codes/E0493.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0493.md
diff --git a/src/librustc_error_codes/error_codes/E0495.md b/compiler/rustc_error_codes/src/error_codes/E0495.md
index f956237b80b..f956237b80b 100644
--- a/src/librustc_error_codes/error_codes/E0495.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0495.md
diff --git a/src/librustc_error_codes/error_codes/E0496.md b/compiler/rustc_error_codes/src/error_codes/E0496.md
index 83d65cd3e09..83d65cd3e09 100644
--- a/src/librustc_error_codes/error_codes/E0496.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0496.md
diff --git a/src/librustc_error_codes/error_codes/E0497.md b/compiler/rustc_error_codes/src/error_codes/E0497.md
index ef2882415d2..ef2882415d2 100644
--- a/src/librustc_error_codes/error_codes/E0497.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0497.md
diff --git a/src/librustc_error_codes/error_codes/E0499.md b/compiler/rustc_error_codes/src/error_codes/E0499.md
index a07e8eb3b38..a07e8eb3b38 100644
--- a/src/librustc_error_codes/error_codes/E0499.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0499.md
diff --git a/src/librustc_error_codes/error_codes/E0500.md b/compiler/rustc_error_codes/src/error_codes/E0500.md
index fde31d2c745..fde31d2c745 100644
--- a/src/librustc_error_codes/error_codes/E0500.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0500.md
diff --git a/src/librustc_error_codes/error_codes/E0501.md b/compiler/rustc_error_codes/src/error_codes/E0501.md
index ffdbc443905..ffdbc443905 100644
--- a/src/librustc_error_codes/error_codes/E0501.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0501.md
diff --git a/src/librustc_error_codes/error_codes/E0502.md b/compiler/rustc_error_codes/src/error_codes/E0502.md
index dc3ffdfddd9..dc3ffdfddd9 100644
--- a/src/librustc_error_codes/error_codes/E0502.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0502.md
diff --git a/src/librustc_error_codes/error_codes/E0503.md b/compiler/rustc_error_codes/src/error_codes/E0503.md
index c52525fee54..c52525fee54 100644
--- a/src/librustc_error_codes/error_codes/E0503.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0503.md
diff --git a/src/librustc_error_codes/error_codes/E0504.md b/compiler/rustc_error_codes/src/error_codes/E0504.md
index bcbd00a8690..bcbd00a8690 100644
--- a/src/librustc_error_codes/error_codes/E0504.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0504.md
diff --git a/src/librustc_error_codes/error_codes/E0505.md b/compiler/rustc_error_codes/src/error_codes/E0505.md
index b11e3c0e947..b11e3c0e947 100644
--- a/src/librustc_error_codes/error_codes/E0505.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0505.md
diff --git a/src/librustc_error_codes/error_codes/E0506.md b/compiler/rustc_error_codes/src/error_codes/E0506.md
index c312a0460e3..c312a0460e3 100644
--- a/src/librustc_error_codes/error_codes/E0506.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0506.md
diff --git a/src/librustc_error_codes/error_codes/E0507.md b/compiler/rustc_error_codes/src/error_codes/E0507.md
index 254751fc45e..254751fc45e 100644
--- a/src/librustc_error_codes/error_codes/E0507.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0507.md
diff --git a/src/librustc_error_codes/error_codes/E0508.md b/compiler/rustc_error_codes/src/error_codes/E0508.md
index 33572fca6a3..33572fca6a3 100644
--- a/src/librustc_error_codes/error_codes/E0508.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0508.md
diff --git a/src/librustc_error_codes/error_codes/E0509.md b/compiler/rustc_error_codes/src/error_codes/E0509.md
index 9cbd7d695aa..9cbd7d695aa 100644
--- a/src/librustc_error_codes/error_codes/E0509.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0509.md
diff --git a/src/librustc_error_codes/error_codes/E0510.md b/compiler/rustc_error_codes/src/error_codes/E0510.md
index e045e04bdbe..e045e04bdbe 100644
--- a/src/librustc_error_codes/error_codes/E0510.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0510.md
diff --git a/src/librustc_error_codes/error_codes/E0511.md b/compiler/rustc_error_codes/src/error_codes/E0511.md
index 5351a685eb5..5351a685eb5 100644
--- a/src/librustc_error_codes/error_codes/E0511.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0511.md
diff --git a/src/librustc_error_codes/error_codes/E0512.md b/compiler/rustc_error_codes/src/error_codes/E0512.md
index 00c09612285..00c09612285 100644
--- a/src/librustc_error_codes/error_codes/E0512.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0512.md
diff --git a/src/librustc_error_codes/error_codes/E0515.md b/compiler/rustc_error_codes/src/error_codes/E0515.md
index 0f4fbf67223..0f4fbf67223 100644
--- a/src/librustc_error_codes/error_codes/E0515.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0515.md
diff --git a/src/librustc_error_codes/error_codes/E0516.md b/compiler/rustc_error_codes/src/error_codes/E0516.md
index 935c31bbab9..935c31bbab9 100644
--- a/src/librustc_error_codes/error_codes/E0516.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0516.md
diff --git a/src/librustc_error_codes/error_codes/E0517.md b/compiler/rustc_error_codes/src/error_codes/E0517.md
index ae802245bd1..ae802245bd1 100644
--- a/src/librustc_error_codes/error_codes/E0517.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0517.md
diff --git a/src/librustc_error_codes/error_codes/E0518.md b/compiler/rustc_error_codes/src/error_codes/E0518.md
index f04329bc4e6..f04329bc4e6 100644
--- a/src/librustc_error_codes/error_codes/E0518.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0518.md
diff --git a/src/librustc_error_codes/error_codes/E0520.md b/compiler/rustc_error_codes/src/error_codes/E0520.md
index f9d7e02e5c8..f9d7e02e5c8 100644
--- a/src/librustc_error_codes/error_codes/E0520.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0520.md
diff --git a/src/librustc_error_codes/error_codes/E0522.md b/compiler/rustc_error_codes/src/error_codes/E0522.md
index 83272314a87..83272314a87 100644
--- a/src/librustc_error_codes/error_codes/E0522.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0522.md
diff --git a/src/librustc_error_codes/error_codes/E0524.md b/compiler/rustc_error_codes/src/error_codes/E0524.md
index bab241b5a95..bab241b5a95 100644
--- a/src/librustc_error_codes/error_codes/E0524.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0524.md
diff --git a/src/librustc_error_codes/error_codes/E0525.md b/compiler/rustc_error_codes/src/error_codes/E0525.md
index a769440ca1b..a769440ca1b 100644
--- a/src/librustc_error_codes/error_codes/E0525.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0525.md
diff --git a/src/librustc_error_codes/error_codes/E0527.md b/compiler/rustc_error_codes/src/error_codes/E0527.md
index 97ea3126938..97ea3126938 100644
--- a/src/librustc_error_codes/error_codes/E0527.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0527.md
diff --git a/src/librustc_error_codes/error_codes/E0528.md b/compiler/rustc_error_codes/src/error_codes/E0528.md
index 54c2c4d4e9d..54c2c4d4e9d 100644
--- a/src/librustc_error_codes/error_codes/E0528.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0528.md
diff --git a/src/librustc_error_codes/error_codes/E0529.md b/compiler/rustc_error_codes/src/error_codes/E0529.md
index 013f438ba93..013f438ba93 100644
--- a/src/librustc_error_codes/error_codes/E0529.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0529.md
diff --git a/src/librustc_error_codes/error_codes/E0530.md b/compiler/rustc_error_codes/src/error_codes/E0530.md
index 502f674fc1d..502f674fc1d 100644
--- a/src/librustc_error_codes/error_codes/E0530.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0530.md
diff --git a/src/librustc_error_codes/error_codes/E0531.md b/compiler/rustc_error_codes/src/error_codes/E0531.md
index 2814046fbdd..2814046fbdd 100644
--- a/src/librustc_error_codes/error_codes/E0531.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0531.md
diff --git a/src/librustc_error_codes/error_codes/E0532.md b/compiler/rustc_error_codes/src/error_codes/E0532.md
index 6fb315a3716..6fb315a3716 100644
--- a/src/librustc_error_codes/error_codes/E0532.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0532.md
diff --git a/src/librustc_error_codes/error_codes/E0533.md b/compiler/rustc_error_codes/src/error_codes/E0533.md
index 279d728caae..279d728caae 100644
--- a/src/librustc_error_codes/error_codes/E0533.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0533.md
diff --git a/src/librustc_error_codes/error_codes/E0534.md b/compiler/rustc_error_codes/src/error_codes/E0534.md
index 1ca9411b8d4..1ca9411b8d4 100644
--- a/src/librustc_error_codes/error_codes/E0534.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0534.md
diff --git a/src/librustc_error_codes/error_codes/E0535.md b/compiler/rustc_error_codes/src/error_codes/E0535.md
index 0cf3118b02c..0cf3118b02c 100644
--- a/src/librustc_error_codes/error_codes/E0535.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0535.md
diff --git a/src/librustc_error_codes/error_codes/E0536.md b/compiler/rustc_error_codes/src/error_codes/E0536.md
index c081a3d9cfa..c081a3d9cfa 100644
--- a/src/librustc_error_codes/error_codes/E0536.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0536.md
diff --git a/src/librustc_error_codes/error_codes/E0537.md b/compiler/rustc_error_codes/src/error_codes/E0537.md
index 123efd4f57d..123efd4f57d 100644
--- a/src/librustc_error_codes/error_codes/E0537.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0537.md
diff --git a/src/librustc_error_codes/error_codes/E0538.md b/compiler/rustc_error_codes/src/error_codes/E0538.md
index 5858771ce88..5858771ce88 100644
--- a/src/librustc_error_codes/error_codes/E0538.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0538.md
diff --git a/src/librustc_error_codes/error_codes/E0539.md b/compiler/rustc_error_codes/src/error_codes/E0539.md
index df2d7d910bb..df2d7d910bb 100644
--- a/src/librustc_error_codes/error_codes/E0539.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0539.md
diff --git a/src/librustc_error_codes/error_codes/E0541.md b/compiler/rustc_error_codes/src/error_codes/E0541.md
index 96334088fee..96334088fee 100644
--- a/src/librustc_error_codes/error_codes/E0541.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0541.md
diff --git a/src/librustc_error_codes/error_codes/E0550.md b/compiler/rustc_error_codes/src/error_codes/E0550.md
index 1487d701847..1487d701847 100644
--- a/src/librustc_error_codes/error_codes/E0550.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0550.md
diff --git a/src/librustc_error_codes/error_codes/E0551.md b/compiler/rustc_error_codes/src/error_codes/E0551.md
index 53db559a4fc..53db559a4fc 100644
--- a/src/librustc_error_codes/error_codes/E0551.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0551.md
diff --git a/src/librustc_error_codes/error_codes/E0552.md b/compiler/rustc_error_codes/src/error_codes/E0552.md
index 0fbc861fb7c..0fbc861fb7c 100644
--- a/src/librustc_error_codes/error_codes/E0552.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0552.md
diff --git a/src/librustc_error_codes/error_codes/E0554.md b/compiler/rustc_error_codes/src/error_codes/E0554.md
index e55fa4c6ede..e55fa4c6ede 100644
--- a/src/librustc_error_codes/error_codes/E0554.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0554.md
diff --git a/src/librustc_error_codes/error_codes/E0556.md b/compiler/rustc_error_codes/src/error_codes/E0556.md
index 2aac8240d29..2aac8240d29 100644
--- a/src/librustc_error_codes/error_codes/E0556.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0556.md
diff --git a/src/librustc_error_codes/error_codes/E0557.md b/compiler/rustc_error_codes/src/error_codes/E0557.md
index f330efe5933..f330efe5933 100644
--- a/src/librustc_error_codes/error_codes/E0557.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0557.md
diff --git a/src/librustc_error_codes/error_codes/E0559.md b/compiler/rustc_error_codes/src/error_codes/E0559.md
index b9f7b650892..b9f7b650892 100644
--- a/src/librustc_error_codes/error_codes/E0559.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0559.md
diff --git a/src/librustc_error_codes/error_codes/E0560.md b/compiler/rustc_error_codes/src/error_codes/E0560.md
index 7185bf38c23..7185bf38c23 100644
--- a/src/librustc_error_codes/error_codes/E0560.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0560.md
diff --git a/src/librustc_error_codes/error_codes/E0561.md b/compiler/rustc_error_codes/src/error_codes/E0561.md
index 52900189014..52900189014 100644
--- a/src/librustc_error_codes/error_codes/E0561.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0561.md
diff --git a/src/librustc_error_codes/error_codes/E0562.md b/compiler/rustc_error_codes/src/error_codes/E0562.md
index 95f038df56d..95f038df56d 100644
--- a/src/librustc_error_codes/error_codes/E0562.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0562.md
diff --git a/src/librustc_error_codes/error_codes/E0565.md b/compiler/rustc_error_codes/src/error_codes/E0565.md
index d5bba941c1d..d5bba941c1d 100644
--- a/src/librustc_error_codes/error_codes/E0565.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0565.md
diff --git a/src/librustc_error_codes/error_codes/E0566.md b/compiler/rustc_error_codes/src/error_codes/E0566.md
index 3dcd801a21a..3dcd801a21a 100644
--- a/src/librustc_error_codes/error_codes/E0566.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0566.md
diff --git a/src/librustc_error_codes/error_codes/E0567.md b/compiler/rustc_error_codes/src/error_codes/E0567.md
index 05cf8fed031..05cf8fed031 100644
--- a/src/librustc_error_codes/error_codes/E0567.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0567.md
diff --git a/src/librustc_error_codes/error_codes/E0568.md b/compiler/rustc_error_codes/src/error_codes/E0568.md
index a37381f1cbd..a37381f1cbd 100644
--- a/src/librustc_error_codes/error_codes/E0568.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0568.md
diff --git a/src/librustc_error_codes/error_codes/E0569.md b/compiler/rustc_error_codes/src/error_codes/E0569.md
index 2ca2b57ecac..2ca2b57ecac 100644
--- a/src/librustc_error_codes/error_codes/E0569.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0569.md
diff --git a/src/librustc_error_codes/error_codes/E0570.md b/compiler/rustc_error_codes/src/error_codes/E0570.md
index 355e71ffb43..355e71ffb43 100644
--- a/src/librustc_error_codes/error_codes/E0570.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0570.md
diff --git a/src/librustc_error_codes/error_codes/E0571.md b/compiler/rustc_error_codes/src/error_codes/E0571.md
index eadae05aa30..eadae05aa30 100644
--- a/src/librustc_error_codes/error_codes/E0571.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0571.md
diff --git a/src/librustc_error_codes/error_codes/E0572.md b/compiler/rustc_error_codes/src/error_codes/E0572.md
index b2660650f1b..b2660650f1b 100644
--- a/src/librustc_error_codes/error_codes/E0572.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0572.md
diff --git a/src/librustc_error_codes/error_codes/E0573.md b/compiler/rustc_error_codes/src/error_codes/E0573.md
index 6021ed0ef21..6021ed0ef21 100644
--- a/src/librustc_error_codes/error_codes/E0573.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0573.md
diff --git a/src/librustc_error_codes/error_codes/E0574.md b/compiler/rustc_error_codes/src/error_codes/E0574.md
index 8154d5b782e..8154d5b782e 100644
--- a/src/librustc_error_codes/error_codes/E0574.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0574.md
diff --git a/src/librustc_error_codes/error_codes/E0575.md b/compiler/rustc_error_codes/src/error_codes/E0575.md
index 903939a9af9..903939a9af9 100644
--- a/src/librustc_error_codes/error_codes/E0575.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0575.md
diff --git a/src/librustc_error_codes/error_codes/E0576.md b/compiler/rustc_error_codes/src/error_codes/E0576.md
index 8eead4e7e3b..8eead4e7e3b 100644
--- a/src/librustc_error_codes/error_codes/E0576.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0576.md
diff --git a/src/librustc_error_codes/error_codes/E0577.md b/compiler/rustc_error_codes/src/error_codes/E0577.md
index 1feb9c0acf3..1feb9c0acf3 100644
--- a/src/librustc_error_codes/error_codes/E0577.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0577.md
diff --git a/src/librustc_error_codes/error_codes/E0578.md b/compiler/rustc_error_codes/src/error_codes/E0578.md
index fca89757287..fca89757287 100644
--- a/src/librustc_error_codes/error_codes/E0578.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0578.md
diff --git a/src/librustc_error_codes/error_codes/E0579.md b/compiler/rustc_error_codes/src/error_codes/E0579.md
index f554242a3d4..f554242a3d4 100644
--- a/src/librustc_error_codes/error_codes/E0579.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0579.md
diff --git a/src/librustc_error_codes/error_codes/E0580.md b/compiler/rustc_error_codes/src/error_codes/E0580.md
index 260575d5de4..260575d5de4 100644
--- a/src/librustc_error_codes/error_codes/E0580.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0580.md
diff --git a/src/librustc_error_codes/error_codes/E0581.md b/compiler/rustc_error_codes/src/error_codes/E0581.md
index 89f6e3269ec..89f6e3269ec 100644
--- a/src/librustc_error_codes/error_codes/E0581.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0581.md
diff --git a/src/librustc_error_codes/error_codes/E0582.md b/compiler/rustc_error_codes/src/error_codes/E0582.md
index e50cc60ea33..e50cc60ea33 100644
--- a/src/librustc_error_codes/error_codes/E0582.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0582.md
diff --git a/src/librustc_error_codes/error_codes/E0583.md b/compiler/rustc_error_codes/src/error_codes/E0583.md
index 701900bb0cd..701900bb0cd 100644
--- a/src/librustc_error_codes/error_codes/E0583.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0583.md
diff --git a/src/librustc_error_codes/error_codes/E0584.md b/compiler/rustc_error_codes/src/error_codes/E0584.md
index 8b00655ee78..8b00655ee78 100644
--- a/src/librustc_error_codes/error_codes/E0584.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0584.md
diff --git a/src/librustc_error_codes/error_codes/E0585.md b/compiler/rustc_error_codes/src/error_codes/E0585.md
index de27cc19d18..de27cc19d18 100644
--- a/src/librustc_error_codes/error_codes/E0585.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0585.md
diff --git a/src/librustc_error_codes/error_codes/E0586.md b/compiler/rustc_error_codes/src/error_codes/E0586.md
index bc6572ecadb..bc6572ecadb 100644
--- a/src/librustc_error_codes/error_codes/E0586.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0586.md
diff --git a/src/librustc_error_codes/error_codes/E0587.md b/compiler/rustc_error_codes/src/error_codes/E0587.md
index ee9031dc379..ee9031dc379 100644
--- a/src/librustc_error_codes/error_codes/E0587.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0587.md
diff --git a/src/librustc_error_codes/error_codes/E0588.md b/compiler/rustc_error_codes/src/error_codes/E0588.md
index 040c7a02ef4..040c7a02ef4 100644
--- a/src/librustc_error_codes/error_codes/E0588.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0588.md
diff --git a/src/librustc_error_codes/error_codes/E0589.md b/compiler/rustc_error_codes/src/error_codes/E0589.md
index 8a4f8d21725..8a4f8d21725 100644
--- a/src/librustc_error_codes/error_codes/E0589.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0589.md
diff --git a/src/librustc_error_codes/error_codes/E0590.md b/compiler/rustc_error_codes/src/error_codes/E0590.md
index 11005b8336f..11005b8336f 100644
--- a/src/librustc_error_codes/error_codes/E0590.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0590.md
diff --git a/src/librustc_error_codes/error_codes/E0591.md b/compiler/rustc_error_codes/src/error_codes/E0591.md
index 7f68815b1c2..7f68815b1c2 100644
--- a/src/librustc_error_codes/error_codes/E0591.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0591.md
diff --git a/src/librustc_error_codes/error_codes/E0592.md b/compiler/rustc_error_codes/src/error_codes/E0592.md
index 06959b5d765..06959b5d765 100644
--- a/src/librustc_error_codes/error_codes/E0592.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0592.md
diff --git a/src/librustc_error_codes/error_codes/E0593.md b/compiler/rustc_error_codes/src/error_codes/E0593.md
index 1902d73f4d0..1902d73f4d0 100644
--- a/src/librustc_error_codes/error_codes/E0593.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0593.md
diff --git a/src/librustc_error_codes/error_codes/E0594.md b/compiler/rustc_error_codes/src/error_codes/E0594.md
index ad8eb631e63..ad8eb631e63 100644
--- a/src/librustc_error_codes/error_codes/E0594.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0594.md
diff --git a/src/librustc_error_codes/error_codes/E0595.md b/compiler/rustc_error_codes/src/error_codes/E0595.md
index e6729013243..e6729013243 100644
--- a/src/librustc_error_codes/error_codes/E0595.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0595.md
diff --git a/src/librustc_error_codes/error_codes/E0596.md b/compiler/rustc_error_codes/src/error_codes/E0596.md
index 95669309b3b..95669309b3b 100644
--- a/src/librustc_error_codes/error_codes/E0596.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0596.md
diff --git a/src/librustc_error_codes/error_codes/E0597.md b/compiler/rustc_error_codes/src/error_codes/E0597.md
index 3340768fa82..3340768fa82 100644
--- a/src/librustc_error_codes/error_codes/E0597.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0597.md
diff --git a/src/librustc_error_codes/error_codes/E0599.md b/compiler/rustc_error_codes/src/error_codes/E0599.md
index 5b1590b2999..5b1590b2999 100644
--- a/src/librustc_error_codes/error_codes/E0599.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0599.md
diff --git a/src/librustc_error_codes/error_codes/E0600.md b/compiler/rustc_error_codes/src/error_codes/E0600.md
index 356006c72f3..356006c72f3 100644
--- a/src/librustc_error_codes/error_codes/E0600.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0600.md
diff --git a/src/librustc_error_codes/error_codes/E0601.md b/compiler/rustc_error_codes/src/error_codes/E0601.md
index 7194b7971d3..7194b7971d3 100644
--- a/src/librustc_error_codes/error_codes/E0601.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0601.md
diff --git a/src/librustc_error_codes/error_codes/E0602.md b/compiler/rustc_error_codes/src/error_codes/E0602.md
index dcaf251a96b..dcaf251a96b 100644
--- a/src/librustc_error_codes/error_codes/E0602.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0602.md
diff --git a/src/librustc_error_codes/error_codes/E0603.md b/compiler/rustc_error_codes/src/error_codes/E0603.md
index 69fefce3908..69fefce3908 100644
--- a/src/librustc_error_codes/error_codes/E0603.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0603.md
diff --git a/src/librustc_error_codes/error_codes/E0604.md b/compiler/rustc_error_codes/src/error_codes/E0604.md
index adbf76509ed..adbf76509ed 100644
--- a/src/librustc_error_codes/error_codes/E0604.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0604.md
diff --git a/src/librustc_error_codes/error_codes/E0605.md b/compiler/rustc_error_codes/src/error_codes/E0605.md
index f3cc65dd8cf..f3cc65dd8cf 100644
--- a/src/librustc_error_codes/error_codes/E0605.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0605.md
diff --git a/src/librustc_error_codes/error_codes/E0606.md b/compiler/rustc_error_codes/src/error_codes/E0606.md
index 06ee7497fdf..06ee7497fdf 100644
--- a/src/librustc_error_codes/error_codes/E0606.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0606.md
diff --git a/src/librustc_error_codes/error_codes/E0607.md b/compiler/rustc_error_codes/src/error_codes/E0607.md
index ea6e10105b0..ea6e10105b0 100644
--- a/src/librustc_error_codes/error_codes/E0607.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0607.md
diff --git a/src/librustc_error_codes/error_codes/E0608.md b/compiler/rustc_error_codes/src/error_codes/E0608.md
index d0ebc3a26f0..d0ebc3a26f0 100644
--- a/src/librustc_error_codes/error_codes/E0608.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0608.md
diff --git a/src/librustc_error_codes/error_codes/E0609.md b/compiler/rustc_error_codes/src/error_codes/E0609.md
index a9db34f474e..a9db34f474e 100644
--- a/src/librustc_error_codes/error_codes/E0609.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0609.md
diff --git a/src/librustc_error_codes/error_codes/E0610.md b/compiler/rustc_error_codes/src/error_codes/E0610.md
index c737bd618c3..c737bd618c3 100644
--- a/src/librustc_error_codes/error_codes/E0610.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0610.md
diff --git a/src/librustc_error_codes/error_codes/E0614.md b/compiler/rustc_error_codes/src/error_codes/E0614.md
index d0ed06ebcee..d0ed06ebcee 100644
--- a/src/librustc_error_codes/error_codes/E0614.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0614.md
diff --git a/src/librustc_error_codes/error_codes/E0615.md b/compiler/rustc_error_codes/src/error_codes/E0615.md
index f513d059625..f513d059625 100644
--- a/src/librustc_error_codes/error_codes/E0615.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0615.md
diff --git a/src/librustc_error_codes/error_codes/E0616.md b/compiler/rustc_error_codes/src/error_codes/E0616.md
index 5acbc6e44e1..5acbc6e44e1 100644
--- a/src/librustc_error_codes/error_codes/E0616.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0616.md
diff --git a/src/librustc_error_codes/error_codes/E0617.md b/compiler/rustc_error_codes/src/error_codes/E0617.md
index 61b56766c26..61b56766c26 100644
--- a/src/librustc_error_codes/error_codes/E0617.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0617.md
diff --git a/src/librustc_error_codes/error_codes/E0618.md b/compiler/rustc_error_codes/src/error_codes/E0618.md
index c8dc9040cf1..c8dc9040cf1 100644
--- a/src/librustc_error_codes/error_codes/E0618.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0618.md
diff --git a/src/librustc_error_codes/error_codes/E0619.md b/compiler/rustc_error_codes/src/error_codes/E0619.md
index f516de43095..f516de43095 100644
--- a/src/librustc_error_codes/error_codes/E0619.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0619.md
diff --git a/src/librustc_error_codes/error_codes/E0620.md b/compiler/rustc_error_codes/src/error_codes/E0620.md
index f8e442807e5..f8e442807e5 100644
--- a/src/librustc_error_codes/error_codes/E0620.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0620.md
diff --git a/src/librustc_error_codes/error_codes/E0621.md b/compiler/rustc_error_codes/src/error_codes/E0621.md
index 7c0878df25e..7c0878df25e 100644
--- a/src/librustc_error_codes/error_codes/E0621.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0621.md
diff --git a/src/librustc_error_codes/error_codes/E0622.md b/compiler/rustc_error_codes/src/error_codes/E0622.md
index 990a2549412..990a2549412 100644
--- a/src/librustc_error_codes/error_codes/E0622.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0622.md
diff --git a/src/librustc_error_codes/error_codes/E0623.md b/compiler/rustc_error_codes/src/error_codes/E0623.md
index 1290edd0a0e..1290edd0a0e 100644
--- a/src/librustc_error_codes/error_codes/E0623.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0623.md
diff --git a/src/librustc_error_codes/error_codes/E0624.md b/compiler/rustc_error_codes/src/error_codes/E0624.md
index 0fd21c44b3d..0fd21c44b3d 100644
--- a/src/librustc_error_codes/error_codes/E0624.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0624.md
diff --git a/src/librustc_error_codes/error_codes/E0626.md b/compiler/rustc_error_codes/src/error_codes/E0626.md
index cc6e03d1ca7..cc6e03d1ca7 100644
--- a/src/librustc_error_codes/error_codes/E0626.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0626.md
diff --git a/src/librustc_error_codes/error_codes/E0627.md b/compiler/rustc_error_codes/src/error_codes/E0627.md
index 21358e1e567..21358e1e567 100644
--- a/src/librustc_error_codes/error_codes/E0627.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0627.md
diff --git a/src/librustc_error_codes/error_codes/E0628.md b/compiler/rustc_error_codes/src/error_codes/E0628.md
index 40040c9a56a..40040c9a56a 100644
--- a/src/librustc_error_codes/error_codes/E0628.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0628.md
diff --git a/src/librustc_error_codes/error_codes/E0631.md b/compiler/rustc_error_codes/src/error_codes/E0631.md
index 6188d5f61a7..6188d5f61a7 100644
--- a/src/librustc_error_codes/error_codes/E0631.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0631.md
diff --git a/src/librustc_error_codes/error_codes/E0633.md b/compiler/rustc_error_codes/src/error_codes/E0633.md
index 7f488cde664..7f488cde664 100644
--- a/src/librustc_error_codes/error_codes/E0633.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0633.md
diff --git a/src/librustc_error_codes/error_codes/E0634.md b/compiler/rustc_error_codes/src/error_codes/E0634.md
index 0c4ed2596e2..0c4ed2596e2 100644
--- a/src/librustc_error_codes/error_codes/E0634.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0634.md
diff --git a/src/librustc_error_codes/error_codes/E0635.md b/compiler/rustc_error_codes/src/error_codes/E0635.md
index a39d2be4f8f..a39d2be4f8f 100644
--- a/src/librustc_error_codes/error_codes/E0635.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0635.md
diff --git a/src/librustc_error_codes/error_codes/E0636.md b/compiler/rustc_error_codes/src/error_codes/E0636.md
index 57cf72db556..57cf72db556 100644
--- a/src/librustc_error_codes/error_codes/E0636.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0636.md
diff --git a/src/librustc_error_codes/error_codes/E0637.md b/compiler/rustc_error_codes/src/error_codes/E0637.md
index d9068950bdf..d9068950bdf 100644
--- a/src/librustc_error_codes/error_codes/E0637.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0637.md
diff --git a/src/librustc_error_codes/error_codes/E0638.md b/compiler/rustc_error_codes/src/error_codes/E0638.md
index 14cd31502b6..14cd31502b6 100644
--- a/src/librustc_error_codes/error_codes/E0638.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0638.md
diff --git a/src/librustc_error_codes/error_codes/E0639.md b/compiler/rustc_error_codes/src/error_codes/E0639.md
index 4646e37fb75..4646e37fb75 100644
--- a/src/librustc_error_codes/error_codes/E0639.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0639.md
diff --git a/src/librustc_error_codes/error_codes/E0641.md b/compiler/rustc_error_codes/src/error_codes/E0641.md
index 5848e9b5c05..5848e9b5c05 100644
--- a/src/librustc_error_codes/error_codes/E0641.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0641.md
diff --git a/src/librustc_error_codes/error_codes/E0642.md b/compiler/rustc_error_codes/src/error_codes/E0642.md
index c790aa154bd..c790aa154bd 100644
--- a/src/librustc_error_codes/error_codes/E0642.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0642.md
diff --git a/src/librustc_error_codes/error_codes/E0643.md b/compiler/rustc_error_codes/src/error_codes/E0643.md
index 53919607dfb..53919607dfb 100644
--- a/src/librustc_error_codes/error_codes/E0643.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0643.md
diff --git a/src/librustc_error_codes/error_codes/E0644.md b/compiler/rustc_error_codes/src/error_codes/E0644.md
index 8c68da3b2f3..8c68da3b2f3 100644
--- a/src/librustc_error_codes/error_codes/E0644.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0644.md
diff --git a/src/librustc_error_codes/error_codes/E0646.md b/compiler/rustc_error_codes/src/error_codes/E0646.md
index 1e9ec7d4380..1e9ec7d4380 100644
--- a/src/librustc_error_codes/error_codes/E0646.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0646.md
diff --git a/src/librustc_error_codes/error_codes/E0647.md b/compiler/rustc_error_codes/src/error_codes/E0647.md
index 8ca6e777f30..8ca6e777f30 100644
--- a/src/librustc_error_codes/error_codes/E0647.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0647.md
diff --git a/src/librustc_error_codes/error_codes/E0648.md b/compiler/rustc_error_codes/src/error_codes/E0648.md
index d99dc19503d..d99dc19503d 100644
--- a/src/librustc_error_codes/error_codes/E0648.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0648.md
diff --git a/src/librustc_error_codes/error_codes/E0657.md b/compiler/rustc_error_codes/src/error_codes/E0657.md
index 7fe48c51147..7fe48c51147 100644
--- a/src/librustc_error_codes/error_codes/E0657.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0657.md
diff --git a/src/librustc_error_codes/error_codes/E0658.md b/compiler/rustc_error_codes/src/error_codes/E0658.md
index d821b9027f1..d821b9027f1 100644
--- a/src/librustc_error_codes/error_codes/E0658.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0658.md
diff --git a/src/librustc_error_codes/error_codes/E0659.md b/compiler/rustc_error_codes/src/error_codes/E0659.md
index e2c7e25cc84..e2c7e25cc84 100644
--- a/src/librustc_error_codes/error_codes/E0659.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0659.md
diff --git a/src/librustc_error_codes/error_codes/E0660.md b/compiler/rustc_error_codes/src/error_codes/E0660.md
index fccd1b96f60..fccd1b96f60 100644
--- a/src/librustc_error_codes/error_codes/E0660.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0660.md
diff --git a/src/librustc_error_codes/error_codes/E0661.md b/compiler/rustc_error_codes/src/error_codes/E0661.md
index f1debee7a18..f1debee7a18 100644
--- a/src/librustc_error_codes/error_codes/E0661.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0661.md
diff --git a/src/librustc_error_codes/error_codes/E0662.md b/compiler/rustc_error_codes/src/error_codes/E0662.md
index d4765f078b0..d4765f078b0 100644
--- a/src/librustc_error_codes/error_codes/E0662.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0662.md
diff --git a/src/librustc_error_codes/error_codes/E0663.md b/compiler/rustc_error_codes/src/error_codes/E0663.md
index d5a85b275db..d5a85b275db 100644
--- a/src/librustc_error_codes/error_codes/E0663.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0663.md
diff --git a/src/librustc_error_codes/error_codes/E0664.md b/compiler/rustc_error_codes/src/error_codes/E0664.md
index ce9c9491df3..ce9c9491df3 100644
--- a/src/librustc_error_codes/error_codes/E0664.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0664.md
diff --git a/src/librustc_error_codes/error_codes/E0665.md b/compiler/rustc_error_codes/src/error_codes/E0665.md
index a15f4021c71..a15f4021c71 100644
--- a/src/librustc_error_codes/error_codes/E0665.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0665.md
diff --git a/src/librustc_error_codes/error_codes/E0666.md b/compiler/rustc_error_codes/src/error_codes/E0666.md
index 1a0dc5a5229..1a0dc5a5229 100644
--- a/src/librustc_error_codes/error_codes/E0666.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0666.md
diff --git a/src/librustc_error_codes/error_codes/E0668.md b/compiler/rustc_error_codes/src/error_codes/E0668.md
index b6fedfe53fc..b6fedfe53fc 100644
--- a/src/librustc_error_codes/error_codes/E0668.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0668.md
diff --git a/src/librustc_error_codes/error_codes/E0669.md b/compiler/rustc_error_codes/src/error_codes/E0669.md
index f078c441b34..f078c441b34 100644
--- a/src/librustc_error_codes/error_codes/E0669.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0669.md
diff --git a/src/librustc_error_codes/error_codes/E0670.md b/compiler/rustc_error_codes/src/error_codes/E0670.md
index 74c1af06cf4..74c1af06cf4 100644
--- a/src/librustc_error_codes/error_codes/E0670.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0670.md
diff --git a/src/librustc_error_codes/error_codes/E0671.md b/compiler/rustc_error_codes/src/error_codes/E0671.md
index a993ce826a7..a993ce826a7 100644
--- a/src/librustc_error_codes/error_codes/E0671.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0671.md
diff --git a/src/librustc_error_codes/error_codes/E0687.md b/compiler/rustc_error_codes/src/error_codes/E0687.md
index 67b7db2d31f..67b7db2d31f 100644
--- a/src/librustc_error_codes/error_codes/E0687.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0687.md
diff --git a/src/librustc_error_codes/error_codes/E0688.md b/compiler/rustc_error_codes/src/error_codes/E0688.md
index db50f490208..db50f490208 100644
--- a/src/librustc_error_codes/error_codes/E0688.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0688.md
diff --git a/src/librustc_error_codes/error_codes/E0689.md b/compiler/rustc_error_codes/src/error_codes/E0689.md
index a680a204211..a680a204211 100644
--- a/src/librustc_error_codes/error_codes/E0689.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0689.md
diff --git a/src/librustc_error_codes/error_codes/E0690.md b/compiler/rustc_error_codes/src/error_codes/E0690.md
index 1673456580a..1673456580a 100644
--- a/src/librustc_error_codes/error_codes/E0690.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0690.md
diff --git a/src/librustc_error_codes/error_codes/E0691.md b/compiler/rustc_error_codes/src/error_codes/E0691.md
index 60060cacbd6..60060cacbd6 100644
--- a/src/librustc_error_codes/error_codes/E0691.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0691.md
diff --git a/src/librustc_error_codes/error_codes/E0692.md b/compiler/rustc_error_codes/src/error_codes/E0692.md
index 596cb1e777e..596cb1e777e 100644
--- a/src/librustc_error_codes/error_codes/E0692.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0692.md
diff --git a/src/librustc_error_codes/error_codes/E0693.md b/compiler/rustc_error_codes/src/error_codes/E0693.md
index 43e9d17979e..43e9d17979e 100644
--- a/src/librustc_error_codes/error_codes/E0693.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0693.md
diff --git a/src/librustc_error_codes/error_codes/E0695.md b/compiler/rustc_error_codes/src/error_codes/E0695.md
index 5013e83ca03..5013e83ca03 100644
--- a/src/librustc_error_codes/error_codes/E0695.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0695.md
diff --git a/src/librustc_error_codes/error_codes/E0696.md b/compiler/rustc_error_codes/src/error_codes/E0696.md
index fc32d1cc5f7..fc32d1cc5f7 100644
--- a/src/librustc_error_codes/error_codes/E0696.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0696.md
diff --git a/src/librustc_error_codes/error_codes/E0697.md b/compiler/rustc_error_codes/src/error_codes/E0697.md
index ab63d2e73f7..ab63d2e73f7 100644
--- a/src/librustc_error_codes/error_codes/E0697.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0697.md
diff --git a/src/librustc_error_codes/error_codes/E0698.md b/compiler/rustc_error_codes/src/error_codes/E0698.md
index 3ba992a8476..3ba992a8476 100644
--- a/src/librustc_error_codes/error_codes/E0698.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0698.md
diff --git a/src/librustc_error_codes/error_codes/E0699.md b/compiler/rustc_error_codes/src/error_codes/E0699.md
index 454d2507e5e..454d2507e5e 100644
--- a/src/librustc_error_codes/error_codes/E0699.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0699.md
diff --git a/src/librustc_error_codes/error_codes/E0700.md b/compiler/rustc_error_codes/src/error_codes/E0700.md
index b1eb8b66ad6..b1eb8b66ad6 100644
--- a/src/librustc_error_codes/error_codes/E0700.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0700.md
diff --git a/src/librustc_error_codes/error_codes/E0701.md b/compiler/rustc_error_codes/src/error_codes/E0701.md
index 4965e643105..4965e643105 100644
--- a/src/librustc_error_codes/error_codes/E0701.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0701.md
diff --git a/src/librustc_error_codes/error_codes/E0703.md b/compiler/rustc_error_codes/src/error_codes/E0703.md
index b42677d52cb..b42677d52cb 100644
--- a/src/librustc_error_codes/error_codes/E0703.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0703.md
diff --git a/src/librustc_error_codes/error_codes/E0704.md b/compiler/rustc_error_codes/src/error_codes/E0704.md
index c22b274fb22..c22b274fb22 100644
--- a/src/librustc_error_codes/error_codes/E0704.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0704.md
diff --git a/src/librustc_error_codes/error_codes/E0705.md b/compiler/rustc_error_codes/src/error_codes/E0705.md
index 1edd47de4cb..1edd47de4cb 100644
--- a/src/librustc_error_codes/error_codes/E0705.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0705.md
diff --git a/src/librustc_error_codes/error_codes/E0706.md b/compiler/rustc_error_codes/src/error_codes/E0706.md
index d379b8a2384..d379b8a2384 100644
--- a/src/librustc_error_codes/error_codes/E0706.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0706.md
diff --git a/src/librustc_error_codes/error_codes/E0708.md b/compiler/rustc_error_codes/src/error_codes/E0708.md
index 9287fc803d1..9287fc803d1 100644
--- a/src/librustc_error_codes/error_codes/E0708.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0708.md
diff --git a/src/librustc_error_codes/error_codes/E0710.md b/compiler/rustc_error_codes/src/error_codes/E0710.md
index b7037ea611b..b7037ea611b 100644
--- a/src/librustc_error_codes/error_codes/E0710.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0710.md
diff --git a/src/librustc_error_codes/error_codes/E0712.md b/compiler/rustc_error_codes/src/error_codes/E0712.md
index 7e09210e787..7e09210e787 100644
--- a/src/librustc_error_codes/error_codes/E0712.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0712.md
diff --git a/src/librustc_error_codes/error_codes/E0713.md b/compiler/rustc_error_codes/src/error_codes/E0713.md
index 9361046943f..9361046943f 100644
--- a/src/librustc_error_codes/error_codes/E0713.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0713.md
diff --git a/src/librustc_error_codes/error_codes/E0714.md b/compiler/rustc_error_codes/src/error_codes/E0714.md
index 45d1cafa690..45d1cafa690 100644
--- a/src/librustc_error_codes/error_codes/E0714.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0714.md
diff --git a/src/librustc_error_codes/error_codes/E0715.md b/compiler/rustc_error_codes/src/error_codes/E0715.md
index b27702b3c26..b27702b3c26 100644
--- a/src/librustc_error_codes/error_codes/E0715.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0715.md
diff --git a/src/librustc_error_codes/error_codes/E0716.md b/compiler/rustc_error_codes/src/error_codes/E0716.md
index c6d0337ddda..c6d0337ddda 100644
--- a/src/librustc_error_codes/error_codes/E0716.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0716.md
diff --git a/src/librustc_error_codes/error_codes/E0718.md b/compiler/rustc_error_codes/src/error_codes/E0718.md
index 1fe62ecf1f4..1fe62ecf1f4 100644
--- a/src/librustc_error_codes/error_codes/E0718.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0718.md
diff --git a/src/librustc_error_codes/error_codes/E0719.md b/compiler/rustc_error_codes/src/error_codes/E0719.md
index 057a0b1645c..057a0b1645c 100644
--- a/src/librustc_error_codes/error_codes/E0719.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0719.md
diff --git a/src/librustc_error_codes/error_codes/E0720.md b/compiler/rustc_error_codes/src/error_codes/E0720.md
index 40dfa484d3f..40dfa484d3f 100644
--- a/src/librustc_error_codes/error_codes/E0720.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0720.md
diff --git a/src/librustc_error_codes/error_codes/E0723.md b/compiler/rustc_error_codes/src/error_codes/E0723.md
index 95d47ab21cb..95d47ab21cb 100644
--- a/src/librustc_error_codes/error_codes/E0723.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0723.md
diff --git a/src/librustc_error_codes/error_codes/E0724.md b/compiler/rustc_error_codes/src/error_codes/E0724.md
index e8f84d0fc7d..e8f84d0fc7d 100644
--- a/src/librustc_error_codes/error_codes/E0724.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0724.md
diff --git a/src/librustc_error_codes/error_codes/E0725.md b/compiler/rustc_error_codes/src/error_codes/E0725.md
index 9bd321e5f82..9bd321e5f82 100644
--- a/src/librustc_error_codes/error_codes/E0725.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0725.md
diff --git a/src/librustc_error_codes/error_codes/E0727.md b/compiler/rustc_error_codes/src/error_codes/E0727.md
index 386daea0c57..386daea0c57 100644
--- a/src/librustc_error_codes/error_codes/E0727.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0727.md
diff --git a/src/librustc_error_codes/error_codes/E0728.md b/compiler/rustc_error_codes/src/error_codes/E0728.md
index f4968a4f00e..f4968a4f00e 100644
--- a/src/librustc_error_codes/error_codes/E0728.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0728.md
diff --git a/src/librustc_error_codes/error_codes/E0729.md b/compiler/rustc_error_codes/src/error_codes/E0729.md
index 74f89080b91..74f89080b91 100644
--- a/src/librustc_error_codes/error_codes/E0729.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0729.md
diff --git a/src/librustc_error_codes/error_codes/E0730.md b/compiler/rustc_error_codes/src/error_codes/E0730.md
index 016b3f38aa3..016b3f38aa3 100644
--- a/src/librustc_error_codes/error_codes/E0730.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0730.md
diff --git a/src/librustc_error_codes/error_codes/E0731.md b/compiler/rustc_error_codes/src/error_codes/E0731.md
index 096c053fe83..096c053fe83 100644
--- a/src/librustc_error_codes/error_codes/E0731.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0731.md
diff --git a/src/librustc_error_codes/error_codes/E0732.md b/compiler/rustc_error_codes/src/error_codes/E0732.md
index 7347e6654c5..7347e6654c5 100644
--- a/src/librustc_error_codes/error_codes/E0732.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0732.md
diff --git a/src/librustc_error_codes/error_codes/E0733.md b/compiler/rustc_error_codes/src/error_codes/E0733.md
index 051b75148e5..051b75148e5 100644
--- a/src/librustc_error_codes/error_codes/E0733.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0733.md
diff --git a/src/librustc_error_codes/error_codes/E0734.md b/compiler/rustc_error_codes/src/error_codes/E0734.md
index 4b8e89a7060..4b8e89a7060 100644
--- a/src/librustc_error_codes/error_codes/E0734.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0734.md
diff --git a/src/librustc_error_codes/error_codes/E0735.md b/compiler/rustc_error_codes/src/error_codes/E0735.md
index e8268a5836c..e8268a5836c 100644
--- a/src/librustc_error_codes/error_codes/E0735.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0735.md
diff --git a/src/librustc_error_codes/error_codes/E0736.md b/compiler/rustc_error_codes/src/error_codes/E0736.md
index 0f3d41ba66d..0f3d41ba66d 100644
--- a/src/librustc_error_codes/error_codes/E0736.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0736.md
diff --git a/src/librustc_error_codes/error_codes/E0737.md b/compiler/rustc_error_codes/src/error_codes/E0737.md
index ab5e60692b4..ab5e60692b4 100644
--- a/src/librustc_error_codes/error_codes/E0737.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0737.md
diff --git a/src/librustc_error_codes/error_codes/E0739.md b/compiler/rustc_error_codes/src/error_codes/E0739.md
index 8d9039bef93..8d9039bef93 100644
--- a/src/librustc_error_codes/error_codes/E0739.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0739.md
diff --git a/src/librustc_error_codes/error_codes/E0740.md b/compiler/rustc_error_codes/src/error_codes/E0740.md
index 6240099a99f..6240099a99f 100644
--- a/src/librustc_error_codes/error_codes/E0740.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0740.md
diff --git a/src/librustc_error_codes/error_codes/E0741.md b/compiler/rustc_error_codes/src/error_codes/E0741.md
index 91379bfe05c..91379bfe05c 100644
--- a/src/librustc_error_codes/error_codes/E0741.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0741.md
diff --git a/src/librustc_error_codes/error_codes/E0742.md b/compiler/rustc_error_codes/src/error_codes/E0742.md
index fed9f1f4cee..fed9f1f4cee 100644
--- a/src/librustc_error_codes/error_codes/E0742.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0742.md
diff --git a/src/librustc_error_codes/error_codes/E0743.md b/compiler/rustc_error_codes/src/error_codes/E0743.md
index ddd3136df0c..ddd3136df0c 100644
--- a/src/librustc_error_codes/error_codes/E0743.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0743.md
diff --git a/src/librustc_error_codes/error_codes/E0744.md b/compiler/rustc_error_codes/src/error_codes/E0744.md
index 14cff3613e0..14cff3613e0 100644
--- a/src/librustc_error_codes/error_codes/E0744.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0744.md
diff --git a/src/librustc_error_codes/error_codes/E0745.md b/compiler/rustc_error_codes/src/error_codes/E0745.md
index 23ee7af30f4..23ee7af30f4 100644
--- a/src/librustc_error_codes/error_codes/E0745.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0745.md
diff --git a/src/librustc_error_codes/error_codes/E0746.md b/compiler/rustc_error_codes/src/error_codes/E0746.md
index 90755d47f67..90755d47f67 100644
--- a/src/librustc_error_codes/error_codes/E0746.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0746.md
diff --git a/src/librustc_error_codes/error_codes/E0747.md b/compiler/rustc_error_codes/src/error_codes/E0747.md
index caf7e0fba07..caf7e0fba07 100644
--- a/src/librustc_error_codes/error_codes/E0747.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0747.md
diff --git a/src/librustc_error_codes/error_codes/E0748.md b/compiler/rustc_error_codes/src/error_codes/E0748.md
index 69f1c026125..69f1c026125 100644
--- a/src/librustc_error_codes/error_codes/E0748.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0748.md
diff --git a/src/librustc_error_codes/error_codes/E0749.md b/compiler/rustc_error_codes/src/error_codes/E0749.md
index dfe90ae89e4..dfe90ae89e4 100644
--- a/src/librustc_error_codes/error_codes/E0749.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0749.md
diff --git a/src/librustc_error_codes/error_codes/E0750.md b/compiler/rustc_error_codes/src/error_codes/E0750.md
index 905e852f8d5..905e852f8d5 100644
--- a/src/librustc_error_codes/error_codes/E0750.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0750.md
diff --git a/src/librustc_error_codes/error_codes/E0751.md b/compiler/rustc_error_codes/src/error_codes/E0751.md
index 8794f7868f3..8794f7868f3 100644
--- a/src/librustc_error_codes/error_codes/E0751.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0751.md
diff --git a/src/librustc_error_codes/error_codes/E0752.md b/compiler/rustc_error_codes/src/error_codes/E0752.md
index 9736da80c2b..9736da80c2b 100644
--- a/src/librustc_error_codes/error_codes/E0752.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0752.md
diff --git a/src/librustc_error_codes/error_codes/E0753.md b/compiler/rustc_error_codes/src/error_codes/E0753.md
index a69da964aee..a69da964aee 100644
--- a/src/librustc_error_codes/error_codes/E0753.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0753.md
diff --git a/src/librustc_error_codes/error_codes/E0754.md b/compiler/rustc_error_codes/src/error_codes/E0754.md
index 57620bcd65c..57620bcd65c 100644
--- a/src/librustc_error_codes/error_codes/E0754.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0754.md
diff --git a/src/librustc_error_codes/error_codes/E0758.md b/compiler/rustc_error_codes/src/error_codes/E0758.md
index ddca4b3d75f..ddca4b3d75f 100644
--- a/src/librustc_error_codes/error_codes/E0758.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0758.md
diff --git a/src/librustc_error_codes/error_codes/E0759.md b/compiler/rustc_error_codes/src/error_codes/E0759.md
index 6d525310f75..6d525310f75 100644
--- a/src/librustc_error_codes/error_codes/E0759.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0759.md
diff --git a/src/librustc_error_codes/error_codes/E0760.md b/compiler/rustc_error_codes/src/error_codes/E0760.md
index e1dcfefebcd..e1dcfefebcd 100644
--- a/src/librustc_error_codes/error_codes/E0760.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0760.md
diff --git a/src/librustc_error_codes/error_codes/E0761.md b/compiler/rustc_error_codes/src/error_codes/E0761.md
index e112674fbcc..e112674fbcc 100644
--- a/src/librustc_error_codes/error_codes/E0761.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0761.md
diff --git a/src/librustc_error_codes/error_codes/E0762.md b/compiler/rustc_error_codes/src/error_codes/E0762.md
index b01ded4a866..b01ded4a866 100644
--- a/src/librustc_error_codes/error_codes/E0762.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0762.md
diff --git a/src/librustc_error_codes/error_codes/E0763.md b/compiler/rustc_error_codes/src/error_codes/E0763.md
index 095b779f3e7..095b779f3e7 100644
--- a/src/librustc_error_codes/error_codes/E0763.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0763.md
diff --git a/src/librustc_error_codes/error_codes/E0764.md b/compiler/rustc_error_codes/src/error_codes/E0764.md
index e9061f988ac..0a2e2290e77 100644
--- a/src/librustc_error_codes/error_codes/E0764.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0764.md
@@ -1,12 +1,4 @@
-Mutable references (`&mut`) can only be used in constant functions, not statics
-or constants. This limitation exists to prevent the creation of constants that
-have a mutable reference in their final value. If you had a constant of `&mut
-i32` type, you could modify the value through that reference, making the
-constant essentially mutable. While there could be a more fine-grained scheme
-in the future that allows mutable references if they are not "leaked" to the
-final value, a more conservative approach was chosen for now. `const fn` do not
-have this problem, as the borrow checker will prevent the `const fn` from
-returning new mutable references.
+A mutable reference was used in a constant.
 
 Erroneous code example:
 
@@ -19,6 +11,18 @@ fn main() {
 }
 ```
 
+Mutable references (`&mut`) can only be used in constant functions, not statics
+or constants. This limitation exists to prevent the creation of constants that
+have a mutable reference in their final value. If you had a constant of
+`&mut i32` type, you could modify the value through that reference, making the
+constant essentially mutable.
+
+While there could be a more fine-grained scheme in the future that allows
+mutable references if they are not "leaked" to the final value, a more
+conservative approach was chosen for now. `const fn` do not have this problem,
+as the borrow checker will prevent the `const fn` from returning new mutable
+references.
+
 Remember: you cannot use a function call inside a constant or static. However,
 you can totally use it in constant functions:
 
diff --git a/src/librustc_error_codes/error_codes/E0765.md b/compiler/rustc_error_codes/src/error_codes/E0765.md
index 456e3f3e9e4..456e3f3e9e4 100644
--- a/src/librustc_error_codes/error_codes/E0765.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0765.md
diff --git a/src/librustc_error_codes/error_codes/E0766.md b/compiler/rustc_error_codes/src/error_codes/E0766.md
index 4e775df2cac..4e775df2cac 100644
--- a/src/librustc_error_codes/error_codes/E0766.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0766.md
diff --git a/src/librustc_error_codes/error_codes/E0767.md b/compiler/rustc_error_codes/src/error_codes/E0767.md
index 679fe7e41e9..679fe7e41e9 100644
--- a/src/librustc_error_codes/error_codes/E0767.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0767.md
diff --git a/src/librustc_error_codes/error_codes/E0768.md b/compiler/rustc_error_codes/src/error_codes/E0768.md
index 24169ef512e..24169ef512e 100644
--- a/src/librustc_error_codes/error_codes/E0768.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0768.md
diff --git a/src/librustc_error_codes/error_codes/E0769.md b/compiler/rustc_error_codes/src/error_codes/E0769.md
index d1995be9899..4a3b674b058 100644
--- a/src/librustc_error_codes/error_codes/E0769.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0769.md
@@ -1,5 +1,5 @@
-A tuple struct or tuple variant was used in a pattern as if it were a
-struct or struct variant.
+A tuple struct or tuple variant was used in a pattern as if it were a struct or
+struct variant.
 
 Erroneous code example:
 
@@ -7,9 +7,13 @@ Erroneous code example:
 enum E {
     A(i32),
 }
+
 let e = E::A(42);
+
 match e {
-    E::A { number } => println!("{}", x),
+    E::A { number } => { // error!
+        println!("{}", number);
+    }
 }
 ```
 
@@ -21,12 +25,14 @@ To fix this error, you can use the tuple pattern:
 # }
 # let e = E::A(42);
 match e {
-    E::A(number) => println!("{}", number),
+    E::A(number) => { // ok!
+        println!("{}", number);
+    }
 }
 ```
 
-Alternatively, you can also use the struct pattern by using the correct
-field names and binding them to new identifiers:
+Alternatively, you can also use the struct pattern by using the correct field
+names and binding them to new identifiers:
 
 ```
 # enum E {
@@ -34,6 +40,8 @@ field names and binding them to new identifiers:
 # }
 # let e = E::A(42);
 match e {
-    E::A { 0: number } => println!("{}", number),
+    E::A { 0: number } => { // ok!
+        println!("{}", number);
+    }
 }
 ```
diff --git a/src/librustc_error_codes/error_codes/E0770.md b/compiler/rustc_error_codes/src/error_codes/E0770.md
index 278bf9b907b..278bf9b907b 100644
--- a/src/librustc_error_codes/error_codes/E0770.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0770.md
diff --git a/src/librustc_error_codes/error_codes/E0771.md b/compiler/rustc_error_codes/src/error_codes/E0771.md
index 824a955f6b3..824a955f6b3 100644
--- a/src/librustc_error_codes/error_codes/E0771.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0771.md
diff --git a/compiler/rustc_error_codes/src/error_codes/E0773.md b/compiler/rustc_error_codes/src/error_codes/E0773.md
new file mode 100644
index 00000000000..b19a58bf33d
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0773.md
@@ -0,0 +1,38 @@
+A builtin-macro was defined more than once.
+
+Erroneous code example:
+
+```compile_fail,E0773
+#![feature(decl_macro)]
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+pub macro test($item:item) {
+    /* compiler built-in */
+}
+
+mod inner {
+    #[rustc_builtin_macro]
+    pub macro test($item:item) {
+        /* compiler built-in */
+    }
+}
+```
+
+To fix the issue, remove the duplicate declaration:
+
+```
+#![feature(decl_macro)]
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+pub macro test($item:item) {
+    /* compiler built-in */
+}
+```
+
+In very rare edge cases, this may happen when loading `core` or `std` twice,
+once with `check` metadata and once with `build` metadata.
+For more information, see [#75176].
+
+[#75176]: https://github.com/rust-lang/rust/pull/75176#issuecomment-683234468
diff --git a/src/librustc_error_codes/lib.rs b/compiler/rustc_error_codes/src/lib.rs
index 4353a294cc3..4353a294cc3 100644
--- a/src/librustc_error_codes/lib.rs
+++ b/compiler/rustc_error_codes/src/lib.rs
diff --git a/src/librustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml
index 7c794bcd98f..e4dbb8db381 100644
--- a/src/librustc_errors/Cargo.toml
+++ b/compiler/rustc_errors/Cargo.toml
@@ -5,16 +5,14 @@ version = "0.0.0"
 edition = "2018"
 
 [lib]
-name = "rustc_errors"
-path = "lib.rs"
 doctest = false
 
 [dependencies]
 tracing = "0.1"
-rustc_serialize = { path = "../librustc_serialize" }
-rustc_span = { path = "../librustc_span" }
-rustc_macros = { path = "../librustc_macros" }
-rustc_data_structures = { path = "../librustc_data_structures" }
+rustc_serialize = { path = "../rustc_serialize" }
+rustc_span = { path = "../rustc_span" }
+rustc_macros = { path = "../rustc_macros" }
+rustc_data_structures = { path = "../rustc_data_structures" }
 unicode-width = "0.1.4"
 atty = "0.2"
 termcolor = "1.0"
diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
index 265ba59cccb..265ba59cccb 100644
--- a/src/librustc_errors/annotate_snippet_emitter_writer.rs
+++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
diff --git a/src/librustc_errors/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 870f7b81e21..870f7b81e21 100644
--- a/src/librustc_errors/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
diff --git a/src/librustc_errors/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index d1ff6f721c4..d1ff6f721c4 100644
--- a/src/librustc_errors/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
diff --git a/src/librustc_errors/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 5a654e83aed..5a654e83aed 100644
--- a/src/librustc_errors/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
diff --git a/src/librustc_errors/json.rs b/compiler/rustc_errors/src/json.rs
index 750d36d3d89..750d36d3d89 100644
--- a/src/librustc_errors/json.rs
+++ b/compiler/rustc_errors/src/json.rs
diff --git a/src/librustc_errors/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs
index e69e868c8ed..e69e868c8ed 100644
--- a/src/librustc_errors/json/tests.rs
+++ b/compiler/rustc_errors/src/json/tests.rs
diff --git a/src/librustc_errors/lib.rs b/compiler/rustc_errors/src/lib.rs
index d4f0a9d83ef..d4f0a9d83ef 100644
--- a/src/librustc_errors/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
diff --git a/src/librustc_errors/lock.rs b/compiler/rustc_errors/src/lock.rs
index a73472021d4..a73472021d4 100644
--- a/src/librustc_errors/lock.rs
+++ b/compiler/rustc_errors/src/lock.rs
diff --git a/src/librustc_errors/registry.rs b/compiler/rustc_errors/src/registry.rs
index b1d770d5bd5..b1d770d5bd5 100644
--- a/src/librustc_errors/registry.rs
+++ b/compiler/rustc_errors/src/registry.rs
diff --git a/src/librustc_errors/snippet.rs b/compiler/rustc_errors/src/snippet.rs
index 160bf577799..160bf577799 100644
--- a/src/librustc_errors/snippet.rs
+++ b/compiler/rustc_errors/src/snippet.rs
diff --git a/src/librustc_errors/styled_buffer.rs b/compiler/rustc_errors/src/styled_buffer.rs
index f2d255d7d95..f2d255d7d95 100644
--- a/src/librustc_errors/styled_buffer.rs
+++ b/compiler/rustc_errors/src/styled_buffer.rs
diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml
new file mode 100644
index 00000000000..25c2851f6de
--- /dev/null
+++ b/compiler/rustc_expand/Cargo.toml
@@ -0,0 +1,26 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_expand"
+version = "0.0.0"
+edition = "2018"
+build = false
+
+[lib]
+doctest = false
+
+[dependencies]
+rustc_serialize = { path = "../rustc_serialize" }
+tracing = "0.1"
+rustc_span = { path = "../rustc_span" }
+rustc_ast_pretty = { path = "../rustc_ast_pretty" }
+rustc_ast_passes = { path = "../rustc_ast_passes" }
+rustc_attr = { path = "../rustc_attr" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_feature = { path = "../rustc_feature" }
+rustc_macros = { path = "../rustc_macros" }
+rustc_lexer = { path = "../rustc_lexer" }
+rustc_parse = { path = "../rustc_parse" }
+rustc_session = { path = "../rustc_session" }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
+rustc_ast = { path = "../rustc_ast" }
diff --git a/src/librustc_expand/base.rs b/compiler/rustc_expand/src/base.rs
index 4c01cb8159a..4c01cb8159a 100644
--- a/src/librustc_expand/base.rs
+++ b/compiler/rustc_expand/src/base.rs
diff --git a/src/librustc_expand/build.rs b/compiler/rustc_expand/src/build.rs
index 9490b62aa17..9490b62aa17 100644
--- a/src/librustc_expand/build.rs
+++ b/compiler/rustc_expand/src/build.rs
diff --git a/src/librustc_expand/config.rs b/compiler/rustc_expand/src/config.rs
index afd1e606402..97608a38903 100644
--- a/src/librustc_expand/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -403,10 +403,6 @@ impl<'a> StripUnconfigured<'a> {
         items.flat_map_in_place(|item| self.configure(item));
     }
 
-    pub fn configure_generic_params(&mut self, params: &mut Vec<ast::GenericParam>) {
-        params.flat_map_in_place(|param| self.configure(param));
-    }
-
     fn configure_variant_data(&mut self, vdata: &mut ast::VariantData) {
         match vdata {
             ast::VariantData::Struct(fields, ..) | ast::VariantData::Tuple(fields, _) => {
@@ -496,6 +492,13 @@ impl<'a> MutVisitor for StripUnconfigured<'a> {
         Some(expr)
     }
 
+    fn flat_map_generic_param(
+        &mut self,
+        param: ast::GenericParam,
+    ) -> SmallVec<[ast::GenericParam; 1]> {
+        noop_flat_map_generic_param(configure!(self, param), self)
+    }
+
     fn flat_map_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> {
         noop_flat_map_stmt(configure!(self, stmt), self)
     }
diff --git a/src/librustc_expand/expand.rs b/compiler/rustc_expand/src/expand.rs
index 7a21caf255a..105f81c6e0f 100644
--- a/src/librustc_expand/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -13,7 +13,7 @@ use rustc_ast::token;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::visit::{self, AssocCtxt, Visitor};
 use rustc_ast::{self as ast, AttrItem, Block, LitKind, NodeId, PatKind, Path};
-use rustc_ast::{ItemKind, MacArgs, MacStmtStyle, StmtKind};
+use rustc_ast::{ItemKind, MacArgs, MacCallStmt, MacStmtStyle, StmtKind};
 use rustc_ast_pretty::pprust;
 use rustc_attr::{self as attr, is_builtin_attr, HasAttrs};
 use rustc_data_structures::map_in_place::MapInPlace;
@@ -1363,7 +1363,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
         }
 
         if let StmtKind::MacCall(mac) = stmt.kind {
-            let (mac, style, attrs) = mac.into_inner();
+            let MacCallStmt { mac, style, attrs } = mac.into_inner();
             self.check_attributes(&attrs);
             let mut placeholder =
                 self.collect_bang(mac, stmt.span, AstFragmentKind::Stmts).make_stmts();
@@ -1788,6 +1788,7 @@ pub struct ExpansionConfig<'feat> {
     pub should_test: bool, // If false, strip `#[test]` nodes
     pub keep_macs: bool,
     pub span_debug: bool, // If true, use verbose debugging for `proc_macro::Span`
+    pub proc_macro_backtrace: bool, // If true, show backtraces for proc-macro panics
 }
 
 impl<'feat> ExpansionConfig<'feat> {
@@ -1800,6 +1801,7 @@ impl<'feat> ExpansionConfig<'feat> {
             should_test: false,
             keep_macs: false,
             span_debug: false,
+            proc_macro_backtrace: false,
         }
     }
 
diff --git a/src/librustc_expand/lib.rs b/compiler/rustc_expand/src/lib.rs
index 7f631cb71af..5436b1ef737 100644
--- a/src/librustc_expand/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -39,11 +39,6 @@ mod tests;
 mod parse {
     #[cfg(test)]
     mod tests;
-    #[cfg(test)]
-    mod lexer {
-        #[cfg(test)]
-        mod tests;
-    }
 }
 #[cfg(test)]
 mod tokenstream {
diff --git a/src/librustc_expand/mbe.rs b/compiler/rustc_expand/src/mbe.rs
index 9aed307ec93..9aed307ec93 100644
--- a/src/librustc_expand/mbe.rs
+++ b/compiler/rustc_expand/src/mbe.rs
diff --git a/src/librustc_expand/mbe/macro_check.rs b/compiler/rustc_expand/src/mbe/macro_check.rs
index 6b419dae3f6..6b419dae3f6 100644
--- a/src/librustc_expand/mbe/macro_check.rs
+++ b/compiler/rustc_expand/src/mbe/macro_check.rs
diff --git a/src/librustc_expand/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index 92a8f231126..92a8f231126 100644
--- a/src/librustc_expand/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
diff --git a/src/librustc_expand/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index f0e6fe39a3c..f0e6fe39a3c 100644
--- a/src/librustc_expand/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
diff --git a/src/librustc_expand/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs
index 48db532c78f..48db532c78f 100644
--- a/src/librustc_expand/mbe/quoted.rs
+++ b/compiler/rustc_expand/src/mbe/quoted.rs
diff --git a/src/librustc_expand/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs
index b908a12c1fc..b908a12c1fc 100644
--- a/src/librustc_expand/mbe/transcribe.rs
+++ b/compiler/rustc_expand/src/mbe/transcribe.rs
diff --git a/src/librustc_expand/module.rs b/compiler/rustc_expand/src/module.rs
index 1e123a2e145..1e123a2e145 100644
--- a/src/librustc_expand/module.rs
+++ b/compiler/rustc_expand/src/module.rs
diff --git a/src/librustc_expand/mut_visit/tests.rs b/compiler/rustc_expand/src/mut_visit/tests.rs
index 38ff594b6e9..38ff594b6e9 100644
--- a/src/librustc_expand/mut_visit/tests.rs
+++ b/compiler/rustc_expand/src/mut_visit/tests.rs
diff --git a/src/librustc_expand/parse/tests.rs b/compiler/rustc_expand/src/parse/tests.rs
index 643305f153c..643305f153c 100644
--- a/src/librustc_expand/parse/tests.rs
+++ b/compiler/rustc_expand/src/parse/tests.rs
diff --git a/src/librustc_expand/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs
index 29fb4c95ec6..dbd2e70af6a 100644
--- a/src/librustc_expand/placeholders.rs
+++ b/compiler/rustc_expand/src/placeholders.rs
@@ -92,7 +92,11 @@ pub fn placeholder(
             AstFragment::Ty(P(ast::Ty { id, span, kind: ast::TyKind::MacCall(mac_placeholder()) }))
         }
         AstFragmentKind::Stmts => AstFragment::Stmts(smallvec![{
-            let mac = P((mac_placeholder(), ast::MacStmtStyle::Braces, ast::AttrVec::new()));
+            let mac = P(ast::MacCallStmt {
+                mac: mac_placeholder(),
+                style: ast::MacStmtStyle::Braces,
+                attrs: ast::AttrVec::new(),
+            });
             ast::Stmt { id, span, kind: ast::StmtKind::MacCall(mac) }
         }]),
         AstFragmentKind::Arms => AstFragment::Arms(smallvec![ast::Arm {
@@ -293,7 +297,7 @@ impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> {
 
     fn flat_map_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> {
         let (style, mut stmts) = match stmt.kind {
-            ast::StmtKind::MacCall(mac) => (mac.1, self.remove(stmt.id).make_stmts()),
+            ast::StmtKind::MacCall(mac) => (mac.style, self.remove(stmt.id).make_stmts()),
             _ => return noop_flat_map_stmt(stmt, self),
         };
 
diff --git a/src/librustc_expand/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs
index 4e865c20d6f..94b3fcf2850 100644
--- a/src/librustc_expand/proc_macro.rs
+++ b/compiler/rustc_expand/src/proc_macro.rs
@@ -24,7 +24,7 @@ impl base::ProcMacro for BangProcMacro {
         input: TokenStream,
     ) -> Result<TokenStream, ErrorReported> {
         let server = proc_macro_server::Rustc::new(ecx);
-        self.client.run(&EXEC_STRATEGY, server, input).map_err(|e| {
+        self.client.run(&EXEC_STRATEGY, server, input, ecx.ecfg.proc_macro_backtrace).map_err(|e| {
             let mut err = ecx.struct_span_err(span, "proc macro panicked");
             if let Some(s) = e.as_str() {
                 err.help(&format!("message: {}", s));
@@ -48,14 +48,16 @@ impl base::AttrProcMacro for AttrProcMacro {
         annotated: TokenStream,
     ) -> Result<TokenStream, ErrorReported> {
         let server = proc_macro_server::Rustc::new(ecx);
-        self.client.run(&EXEC_STRATEGY, server, annotation, annotated).map_err(|e| {
-            let mut err = ecx.struct_span_err(span, "custom attribute panicked");
-            if let Some(s) = e.as_str() {
-                err.help(&format!("message: {}", s));
-            }
-            err.emit();
-            ErrorReported
-        })
+        self.client
+            .run(&EXEC_STRATEGY, server, annotation, annotated, ecx.ecfg.proc_macro_backtrace)
+            .map_err(|e| {
+                let mut err = ecx.struct_span_err(span, "custom attribute panicked");
+                if let Some(s) = e.as_str() {
+                    err.help(&format!("message: {}", s));
+                }
+                err.emit();
+                ErrorReported
+            })
     }
 }
 
@@ -111,17 +113,18 @@ impl MultiItemModifier for ProcMacroDerive {
         };
 
         let server = proc_macro_server::Rustc::new(ecx);
-        let stream = match self.client.run(&EXEC_STRATEGY, server, input) {
-            Ok(stream) => stream,
-            Err(e) => {
-                let mut err = ecx.struct_span_err(span, "proc-macro derive panicked");
-                if let Some(s) = e.as_str() {
-                    err.help(&format!("message: {}", s));
+        let stream =
+            match self.client.run(&EXEC_STRATEGY, server, input, ecx.ecfg.proc_macro_backtrace) {
+                Ok(stream) => stream,
+                Err(e) => {
+                    let mut err = ecx.struct_span_err(span, "proc-macro derive panicked");
+                    if let Some(s) = e.as_str() {
+                        err.help(&format!("message: {}", s));
+                    }
+                    err.emit();
+                    return ExpandResult::Ready(vec![]);
                 }
-                err.emit();
-                return ExpandResult::Ready(vec![]);
-            }
-        };
+            };
 
         let error_count_before = ecx.sess.parse_sess.span_diagnostic.err_count();
         let mut parser =
diff --git a/src/librustc_expand/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 409784812f5..39c82f97e0a 100644
--- a/src/librustc_expand/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -189,7 +189,7 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
             }
 
             OpenDelim(..) | CloseDelim(..) => unreachable!(),
-            Whitespace | Comment | Shebang(..) | Unknown(..) | Eof => unreachable!(),
+            Eof => unreachable!(),
         }
     }
 }
diff --git a/src/librustc_expand/tests.rs b/compiler/rustc_expand/src/tests.rs
index 6993ce58fa6..6993ce58fa6 100644
--- a/src/librustc_expand/tests.rs
+++ b/compiler/rustc_expand/src/tests.rs
diff --git a/src/librustc_expand/tokenstream/tests.rs b/compiler/rustc_expand/src/tokenstream/tests.rs
index 4e818e9feb0..4e818e9feb0 100644
--- a/src/librustc_expand/tokenstream/tests.rs
+++ b/compiler/rustc_expand/src/tokenstream/tests.rs
diff --git a/compiler/rustc_feature/Cargo.toml b/compiler/rustc_feature/Cargo.toml
new file mode 100644
index 00000000000..7a06bce13c8
--- /dev/null
+++ b/compiler/rustc_feature/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_feature"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_span = { path = "../rustc_span" }
diff --git a/src/librustc_feature/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index d16f023c00a..d16f023c00a 100644
--- a/src/librustc_feature/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
diff --git a/src/librustc_feature/active.rs b/compiler/rustc_feature/src/active.rs
index e858980738d..e858980738d 100644
--- a/src/librustc_feature/active.rs
+++ b/compiler/rustc_feature/src/active.rs
diff --git a/src/librustc_feature/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 879f06f89a7..fc122db8ac1 100644
--- a/src/librustc_feature/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -5,10 +5,11 @@ use AttributeType::*;
 
 use crate::{Features, Stability};
 
-use lazy_static::lazy_static;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_span::symbol::{sym, Symbol};
 
+use std::lazy::SyncLazy;
+
 type GateFn = fn(&Features) -> bool;
 
 macro_rules! cfg_fn {
@@ -589,8 +590,8 @@ pub fn is_builtin_attr_name(name: Symbol) -> bool {
     BUILTIN_ATTRIBUTE_MAP.get(&name).is_some()
 }
 
-lazy_static! {
-    pub static ref BUILTIN_ATTRIBUTE_MAP: FxHashMap<Symbol, &'static BuiltinAttribute> = {
+pub static BUILTIN_ATTRIBUTE_MAP: SyncLazy<FxHashMap<Symbol, &'static BuiltinAttribute>> =
+    SyncLazy::new(|| {
         let mut map = FxHashMap::default();
         for attr in BUILTIN_ATTRIBUTES.iter() {
             if map.insert(attr.0, attr).is_some() {
@@ -598,5 +599,4 @@ lazy_static! {
             }
         }
         map
-    };
-}
+    });
diff --git a/src/librustc_feature/lib.rs b/compiler/rustc_feature/src/lib.rs
index f8bf0315d0c..4393368cd45 100644
--- a/src/librustc_feature/lib.rs
+++ b/compiler/rustc_feature/src/lib.rs
@@ -11,6 +11,8 @@
 //! even if it is stabilized or removed, *do not remove it*. Instead, move the
 //! symbol to the `accepted` or `removed` modules respectively.
 
+#![feature(once_cell)]
+
 mod accepted;
 mod active;
 mod builtin_attrs;
diff --git a/src/librustc_feature/removed.rs b/compiler/rustc_feature/src/removed.rs
index 8d410894e8b..8d410894e8b 100644
--- a/src/librustc_feature/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
diff --git a/src/librustc_fs_util/Cargo.toml b/compiler/rustc_fs_util/Cargo.toml
index e74e3809927..e4414c788a7 100644
--- a/src/librustc_fs_util/Cargo.toml
+++ b/compiler/rustc_fs_util/Cargo.toml
@@ -3,9 +3,3 @@ authors = ["The Rust Project Developers"]
 name = "rustc_fs_util"
 version = "0.0.0"
 edition = "2018"
-
-[lib]
-name = "rustc_fs_util"
-path = "lib.rs"
-
-[dependencies]
diff --git a/src/librustc_fs_util/lib.rs b/compiler/rustc_fs_util/src/lib.rs
index 289b9f30c3b..289b9f30c3b 100644
--- a/src/librustc_fs_util/lib.rs
+++ b/compiler/rustc_fs_util/src/lib.rs
diff --git a/src/librustc_graphviz/Cargo.toml b/compiler/rustc_graphviz/Cargo.toml
index 9a5e78a560c..d07b75a5c8f 100644
--- a/src/librustc_graphviz/Cargo.toml
+++ b/compiler/rustc_graphviz/Cargo.toml
@@ -3,7 +3,3 @@ authors = ["The Rust Project Developers"]
 name = "rustc_graphviz"
 version = "0.0.0"
 edition = "2018"
-
-[lib]
-name = "rustc_graphviz"
-path = "lib.rs"
diff --git a/src/librustc_graphviz/lib.rs b/compiler/rustc_graphviz/src/lib.rs
index 4339092b63e..4339092b63e 100644
--- a/src/librustc_graphviz/lib.rs
+++ b/compiler/rustc_graphviz/src/lib.rs
diff --git a/src/librustc_graphviz/tests.rs b/compiler/rustc_graphviz/src/tests.rs
index 055e13156ae..055e13156ae 100644
--- a/src/librustc_graphviz/tests.rs
+++ b/compiler/rustc_graphviz/src/tests.rs
diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml
new file mode 100644
index 00000000000..b24c208c76a
--- /dev/null
+++ b/compiler/rustc_hir/Cargo.toml
@@ -0,0 +1,19 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_hir"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+rustc_target = { path = "../rustc_target" }
+rustc_macros = { path = "../rustc_macros" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_index = { path = "../rustc_index" }
+rustc_span = { path = "../rustc_span" }
+rustc_serialize = { path = "../rustc_serialize" }
+rustc_ast = { path = "../rustc_ast" }
+tracing = "0.1"
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_hir/arena.rs b/compiler/rustc_hir/src/arena.rs
index 85ab7906d25..85ab7906d25 100644
--- a/src/librustc_hir/arena.rs
+++ b/compiler/rustc_hir/src/arena.rs
diff --git a/src/librustc_hir/def.rs b/compiler/rustc_hir/src/def.rs
index 0d61dc037c6..0d61dc037c6 100644
--- a/src/librustc_hir/def.rs
+++ b/compiler/rustc_hir/src/def.rs
diff --git a/src/librustc_hir/definitions.rs b/compiler/rustc_hir/src/definitions.rs
index 45735ead256..45735ead256 100644
--- a/src/librustc_hir/definitions.rs
+++ b/compiler/rustc_hir/src/definitions.rs
diff --git a/src/librustc_hir/hir.rs b/compiler/rustc_hir/src/hir.rs
index cd4185226dc..cd4185226dc 100644
--- a/src/librustc_hir/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
diff --git a/src/librustc_hir/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs
index fea850c12d9..fea850c12d9 100644
--- a/src/librustc_hir/hir_id.rs
+++ b/compiler/rustc_hir/src/hir_id.rs
diff --git a/src/librustc_hir/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 76cf6bd4776..76cf6bd4776 100644
--- a/src/librustc_hir/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
diff --git a/src/librustc_hir/itemlikevisit.rs b/compiler/rustc_hir/src/itemlikevisit.rs
index 369cd49621b..369cd49621b 100644
--- a/src/librustc_hir/itemlikevisit.rs
+++ b/compiler/rustc_hir/src/itemlikevisit.rs
diff --git a/src/librustc_hir/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index acf6847c014..5e4c03bec83 100644
--- a/src/librustc_hir/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -17,7 +17,7 @@ use rustc_macros::HashStable_Generic;
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::Span;
 
-use lazy_static::lazy_static;
+use std::lazy::SyncLazy;
 
 pub enum LangItemGroup {
     Op,
@@ -117,14 +117,12 @@ macro_rules! language_item_table {
             )*
         }
 
-        lazy_static! {
-            /// A mapping from the name of the lang item to its order and the form it must be of.
-            pub static ref ITEM_REFS: FxHashMap<Symbol, (usize, Target)> = {
-                let mut item_refs = FxHashMap::default();
-                $( item_refs.insert($name, (LangItem::$variant as usize, $target)); )*
-                item_refs
-            };
-        }
+        /// A mapping from the name of the lang item to its order and the form it must be of.
+        pub static ITEM_REFS: SyncLazy<FxHashMap<Symbol, (usize, Target)>> = SyncLazy::new(|| {
+            let mut item_refs = FxHashMap::default();
+            $( item_refs.insert($name, (LangItem::$variant as usize, $target)); )*
+            item_refs
+        });
 
 // End of the macro
     }
diff --git a/src/librustc_hir/lib.rs b/compiler/rustc_hir/src/lib.rs
index 19ea1de5683..c69a9b063ae 100644
--- a/src/librustc_hir/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -6,6 +6,7 @@
 #![feature(const_fn)] // For the unsizing cast on `&[]`
 #![feature(const_panic)]
 #![feature(in_band_lifetimes)]
+#![feature(once_cell)]
 #![feature(or_patterns)]
 #![recursion_limit = "256"]
 
diff --git a/src/librustc_hir/pat_util.rs b/compiler/rustc_hir/src/pat_util.rs
index 2f1b5da8e13..2f1b5da8e13 100644
--- a/src/librustc_hir/pat_util.rs
+++ b/compiler/rustc_hir/src/pat_util.rs
diff --git a/src/librustc_hir/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs
index 1d3f44a0899..1d3f44a0899 100644
--- a/src/librustc_hir/stable_hash_impls.rs
+++ b/compiler/rustc_hir/src/stable_hash_impls.rs
diff --git a/src/librustc_hir/target.rs b/compiler/rustc_hir/src/target.rs
index 1efc8bc3124..1efc8bc3124 100644
--- a/src/librustc_hir/target.rs
+++ b/compiler/rustc_hir/src/target.rs
diff --git a/src/librustc_hir/weak_lang_items.rs b/compiler/rustc_hir/src/weak_lang_items.rs
index 129eec7d29e..52f28bf8f4c 100644
--- a/src/librustc_hir/weak_lang_items.rs
+++ b/compiler/rustc_hir/src/weak_lang_items.rs
@@ -7,18 +7,16 @@ use rustc_ast as ast;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_span::symbol::{sym, Symbol};
 
-use lazy_static::lazy_static;
+use std::lazy::SyncLazy;
 
 macro_rules! weak_lang_items {
     ($($name:ident, $item:ident, $sym:ident;)*) => (
 
-lazy_static! {
-    pub static ref WEAK_ITEMS_REFS: FxHashMap<Symbol, LangItem> = {
-        let mut map = FxHashMap::default();
-        $(map.insert(sym::$name, LangItem::$item);)*
-        map
-    };
-}
+pub static WEAK_ITEMS_REFS: SyncLazy<FxHashMap<Symbol, LangItem>> = SyncLazy::new(|| {
+    let mut map = FxHashMap::default();
+    $(map.insert(sym::$name, LangItem::$item);)*
+    map
+});
 
 /// The `check_name` argument avoids the need for `librustc_hir` to depend on
 /// `librustc_session`.
diff --git a/compiler/rustc_hir_pretty/Cargo.toml b/compiler/rustc_hir_pretty/Cargo.toml
new file mode 100644
index 00000000000..1f7643e9fb4
--- /dev/null
+++ b/compiler/rustc_hir_pretty/Cargo.toml
@@ -0,0 +1,15 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_hir_pretty"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+rustc_ast_pretty = { path = "../rustc_ast_pretty" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_target = { path = "../rustc_target" }
+rustc_span = { path = "../rustc_span" }
+rustc_ast = { path = "../rustc_ast" }
diff --git a/src/librustc_hir_pretty/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index f6e4b1fb418..f6e4b1fb418 100644
--- a/src/librustc_hir_pretty/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
diff --git a/compiler/rustc_incremental/Cargo.toml b/compiler/rustc_incremental/Cargo.toml
new file mode 100644
index 00000000000..049e5b8b722
--- /dev/null
+++ b/compiler/rustc_incremental/Cargo.toml
@@ -0,0 +1,22 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_incremental"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+rustc_graphviz = { path = "../rustc_graphviz" }
+tracing = "0.1"
+rand = "0.7"
+rustc_middle = { path = "../rustc_middle" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_serialize = { path = "../rustc_serialize" }
+rustc_ast = { path = "../rustc_ast" }
+rustc_macros = { path = "../rustc_macros" }
+rustc_span = { path = "../rustc_span" }
+rustc_fs_util = { path = "../rustc_fs_util" }
+rustc_session = { path = "../rustc_session" }
diff --git a/src/librustc_incremental/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs
index e17396422f1..e17396422f1 100644
--- a/src/librustc_incremental/assert_dep_graph.rs
+++ b/compiler/rustc_incremental/src/assert_dep_graph.rs
diff --git a/src/librustc_incremental/assert_module_sources.rs b/compiler/rustc_incremental/src/assert_module_sources.rs
index 80448c01a26..80448c01a26 100644
--- a/src/librustc_incremental/assert_module_sources.rs
+++ b/compiler/rustc_incremental/src/assert_module_sources.rs
diff --git a/src/librustc_incremental/lib.rs b/compiler/rustc_incremental/src/lib.rs
index ad189138054..ad189138054 100644
--- a/src/librustc_incremental/lib.rs
+++ b/compiler/rustc_incremental/src/lib.rs
diff --git a/src/librustc_incremental/persist/README.md b/compiler/rustc_incremental/src/persist/README.md
index b01fe219e1e..b01fe219e1e 100644
--- a/src/librustc_incremental/persist/README.md
+++ b/compiler/rustc_incremental/src/persist/README.md
diff --git a/src/librustc_incremental/persist/data.rs b/compiler/rustc_incremental/src/persist/data.rs
index 81e5410978d..81e5410978d 100644
--- a/src/librustc_incremental/persist/data.rs
+++ b/compiler/rustc_incremental/src/persist/data.rs
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs
index f0a10885550..f0a10885550 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs
diff --git a/src/librustc_incremental/persist/file_format.rs b/compiler/rustc_incremental/src/persist/file_format.rs
index 048a81b81ba..048a81b81ba 100644
--- a/src/librustc_incremental/persist/file_format.rs
+++ b/compiler/rustc_incremental/src/persist/file_format.rs
diff --git a/src/librustc_incremental/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs
index 4926f726f35..4926f726f35 100644
--- a/src/librustc_incremental/persist/fs.rs
+++ b/compiler/rustc_incremental/src/persist/fs.rs
diff --git a/src/librustc_incremental/persist/fs/tests.rs b/compiler/rustc_incremental/src/persist/fs/tests.rs
index 652ef6bcdce..652ef6bcdce 100644
--- a/src/librustc_incremental/persist/fs/tests.rs
+++ b/compiler/rustc_incremental/src/persist/fs/tests.rs
diff --git a/src/librustc_incremental/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs
index 966faa9639d..966faa9639d 100644
--- a/src/librustc_incremental/persist/load.rs
+++ b/compiler/rustc_incremental/src/persist/load.rs
diff --git a/src/librustc_incremental/persist/mod.rs b/compiler/rustc_incremental/src/persist/mod.rs
index 7bc3b47e15a..7bc3b47e15a 100644
--- a/src/librustc_incremental/persist/mod.rs
+++ b/compiler/rustc_incremental/src/persist/mod.rs
diff --git a/src/librustc_incremental/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs
index c43d4ad4049..c43d4ad4049 100644
--- a/src/librustc_incremental/persist/save.rs
+++ b/compiler/rustc_incremental/src/persist/save.rs
diff --git a/src/librustc_incremental/persist/work_product.rs b/compiler/rustc_incremental/src/persist/work_product.rs
index 19d64bda56d..19d64bda56d 100644
--- a/src/librustc_incremental/persist/work_product.rs
+++ b/compiler/rustc_incremental/src/persist/work_product.rs
diff --git a/src/librustc_index/Cargo.toml b/compiler/rustc_index/Cargo.toml
index 8aaf1cb9cbc..6ac7c06ee83 100644
--- a/src/librustc_index/Cargo.toml
+++ b/compiler/rustc_index/Cargo.toml
@@ -5,11 +5,9 @@ version = "0.0.0"
 edition = "2018"
 
 [lib]
-name = "rustc_index"
-path = "lib.rs"
 doctest = false
 
 [dependencies]
 arrayvec = "0.5.1"
-rustc_serialize = { path = "../librustc_serialize" }
-rustc_macros = { path = "../librustc_macros" }
+rustc_serialize = { path = "../rustc_serialize" }
+rustc_macros = { path = "../rustc_macros" }
diff --git a/src/librustc_index/bit_set.rs b/compiler/rustc_index/src/bit_set.rs
index c43d1a6830d..c43d1a6830d 100644
--- a/src/librustc_index/bit_set.rs
+++ b/compiler/rustc_index/src/bit_set.rs
diff --git a/src/librustc_index/bit_set/tests.rs b/compiler/rustc_index/src/bit_set/tests.rs
index 6cc3e9427d1..6cc3e9427d1 100644
--- a/src/librustc_index/bit_set/tests.rs
+++ b/compiler/rustc_index/src/bit_set/tests.rs
diff --git a/src/librustc_index/lib.rs b/compiler/rustc_index/src/lib.rs
index 7ee881b0639..7ee881b0639 100644
--- a/src/librustc_index/lib.rs
+++ b/compiler/rustc_index/src/lib.rs
diff --git a/src/librustc_index/vec.rs b/compiler/rustc_index/src/vec.rs
index 2420f82c041..2420f82c041 100644
--- a/src/librustc_index/vec.rs
+++ b/compiler/rustc_index/src/vec.rs
diff --git a/src/librustc_index/vec/tests.rs b/compiler/rustc_index/src/vec/tests.rs
index 15c43c72c7b..15c43c72c7b 100644
--- a/src/librustc_index/vec/tests.rs
+++ b/compiler/rustc_index/src/vec/tests.rs
diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml
new file mode 100644
index 00000000000..5dba4106c94
--- /dev/null
+++ b/compiler/rustc_infer/Cargo.toml
@@ -0,0 +1,24 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_infer"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+rustc_graphviz = { path = "../rustc_graphviz" }
+tracing = "0.1"
+rustc_middle = { path = "../rustc_middle" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_index = { path = "../rustc_index" }
+rustc_macros = { path = "../rustc_macros" }
+rustc_session = { path = "../rustc_session" }
+rustc_serialize = { path = "../rustc_serialize" }
+rustc_span = { path = "../rustc_span" }
+rustc_target = { path = "../rustc_target" }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
+rustc_ast = { path = "../rustc_ast" }
diff --git a/src/librustc_infer/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index a7749d33b7c..a7749d33b7c 100644
--- a/src/librustc_infer/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
diff --git a/src/librustc_infer/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index ea32a1ae5a5..ea32a1ae5a5 100644
--- a/src/librustc_infer/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
diff --git a/src/librustc_infer/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs
index 2b8c46f1de4..2b8c46f1de4 100644
--- a/src/librustc_infer/infer/canonical/mod.rs
+++ b/compiler/rustc_infer/src/infer/canonical/mod.rs
diff --git a/src/librustc_infer/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index 0dbebac7e36..0dbebac7e36 100644
--- a/src/librustc_infer/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
diff --git a/src/librustc_infer/infer/canonical/substitute.rs b/compiler/rustc_infer/src/infer/canonical/substitute.rs
index 65791f6fc65..65791f6fc65 100644
--- a/src/librustc_infer/infer/canonical/substitute.rs
+++ b/compiler/rustc_infer/src/infer/canonical/substitute.rs
diff --git a/src/librustc_infer/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs
index 3a54a647530..3a54a647530 100644
--- a/src/librustc_infer/infer/combine.rs
+++ b/compiler/rustc_infer/src/infer/combine.rs
diff --git a/src/librustc_infer/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs
index 7de752d1de0..7de752d1de0 100644
--- a/src/librustc_infer/infer/equate.rs
+++ b/compiler/rustc_infer/src/infer/equate.rs
diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index d72ed72e3a8..d72ed72e3a8 100644
--- a/src/librustc_infer/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
diff --git a/src/librustc_infer/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index bf087dfacfa..bf087dfacfa 100644
--- a/src/librustc_infer/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs
index 7ab18e54f7e..7ab18e54f7e 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs
index eb1521f0565..eb1521f0565 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/find_anon_type.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs
index cc8f1816bc3..cc8f1816bc3 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
index 89142edb2dc..89142edb2dc 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
index 2187064ec5e..2187064ec5e 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/placeholder_error.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
index 7493b8b0a9f..7493b8b0a9f 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
index 788eabf296d..788eabf296d 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
index 6e2d49f1ad7..6e2d49f1ad7 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
diff --git a/src/librustc_infer/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs
index 9ac27030ade..9ac27030ade 100644
--- a/src/librustc_infer/infer/error_reporting/note.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs
diff --git a/src/librustc_infer/infer/free_regions.rs b/compiler/rustc_infer/src/infer/free_regions.rs
index ffe5fb172be..ffe5fb172be 100644
--- a/src/librustc_infer/infer/free_regions.rs
+++ b/compiler/rustc_infer/src/infer/free_regions.rs
diff --git a/src/librustc_infer/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs
index 02bebe10ed0..02bebe10ed0 100644
--- a/src/librustc_infer/infer/freshen.rs
+++ b/compiler/rustc_infer/src/infer/freshen.rs
diff --git a/src/librustc_infer/infer/fudge.rs b/compiler/rustc_infer/src/infer/fudge.rs
index c6651108df5..c6651108df5 100644
--- a/src/librustc_infer/infer/fudge.rs
+++ b/compiler/rustc_infer/src/infer/fudge.rs
diff --git a/src/librustc_infer/infer/glb.rs b/compiler/rustc_infer/src/infer/glb.rs
index ccba904df9e..ccba904df9e 100644
--- a/src/librustc_infer/infer/glb.rs
+++ b/compiler/rustc_infer/src/infer/glb.rs
diff --git a/src/librustc_infer/infer/higher_ranked/README.md b/compiler/rustc_infer/src/infer/higher_ranked/README.md
index 533d0ef7e6c..533d0ef7e6c 100644
--- a/src/librustc_infer/infer/higher_ranked/README.md
+++ b/compiler/rustc_infer/src/infer/higher_ranked/README.md
diff --git a/src/librustc_infer/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs
index ea19dff7db1..ea19dff7db1 100644
--- a/src/librustc_infer/infer/higher_ranked/mod.rs
+++ b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs
diff --git a/src/librustc_infer/infer/lattice.rs b/compiler/rustc_infer/src/infer/lattice.rs
index 1bf43e74dcd..1bf43e74dcd 100644
--- a/src/librustc_infer/infer/lattice.rs
+++ b/compiler/rustc_infer/src/infer/lattice.rs
diff --git a/src/librustc_infer/infer/lexical_region_resolve/README.md b/compiler/rustc_infer/src/infer/lexical_region_resolve/README.md
index e0b2c0bffee..e0b2c0bffee 100644
--- a/src/librustc_infer/infer/lexical_region_resolve/README.md
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/README.md
diff --git a/src/librustc_infer/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index fcf1949933b..fcf1949933b 100644
--- a/src/librustc_infer/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
diff --git a/src/librustc_infer/infer/lub.rs b/compiler/rustc_infer/src/infer/lub.rs
index 3e2ea3d0f8f..3e2ea3d0f8f 100644
--- a/src/librustc_infer/infer/lub.rs
+++ b/compiler/rustc_infer/src/infer/lub.rs
diff --git a/src/librustc_infer/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 3744ad5d032..3744ad5d032 100644
--- a/src/librustc_infer/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
diff --git a/src/librustc_infer/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
index 3f5ed36035c..3f5ed36035c 100644
--- a/src/librustc_infer/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
diff --git a/src/librustc_infer/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs
index 1a9e20e79fe..1a9e20e79fe 100644
--- a/src/librustc_infer/infer/outlives/env.rs
+++ b/compiler/rustc_infer/src/infer/outlives/env.rs
diff --git a/src/librustc_infer/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs
index a1e7f1fa3e5..a1e7f1fa3e5 100644
--- a/src/librustc_infer/infer/outlives/mod.rs
+++ b/compiler/rustc_infer/src/infer/outlives/mod.rs
diff --git a/src/librustc_infer/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index 48f6d937f2f..48f6d937f2f 100644
--- a/src/librustc_infer/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
diff --git a/src/librustc_infer/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs
index 8f20b5743df..8f20b5743df 100644
--- a/src/librustc_infer/infer/outlives/verify.rs
+++ b/compiler/rustc_infer/src/infer/outlives/verify.rs
diff --git a/src/librustc_infer/infer/region_constraints/README.md b/compiler/rustc_infer/src/infer/region_constraints/README.md
index 0231dd06677..0231dd06677 100644
--- a/src/librustc_infer/infer/region_constraints/README.md
+++ b/compiler/rustc_infer/src/infer/region_constraints/README.md
diff --git a/src/librustc_infer/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
index 2d4c1e5d050..2d4c1e5d050 100644
--- a/src/librustc_infer/infer/region_constraints/leak_check.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
diff --git a/src/librustc_infer/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
index 2902c41a6bc..2902c41a6bc 100644
--- a/src/librustc_infer/infer/region_constraints/mod.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
diff --git a/src/librustc_infer/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs
index 74f365ced23..74f365ced23 100644
--- a/src/librustc_infer/infer/resolve.rs
+++ b/compiler/rustc_infer/src/infer/resolve.rs
diff --git a/src/librustc_infer/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs
index 308f884f9a6..308f884f9a6 100644
--- a/src/librustc_infer/infer/sub.rs
+++ b/compiler/rustc_infer/src/infer/sub.rs
diff --git a/src/librustc_infer/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs
index 53c7dcc6377..53c7dcc6377 100644
--- a/src/librustc_infer/infer/type_variable.rs
+++ b/compiler/rustc_infer/src/infer/type_variable.rs
diff --git a/src/librustc_infer/infer/undo_log.rs b/compiler/rustc_infer/src/infer/undo_log.rs
index 2cfd6bb904c..2cfd6bb904c 100644
--- a/src/librustc_infer/infer/undo_log.rs
+++ b/compiler/rustc_infer/src/infer/undo_log.rs
diff --git a/src/librustc_infer/lib.rs b/compiler/rustc_infer/src/lib.rs
index e05041d8846..e05041d8846 100644
--- a/src/librustc_infer/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
diff --git a/src/librustc_infer/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs
index 2710debea94..2710debea94 100644
--- a/src/librustc_infer/traits/engine.rs
+++ b/compiler/rustc_infer/src/traits/engine.rs
diff --git a/src/librustc_infer/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
index f873358ff9f..f873358ff9f 100644
--- a/src/librustc_infer/traits/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
diff --git a/src/librustc_infer/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs
index 7e7c8588ffb..7e7c8588ffb 100644
--- a/src/librustc_infer/traits/mod.rs
+++ b/compiler/rustc_infer/src/traits/mod.rs
diff --git a/src/librustc_infer/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs
index 65284bcee91..65284bcee91 100644
--- a/src/librustc_infer/traits/project.rs
+++ b/compiler/rustc_infer/src/traits/project.rs
diff --git a/src/librustc_infer/traits/structural_impls.rs b/compiler/rustc_infer/src/traits/structural_impls.rs
index c48e58c0482..c48e58c0482 100644
--- a/src/librustc_infer/traits/structural_impls.rs
+++ b/compiler/rustc_infer/src/traits/structural_impls.rs
diff --git a/src/librustc_infer/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index 93fc7f1f3b8..93fc7f1f3b8 100644
--- a/src/librustc_infer/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml
new file mode 100644
index 00000000000..e214493a567
--- /dev/null
+++ b/compiler/rustc_interface/Cargo.toml
@@ -0,0 +1,54 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_interface"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+libc = "0.2"
+tracing = "0.1"
+rayon = { version = "0.3.0", package = "rustc-rayon" }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
+rustc_ast = { path = "../rustc_ast" }
+rustc_attr = { path = "../rustc_attr" }
+rustc_builtin_macros = { path = "../rustc_builtin_macros" }
+rustc_expand = { path = "../rustc_expand" }
+rustc_parse = { path = "../rustc_parse" }
+rustc_session = { path = "../rustc_session" }
+rustc_span = { path = "../rustc_span" }
+rustc_serialize = { path = "../rustc_serialize" }
+rustc_middle = { path = "../rustc_middle" }
+rustc_ast_lowering = { path = "../rustc_ast_lowering" }
+rustc_ast_passes = { path = "../rustc_ast_passes" }
+rustc_incremental = { path = "../rustc_incremental" }
+rustc_traits = { path = "../rustc_traits" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
+rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
+rustc_codegen_llvm = { path = "../rustc_codegen_llvm", optional = true }
+rustc_hir = { path = "../rustc_hir" }
+rustc_metadata = { path = "../rustc_metadata" }
+rustc_mir = { path = "../rustc_mir" }
+rustc_mir_build = { path = "../rustc_mir_build" }
+rustc_passes = { path = "../rustc_passes" }
+rustc_typeck = { path = "../rustc_typeck" }
+rustc_lint = { path = "../rustc_lint" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_plugin_impl = { path = "../rustc_plugin_impl" }
+rustc_privacy = { path = "../rustc_privacy" }
+rustc_resolve = { path = "../rustc_resolve" }
+rustc_trait_selection = { path = "../rustc_trait_selection" }
+rustc_ty = { path = "../rustc_ty" }
+tempfile = "3.0.5"
+
+[target.'cfg(windows)'.dependencies]
+winapi = { version = "0.3", features = ["libloaderapi"] }
+
+[dev-dependencies]
+rustc_target = { path = "../rustc_target" }
+
+[features]
+llvm = ['rustc_codegen_llvm']
diff --git a/src/librustc_interface/callbacks.rs b/compiler/rustc_interface/src/callbacks.rs
index 7fa1a3eb0f5..7fa1a3eb0f5 100644
--- a/src/librustc_interface/callbacks.rs
+++ b/compiler/rustc_interface/src/callbacks.rs
diff --git a/src/librustc_interface/interface.rs b/compiler/rustc_interface/src/interface.rs
index 4d84462c42b..4d84462c42b 100644
--- a/src/librustc_interface/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
diff --git a/src/librustc_interface/lib.rs b/compiler/rustc_interface/src/lib.rs
index fe40c615f79..88d2efe96d1 100644
--- a/src/librustc_interface/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -4,6 +4,7 @@
 #![feature(nll)]
 #![feature(generator_trait)]
 #![feature(generators)]
+#![feature(once_cell)]
 #![recursion_limit = "256"]
 
 mod callbacks;
diff --git a/src/librustc_interface/passes.rs b/compiler/rustc_interface/src/passes.rs
index 403aea8b304..66d3765d347 100644
--- a/src/librustc_interface/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -2,7 +2,6 @@ use crate::interface::{Compiler, Result};
 use crate::proc_macro_decls;
 use crate::util;
 
-use once_cell::sync::Lazy;
 use rustc_ast::mut_visit::MutVisitor;
 use rustc_ast::{self as ast, visit};
 use rustc_codegen_ssa::back::link::emit_metadata;
@@ -46,6 +45,7 @@ use std::any::Any;
 use std::cell::RefCell;
 use std::ffi::OsString;
 use std::io::{self, BufWriter, Write};
+use std::lazy::SyncLazy;
 use std::path::PathBuf;
 use std::rc::Rc;
 use std::{env, fs, iter, mem};
@@ -291,6 +291,7 @@ fn configure_and_expand_inner<'a>(
             trace_mac: sess.opts.debugging_opts.trace_macros,
             should_test: sess.opts.test,
             span_debug: sess.opts.debugging_opts.span_debug,
+            proc_macro_backtrace: sess.opts.debugging_opts.proc_macro_backtrace,
             ..rustc_expand::expand::ExpansionConfig::default(crate_name.to_string())
         };
 
@@ -680,7 +681,7 @@ pub fn prepare_outputs(
     Ok(outputs)
 }
 
-pub static DEFAULT_QUERY_PROVIDERS: Lazy<Providers> = Lazy::new(|| {
+pub static DEFAULT_QUERY_PROVIDERS: SyncLazy<Providers> = SyncLazy::new(|| {
     let providers = &mut Providers::default();
     providers.analysis = analysis;
     proc_macro_decls::provide(providers);
@@ -703,7 +704,7 @@ pub static DEFAULT_QUERY_PROVIDERS: Lazy<Providers> = Lazy::new(|| {
     *providers
 });
 
-pub static DEFAULT_EXTERN_QUERY_PROVIDERS: Lazy<Providers> = Lazy::new(|| {
+pub static DEFAULT_EXTERN_QUERY_PROVIDERS: SyncLazy<Providers> = SyncLazy::new(|| {
     let mut extern_providers = *DEFAULT_QUERY_PROVIDERS;
     rustc_metadata::provide_extern(&mut extern_providers);
     rustc_codegen_ssa::provide_extern(&mut extern_providers);
diff --git a/src/librustc_interface/proc_macro_decls.rs b/compiler/rustc_interface/src/proc_macro_decls.rs
index d56115fd6ac..d56115fd6ac 100644
--- a/src/librustc_interface/proc_macro_decls.rs
+++ b/compiler/rustc_interface/src/proc_macro_decls.rs
diff --git a/src/librustc_interface/queries.rs b/compiler/rustc_interface/src/queries.rs
index 8b82217a91a..8b82217a91a 100644
--- a/src/librustc_interface/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
diff --git a/src/librustc_interface/tests.rs b/compiler/rustc_interface/src/tests.rs
index e94745519a4..ada8dc90494 100644
--- a/src/librustc_interface/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -402,6 +402,7 @@ fn test_codegen_options_tracking_hash() {
     // `link_arg` is omitted because it just forwards to `link_args`.
     untracked!(link_args, vec![String::from("abc"), String::from("def")]);
     untracked!(link_dead_code, Some(true));
+    untracked!(link_self_contained, Some(true));
     untracked!(linker, Some(PathBuf::from("linker")));
     untracked!(linker_flavor, Some(LinkerFlavor::Gcc));
     untracked!(no_stack_check, true);
@@ -502,6 +503,7 @@ fn test_debugging_options_tracking_hash() {
     untracked!(print_llvm_passes, true);
     untracked!(print_mono_items, Some(String::from("abc")));
     untracked!(print_type_sizes, true);
+    untracked!(proc_macro_backtrace, true);
     untracked!(query_dep_graph, true);
     untracked!(query_stats, true);
     untracked!(save_analysis, true);
diff --git a/src/librustc_interface/util.rs b/compiler/rustc_interface/src/util.rs
index 8816ba198cf..b1b39fd1ad2 100644
--- a/src/librustc_interface/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -25,6 +25,7 @@ use rustc_span::symbol::{sym, Symbol};
 use smallvec::SmallVec;
 use std::env;
 use std::io::{self, Write};
+use std::lazy::SyncOnceCell;
 use std::mem;
 use std::ops::DerefMut;
 use std::path::{Path, PathBuf};
@@ -243,8 +244,7 @@ pub fn get_codegen_backend(sess: &Session) -> Box<dyn CodegenBackend> {
 // loading, so we leave the code here. It is potentially useful for other tools
 // that want to invoke the rustc binary while linking to rustc as well.
 pub fn rustc_path<'a>() -> Option<&'a Path> {
-    static RUSTC_PATH: once_cell::sync::OnceCell<Option<PathBuf>> =
-        once_cell::sync::OnceCell::new();
+    static RUSTC_PATH: SyncOnceCell<Option<PathBuf>> = SyncOnceCell::new();
 
     const BIN_PATH: &str = env!("RUSTC_INSTALL_BINDIR");
 
diff --git a/src/librustc_lexer/Cargo.toml b/compiler/rustc_lexer/Cargo.toml
index 28b56f6fef4..12101776de2 100644
--- a/src/librustc_lexer/Cargo.toml
+++ b/compiler/rustc_lexer/Cargo.toml
@@ -14,11 +14,10 @@ Rust lexer used by rustc. No stability guarantees are provided.
 # This will be used when publishing this crate as `rustc-ap-rustc_lexer`.
 [lib]
 doctest = false
-name = "rustc_lexer"
 
 # Note that this crate purposefully does not depend on other rustc crates
 [dependencies]
 unicode-xid = "0.2.0"
 
 [dev-dependencies]
-expect-test = "0.1"
+expect-test = "1.0"
diff --git a/src/librustc_lexer/src/cursor.rs b/compiler/rustc_lexer/src/cursor.rs
index c0045d3f79b..c0045d3f79b 100644
--- a/src/librustc_lexer/src/cursor.rs
+++ b/compiler/rustc_lexer/src/cursor.rs
diff --git a/src/librustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs
index b7d6194cd77..44999bbe857 100644
--- a/src/librustc_lexer/src/lib.rs
+++ b/compiler/rustc_lexer/src/lib.rs
@@ -191,12 +191,16 @@ pub fn strip_shebang(input: &str) -> Option<usize> {
     // For simplicity we consider any line starting with `#!` a shebang,
     // regardless of restrictions put on shebangs by specific platforms.
     if let Some(input_tail) = input.strip_prefix("#!") {
-        // Ok, this is a shebang but if the next non-whitespace token is `[` or maybe
-        // a doc comment (due to `TokenKind::(Line,Block)Comment` ambiguity at lexer level),
+        // Ok, this is a shebang but if the next non-whitespace token is `[`,
         // then it may be valid Rust code, so consider it Rust code.
-        let next_non_whitespace_token = tokenize(input_tail).map(|tok| tok.kind).find(|tok|
-            !matches!(tok, TokenKind::Whitespace | TokenKind::LineComment { .. } | TokenKind::BlockComment { .. })
-        );
+        let next_non_whitespace_token = tokenize(input_tail).map(|tok| tok.kind).find(|tok| {
+            !matches!(
+                tok,
+                TokenKind::Whitespace
+                    | TokenKind::LineComment { doc_style: None }
+                    | TokenKind::BlockComment { doc_style: None, .. }
+            )
+        });
         if next_non_whitespace_token != Some(TokenKind::OpenBracket) {
             // No other choice than to consider this a shebang.
             return Some(2 + input_tail.lines().next().unwrap_or_default().len());
diff --git a/compiler/rustc_lexer/src/tests.rs b/compiler/rustc_lexer/src/tests.rs
new file mode 100644
index 00000000000..94017b7b286
--- /dev/null
+++ b/compiler/rustc_lexer/src/tests.rs
@@ -0,0 +1,287 @@
+use super::*;
+
+use expect_test::{expect, Expect};
+
+fn check_raw_str(s: &str, expected_hashes: u16, expected_err: Option<RawStrError>) {
+    let s = &format!("r{}", s);
+    let mut cursor = Cursor::new(s);
+    cursor.bump();
+    let (n_hashes, err) = cursor.raw_double_quoted_string(0);
+    assert_eq!(n_hashes, expected_hashes);
+    assert_eq!(err, expected_err);
+}
+
+#[test]
+fn test_naked_raw_str() {
+    check_raw_str(r#""abc""#, 0, None);
+}
+
+#[test]
+fn test_raw_no_start() {
+    check_raw_str(r##""abc"#"##, 0, None);
+}
+
+#[test]
+fn test_too_many_terminators() {
+    // this error is handled in the parser later
+    check_raw_str(r###"#"abc"##"###, 1, None);
+}
+
+#[test]
+fn test_unterminated() {
+    check_raw_str(
+        r#"#"abc"#,
+        1,
+        Some(RawStrError::NoTerminator { expected: 1, found: 0, possible_terminator_offset: None }),
+    );
+    check_raw_str(
+        r###"##"abc"#"###,
+        2,
+        Some(RawStrError::NoTerminator {
+            expected: 2,
+            found: 1,
+            possible_terminator_offset: Some(7),
+        }),
+    );
+    // We're looking for "# not just any #
+    check_raw_str(
+        r###"##"abc#"###,
+        2,
+        Some(RawStrError::NoTerminator { expected: 2, found: 0, possible_terminator_offset: None }),
+    )
+}
+
+#[test]
+fn test_invalid_start() {
+    check_raw_str(r##"#~"abc"#"##, 1, Some(RawStrError::InvalidStarter { bad_char: '~' }));
+}
+
+#[test]
+fn test_unterminated_no_pound() {
+    // https://github.com/rust-lang/rust/issues/70677
+    check_raw_str(
+        r#"""#,
+        0,
+        Some(RawStrError::NoTerminator { expected: 0, found: 0, possible_terminator_offset: None }),
+    );
+}
+
+#[test]
+fn test_valid_shebang() {
+    // https://github.com/rust-lang/rust/issues/70528
+    let input = "#!/usr/bin/rustrun\nlet x = 5;";
+    assert_eq!(strip_shebang(input), Some(18));
+}
+
+#[test]
+fn test_invalid_shebang_valid_rust_syntax() {
+    // https://github.com/rust-lang/rust/issues/70528
+    let input = "#!    [bad_attribute]";
+    assert_eq!(strip_shebang(input), None);
+}
+
+#[test]
+fn test_shebang_second_line() {
+    // Because shebangs are interpreted by the kernel, they must be on the first line
+    let input = "\n#!/bin/bash";
+    assert_eq!(strip_shebang(input), None);
+}
+
+#[test]
+fn test_shebang_space() {
+    let input = "#!    /bin/bash";
+    assert_eq!(strip_shebang(input), Some(input.len()));
+}
+
+#[test]
+fn test_shebang_empty_shebang() {
+    let input = "#!    \n[attribute(foo)]";
+    assert_eq!(strip_shebang(input), None);
+}
+
+#[test]
+fn test_invalid_shebang_comment() {
+    let input = "#!//bin/ami/a/comment\n[";
+    assert_eq!(strip_shebang(input), None)
+}
+
+#[test]
+fn test_invalid_shebang_another_comment() {
+    let input = "#!/*bin/ami/a/comment*/\n[attribute";
+    assert_eq!(strip_shebang(input), None)
+}
+
+#[test]
+fn test_shebang_valid_rust_after() {
+    let input = "#!/*bin/ami/a/comment*/\npub fn main() {}";
+    assert_eq!(strip_shebang(input), Some(23))
+}
+
+#[test]
+fn test_shebang_followed_by_attrib() {
+    let input = "#!/bin/rust-scripts\n#![allow_unused(true)]";
+    assert_eq!(strip_shebang(input), Some(19));
+}
+
+fn check_lexing(src: &str, expect: Expect) {
+    let actual: String = tokenize(src).map(|token| format!("{:?}\n", token)).collect();
+    expect.assert_eq(&actual)
+}
+
+#[test]
+fn smoke_test() {
+    check_lexing(
+        "/* my source file */ fn main() { println!(\"zebra\"); }\n",
+        expect![[r#"
+            Token { kind: BlockComment { doc_style: None, terminated: true }, len: 20 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: Ident, len: 2 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: Ident, len: 4 }
+            Token { kind: OpenParen, len: 1 }
+            Token { kind: CloseParen, len: 1 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: OpenBrace, len: 1 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: Ident, len: 7 }
+            Token { kind: Bang, len: 1 }
+            Token { kind: OpenParen, len: 1 }
+            Token { kind: Literal { kind: Str { terminated: true }, suffix_start: 7 }, len: 7 }
+            Token { kind: CloseParen, len: 1 }
+            Token { kind: Semi, len: 1 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: CloseBrace, len: 1 }
+            Token { kind: Whitespace, len: 1 }
+        "#]],
+    )
+}
+
+#[test]
+fn comment_flavors() {
+    check_lexing(
+        r"
+// line
+//// line as well
+/// outer doc line
+//! inner doc line
+/* block */
+/**/
+/*** also block */
+/** outer doc block */
+/*! inner doc block */
+",
+        expect![[r#"
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: LineComment { doc_style: None }, len: 7 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: LineComment { doc_style: None }, len: 17 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: LineComment { doc_style: Some(Outer) }, len: 18 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: LineComment { doc_style: Some(Inner) }, len: 18 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: BlockComment { doc_style: None, terminated: true }, len: 11 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: BlockComment { doc_style: None, terminated: true }, len: 4 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: BlockComment { doc_style: None, terminated: true }, len: 18 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: BlockComment { doc_style: Some(Outer), terminated: true }, len: 22 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: BlockComment { doc_style: Some(Inner), terminated: true }, len: 22 }
+            Token { kind: Whitespace, len: 1 }
+        "#]],
+    )
+}
+
+#[test]
+fn nested_block_comments() {
+    check_lexing(
+        "/* /* */ */'a'",
+        expect![[r#"
+            Token { kind: BlockComment { doc_style: None, terminated: true }, len: 11 }
+            Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 }
+        "#]],
+    )
+}
+
+#[test]
+fn characters() {
+    check_lexing(
+        "'a' ' ' '\\n'",
+        expect![[r#"
+            Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 4 }, len: 4 }
+        "#]],
+    );
+}
+
+#[test]
+fn lifetime() {
+    check_lexing(
+        "'abc",
+        expect![[r#"
+            Token { kind: Lifetime { starts_with_number: false }, len: 4 }
+        "#]],
+    );
+}
+
+#[test]
+fn raw_string() {
+    check_lexing(
+        "r###\"\"#a\\b\x00c\"\"###",
+        expect![[r#"
+            Token { kind: Literal { kind: RawStr { n_hashes: 3, err: None }, suffix_start: 17 }, len: 17 }
+        "#]],
+    )
+}
+
+#[test]
+fn literal_suffixes() {
+    check_lexing(
+        r####"
+'a'
+b'a'
+"a"
+b"a"
+1234
+0b101
+0xABC
+1.0
+1.0e10
+2us
+r###"raw"###suffix
+br###"raw"###suffix
+"####,
+        expect![[r#"
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: Literal { kind: Byte { terminated: true }, suffix_start: 4 }, len: 4 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: Literal { kind: Str { terminated: true }, suffix_start: 3 }, len: 3 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: Literal { kind: ByteStr { terminated: true }, suffix_start: 4 }, len: 4 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: Literal { kind: Int { base: Decimal, empty_int: false }, suffix_start: 4 }, len: 4 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: Literal { kind: Int { base: Binary, empty_int: false }, suffix_start: 5 }, len: 5 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: Literal { kind: Int { base: Hexadecimal, empty_int: false }, suffix_start: 5 }, len: 5 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: Literal { kind: Float { base: Decimal, empty_exponent: false }, suffix_start: 3 }, len: 3 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: Literal { kind: Float { base: Decimal, empty_exponent: false }, suffix_start: 6 }, len: 6 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: Literal { kind: Int { base: Decimal, empty_int: false }, suffix_start: 1 }, len: 3 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: Literal { kind: RawStr { n_hashes: 3, err: None }, suffix_start: 12 }, len: 18 }
+            Token { kind: Whitespace, len: 1 }
+            Token { kind: Literal { kind: RawByteStr { n_hashes: 3, err: None }, suffix_start: 13 }, len: 19 }
+            Token { kind: Whitespace, len: 1 }
+        "#]],
+    )
+}
diff --git a/src/librustc_lexer/src/unescape.rs b/compiler/rustc_lexer/src/unescape.rs
index 697d25fdb58..697d25fdb58 100644
--- a/src/librustc_lexer/src/unescape.rs
+++ b/compiler/rustc_lexer/src/unescape.rs
diff --git a/src/librustc_lexer/src/unescape/tests.rs b/compiler/rustc_lexer/src/unescape/tests.rs
index f2b751a78f2..f2b751a78f2 100644
--- a/src/librustc_lexer/src/unescape/tests.rs
+++ b/compiler/rustc_lexer/src/unescape/tests.rs
diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml
new file mode 100644
index 00000000000..760a8e385d6
--- /dev/null
+++ b/compiler/rustc_lint/Cargo.toml
@@ -0,0 +1,22 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_lint"
+version = "0.0.0"
+edition = "2018"
+
+[dependencies]
+tracing = "0.1"
+unicode-security = "0.0.5"
+rustc_middle = { path = "../rustc_middle" }
+rustc_ast_pretty = { path = "../rustc_ast_pretty" }
+rustc_attr = { path = "../rustc_attr" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_target = { path = "../rustc_target" }
+rustc_ast = { path = "../rustc_ast" }
+rustc_span = { path = "../rustc_span" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_feature = { path = "../rustc_feature" }
+rustc_index = { path = "../rustc_index" }
+rustc_session = { path = "../rustc_session" }
+rustc_trait_selection = { path = "../rustc_trait_selection" }
diff --git a/src/librustc_lint/array_into_iter.rs b/compiler/rustc_lint/src/array_into_iter.rs
index 9d74ad3b2f5..9d74ad3b2f5 100644
--- a/src/librustc_lint/array_into_iter.rs
+++ b/compiler/rustc_lint/src/array_into_iter.rs
diff --git a/src/librustc_lint/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index ea624b9ed30..ea624b9ed30 100644
--- a/src/librustc_lint/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
diff --git a/src/librustc_lint/context.rs b/compiler/rustc_lint/src/context.rs
index a6784ffffcd..a6784ffffcd 100644
--- a/src/librustc_lint/context.rs
+++ b/compiler/rustc_lint/src/context.rs
diff --git a/src/librustc_lint/early.rs b/compiler/rustc_lint/src/early.rs
index 998676d44d2..998676d44d2 100644
--- a/src/librustc_lint/early.rs
+++ b/compiler/rustc_lint/src/early.rs
diff --git a/src/librustc_lint/internal.rs b/compiler/rustc_lint/src/internal.rs
index 100e555f299..100e555f299 100644
--- a/src/librustc_lint/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
diff --git a/src/librustc_lint/late.rs b/compiler/rustc_lint/src/late.rs
index a6c04fb0b4c..a6c04fb0b4c 100644
--- a/src/librustc_lint/late.rs
+++ b/compiler/rustc_lint/src/late.rs
diff --git a/src/librustc_lint/levels.rs b/compiler/rustc_lint/src/levels.rs
index 48254dcee82..48254dcee82 100644
--- a/src/librustc_lint/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
diff --git a/src/librustc_lint/lib.rs b/compiler/rustc_lint/src/lib.rs
index 0a14b16e274..0a14b16e274 100644
--- a/src/librustc_lint/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
diff --git a/src/librustc_lint/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs
index 2f0b2a8d680..2f0b2a8d680 100644
--- a/src/librustc_lint/non_ascii_idents.rs
+++ b/compiler/rustc_lint/src/non_ascii_idents.rs
diff --git a/src/librustc_lint/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs
index f23e8c5e208..f23e8c5e208 100644
--- a/src/librustc_lint/nonstandard_style.rs
+++ b/compiler/rustc_lint/src/nonstandard_style.rs
diff --git a/src/librustc_lint/nonstandard_style/tests.rs b/compiler/rustc_lint/src/nonstandard_style/tests.rs
index 39c525b8623..39c525b8623 100644
--- a/src/librustc_lint/nonstandard_style/tests.rs
+++ b/compiler/rustc_lint/src/nonstandard_style/tests.rs
diff --git a/src/librustc_lint/passes.rs b/compiler/rustc_lint/src/passes.rs
index 159286c13a4..159286c13a4 100644
--- a/src/librustc_lint/passes.rs
+++ b/compiler/rustc_lint/src/passes.rs
diff --git a/src/librustc_lint/redundant_semicolon.rs b/compiler/rustc_lint/src/redundant_semicolon.rs
index d4aa4968f25..d4aa4968f25 100644
--- a/src/librustc_lint/redundant_semicolon.rs
+++ b/compiler/rustc_lint/src/redundant_semicolon.rs
diff --git a/src/librustc_lint/types.rs b/compiler/rustc_lint/src/types.rs
index 35c462c24c8..35c462c24c8 100644
--- a/src/librustc_lint/types.rs
+++ b/compiler/rustc_lint/src/types.rs
diff --git a/src/librustc_lint/unused.rs b/compiler/rustc_lint/src/unused.rs
index c793e81ebe3..c793e81ebe3 100644
--- a/src/librustc_lint/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
diff --git a/src/librustc_macros/Cargo.toml b/compiler/rustc_macros/Cargo.toml
index 73eb0dd56d7..73eb0dd56d7 100644
--- a/src/librustc_macros/Cargo.toml
+++ b/compiler/rustc_macros/Cargo.toml
diff --git a/src/librustc_macros/src/hash_stable.rs b/compiler/rustc_macros/src/hash_stable.rs
index c955c137782..c955c137782 100644
--- a/src/librustc_macros/src/hash_stable.rs
+++ b/compiler/rustc_macros/src/hash_stable.rs
diff --git a/src/librustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs
index 7fb3b0e7ea6..7fb3b0e7ea6 100644
--- a/src/librustc_macros/src/lib.rs
+++ b/compiler/rustc_macros/src/lib.rs
diff --git a/src/librustc_macros/src/lift.rs b/compiler/rustc_macros/src/lift.rs
index 4bf4ce00a4d..4bf4ce00a4d 100644
--- a/src/librustc_macros/src/lift.rs
+++ b/compiler/rustc_macros/src/lift.rs
diff --git a/src/librustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs
index c17d5311e8f..c17d5311e8f 100644
--- a/src/librustc_macros/src/query.rs
+++ b/compiler/rustc_macros/src/query.rs
diff --git a/src/librustc_macros/src/serialize.rs b/compiler/rustc_macros/src/serialize.rs
index dbeb3c75504..dbeb3c75504 100644
--- a/src/librustc_macros/src/serialize.rs
+++ b/compiler/rustc_macros/src/serialize.rs
diff --git a/src/librustc_macros/src/symbols.rs b/compiler/rustc_macros/src/symbols.rs
index 352665f0ab1..352665f0ab1 100644
--- a/src/librustc_macros/src/symbols.rs
+++ b/compiler/rustc_macros/src/symbols.rs
diff --git a/src/librustc_macros/src/type_foldable.rs b/compiler/rustc_macros/src/type_foldable.rs
index 6931e6552ad..6931e6552ad 100644
--- a/src/librustc_macros/src/type_foldable.rs
+++ b/compiler/rustc_macros/src/type_foldable.rs
diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml
new file mode 100644
index 00000000000..4b144f94ea7
--- /dev/null
+++ b/compiler/rustc_metadata/Cargo.toml
@@ -0,0 +1,33 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_metadata"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+libc = "0.2"
+snap = "1"
+tracing = "0.1"
+memmap = "0.7"
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
+rustc_middle = { path = "../rustc_middle" }
+rustc_attr = { path = "../rustc_attr" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_hir_pretty = { path = "../rustc_hir_pretty" }
+rustc_target = { path = "../rustc_target" }
+rustc_index = { path = "../rustc_index" }
+rustc_macros = { path = "../rustc_macros" }
+rustc_serialize = { path = "../rustc_serialize" }
+stable_deref_trait = "1.0.0"
+rustc_ast = { path = "../rustc_ast" }
+rustc_expand = { path = "../rustc_expand" }
+rustc_span = { path = "../rustc_span" }
+rustc_session = { path = "../rustc_session" }
+
+[target.'cfg(windows)'.dependencies]
+winapi = { version = "0.3", features = ["errhandlingapi", "libloaderapi"] }
diff --git a/src/librustc_metadata/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 7562da6d782..7562da6d782 100644
--- a/src/librustc_metadata/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
diff --git a/src/librustc_metadata/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs
index f7454da90a3..f7454da90a3 100644
--- a/src/librustc_metadata/dependency_format.rs
+++ b/compiler/rustc_metadata/src/dependency_format.rs
diff --git a/src/librustc_metadata/dynamic_lib.rs b/compiler/rustc_metadata/src/dynamic_lib.rs
index bdb53e3f75a..bdb53e3f75a 100644
--- a/src/librustc_metadata/dynamic_lib.rs
+++ b/compiler/rustc_metadata/src/dynamic_lib.rs
diff --git a/src/librustc_metadata/dynamic_lib/tests.rs b/compiler/rustc_metadata/src/dynamic_lib/tests.rs
index 7090bbf61c7..7090bbf61c7 100644
--- a/src/librustc_metadata/dynamic_lib/tests.rs
+++ b/compiler/rustc_metadata/src/dynamic_lib/tests.rs
diff --git a/src/librustc_metadata/foreign_modules.rs b/compiler/rustc_metadata/src/foreign_modules.rs
index 8675197656a..8675197656a 100644
--- a/src/librustc_metadata/foreign_modules.rs
+++ b/compiler/rustc_metadata/src/foreign_modules.rs
diff --git a/src/librustc_metadata/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 85490f5f6e9..85490f5f6e9 100644
--- a/src/librustc_metadata/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
diff --git a/src/librustc_metadata/link_args.rs b/compiler/rustc_metadata/src/link_args.rs
index d8f16796083..d8f16796083 100644
--- a/src/librustc_metadata/link_args.rs
+++ b/compiler/rustc_metadata/src/link_args.rs
diff --git a/src/librustc_metadata/locator.rs b/compiler/rustc_metadata/src/locator.rs
index 0869ec28367..0869ec28367 100644
--- a/src/librustc_metadata/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
diff --git a/src/librustc_metadata/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index 3976475cb06..3976475cb06 100644
--- a/src/librustc_metadata/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
diff --git a/src/librustc_metadata/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 43d76e9fdb4..43d76e9fdb4 100644
--- a/src/librustc_metadata/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 36ff65fc5eb..36ff65fc5eb 100644
--- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
diff --git a/src/librustc_metadata/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 509ef1caf1a..509ef1caf1a 100644
--- a/src/librustc_metadata/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
diff --git a/src/librustc_metadata/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 1ba5962d119..1ba5962d119 100644
--- a/src/librustc_metadata/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
diff --git a/src/librustc_metadata/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs
index 03bd4170ea9..03bd4170ea9 100644
--- a/src/librustc_metadata/rmeta/table.rs
+++ b/compiler/rustc_metadata/src/rmeta/table.rs
diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml
new file mode 100644
index 00000000000..5a82cbf2997
--- /dev/null
+++ b/compiler/rustc_middle/Cargo.toml
@@ -0,0 +1,33 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_middle"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+rustc_arena = { path = "../rustc_arena" }
+bitflags = "1.2.1"
+tracing = "0.1"
+rustc-rayon-core = "0.3.0"
+polonius-engine = "0.12.0"
+rustc_apfloat = { path = "../rustc_apfloat" }
+rustc_attr = { path = "../rustc_attr" }
+rustc_feature = { path = "../rustc_feature" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_target = { path = "../rustc_target" }
+rustc_macros = { path = "../rustc_macros" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_query_system = { path = "../rustc_query_system" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_index = { path = "../rustc_index" }
+rustc_serialize = { path = "../rustc_serialize" }
+rustc_ast = { path = "../rustc_ast" }
+rustc_span = { path = "../rustc_span" }
+byteorder = { version = "1.3" }
+chalk-ir = "0.14.0"
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
+measureme = "0.7.1"
+rustc_session = { path = "../rustc_session" }
diff --git a/src/librustc_middle/README.md b/compiler/rustc_middle/README.md
index de58f546cd3..de58f546cd3 100644
--- a/src/librustc_middle/README.md
+++ b/compiler/rustc_middle/README.md
diff --git a/src/librustc_middle/benches/lib.rs b/compiler/rustc_middle/benches/lib.rs
index 237751bcbd7..237751bcbd7 100644
--- a/src/librustc_middle/benches/lib.rs
+++ b/compiler/rustc_middle/benches/lib.rs
diff --git a/src/librustc_middle/arena.rs b/compiler/rustc_middle/src/arena.rs
index f6570cc95d2..f6570cc95d2 100644
--- a/src/librustc_middle/arena.rs
+++ b/compiler/rustc_middle/src/arena.rs
diff --git a/src/librustc_middle/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs
index a61b9af9bac..a61b9af9bac 100644
--- a/src/librustc_middle/dep_graph/dep_node.rs
+++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
diff --git a/src/librustc_middle/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs
index 66975242798..66975242798 100644
--- a/src/librustc_middle/dep_graph/mod.rs
+++ b/compiler/rustc_middle/src/dep_graph/mod.rs
diff --git a/src/librustc_middle/hir/exports.rs b/compiler/rustc_middle/src/hir/exports.rs
index be9e38aca65..be9e38aca65 100644
--- a/src/librustc_middle/hir/exports.rs
+++ b/compiler/rustc_middle/src/hir/exports.rs
diff --git a/src/librustc_middle/hir/map/blocks.rs b/compiler/rustc_middle/src/hir/map/blocks.rs
index 6f572a4875f..6f572a4875f 100644
--- a/src/librustc_middle/hir/map/blocks.rs
+++ b/compiler/rustc_middle/src/hir/map/blocks.rs
diff --git a/src/librustc_middle/hir/map/collector.rs b/compiler/rustc_middle/src/hir/map/collector.rs
index dce06a5f7ee..dce06a5f7ee 100644
--- a/src/librustc_middle/hir/map/collector.rs
+++ b/compiler/rustc_middle/src/hir/map/collector.rs
diff --git a/src/librustc_middle/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 1e57411f9c5..1e57411f9c5 100644
--- a/src/librustc_middle/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
diff --git a/src/librustc_middle/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index ae3b30217cc..ae3b30217cc 100644
--- a/src/librustc_middle/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
diff --git a/src/librustc_middle/hir/place.rs b/compiler/rustc_middle/src/hir/place.rs
index bcb56fae170..bcb56fae170 100644
--- a/src/librustc_middle/hir/place.rs
+++ b/compiler/rustc_middle/src/hir/place.rs
diff --git a/src/librustc_middle/ich/hcx.rs b/compiler/rustc_middle/src/ich/hcx.rs
index 084fe4cfa16..084fe4cfa16 100644
--- a/src/librustc_middle/ich/hcx.rs
+++ b/compiler/rustc_middle/src/ich/hcx.rs
diff --git a/src/librustc_middle/ich/impls_hir.rs b/compiler/rustc_middle/src/ich/impls_hir.rs
index c2d177b69b6..c2d177b69b6 100644
--- a/src/librustc_middle/ich/impls_hir.rs
+++ b/compiler/rustc_middle/src/ich/impls_hir.rs
diff --git a/src/librustc_middle/ich/impls_syntax.rs b/compiler/rustc_middle/src/ich/impls_syntax.rs
index e3d4655831b..e3d4655831b 100644
--- a/src/librustc_middle/ich/impls_syntax.rs
+++ b/compiler/rustc_middle/src/ich/impls_syntax.rs
diff --git a/src/librustc_middle/ich/impls_ty.rs b/compiler/rustc_middle/src/ich/impls_ty.rs
index 8f15c99f951..8f15c99f951 100644
--- a/src/librustc_middle/ich/impls_ty.rs
+++ b/compiler/rustc_middle/src/ich/impls_ty.rs
diff --git a/src/librustc_middle/ich/mod.rs b/compiler/rustc_middle/src/ich/mod.rs
index c8fb2bf39cc..c8fb2bf39cc 100644
--- a/src/librustc_middle/ich/mod.rs
+++ b/compiler/rustc_middle/src/ich/mod.rs
diff --git a/src/librustc_middle/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index 1e15ae49a0c..1e15ae49a0c 100644
--- a/src/librustc_middle/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
diff --git a/src/librustc_middle/infer/mod.rs b/compiler/rustc_middle/src/infer/mod.rs
index 497d3811f28..497d3811f28 100644
--- a/src/librustc_middle/infer/mod.rs
+++ b/compiler/rustc_middle/src/infer/mod.rs
diff --git a/src/librustc_middle/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs
index 2580ac6bebd..2580ac6bebd 100644
--- a/src/librustc_middle/infer/unify_key.rs
+++ b/compiler/rustc_middle/src/infer/unify_key.rs
diff --git a/src/librustc_middle/lib.rs b/compiler/rustc_middle/src/lib.rs
index 1b2dea8a378..a675aae5b17 100644
--- a/src/librustc_middle/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -38,6 +38,7 @@
 #![feature(exhaustive_patterns)]
 #![feature(extern_types)]
 #![feature(nll)]
+#![feature(once_cell)]
 #![feature(option_expect_none)]
 #![feature(or_patterns)]
 #![feature(min_specialization)]
diff --git a/src/librustc_middle/lint.rs b/compiler/rustc_middle/src/lint.rs
index 25e5379881e..25e5379881e 100644
--- a/src/librustc_middle/lint.rs
+++ b/compiler/rustc_middle/src/lint.rs
diff --git a/src/librustc_middle/macros.rs b/compiler/rustc_middle/src/macros.rs
index a5482b7bdcf..a5482b7bdcf 100644
--- a/src/librustc_middle/macros.rs
+++ b/compiler/rustc_middle/src/macros.rs
diff --git a/src/librustc_middle/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
index 62a6198b9b4..62a6198b9b4 100644
--- a/src/librustc_middle/middle/codegen_fn_attrs.rs
+++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
diff --git a/src/librustc_middle/middle/cstore.rs b/compiler/rustc_middle/src/middle/cstore.rs
index 1af1d581817..1af1d581817 100644
--- a/src/librustc_middle/middle/cstore.rs
+++ b/compiler/rustc_middle/src/middle/cstore.rs
diff --git a/src/librustc_middle/middle/dependency_format.rs b/compiler/rustc_middle/src/middle/dependency_format.rs
index e079843bfbc..e079843bfbc 100644
--- a/src/librustc_middle/middle/dependency_format.rs
+++ b/compiler/rustc_middle/src/middle/dependency_format.rs
diff --git a/src/librustc_middle/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs
index 276e45ce99b..276e45ce99b 100644
--- a/src/librustc_middle/middle/exported_symbols.rs
+++ b/compiler/rustc_middle/src/middle/exported_symbols.rs
diff --git a/src/librustc_middle/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs
index 7194a035e89..7194a035e89 100644
--- a/src/librustc_middle/middle/lang_items.rs
+++ b/compiler/rustc_middle/src/middle/lang_items.rs
diff --git a/src/librustc_middle/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs
index def9e5ebb52..def9e5ebb52 100644
--- a/src/librustc_middle/middle/limits.rs
+++ b/compiler/rustc_middle/src/middle/limits.rs
diff --git a/src/librustc_middle/middle/mod.rs b/compiler/rustc_middle/src/middle/mod.rs
index 9bc9ca6707a..9bc9ca6707a 100644
--- a/src/librustc_middle/middle/mod.rs
+++ b/compiler/rustc_middle/src/middle/mod.rs
diff --git a/src/librustc_middle/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs
index 4756e83b5e9..4756e83b5e9 100644
--- a/src/librustc_middle/middle/privacy.rs
+++ b/compiler/rustc_middle/src/middle/privacy.rs
diff --git a/src/librustc_middle/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs
index 4c6ac820604..4c6ac820604 100644
--- a/src/librustc_middle/middle/region.rs
+++ b/compiler/rustc_middle/src/middle/region.rs
diff --git a/src/librustc_middle/middle/resolve_lifetime.rs b/compiler/rustc_middle/src/middle/resolve_lifetime.rs
index 3d0144e9c8a..3d0144e9c8a 100644
--- a/src/librustc_middle/middle/resolve_lifetime.rs
+++ b/compiler/rustc_middle/src/middle/resolve_lifetime.rs
diff --git a/src/librustc_middle/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index b32eebbb11e..b32eebbb11e 100644
--- a/src/librustc_middle/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
diff --git a/src/librustc_middle/mir/coverage/mod.rs b/compiler/rustc_middle/src/mir/coverage/mod.rs
index ce311c2ee52..ce311c2ee52 100644
--- a/src/librustc_middle/mir/coverage/mod.rs
+++ b/compiler/rustc_middle/src/mir/coverage/mod.rs
diff --git a/src/librustc_middle/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index 505939d56ed..505939d56ed 100644
--- a/src/librustc_middle/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
diff --git a/src/librustc_middle/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index 059925088ce..059925088ce 100644
--- a/src/librustc_middle/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
diff --git a/src/librustc_middle/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index 0dc3d6e344a..0dc3d6e344a 100644
--- a/src/librustc_middle/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
diff --git a/src/librustc_middle/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs
index e3d5a085613..e3d5a085613 100644
--- a/src/librustc_middle/mir/interpret/pointer.rs
+++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs
diff --git a/src/librustc_middle/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index dcc1f8b1a4b..dcc1f8b1a4b 100644
--- a/src/librustc_middle/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
diff --git a/src/librustc_middle/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs
index 7d6ff3eb5c1..7d6ff3eb5c1 100644
--- a/src/librustc_middle/mir/interpret/value.rs
+++ b/compiler/rustc_middle/src/mir/interpret/value.rs
diff --git a/src/librustc_middle/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 785a7f0c51a..785a7f0c51a 100644
--- a/src/librustc_middle/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
diff --git a/src/librustc_middle/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index 0d5f6619df5..79e2c5aac23 100644
--- a/src/librustc_middle/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -1,6 +1,5 @@
 use crate::dep_graph::{DepConstructor, DepNode, WorkProduct, WorkProductId};
 use crate::ich::{NodeIdHashingMode, StableHashingContext};
-use crate::ty::print::obsolete::DefPathBasedNames;
 use crate::ty::{subst::InternalSubsts, Instance, InstanceDef, SymbolName, TyCtxt};
 use rustc_attr::InlineAttr;
 use rustc_data_structures::base_n;
@@ -86,7 +85,7 @@ impl<'tcx> MonoItem<'tcx> {
             .debugging_opts
             .inline_in_all_cgus
             .unwrap_or_else(|| tcx.sess.opts.optimize != OptLevel::No)
-            && tcx.sess.opts.cg.link_dead_code != Some(true);
+            && !tcx.sess.link_dead_code();
 
         match *self {
             MonoItem::Fn(ref instance) => {
@@ -171,30 +170,6 @@ impl<'tcx> MonoItem<'tcx> {
         !tcx.subst_and_check_impossible_predicates((def_id, &substs))
     }
 
-    pub fn to_string(&self, tcx: TyCtxt<'tcx>, debug: bool) -> String {
-        return match *self {
-            MonoItem::Fn(instance) => to_string_internal(tcx, "fn ", instance, debug),
-            MonoItem::Static(def_id) => {
-                let instance = Instance::new(def_id, tcx.intern_substs(&[]));
-                to_string_internal(tcx, "static ", instance, debug)
-            }
-            MonoItem::GlobalAsm(..) => "global_asm".to_string(),
-        };
-
-        fn to_string_internal<'tcx>(
-            tcx: TyCtxt<'tcx>,
-            prefix: &str,
-            instance: Instance<'tcx>,
-            debug: bool,
-        ) -> String {
-            let mut result = String::with_capacity(32);
-            result.push_str(prefix);
-            let printer = DefPathBasedNames::new(tcx, false, false);
-            printer.push_instance_as_string(instance, &mut result, debug);
-            result
-        }
-    }
-
     pub fn local_span(&self, tcx: TyCtxt<'tcx>) -> Option<Span> {
         match *self {
             MonoItem::Fn(Instance { def, .. }) => {
@@ -229,6 +204,18 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for MonoItem<'tcx> {
     }
 }
 
+impl<'tcx> fmt::Display for MonoItem<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match *self {
+            MonoItem::Fn(instance) => write!(f, "fn {}", instance),
+            MonoItem::Static(def_id) => {
+                write!(f, "static {}", Instance::new(def_id, InternalSubsts::empty()))
+            }
+            MonoItem::GlobalAsm(..) => write!(f, "global_asm"),
+        }
+    }
+}
+
 pub struct CodegenUnit<'tcx> {
     /// A name for this CGU. Incremental compilation requires that
     /// name be unique amongst **all** crates. Therefore, it should
diff --git a/src/librustc_middle/mir/predecessors.rs b/compiler/rustc_middle/src/mir/predecessors.rs
index b16a1d53fff..b16a1d53fff 100644
--- a/src/librustc_middle/mir/predecessors.rs
+++ b/compiler/rustc_middle/src/mir/predecessors.rs
diff --git a/src/librustc_middle/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index 0878e9313d8..0878e9313d8 100644
--- a/src/librustc_middle/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
diff --git a/src/librustc_middle/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index efcd41e5c18..efcd41e5c18 100644
--- a/src/librustc_middle/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
diff --git a/src/librustc_middle/mir/terminator/mod.rs b/compiler/rustc_middle/src/mir/terminator/mod.rs
index fcfd648c2b7..fcfd648c2b7 100644
--- a/src/librustc_middle/mir/terminator/mod.rs
+++ b/compiler/rustc_middle/src/mir/terminator/mod.rs
diff --git a/src/librustc_middle/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs
index 36e277d1a88..36e277d1a88 100644
--- a/src/librustc_middle/mir/traversal.rs
+++ b/compiler/rustc_middle/src/mir/traversal.rs
diff --git a/src/librustc_middle/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs
index 6bb6abe0289..6bb6abe0289 100644
--- a/src/librustc_middle/mir/type_foldable.rs
+++ b/compiler/rustc_middle/src/mir/type_foldable.rs
diff --git a/src/librustc_middle/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 6515ae31b46..6515ae31b46 100644
--- a/src/librustc_middle/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
diff --git a/src/librustc_middle/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index e05752f08f6..e05752f08f6 100644
--- a/src/librustc_middle/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
diff --git a/src/librustc_middle/tests.rs b/compiler/rustc_middle/src/tests.rs
index 757e0bd3bfb..757e0bd3bfb 100644
--- a/src/librustc_middle/tests.rs
+++ b/compiler/rustc_middle/src/tests.rs
diff --git a/src/librustc_middle/traits/chalk.rs b/compiler/rustc_middle/src/traits/chalk.rs
index 405af8cb240..405af8cb240 100644
--- a/src/librustc_middle/traits/chalk.rs
+++ b/compiler/rustc_middle/src/traits/chalk.rs
diff --git a/src/librustc_middle/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index f86403fa502..f86403fa502 100644
--- a/src/librustc_middle/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
diff --git a/src/librustc_middle/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs
index 4b7663e9ade..4b7663e9ade 100644
--- a/src/librustc_middle/traits/query.rs
+++ b/compiler/rustc_middle/src/traits/query.rs
diff --git a/src/librustc_middle/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs
index 6ad514c6be2..6ad514c6be2 100644
--- a/src/librustc_middle/traits/select.rs
+++ b/compiler/rustc_middle/src/traits/select.rs
diff --git a/src/librustc_middle/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs
index 969404c68ca..969404c68ca 100644
--- a/src/librustc_middle/traits/specialization_graph.rs
+++ b/compiler/rustc_middle/src/traits/specialization_graph.rs
diff --git a/src/librustc_middle/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs
index d73fc628ceb..d73fc628ceb 100644
--- a/src/librustc_middle/traits/structural_impls.rs
+++ b/compiler/rustc_middle/src/traits/structural_impls.rs
diff --git a/src/librustc_middle/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs
index 4693a2f66fb..4693a2f66fb 100644
--- a/src/librustc_middle/ty/_match.rs
+++ b/compiler/rustc_middle/src/ty/_match.rs
diff --git a/src/librustc_middle/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs
index 6a9bb8d6c28..6a9bb8d6c28 100644
--- a/src/librustc_middle/ty/adjustment.rs
+++ b/compiler/rustc_middle/src/ty/adjustment.rs
diff --git a/src/librustc_middle/ty/binding.rs b/compiler/rustc_middle/src/ty/binding.rs
index 3237147c8ba..3237147c8ba 100644
--- a/src/librustc_middle/ty/binding.rs
+++ b/compiler/rustc_middle/src/ty/binding.rs
diff --git a/src/librustc_middle/ty/cast.rs b/compiler/rustc_middle/src/ty/cast.rs
index 79a3008c364..79a3008c364 100644
--- a/src/librustc_middle/ty/cast.rs
+++ b/compiler/rustc_middle/src/ty/cast.rs
diff --git a/src/librustc_middle/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index 291648869fb..291648869fb 100644
--- a/src/librustc_middle/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
diff --git a/src/librustc_middle/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index 64faacc1c0b..64faacc1c0b 100644
--- a/src/librustc_middle/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
diff --git a/src/librustc_middle/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs
index ced0429deab..ced0429deab 100644
--- a/src/librustc_middle/ty/consts/int.rs
+++ b/compiler/rustc_middle/src/ty/consts/int.rs
diff --git a/src/librustc_middle/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index ede28522000..ede28522000 100644
--- a/src/librustc_middle/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
diff --git a/src/librustc_middle/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 18ae744cb1e..5819c774bc2 100644
--- a/src/librustc_middle/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -34,6 +34,7 @@ use rustc_data_structures::stable_hasher::{
     hash_stable_hashmap, HashStable, StableHasher, StableVec,
 };
 use rustc_data_structures::sync::{self, Lock, Lrc, WorkerLocal};
+use rustc_data_structures::unhash::UnhashMap;
 use rustc_errors::ErrorReported;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -935,7 +936,7 @@ pub struct GlobalCtxt<'tcx> {
 
     /// A map from `DefPathHash` -> `DefId`. Includes `DefId`s from the local crate
     /// as well as all upstream crates. Only populated in incremental mode.
-    pub def_path_hash_to_def_id: Option<FxHashMap<DefPathHash, DefId>>,
+    pub def_path_hash_to_def_id: Option<UnhashMap<DefPathHash, DefId>>,
 
     pub queries: query::Queries<'tcx>,
 
@@ -1104,7 +1105,7 @@ impl<'tcx> TyCtxt<'tcx> {
         let def_path_hash_to_def_id = if s.opts.build_dep_graph() {
             let capacity = definitions.def_path_table().num_def_ids()
                 + crates.iter().map(|cnum| cstore.num_def_ids(*cnum)).sum::<usize>();
-            let mut map = FxHashMap::with_capacity_and_hasher(capacity, Default::default());
+            let mut map = UnhashMap::with_capacity_and_hasher(capacity, Default::default());
 
             map.extend(definitions.def_path_table().all_def_path_hashes_and_def_ids(LOCAL_CRATE));
             for cnum in &crates {
diff --git a/src/librustc_middle/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index b22727bdd75..b22727bdd75 100644
--- a/src/librustc_middle/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
diff --git a/src/librustc_middle/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs
index 48d0fc1839e..48d0fc1839e 100644
--- a/src/librustc_middle/ty/erase_regions.rs
+++ b/compiler/rustc_middle/src/ty/erase_regions.rs
diff --git a/src/librustc_middle/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 1963881626e..1963881626e 100644
--- a/src/librustc_middle/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
diff --git a/src/librustc_middle/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs
index 1bee2d60f75..1bee2d60f75 100644
--- a/src/librustc_middle/ty/fast_reject.rs
+++ b/compiler/rustc_middle/src/ty/fast_reject.rs
diff --git a/src/librustc_middle/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index 27f50c240db..27f50c240db 100644
--- a/src/librustc_middle/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
diff --git a/src/librustc_middle/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index 492f8ce9ef1..492f8ce9ef1 100644
--- a/src/librustc_middle/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
diff --git a/src/librustc_middle/ty/inhabitedness/def_id_forest.rs b/compiler/rustc_middle/src/ty/inhabitedness/def_id_forest.rs
index ee6b06a1cc8..ee6b06a1cc8 100644
--- a/src/librustc_middle/ty/inhabitedness/def_id_forest.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/def_id_forest.rs
diff --git a/src/librustc_middle/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
index d1b5eed921b..d1b5eed921b 100644
--- a/src/librustc_middle/ty/inhabitedness/mod.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
diff --git a/src/librustc_middle/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 8e08fe4b87b..8e08fe4b87b 100644
--- a/src/librustc_middle/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
diff --git a/src/librustc_middle/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 08bd131565b..08bd131565b 100644
--- a/src/librustc_middle/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
diff --git a/src/librustc_middle/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs
index 83a2bdf90f9..83a2bdf90f9 100644
--- a/src/librustc_middle/ty/list.rs
+++ b/compiler/rustc_middle/src/ty/list.rs
diff --git a/src/librustc_middle/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index b6300a40b0d..b6300a40b0d 100644
--- a/src/librustc_middle/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
diff --git a/src/librustc_middle/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
index 48a62b64604..48a62b64604 100644
--- a/src/librustc_middle/ty/normalize_erasing_regions.rs
+++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
diff --git a/src/librustc_middle/ty/outlives.rs b/compiler/rustc_middle/src/ty/outlives.rs
index 1a8693b8df7..1a8693b8df7 100644
--- a/src/librustc_middle/ty/outlives.rs
+++ b/compiler/rustc_middle/src/ty/outlives.rs
diff --git a/src/librustc_middle/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs
index 6c8f23c139f..bfeef7892c3 100644
--- a/src/librustc_middle/ty/print/mod.rs
+++ b/compiler/rustc_middle/src/ty/print/mod.rs
@@ -9,8 +9,6 @@ use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
 mod pretty;
 pub use self::pretty::*;
 
-pub mod obsolete;
-
 // FIXME(eddyb) false positive, the lifetime parameters are used with `P:  Printer<...>`.
 #[allow(unused_lifetimes)]
 pub trait Print<'tcx, P> {
diff --git a/src/librustc_middle/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 999a1d52a26..999a1d52a26 100644
--- a/src/librustc_middle/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
diff --git a/src/librustc_middle/ty/query/README.md b/compiler/rustc_middle/src/ty/query/README.md
index 8ec07b9fdeb..8ec07b9fdeb 100644
--- a/src/librustc_middle/ty/query/README.md
+++ b/compiler/rustc_middle/src/ty/query/README.md
diff --git a/src/librustc_middle/ty/query/job.rs b/compiler/rustc_middle/src/ty/query/job.rs
index bd2e7747b7d..bd2e7747b7d 100644
--- a/src/librustc_middle/ty/query/job.rs
+++ b/compiler/rustc_middle/src/ty/query/job.rs
diff --git a/src/librustc_middle/ty/query/keys.rs b/compiler/rustc_middle/src/ty/query/keys.rs
index 3f7a20bba2b..3f7a20bba2b 100644
--- a/src/librustc_middle/ty/query/keys.rs
+++ b/compiler/rustc_middle/src/ty/query/keys.rs
diff --git a/src/librustc_middle/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs
index ee9b203b151..ee9b203b151 100644
--- a/src/librustc_middle/ty/query/mod.rs
+++ b/compiler/rustc_middle/src/ty/query/mod.rs
diff --git a/src/librustc_middle/ty/query/on_disk_cache.rs b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs
index dcfb8d31430..dcfb8d31430 100644
--- a/src/librustc_middle/ty/query/on_disk_cache.rs
+++ b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs
diff --git a/src/librustc_middle/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs
index f3fa3634026..f3fa3634026 100644
--- a/src/librustc_middle/ty/query/plumbing.rs
+++ b/compiler/rustc_middle/src/ty/query/plumbing.rs
diff --git a/src/librustc_middle/ty/query/profiling_support.rs b/compiler/rustc_middle/src/ty/query/profiling_support.rs
index 9b1837356e3..9b1837356e3 100644
--- a/src/librustc_middle/ty/query/profiling_support.rs
+++ b/compiler/rustc_middle/src/ty/query/profiling_support.rs
diff --git a/src/librustc_middle/ty/query/stats.rs b/compiler/rustc_middle/src/ty/query/stats.rs
index b496bf839ab..b496bf839ab 100644
--- a/src/librustc_middle/ty/query/stats.rs
+++ b/compiler/rustc_middle/src/ty/query/stats.rs
diff --git a/src/librustc_middle/ty/query/values.rs b/compiler/rustc_middle/src/ty/query/values.rs
index f28b0f499f0..f28b0f499f0 100644
--- a/src/librustc_middle/ty/query/values.rs
+++ b/compiler/rustc_middle/src/ty/query/values.rs
diff --git a/src/librustc_middle/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index ae2820b460f..ae2820b460f 100644
--- a/src/librustc_middle/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
diff --git a/src/librustc_middle/ty/steal.rs b/compiler/rustc_middle/src/ty/steal.rs
index 224e76845d7..224e76845d7 100644
--- a/src/librustc_middle/ty/steal.rs
+++ b/compiler/rustc_middle/src/ty/steal.rs
diff --git a/src/librustc_middle/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 605e3545dea..605e3545dea 100644
--- a/src/librustc_middle/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
diff --git a/src/librustc_middle/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index c1f354c7a15..c1f354c7a15 100644
--- a/src/librustc_middle/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
diff --git a/src/librustc_middle/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs
index acd58ab7f96..acd58ab7f96 100644
--- a/src/librustc_middle/ty/subst.rs
+++ b/compiler/rustc_middle/src/ty/subst.rs
diff --git a/src/librustc_middle/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs
index 86fe3ac3751..86fe3ac3751 100644
--- a/src/librustc_middle/ty/trait_def.rs
+++ b/compiler/rustc_middle/src/ty/trait_def.rs
diff --git a/src/librustc_middle/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 63d4dcca080..63d4dcca080 100644
--- a/src/librustc_middle/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
diff --git a/src/librustc_middle/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs
index 82c649b8f54..ece8da7e51e 100644
--- a/src/librustc_middle/ty/walk.rs
+++ b/compiler/rustc_middle/src/ty/walk.rs
@@ -55,7 +55,7 @@ impl GenericArg<'tcx> {
     /// that appear in `self`, it does not descend into the fields of
     /// structs or variants. For example:
     ///
-    /// ```notrust
+    /// ```text
     /// isize => { isize }
     /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
     /// [isize] => { [isize], isize }
@@ -80,7 +80,7 @@ impl<'tcx> super::TyS<'tcx> {
     /// that appear in `self`, it does not descend into the fields of
     /// structs or variants. For example:
     ///
-    /// ```notrust
+    /// ```text
     /// isize => { isize }
     /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
     /// [isize] => { [isize], isize }
diff --git a/src/librustc_middle/util/bug.rs b/compiler/rustc_middle/src/util/bug.rs
index 0903ef50898..0903ef50898 100644
--- a/src/librustc_middle/util/bug.rs
+++ b/compiler/rustc_middle/src/util/bug.rs
diff --git a/src/librustc_middle/util/common.rs b/compiler/rustc_middle/src/util/common.rs
index 1e09702bf27..1e09702bf27 100644
--- a/src/librustc_middle/util/common.rs
+++ b/compiler/rustc_middle/src/util/common.rs
diff --git a/src/librustc_middle/util/common/tests.rs b/compiler/rustc_middle/src/util/common/tests.rs
index 9a9fb203c62..9a9fb203c62 100644
--- a/src/librustc_middle/util/common/tests.rs
+++ b/compiler/rustc_middle/src/util/common/tests.rs
diff --git a/compiler/rustc_mir/Cargo.toml b/compiler/rustc_mir/Cargo.toml
new file mode 100644
index 00000000000..6b0412ece7a
--- /dev/null
+++ b/compiler/rustc_mir/Cargo.toml
@@ -0,0 +1,33 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_mir"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+either = "1.5.0"
+rustc_graphviz = { path = "../rustc_graphviz" }
+itertools = "0.8"
+tracing = "0.1"
+log_settings = "0.1.1"
+polonius-engine = "0.12.0"
+rustc_middle = { path = "../rustc_middle" }
+rustc_attr = { path = "../rustc_attr" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_index = { path = "../rustc_index" }
+rustc_infer = { path = "../rustc_infer" }
+rustc_lexer = { path = "../rustc_lexer" }
+rustc_macros = { path = "../rustc_macros" }
+rustc_serialize = { path = "../rustc_serialize" }
+rustc_session = { path = "../rustc_session" }
+rustc_target = { path = "../rustc_target" }
+rustc_trait_selection = { path = "../rustc_trait_selection" }
+rustc_ast = { path = "../rustc_ast" }
+rustc_span = { path = "../rustc_span" }
+rustc_apfloat = { path = "../rustc_apfloat" }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/compiler/rustc_mir/src/borrow_check/borrow_set.rs
index b4299fbc5a1..b4299fbc5a1 100644
--- a/src/librustc_mir/borrow_check/borrow_set.rs
+++ b/compiler/rustc_mir/src/borrow_check/borrow_set.rs
diff --git a/src/librustc_mir/borrow_check/constraint_generation.rs b/compiler/rustc_mir/src/borrow_check/constraint_generation.rs
index 33b09dcb888..33b09dcb888 100644
--- a/src/librustc_mir/borrow_check/constraint_generation.rs
+++ b/compiler/rustc_mir/src/borrow_check/constraint_generation.rs
diff --git a/src/librustc_mir/borrow_check/constraints/graph.rs b/compiler/rustc_mir/src/borrow_check/constraints/graph.rs
index f3f6b8c10da..f3f6b8c10da 100644
--- a/src/librustc_mir/borrow_check/constraints/graph.rs
+++ b/compiler/rustc_mir/src/borrow_check/constraints/graph.rs
diff --git a/src/librustc_mir/borrow_check/constraints/mod.rs b/compiler/rustc_mir/src/borrow_check/constraints/mod.rs
index 3772b7d8f98..3772b7d8f98 100644
--- a/src/librustc_mir/borrow_check/constraints/mod.rs
+++ b/compiler/rustc_mir/src/borrow_check/constraints/mod.rs
diff --git a/src/librustc_mir/borrow_check/def_use.rs b/compiler/rustc_mir/src/borrow_check/def_use.rs
index 6574e584406..6574e584406 100644
--- a/src/librustc_mir/borrow_check/def_use.rs
+++ b/compiler/rustc_mir/src/borrow_check/def_use.rs
diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
index 9076dbccb52..9076dbccb52 100644
--- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
diff --git a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs
index b591b938b5a..b591b938b5a 100644
--- a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs
diff --git a/src/librustc_mir/borrow_check/diagnostics/find_use.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/find_use.rs
index 8d8cdfb5293..8d8cdfb5293 100644
--- a/src/librustc_mir/borrow_check/diagnostics/find_use.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/find_use.rs
diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs
index dfaa75d9f23..dfaa75d9f23 100644
--- a/src/librustc_mir/borrow_check/diagnostics/mod.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs
diff --git a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs
index 1c8da212f10..1c8da212f10 100644
--- a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs
diff --git a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs
index d26436ff1de..d26436ff1de 100644
--- a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs
diff --git a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/outlives_suggestion.rs
index a775fa59c1b..a775fa59c1b 100644
--- a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/outlives_suggestion.rs
diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs
index a0d99ac33c0..a0d99ac33c0 100644
--- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs
diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs
index 2603b1e048d..2603b1e048d 100644
--- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs
diff --git a/src/librustc_mir/borrow_check/diagnostics/var_name.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/var_name.rs
index a850b85e9bb..a850b85e9bb 100644
--- a/src/librustc_mir/borrow_check/diagnostics/var_name.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/var_name.rs
diff --git a/src/librustc_mir/borrow_check/facts.rs b/compiler/rustc_mir/src/borrow_check/facts.rs
index 6d6b94ecf64..6d6b94ecf64 100644
--- a/src/librustc_mir/borrow_check/facts.rs
+++ b/compiler/rustc_mir/src/borrow_check/facts.rs
diff --git a/src/librustc_mir/borrow_check/invalidation.rs b/compiler/rustc_mir/src/borrow_check/invalidation.rs
index c84ccafaff5..c84ccafaff5 100644
--- a/src/librustc_mir/borrow_check/invalidation.rs
+++ b/compiler/rustc_mir/src/borrow_check/invalidation.rs
diff --git a/src/librustc_mir/borrow_check/location.rs b/compiler/rustc_mir/src/borrow_check/location.rs
index 375ff72679f..375ff72679f 100644
--- a/src/librustc_mir/borrow_check/location.rs
+++ b/compiler/rustc_mir/src/borrow_check/location.rs
diff --git a/src/librustc_mir/borrow_check/member_constraints.rs b/compiler/rustc_mir/src/borrow_check/member_constraints.rs
index d4baa5d809a..d4baa5d809a 100644
--- a/src/librustc_mir/borrow_check/member_constraints.rs
+++ b/compiler/rustc_mir/src/borrow_check/member_constraints.rs
diff --git a/src/librustc_mir/borrow_check/mod.rs b/compiler/rustc_mir/src/borrow_check/mod.rs
index 86908eaabd1..86908eaabd1 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/compiler/rustc_mir/src/borrow_check/mod.rs
diff --git a/src/librustc_mir/borrow_check/nll.rs b/compiler/rustc_mir/src/borrow_check/nll.rs
index 66a17cba6bb..66a17cba6bb 100644
--- a/src/librustc_mir/borrow_check/nll.rs
+++ b/compiler/rustc_mir/src/borrow_check/nll.rs
diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/compiler/rustc_mir/src/borrow_check/path_utils.rs
index 934729553a7..934729553a7 100644
--- a/src/librustc_mir/borrow_check/path_utils.rs
+++ b/compiler/rustc_mir/src/borrow_check/path_utils.rs
diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/compiler/rustc_mir/src/borrow_check/place_ext.rs
index cadf1ebf1b7..cadf1ebf1b7 100644
--- a/src/librustc_mir/borrow_check/place_ext.rs
+++ b/compiler/rustc_mir/src/borrow_check/place_ext.rs
diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/compiler/rustc_mir/src/borrow_check/places_conflict.rs
index 246e4826e0e..246e4826e0e 100644
--- a/src/librustc_mir/borrow_check/places_conflict.rs
+++ b/compiler/rustc_mir/src/borrow_check/places_conflict.rs
diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/compiler/rustc_mir/src/borrow_check/prefixes.rs
index a2475e0ff29..a2475e0ff29 100644
--- a/src/librustc_mir/borrow_check/prefixes.rs
+++ b/compiler/rustc_mir/src/borrow_check/prefixes.rs
diff --git a/src/librustc_mir/borrow_check/region_infer/dump_mir.rs b/compiler/rustc_mir/src/borrow_check/region_infer/dump_mir.rs
index d6e48deb031..d6e48deb031 100644
--- a/src/librustc_mir/borrow_check/region_infer/dump_mir.rs
+++ b/compiler/rustc_mir/src/borrow_check/region_infer/dump_mir.rs
diff --git a/src/librustc_mir/borrow_check/region_infer/graphviz.rs b/compiler/rustc_mir/src/borrow_check/region_infer/graphviz.rs
index a272e922a50..a272e922a50 100644
--- a/src/librustc_mir/borrow_check/region_infer/graphviz.rs
+++ b/compiler/rustc_mir/src/borrow_check/region_infer/graphviz.rs
diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/compiler/rustc_mir/src/borrow_check/region_infer/mod.rs
index 081125cb625..081125cb625 100644
--- a/src/librustc_mir/borrow_check/region_infer/mod.rs
+++ b/compiler/rustc_mir/src/borrow_check/region_infer/mod.rs
diff --git a/src/librustc_mir/borrow_check/region_infer/opaque_types.rs b/compiler/rustc_mir/src/borrow_check/region_infer/opaque_types.rs
index 325dca8c8ca..325dca8c8ca 100644
--- a/src/librustc_mir/borrow_check/region_infer/opaque_types.rs
+++ b/compiler/rustc_mir/src/borrow_check/region_infer/opaque_types.rs
diff --git a/src/librustc_mir/borrow_check/region_infer/reverse_sccs.rs b/compiler/rustc_mir/src/borrow_check/region_infer/reverse_sccs.rs
index 5d345a6e63d..5d345a6e63d 100644
--- a/src/librustc_mir/borrow_check/region_infer/reverse_sccs.rs
+++ b/compiler/rustc_mir/src/borrow_check/region_infer/reverse_sccs.rs
diff --git a/src/librustc_mir/borrow_check/region_infer/values.rs b/compiler/rustc_mir/src/borrow_check/region_infer/values.rs
index 8a5a600cfdd..8a5a600cfdd 100644
--- a/src/librustc_mir/borrow_check/region_infer/values.rs
+++ b/compiler/rustc_mir/src/borrow_check/region_infer/values.rs
diff --git a/src/librustc_mir/borrow_check/renumber.rs b/compiler/rustc_mir/src/borrow_check/renumber.rs
index 5df033b48c1..5df033b48c1 100644
--- a/src/librustc_mir/borrow_check/renumber.rs
+++ b/compiler/rustc_mir/src/borrow_check/renumber.rs
diff --git a/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs b/compiler/rustc_mir/src/borrow_check/type_check/constraint_conversion.rs
index 711271a63fb..711271a63fb 100644
--- a/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs
+++ b/compiler/rustc_mir/src/borrow_check/type_check/constraint_conversion.rs
diff --git a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs b/compiler/rustc_mir/src/borrow_check/type_check/free_region_relations.rs
index beee3181256..beee3181256 100644
--- a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs
+++ b/compiler/rustc_mir/src/borrow_check/type_check/free_region_relations.rs
diff --git a/src/librustc_mir/borrow_check/type_check/input_output.rs b/compiler/rustc_mir/src/borrow_check/type_check/input_output.rs
index 4846ef06a8b..4846ef06a8b 100644
--- a/src/librustc_mir/borrow_check/type_check/input_output.rs
+++ b/compiler/rustc_mir/src/borrow_check/type_check/input_output.rs
diff --git a/src/librustc_mir/borrow_check/type_check/liveness/local_use_map.rs b/compiler/rustc_mir/src/borrow_check/type_check/liveness/local_use_map.rs
index 995e3a60a0c..995e3a60a0c 100644
--- a/src/librustc_mir/borrow_check/type_check/liveness/local_use_map.rs
+++ b/compiler/rustc_mir/src/borrow_check/type_check/liveness/local_use_map.rs
diff --git a/src/librustc_mir/borrow_check/type_check/liveness/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/liveness/mod.rs
index bddcd34ed3e..bddcd34ed3e 100644
--- a/src/librustc_mir/borrow_check/type_check/liveness/mod.rs
+++ b/compiler/rustc_mir/src/borrow_check/type_check/liveness/mod.rs
diff --git a/src/librustc_mir/borrow_check/type_check/liveness/polonius.rs b/compiler/rustc_mir/src/borrow_check/type_check/liveness/polonius.rs
index d285098c52a..d285098c52a 100644
--- a/src/librustc_mir/borrow_check/type_check/liveness/polonius.rs
+++ b/compiler/rustc_mir/src/borrow_check/type_check/liveness/polonius.rs
diff --git a/src/librustc_mir/borrow_check/type_check/liveness/trace.rs b/compiler/rustc_mir/src/borrow_check/type_check/liveness/trace.rs
index f04736e04a0..f04736e04a0 100644
--- a/src/librustc_mir/borrow_check/type_check/liveness/trace.rs
+++ b/compiler/rustc_mir/src/borrow_check/type_check/liveness/trace.rs
diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs
index 69c4f633770..69c4f633770 100644
--- a/src/librustc_mir/borrow_check/type_check/mod.rs
+++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs
diff --git a/src/librustc_mir/borrow_check/type_check/relate_tys.rs b/compiler/rustc_mir/src/borrow_check/type_check/relate_tys.rs
index 91b1a1fbd97..91b1a1fbd97 100644
--- a/src/librustc_mir/borrow_check/type_check/relate_tys.rs
+++ b/compiler/rustc_mir/src/borrow_check/type_check/relate_tys.rs
diff --git a/src/librustc_mir/borrow_check/universal_regions.rs b/compiler/rustc_mir/src/borrow_check/universal_regions.rs
index 9dfc67bcf67..9dfc67bcf67 100644
--- a/src/librustc_mir/borrow_check/universal_regions.rs
+++ b/compiler/rustc_mir/src/borrow_check/universal_regions.rs
diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/compiler/rustc_mir/src/borrow_check/used_muts.rs
index e027056842d..e027056842d 100644
--- a/src/librustc_mir/borrow_check/used_muts.rs
+++ b/compiler/rustc_mir/src/borrow_check/used_muts.rs
diff --git a/src/librustc_mir/const_eval/error.rs b/compiler/rustc_mir/src/const_eval/error.rs
index 044d27a6a9d..044d27a6a9d 100644
--- a/src/librustc_mir/const_eval/error.rs
+++ b/compiler/rustc_mir/src/const_eval/error.rs
diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs
index 291b42c12d7..291b42c12d7 100644
--- a/src/librustc_mir/const_eval/eval_queries.rs
+++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs
diff --git a/src/librustc_mir/const_eval/fn_queries.rs b/compiler/rustc_mir/src/const_eval/fn_queries.rs
index 9ef63b3322d..9ef63b3322d 100644
--- a/src/librustc_mir/const_eval/fn_queries.rs
+++ b/compiler/rustc_mir/src/const_eval/fn_queries.rs
diff --git a/src/librustc_mir/const_eval/machine.rs b/compiler/rustc_mir/src/const_eval/machine.rs
index b0357c508a3..b0357c508a3 100644
--- a/src/librustc_mir/const_eval/machine.rs
+++ b/compiler/rustc_mir/src/const_eval/machine.rs
diff --git a/src/librustc_mir/const_eval/mod.rs b/compiler/rustc_mir/src/const_eval/mod.rs
index e7eeb4b4de4..e7eeb4b4de4 100644
--- a/src/librustc_mir/const_eval/mod.rs
+++ b/compiler/rustc_mir/src/const_eval/mod.rs
diff --git a/src/librustc_mir/dataflow/drop_flag_effects.rs b/compiler/rustc_mir/src/dataflow/drop_flag_effects.rs
index 707e136678e..707e136678e 100644
--- a/src/librustc_mir/dataflow/drop_flag_effects.rs
+++ b/compiler/rustc_mir/src/dataflow/drop_flag_effects.rs
diff --git a/src/librustc_mir/dataflow/framework/cursor.rs b/compiler/rustc_mir/src/dataflow/framework/cursor.rs
index 4f5930dc3f5..4f5930dc3f5 100644
--- a/src/librustc_mir/dataflow/framework/cursor.rs
+++ b/compiler/rustc_mir/src/dataflow/framework/cursor.rs
diff --git a/src/librustc_mir/dataflow/framework/direction.rs b/compiler/rustc_mir/src/dataflow/framework/direction.rs
index 4512ae96c08..4512ae96c08 100644
--- a/src/librustc_mir/dataflow/framework/direction.rs
+++ b/compiler/rustc_mir/src/dataflow/framework/direction.rs
diff --git a/src/librustc_mir/dataflow/framework/engine.rs b/compiler/rustc_mir/src/dataflow/framework/engine.rs
index b703852b1de..b703852b1de 100644
--- a/src/librustc_mir/dataflow/framework/engine.rs
+++ b/compiler/rustc_mir/src/dataflow/framework/engine.rs
diff --git a/src/librustc_mir/dataflow/framework/graphviz.rs b/compiler/rustc_mir/src/dataflow/framework/graphviz.rs
index 896616a2175..896616a2175 100644
--- a/src/librustc_mir/dataflow/framework/graphviz.rs
+++ b/compiler/rustc_mir/src/dataflow/framework/graphviz.rs
diff --git a/src/librustc_mir/dataflow/framework/mod.rs b/compiler/rustc_mir/src/dataflow/framework/mod.rs
index a21bbacb467..a21bbacb467 100644
--- a/src/librustc_mir/dataflow/framework/mod.rs
+++ b/compiler/rustc_mir/src/dataflow/framework/mod.rs
diff --git a/src/librustc_mir/dataflow/framework/tests.rs b/compiler/rustc_mir/src/dataflow/framework/tests.rs
index 9349f5133a5..9349f5133a5 100644
--- a/src/librustc_mir/dataflow/framework/tests.rs
+++ b/compiler/rustc_mir/src/dataflow/framework/tests.rs
diff --git a/src/librustc_mir/dataflow/framework/visitor.rs b/compiler/rustc_mir/src/dataflow/framework/visitor.rs
index 257f3cb9a6d..257f3cb9a6d 100644
--- a/src/librustc_mir/dataflow/framework/visitor.rs
+++ b/compiler/rustc_mir/src/dataflow/framework/visitor.rs
diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/compiler/rustc_mir/src/dataflow/impls/borrowed_locals.rs
index a3fc51cad65..a3fc51cad65 100644
--- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs
+++ b/compiler/rustc_mir/src/dataflow/impls/borrowed_locals.rs
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/compiler/rustc_mir/src/dataflow/impls/borrows.rs
index aeb7ffe3e3b..aeb7ffe3e3b 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/compiler/rustc_mir/src/dataflow/impls/borrows.rs
diff --git a/src/librustc_mir/dataflow/impls/init_locals.rs b/compiler/rustc_mir/src/dataflow/impls/init_locals.rs
index 0e7cd1bb0e4..0e7cd1bb0e4 100644
--- a/src/librustc_mir/dataflow/impls/init_locals.rs
+++ b/compiler/rustc_mir/src/dataflow/impls/init_locals.rs
diff --git a/src/librustc_mir/dataflow/impls/liveness.rs b/compiler/rustc_mir/src/dataflow/impls/liveness.rs
index 784b0bd9293..784b0bd9293 100644
--- a/src/librustc_mir/dataflow/impls/liveness.rs
+++ b/compiler/rustc_mir/src/dataflow/impls/liveness.rs
diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/compiler/rustc_mir/src/dataflow/impls/mod.rs
index 8975faec487..8975faec487 100644
--- a/src/librustc_mir/dataflow/impls/mod.rs
+++ b/compiler/rustc_mir/src/dataflow/impls/mod.rs
diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/compiler/rustc_mir/src/dataflow/impls/storage_liveness.rs
index 21623e3cad5..21623e3cad5 100644
--- a/src/librustc_mir/dataflow/impls/storage_liveness.rs
+++ b/compiler/rustc_mir/src/dataflow/impls/storage_liveness.rs
diff --git a/src/librustc_mir/dataflow/mod.rs b/compiler/rustc_mir/src/dataflow/mod.rs
index a0c24636059..a0c24636059 100644
--- a/src/librustc_mir/dataflow/mod.rs
+++ b/compiler/rustc_mir/src/dataflow/mod.rs
diff --git a/src/librustc_mir/dataflow/move_paths/abs_domain.rs b/compiler/rustc_mir/src/dataflow/move_paths/abs_domain.rs
index 28936274baa..28936274baa 100644
--- a/src/librustc_mir/dataflow/move_paths/abs_domain.rs
+++ b/compiler/rustc_mir/src/dataflow/move_paths/abs_domain.rs
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/compiler/rustc_mir/src/dataflow/move_paths/builder.rs
index e088dc6a954..e088dc6a954 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/compiler/rustc_mir/src/dataflow/move_paths/builder.rs
diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/compiler/rustc_mir/src/dataflow/move_paths/mod.rs
index d66d2625d78..d66d2625d78 100644
--- a/src/librustc_mir/dataflow/move_paths/mod.rs
+++ b/compiler/rustc_mir/src/dataflow/move_paths/mod.rs
diff --git a/src/librustc_mir/interpret/cast.rs b/compiler/rustc_mir/src/interpret/cast.rs
index 501a5bcddb3..501a5bcddb3 100644
--- a/src/librustc_mir/interpret/cast.rs
+++ b/compiler/rustc_mir/src/interpret/cast.rs
diff --git a/src/librustc_mir/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs
index 525da87463a..525da87463a 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/compiler/rustc_mir/src/interpret/eval_context.rs
diff --git a/src/librustc_mir/interpret/intern.rs b/compiler/rustc_mir/src/interpret/intern.rs
index 606be7cad2b..606be7cad2b 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/compiler/rustc_mir/src/interpret/intern.rs
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/compiler/rustc_mir/src/interpret/intrinsics.rs
index b37dcd42f4c..b37dcd42f4c 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/compiler/rustc_mir/src/interpret/intrinsics.rs
diff --git a/src/librustc_mir/interpret/intrinsics/caller_location.rs b/compiler/rustc_mir/src/interpret/intrinsics/caller_location.rs
index d9be28cf9db..d9be28cf9db 100644
--- a/src/librustc_mir/interpret/intrinsics/caller_location.rs
+++ b/compiler/rustc_mir/src/interpret/intrinsics/caller_location.rs
diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/compiler/rustc_mir/src/interpret/intrinsics/type_name.rs
index 379117f3b84..379117f3b84 100644
--- a/src/librustc_mir/interpret/intrinsics/type_name.rs
+++ b/compiler/rustc_mir/src/interpret/intrinsics/type_name.rs
diff --git a/src/librustc_mir/interpret/machine.rs b/compiler/rustc_mir/src/interpret/machine.rs
index 3718da1723b..3718da1723b 100644
--- a/src/librustc_mir/interpret/machine.rs
+++ b/compiler/rustc_mir/src/interpret/machine.rs
diff --git a/src/librustc_mir/interpret/memory.rs b/compiler/rustc_mir/src/interpret/memory.rs
index d4be2ce0568..d4be2ce0568 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/compiler/rustc_mir/src/interpret/memory.rs
diff --git a/src/librustc_mir/interpret/mod.rs b/compiler/rustc_mir/src/interpret/mod.rs
index a931b0bbe97..a931b0bbe97 100644
--- a/src/librustc_mir/interpret/mod.rs
+++ b/compiler/rustc_mir/src/interpret/mod.rs
diff --git a/src/librustc_mir/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs
index 0b58caef54d..0b58caef54d 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/compiler/rustc_mir/src/interpret/operand.rs
diff --git a/src/librustc_mir/interpret/operator.rs b/compiler/rustc_mir/src/interpret/operator.rs
index 30c40b8fde9..30c40b8fde9 100644
--- a/src/librustc_mir/interpret/operator.rs
+++ b/compiler/rustc_mir/src/interpret/operator.rs
diff --git a/src/librustc_mir/interpret/place.rs b/compiler/rustc_mir/src/interpret/place.rs
index 6ba6103b311..6ba6103b311 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/compiler/rustc_mir/src/interpret/place.rs
diff --git a/src/librustc_mir/interpret/step.rs b/compiler/rustc_mir/src/interpret/step.rs
index 156da84f291..156da84f291 100644
--- a/src/librustc_mir/interpret/step.rs
+++ b/compiler/rustc_mir/src/interpret/step.rs
diff --git a/src/librustc_mir/interpret/terminator.rs b/compiler/rustc_mir/src/interpret/terminator.rs
index 9a036a0f299..9a036a0f299 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/compiler/rustc_mir/src/interpret/terminator.rs
diff --git a/src/librustc_mir/interpret/traits.rs b/compiler/rustc_mir/src/interpret/traits.rs
index 77f4593fa16..77f4593fa16 100644
--- a/src/librustc_mir/interpret/traits.rs
+++ b/compiler/rustc_mir/src/interpret/traits.rs
diff --git a/src/librustc_mir/interpret/util.rs b/compiler/rustc_mir/src/interpret/util.rs
index 57c5fc59cc0..57c5fc59cc0 100644
--- a/src/librustc_mir/interpret/util.rs
+++ b/compiler/rustc_mir/src/interpret/util.rs
diff --git a/src/librustc_mir/interpret/validity.rs b/compiler/rustc_mir/src/interpret/validity.rs
index 9cd20340138..9cd20340138 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/compiler/rustc_mir/src/interpret/validity.rs
diff --git a/src/librustc_mir/interpret/visitor.rs b/compiler/rustc_mir/src/interpret/visitor.rs
index 6c53df40a7c..6c53df40a7c 100644
--- a/src/librustc_mir/interpret/visitor.rs
+++ b/compiler/rustc_mir/src/interpret/visitor.rs
diff --git a/src/librustc_mir/lib.rs b/compiler/rustc_mir/src/lib.rs
index 2e3b5084635..2e3b5084635 100644
--- a/src/librustc_mir/lib.rs
+++ b/compiler/rustc_mir/src/lib.rs
diff --git a/src/librustc_mir/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs
index d379f4ef428..43cac8e5ee6 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/compiler/rustc_mir/src/monomorphize/collector.rs
@@ -191,7 +191,6 @@ 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::{GenericArgKind, InternalSubsts};
 use rustc_middle::ty::{self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable};
 use rustc_session::config::EntryFnType;
@@ -348,7 +347,7 @@ fn collect_items_rec<'tcx>(
         // We've been here already, no need to search again.
         return;
     }
-    debug!("BEGIN collect_items_rec({})", starting_point.node.to_string(tcx, true));
+    debug!("BEGIN collect_items_rec({})", starting_point.node);
 
     let mut neighbors = Vec::new();
     let recursion_depth_reset;
@@ -397,7 +396,7 @@ fn collect_items_rec<'tcx>(
         recursion_depths.insert(def_id, depth);
     }
 
-    debug!("END collect_items_rec({})", starting_point.node.to_string(tcx, true));
+    debug!("END collect_items_rec({})", starting_point.node);
 }
 
 fn record_accesses<'a, 'tcx: 'a>(
@@ -992,7 +991,7 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> {
                         let def_id = self.tcx.hir().local_def_id(item.hir_id);
                         debug!(
                             "RootCollector: ADT drop-glue for {}",
-                            def_id_to_string(self.tcx, def_id)
+                            self.tcx.def_path_str(def_id.to_def_id())
                         );
 
                         let ty = Instance::new(def_id.to_def_id(), InternalSubsts::empty())
@@ -1004,14 +1003,14 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> {
             hir::ItemKind::GlobalAsm(..) => {
                 debug!(
                     "RootCollector: ItemKind::GlobalAsm({})",
-                    def_id_to_string(self.tcx, self.tcx.hir().local_def_id(item.hir_id))
+                    self.tcx.def_path_str(self.tcx.hir().local_def_id(item.hir_id).to_def_id())
                 );
                 self.output.push(dummy_spanned(MonoItem::GlobalAsm(item.hir_id)));
             }
             hir::ItemKind::Static(..) => {
-                let def_id = self.tcx.hir().local_def_id(item.hir_id);
-                debug!("RootCollector: ItemKind::Static({})", def_id_to_string(self.tcx, def_id));
-                self.output.push(dummy_spanned(MonoItem::Static(def_id.to_def_id())));
+                let def_id = self.tcx.hir().local_def_id(item.hir_id).to_def_id();
+                debug!("RootCollector: ItemKind::Static({})", self.tcx.def_path_str(def_id));
+                self.output.push(dummy_spanned(MonoItem::Static(def_id)));
             }
             hir::ItemKind::Const(..) => {
                 // const items only generate mono items if they are
@@ -1134,7 +1133,7 @@ fn create_mono_items_for_default_impls<'tcx>(
 
             debug!(
                 "create_mono_items_for_default_impls(item={})",
-                def_id_to_string(tcx, impl_def_id)
+                tcx.def_path_str(impl_def_id.to_def_id())
             );
 
             if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) {
@@ -1218,13 +1217,6 @@ fn collect_neighbours<'tcx>(
     MirNeighborCollector { tcx, body: &body, output, instance }.visit_body(&body);
 }
 
-fn def_id_to_string(tcx: TyCtxt<'_>, def_id: LocalDefId) -> String {
-    let mut output = String::new();
-    let printer = DefPathBasedNames::new(tcx, false, false);
-    printer.push_def_path(def_id.to_def_id(), &mut output);
-    output
-}
-
 fn collect_const_value<'tcx>(
     tcx: TyCtxt<'tcx>,
     value: ConstValue<'tcx>,
diff --git a/src/librustc_mir/monomorphize/mod.rs b/compiler/rustc_mir/src/monomorphize/mod.rs
index edafa00a03a..edafa00a03a 100644
--- a/src/librustc_mir/monomorphize/mod.rs
+++ b/compiler/rustc_mir/src/monomorphize/mod.rs
diff --git a/src/librustc_mir/monomorphize/partitioning/default.rs b/compiler/rustc_mir/src/monomorphize/partitioning/default.rs
index b48bae83787..b48bae83787 100644
--- a/src/librustc_mir/monomorphize/partitioning/default.rs
+++ b/compiler/rustc_mir/src/monomorphize/partitioning/default.rs
diff --git a/src/librustc_mir/monomorphize/partitioning/merging.rs b/compiler/rustc_mir/src/monomorphize/partitioning/merging.rs
index 1787e6df1b9..1787e6df1b9 100644
--- a/src/librustc_mir/monomorphize/partitioning/merging.rs
+++ b/compiler/rustc_mir/src/monomorphize/partitioning/merging.rs
diff --git a/src/librustc_mir/monomorphize/partitioning/mod.rs b/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs
index 9dfbd65e1b1..b45fe0ee010 100644
--- a/src/librustc_mir/monomorphize/partitioning/mod.rs
+++ b/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs
@@ -190,7 +190,7 @@ pub fn partition<'tcx>(
 
     // Next we try to make as many symbols "internal" as possible, so LLVM has
     // more freedom to optimize.
-    if tcx.sess.opts.cg.link_dead_code != Some(true) {
+    if !tcx.sess.link_dead_code() {
         let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_internalize_symbols");
         partitioner.internalize_symbols(tcx, &mut post_inlining, inlining_map);
     }
@@ -246,7 +246,7 @@ where
 
                 debug!(
                     " - {} [{:?}] [{}] estimated size {}",
-                    mono_item.to_string(tcx, true),
+                    mono_item,
                     linkage,
                     symbol_hash,
                     mono_item.size_estimate(tcx)
@@ -327,7 +327,7 @@ fn collect_and_partition_mono_items<'tcx>(
             }
         }
         None => {
-            if tcx.sess.opts.cg.link_dead_code == Some(true) {
+            if tcx.sess.link_dead_code() {
                 MonoItemCollectionMode::Eager
             } else {
                 MonoItemCollectionMode::Lazy
@@ -374,7 +374,7 @@ fn collect_and_partition_mono_items<'tcx>(
         let mut item_keys: Vec<_> = items
             .iter()
             .map(|i| {
-                let mut output = i.to_string(tcx, false);
+                let mut output = i.to_string();
                 output.push_str(" @@");
                 let mut empty = Vec::new();
                 let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
diff --git a/src/librustc_mir/monomorphize/polymorphize.rs b/compiler/rustc_mir/src/monomorphize/polymorphize.rs
index 69f3288ee39..69f3288ee39 100644
--- a/src/librustc_mir/monomorphize/polymorphize.rs
+++ b/compiler/rustc_mir/src/monomorphize/polymorphize.rs
diff --git a/src/librustc_mir/shim.rs b/compiler/rustc_mir/src/shim.rs
index 479b6c2a6ca..479b6c2a6ca 100644
--- a/src/librustc_mir/shim.rs
+++ b/compiler/rustc_mir/src/shim.rs
diff --git a/src/librustc_mir/transform/add_call_guards.rs b/compiler/rustc_mir/src/transform/add_call_guards.rs
index 33859115359..33859115359 100644
--- a/src/librustc_mir/transform/add_call_guards.rs
+++ b/compiler/rustc_mir/src/transform/add_call_guards.rs
diff --git a/src/librustc_mir/transform/add_moves_for_packed_drops.rs b/compiler/rustc_mir/src/transform/add_moves_for_packed_drops.rs
index a02d0f65560..a02d0f65560 100644
--- a/src/librustc_mir/transform/add_moves_for_packed_drops.rs
+++ b/compiler/rustc_mir/src/transform/add_moves_for_packed_drops.rs
diff --git a/src/librustc_mir/transform/add_retag.rs b/compiler/rustc_mir/src/transform/add_retag.rs
index 324289166b9..324289166b9 100644
--- a/src/librustc_mir/transform/add_retag.rs
+++ b/compiler/rustc_mir/src/transform/add_retag.rs
diff --git a/src/librustc_mir/transform/check_consts/mod.rs b/compiler/rustc_mir/src/transform/check_consts/mod.rs
index 81c1b0b5bd4..81c1b0b5bd4 100644
--- a/src/librustc_mir/transform/check_consts/mod.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/mod.rs
diff --git a/src/librustc_mir/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs
index ea025f208e4..ea025f208e4 100644
--- a/src/librustc_mir/transform/check_consts/ops.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs
diff --git a/src/librustc_mir/transform/check_consts/post_drop_elaboration.rs b/compiler/rustc_mir/src/transform/check_consts/post_drop_elaboration.rs
index 55075b3ab5e..55075b3ab5e 100644
--- a/src/librustc_mir/transform/check_consts/post_drop_elaboration.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/post_drop_elaboration.rs
diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/compiler/rustc_mir/src/transform/check_consts/qualifs.rs
index 445a0230afd..445a0230afd 100644
--- a/src/librustc_mir/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/qualifs.rs
diff --git a/src/librustc_mir/transform/check_consts/resolver.rs b/compiler/rustc_mir/src/transform/check_consts/resolver.rs
index b8104292aab..b8104292aab 100644
--- a/src/librustc_mir/transform/check_consts/resolver.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/resolver.rs
diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs
index e21f314ca15..e21f314ca15 100644
--- a/src/librustc_mir/transform/check_consts/validation.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs
diff --git a/src/librustc_mir/transform/check_packed_ref.rs b/compiler/rustc_mir/src/transform/check_packed_ref.rs
index 043b2d0d170..043b2d0d170 100644
--- a/src/librustc_mir/transform/check_packed_ref.rs
+++ b/compiler/rustc_mir/src/transform/check_packed_ref.rs
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/compiler/rustc_mir/src/transform/check_unsafety.rs
index c3e04e698db..c3e04e698db 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/compiler/rustc_mir/src/transform/check_unsafety.rs
diff --git a/src/librustc_mir/transform/cleanup_post_borrowck.rs b/compiler/rustc_mir/src/transform/cleanup_post_borrowck.rs
index 3f3d247a829..3f3d247a829 100644
--- a/src/librustc_mir/transform/cleanup_post_borrowck.rs
+++ b/compiler/rustc_mir/src/transform/cleanup_post_borrowck.rs
diff --git a/src/librustc_mir/transform/const_prop.rs b/compiler/rustc_mir/src/transform/const_prop.rs
index 56479b047fa..56479b047fa 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/compiler/rustc_mir/src/transform/const_prop.rs
diff --git a/src/librustc_mir/transform/copy_prop.rs b/compiler/rustc_mir/src/transform/copy_prop.rs
index ba406c72df8..ba406c72df8 100644
--- a/src/librustc_mir/transform/copy_prop.rs
+++ b/compiler/rustc_mir/src/transform/copy_prop.rs
diff --git a/src/librustc_mir/transform/deaggregator.rs b/compiler/rustc_mir/src/transform/deaggregator.rs
index 66989a90244..66989a90244 100644
--- a/src/librustc_mir/transform/deaggregator.rs
+++ b/compiler/rustc_mir/src/transform/deaggregator.rs
diff --git a/src/librustc_mir/transform/dump_mir.rs b/compiler/rustc_mir/src/transform/dump_mir.rs
index 5ce6f4fa741..5ce6f4fa741 100644
--- a/src/librustc_mir/transform/dump_mir.rs
+++ b/compiler/rustc_mir/src/transform/dump_mir.rs
diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/compiler/rustc_mir/src/transform/elaborate_drops.rs
index 5f193069356..5f193069356 100644
--- a/src/librustc_mir/transform/elaborate_drops.rs
+++ b/compiler/rustc_mir/src/transform/elaborate_drops.rs
diff --git a/src/librustc_mir/transform/generator.rs b/compiler/rustc_mir/src/transform/generator.rs
index a22075e760a..a22075e760a 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/compiler/rustc_mir/src/transform/generator.rs
diff --git a/src/librustc_mir/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs
index 315d4fa9d47..428f4e138c7 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/compiler/rustc_mir/src/transform/inline.rs
@@ -107,8 +107,14 @@ impl Inliner<'tcx> {
                     // Avoid a cycle here by only using `optimized_mir` only if we have
                     // a lower `HirId` than the callee. This ensures that the callee will
                     // not inline us. This trick only works without incremental compilation.
-                    // So don't do it if that is enabled.
-                    if !self.tcx.dep_graph.is_fully_enabled() && self_hir_id < callee_hir_id {
+                    // So don't do it if that is enabled. Also avoid inlining into generators,
+                    // since their `optimized_mir` is used for layout computation, which can
+                    // create a cycle, even when no attempt is made to inline the function
+                    // in the other direction.
+                    if !self.tcx.dep_graph.is_fully_enabled()
+                        && self_hir_id < callee_hir_id
+                        && caller_body.generator_kind.is_none()
+                    {
                         self.tcx.optimized_mir(callsite.callee)
                     } else {
                         continue;
diff --git a/src/librustc_mir/transform/instcombine.rs b/compiler/rustc_mir/src/transform/instcombine.rs
index 7967137e01e..7967137e01e 100644
--- a/src/librustc_mir/transform/instcombine.rs
+++ b/compiler/rustc_mir/src/transform/instcombine.rs
diff --git a/src/librustc_mir/transform/instrument_coverage.rs b/compiler/rustc_mir/src/transform/instrument_coverage.rs
index f60e6da714a..f60e6da714a 100644
--- a/src/librustc_mir/transform/instrument_coverage.rs
+++ b/compiler/rustc_mir/src/transform/instrument_coverage.rs
diff --git a/src/librustc_mir/transform/match_branches.rs b/compiler/rustc_mir/src/transform/match_branches.rs
index c1d574d6ef2..c1d574d6ef2 100644
--- a/src/librustc_mir/transform/match_branches.rs
+++ b/compiler/rustc_mir/src/transform/match_branches.rs
diff --git a/src/librustc_mir/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs
index c3a34756122..c3a34756122 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/compiler/rustc_mir/src/transform/mod.rs
diff --git a/src/librustc_mir/transform/no_landing_pads.rs b/compiler/rustc_mir/src/transform/no_landing_pads.rs
index 1d83733e4cd..1d83733e4cd 100644
--- a/src/librustc_mir/transform/no_landing_pads.rs
+++ b/compiler/rustc_mir/src/transform/no_landing_pads.rs
diff --git a/src/librustc_mir/transform/nrvo.rs b/compiler/rustc_mir/src/transform/nrvo.rs
index 1f3d7bb7cc6..1f3d7bb7cc6 100644
--- a/src/librustc_mir/transform/nrvo.rs
+++ b/compiler/rustc_mir/src/transform/nrvo.rs
diff --git a/src/librustc_mir/transform/promote_consts.rs b/compiler/rustc_mir/src/transform/promote_consts.rs
index b2dda1caa54..b2dda1caa54 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/compiler/rustc_mir/src/transform/promote_consts.rs
diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/compiler/rustc_mir/src/transform/qualify_min_const_fn.rs
index 26db4600a2b..26db4600a2b 100644
--- a/src/librustc_mir/transform/qualify_min_const_fn.rs
+++ b/compiler/rustc_mir/src/transform/qualify_min_const_fn.rs
diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/compiler/rustc_mir/src/transform/remove_noop_landing_pads.rs
index 0bad1e5037a..0bad1e5037a 100644
--- a/src/librustc_mir/transform/remove_noop_landing_pads.rs
+++ b/compiler/rustc_mir/src/transform/remove_noop_landing_pads.rs
diff --git a/src/librustc_mir/transform/required_consts.rs b/compiler/rustc_mir/src/transform/required_consts.rs
index a63ab30a68f..a63ab30a68f 100644
--- a/src/librustc_mir/transform/required_consts.rs
+++ b/compiler/rustc_mir/src/transform/required_consts.rs
diff --git a/src/librustc_mir/transform/rustc_peek.rs b/compiler/rustc_mir/src/transform/rustc_peek.rs
index 00d269a4af8..00d269a4af8 100644
--- a/src/librustc_mir/transform/rustc_peek.rs
+++ b/compiler/rustc_mir/src/transform/rustc_peek.rs
diff --git a/src/librustc_mir/transform/simplify.rs b/compiler/rustc_mir/src/transform/simplify.rs
index d8995e92abf..d8995e92abf 100644
--- a/src/librustc_mir/transform/simplify.rs
+++ b/compiler/rustc_mir/src/transform/simplify.rs
diff --git a/src/librustc_mir/transform/simplify_branches.rs b/compiler/rustc_mir/src/transform/simplify_branches.rs
index 4c30a0946bc..4c30a0946bc 100644
--- a/src/librustc_mir/transform/simplify_branches.rs
+++ b/compiler/rustc_mir/src/transform/simplify_branches.rs
diff --git a/src/librustc_mir/transform/simplify_comparison_integral.rs b/compiler/rustc_mir/src/transform/simplify_comparison_integral.rs
index a450a75d091..a450a75d091 100644
--- a/src/librustc_mir/transform/simplify_comparison_integral.rs
+++ b/compiler/rustc_mir/src/transform/simplify_comparison_integral.rs
diff --git a/src/librustc_mir/transform/simplify_try.rs b/compiler/rustc_mir/src/transform/simplify_try.rs
index 06829cc2f14..06829cc2f14 100644
--- a/src/librustc_mir/transform/simplify_try.rs
+++ b/compiler/rustc_mir/src/transform/simplify_try.rs
diff --git a/src/librustc_mir/transform/uninhabited_enum_branching.rs b/compiler/rustc_mir/src/transform/uninhabited_enum_branching.rs
index 4cca4d223c0..4cca4d223c0 100644
--- a/src/librustc_mir/transform/uninhabited_enum_branching.rs
+++ b/compiler/rustc_mir/src/transform/uninhabited_enum_branching.rs
diff --git a/src/librustc_mir/transform/unreachable_prop.rs b/compiler/rustc_mir/src/transform/unreachable_prop.rs
index fa362c66fb2..fa362c66fb2 100644
--- a/src/librustc_mir/transform/unreachable_prop.rs
+++ b/compiler/rustc_mir/src/transform/unreachable_prop.rs
diff --git a/src/librustc_mir/transform/validate.rs b/compiler/rustc_mir/src/transform/validate.rs
index d7c9ecd0655..d7c9ecd0655 100644
--- a/src/librustc_mir/transform/validate.rs
+++ b/compiler/rustc_mir/src/transform/validate.rs
diff --git a/src/librustc_mir/util/aggregate.rs b/compiler/rustc_mir/src/util/aggregate.rs
index 130409b9df5..130409b9df5 100644
--- a/src/librustc_mir/util/aggregate.rs
+++ b/compiler/rustc_mir/src/util/aggregate.rs
diff --git a/src/librustc_mir/util/alignment.rs b/compiler/rustc_mir/src/util/alignment.rs
index 202e5e27f1d..202e5e27f1d 100644
--- a/src/librustc_mir/util/alignment.rs
+++ b/compiler/rustc_mir/src/util/alignment.rs
diff --git a/src/librustc_mir/util/borrowck_errors.rs b/compiler/rustc_mir/src/util/borrowck_errors.rs
index f8bb7e7a85d..f8bb7e7a85d 100644
--- a/src/librustc_mir/util/borrowck_errors.rs
+++ b/compiler/rustc_mir/src/util/borrowck_errors.rs
diff --git a/src/librustc_mir/util/collect_writes.rs b/compiler/rustc_mir/src/util/collect_writes.rs
index ecf3b08a96e..ecf3b08a96e 100644
--- a/src/librustc_mir/util/collect_writes.rs
+++ b/compiler/rustc_mir/src/util/collect_writes.rs
diff --git a/src/librustc_mir/util/def_use.rs b/compiler/rustc_mir/src/util/def_use.rs
index b4448ead8eb..b4448ead8eb 100644
--- a/src/librustc_mir/util/def_use.rs
+++ b/compiler/rustc_mir/src/util/def_use.rs
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/compiler/rustc_mir/src/util/elaborate_drops.rs
index 642935d243d..642935d243d 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/compiler/rustc_mir/src/util/elaborate_drops.rs
diff --git a/src/librustc_mir/util/graphviz.rs b/compiler/rustc_mir/src/util/graphviz.rs
index 50193c4a0db..50193c4a0db 100644
--- a/src/librustc_mir/util/graphviz.rs
+++ b/compiler/rustc_mir/src/util/graphviz.rs
diff --git a/src/librustc_mir/util/mod.rs b/compiler/rustc_mir/src/util/mod.rs
index 8bbe207c077..ed0fafb1aac 100644
--- a/src/librustc_mir/util/mod.rs
+++ b/compiler/rustc_mir/src/util/mod.rs
@@ -9,6 +9,7 @@ mod alignment;
 pub mod collect_writes;
 mod graphviz;
 pub(crate) mod pretty;
+pub(crate) mod spanview;
 
 pub use self::aggregate::expand_aggregate;
 pub use self::alignment::is_disaligned;
diff --git a/src/librustc_mir/util/patch.rs b/compiler/rustc_mir/src/util/patch.rs
index 6566a996fe4..6566a996fe4 100644
--- a/src/librustc_mir/util/patch.rs
+++ b/compiler/rustc_mir/src/util/patch.rs
diff --git a/src/librustc_mir/util/pretty.rs b/compiler/rustc_mir/src/util/pretty.rs
index 2a9cbc7fc0e..db57766620e 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/compiler/rustc_mir/src/util/pretty.rs
@@ -6,6 +6,7 @@ use std::io::{self, Write};
 use std::path::{Path, PathBuf};
 
 use super::graphviz::write_mir_fn_graphviz;
+use super::spanview::write_mir_fn_spanview;
 use crate::transform::MirSource;
 use either::Either;
 use rustc_data_structures::fx::FxHashMap;
@@ -147,6 +148,16 @@ fn dump_matched_mir_node<'tcx, F>(
             write_mir_fn_graphviz(tcx, source.def_id(), body, false, &mut file)?;
         };
     }
+
+    if let Some(spanview) = tcx.sess.opts.debugging_opts.dump_mir_spanview {
+        let _: io::Result<()> = try {
+            let mut file =
+                create_dump_file(tcx, "html", pass_num, pass_name, disambiguator, source)?;
+            if source.def_id().is_local() {
+                write_mir_fn_spanview(tcx, source.def_id(), body, spanview, &mut file)?;
+            }
+        };
+    }
 }
 
 /// Returns the path to the filename where we should dump a given MIR.
diff --git a/compiler/rustc_mir/src/util/spanview.rs b/compiler/rustc_mir/src/util/spanview.rs
new file mode 100644
index 00000000000..b2f2b5fc1e6
--- /dev/null
+++ b/compiler/rustc_mir/src/util/spanview.rs
@@ -0,0 +1,461 @@
+use rustc_hir::def_id::DefId;
+use rustc_middle::hir;
+use rustc_middle::mir::*;
+use rustc_middle::ty::TyCtxt;
+use rustc_session::config::MirSpanview;
+use rustc_span::{BytePos, Pos, Span};
+
+use std::io::{self, Write};
+use std::iter::Peekable;
+
+pub const TOOLTIP_INDENT: &str = "    ";
+
+const NEW_LINE_SPAN: &str = "</span>\n<span class=\"line\">";
+const HEADER: &str = r#"<!DOCTYPE html>
+<html>
+<head>
+    <title>coverage_of_if_else - Code Regions</title>
+    <style>
+    .line {
+        counter-increment: line;
+    }
+    .line:before {
+        content: counter(line) ": ";
+        font-family: Menlo, Monaco, monospace;
+        font-style: italic;
+        width: 3.8em;
+        display: inline-block;
+        text-align: right;
+        filter: opacity(50%);
+        -webkit-user-select: none;
+    }
+    .code {
+        color: #dddddd;
+        background-color: #222222;
+        font-family: Menlo, Monaco, monospace;
+        line-height: 1.4em;
+        border-bottom: 2px solid #222222;
+        white-space: pre;
+        display: inline-block;
+    }
+    .odd {
+        background-color: #55bbff;
+        color: #223311;
+    }
+    .even {
+        background-color: #ee7756;
+        color: #551133;
+    }
+    .code {
+        --index: calc(var(--layer) - 1);
+        padding-top: calc(var(--index) * 0.15em);
+        filter:
+            hue-rotate(calc(var(--index) * 25deg))
+            saturate(calc(100% - (var(--index) * 2%)))
+            brightness(calc(100% - (var(--index) * 1.5%)));
+    }
+    .annotation {
+        color: #4444ff;
+        font-family: monospace;
+        font-style: italic;
+        display: none;
+        -webkit-user-select: none;
+    }
+    body:active .annotation {
+        /* requires holding mouse down anywhere on the page */
+        display: inline-block;
+    }
+    span:hover .annotation {
+        /* requires hover over a span ONLY on its first line */
+        display: inline-block;
+    }
+    </style>
+</head>
+<body>"#;
+
+const FOOTER: &str = r#"
+</body>
+</html>"#;
+
+/// Metadata to highlight the span of a MIR BasicBlock, Statement, or Terminator.
+pub struct SpanViewable {
+    pub span: Span,
+    pub title: String,
+    pub tooltip: String,
+}
+
+/// Write a spanview HTML+CSS file to analyze MIR element spans.
+pub fn write_mir_fn_spanview<'tcx, W>(
+    tcx: TyCtxt<'tcx>,
+    def_id: DefId,
+    body: &Body<'tcx>,
+    spanview: MirSpanview,
+    w: &mut W,
+) -> io::Result<()>
+where
+    W: Write,
+{
+    let body_span = hir_body(tcx, def_id).value.span;
+    let mut span_viewables = Vec::new();
+    for (bb, data) in body.basic_blocks().iter_enumerated() {
+        match spanview {
+            MirSpanview::Statement => {
+                for (i, statement) in data.statements.iter().enumerate() {
+                    if let Some(span_viewable) =
+                        statement_span_viewable(tcx, body_span, bb, i, statement)
+                    {
+                        span_viewables.push(span_viewable);
+                    }
+                }
+                if let Some(span_viewable) = terminator_span_viewable(tcx, body_span, bb, data) {
+                    span_viewables.push(span_viewable);
+                }
+            }
+            MirSpanview::Terminator => {
+                if let Some(span_viewable) = terminator_span_viewable(tcx, body_span, bb, data) {
+                    span_viewables.push(span_viewable);
+                }
+            }
+            MirSpanview::Block => {
+                if let Some(span_viewable) = block_span_viewable(tcx, body_span, bb, data) {
+                    span_viewables.push(span_viewable);
+                }
+            }
+        }
+    }
+    write_spanview_document(tcx, def_id, span_viewables, w)?;
+    Ok(())
+}
+
+/// Generate a spanview HTML+CSS document for the given local function `def_id`, and a pre-generated
+/// list `SpanViewable`s.
+pub fn write_spanview_document<'tcx, W>(
+    tcx: TyCtxt<'tcx>,
+    def_id: DefId,
+    mut span_viewables: Vec<SpanViewable>,
+    w: &mut W,
+) -> io::Result<()>
+where
+    W: Write,
+{
+    let fn_span = fn_span(tcx, def_id);
+    writeln!(w, "{}", HEADER)?;
+    let mut next_pos = fn_span.lo();
+    let end_pos = fn_span.hi();
+    let source_map = tcx.sess.source_map();
+    let start = source_map.lookup_char_pos(next_pos);
+    write!(
+        w,
+        r#"<div class="code" style="counter-reset: line {}"><span class="line">{}"#,
+        start.line - 1,
+        " ".repeat(start.col.to_usize())
+    )?;
+    span_viewables.sort_unstable_by(|a, b| {
+        let a = a.span;
+        let b = b.span;
+        if a.lo() == b.lo() {
+            // Sort hi() in reverse order so shorter spans are attempted after longer spans.
+            // This should give shorter spans a higher "layer", so they are not covered by
+            // the longer spans.
+            b.hi().partial_cmp(&a.hi())
+        } else {
+            a.lo().partial_cmp(&b.lo())
+        }
+        .unwrap()
+    });
+    let mut ordered_span_viewables = span_viewables.iter().peekable();
+    let mut alt = false;
+    while ordered_span_viewables.peek().is_some() {
+        next_pos = write_span_viewables(tcx, next_pos, &mut ordered_span_viewables, false, 1, w)?;
+        alt = !alt;
+    }
+    if next_pos < end_pos {
+        write_coverage_gap(tcx, next_pos, end_pos, w)?;
+    }
+    write!(w, r#"</span></div>"#)?;
+    writeln!(w, "{}", FOOTER)?;
+    Ok(())
+}
+
+/// Format a string showing the start line and column, and end line and column within a file.
+pub fn source_range_no_file<'tcx>(tcx: TyCtxt<'tcx>, span: &Span) -> String {
+    let source_map = tcx.sess.source_map();
+    let start = source_map.lookup_char_pos(span.lo());
+    let end = source_map.lookup_char_pos(span.hi());
+    format!("{}:{}-{}:{}", start.line, start.col.to_usize() + 1, end.line, end.col.to_usize() + 1)
+}
+
+pub fn statement_kind_name(statement: &Statement<'_>) -> &'static str {
+    use StatementKind::*;
+    match statement.kind {
+        Assign(..) => "Assign",
+        FakeRead(..) => "FakeRead",
+        SetDiscriminant { .. } => "SetDiscriminant",
+        StorageLive(..) => "StorageLive",
+        StorageDead(..) => "StorageDead",
+        LlvmInlineAsm(..) => "LlvmInlineAsm",
+        Retag(..) => "Retag",
+        AscribeUserType(..) => "AscribeUserType",
+        Coverage(..) => "Coverage",
+        Nop => "Nop",
+    }
+}
+
+pub fn terminator_kind_name(term: &Terminator<'_>) -> &'static str {
+    use TerminatorKind::*;
+    match term.kind {
+        Goto { .. } => "Goto",
+        SwitchInt { .. } => "SwitchInt",
+        Resume => "Resume",
+        Abort => "Abort",
+        Return => "Return",
+        Unreachable => "Unreachable",
+        Drop { .. } => "Drop",
+        DropAndReplace { .. } => "DropAndReplace",
+        Call { .. } => "Call",
+        Assert { .. } => "Assert",
+        Yield { .. } => "Yield",
+        GeneratorDrop => "GeneratorDrop",
+        FalseEdge { .. } => "FalseEdge",
+        FalseUnwind { .. } => "FalseUnwind",
+        InlineAsm { .. } => "InlineAsm",
+    }
+}
+
+fn statement_span_viewable<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    body_span: Span,
+    bb: BasicBlock,
+    i: usize,
+    statement: &Statement<'tcx>,
+) -> Option<SpanViewable> {
+    let span = statement.source_info.span;
+    if !body_span.contains(span) {
+        return None;
+    }
+    let title = format!("bb{}[{}]", bb.index(), i);
+    let tooltip = tooltip(tcx, &title, span, vec![statement.clone()], &None);
+    Some(SpanViewable { span, title, tooltip })
+}
+
+fn terminator_span_viewable<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    body_span: Span,
+    bb: BasicBlock,
+    data: &BasicBlockData<'tcx>,
+) -> Option<SpanViewable> {
+    let term = data.terminator();
+    let span = term.source_info.span;
+    if !body_span.contains(span) {
+        return None;
+    }
+    let title = format!("bb{}`{}`", bb.index(), terminator_kind_name(term));
+    let tooltip = tooltip(tcx, &title, span, vec![], &data.terminator);
+    Some(SpanViewable { span, title, tooltip })
+}
+
+fn block_span_viewable<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    body_span: Span,
+    bb: BasicBlock,
+    data: &BasicBlockData<'tcx>,
+) -> Option<SpanViewable> {
+    let span = compute_block_span(data, body_span);
+    if !body_span.contains(span) {
+        return None;
+    }
+    let title = format!("bb{}", bb.index());
+    let tooltip = tooltip(tcx, &title, span, data.statements.clone(), &data.terminator);
+    Some(SpanViewable { span, title, tooltip })
+}
+
+fn compute_block_span<'tcx>(data: &BasicBlockData<'tcx>, body_span: Span) -> Span {
+    let mut span = data.terminator().source_info.span;
+    for statement_span in data.statements.iter().map(|statement| statement.source_info.span) {
+        // Only combine Spans from the function's body_span.
+        if body_span.contains(statement_span) {
+            span = span.to(statement_span);
+        }
+    }
+    span
+}
+
+/// Recursively process each ordered span. Spans that overlap will have progressively varying
+/// styles, such as increased padding for each overlap. Non-overlapping adjacent spans will
+/// have alternating style choices, to help distinguish between them if, visually adjacent.
+/// The `layer` is incremented for each overlap, and the `alt` bool alternates between true
+/// and false, for each adjacent non-overlapping span. Source code between the spans (code
+/// that is not in any coverage region) has neutral styling.
+fn write_span_viewables<'tcx, 'b, W>(
+    tcx: TyCtxt<'tcx>,
+    next_pos: BytePos,
+    ordered_span_viewables: &mut Peekable<impl Iterator<Item = &'b SpanViewable>>,
+    alt: bool,
+    layer: usize,
+    w: &mut W,
+) -> io::Result<BytePos>
+where
+    W: Write,
+{
+    let span_viewable =
+        ordered_span_viewables.next().expect("ordered_span_viewables should have some");
+    if next_pos < span_viewable.span.lo() {
+        write_coverage_gap(tcx, next_pos, span_viewable.span.lo(), w)?;
+    }
+    let mut remaining_span = span_viewable.span;
+    let mut subalt = false;
+    loop {
+        let next_span_viewable = match ordered_span_viewables.peek() {
+            None => break,
+            Some(span_viewable) => *span_viewable,
+        };
+        if !next_span_viewable.span.overlaps(remaining_span) {
+            break;
+        }
+        write_span(
+            tcx,
+            remaining_span.until(next_span_viewable.span),
+            Some(span_viewable),
+            alt,
+            layer,
+            w,
+        )?;
+        let next_pos = write_span_viewables(
+            tcx,
+            next_span_viewable.span.lo(),
+            ordered_span_viewables,
+            subalt,
+            layer + 1,
+            w,
+        )?;
+        subalt = !subalt;
+        if next_pos < remaining_span.hi() {
+            remaining_span = remaining_span.with_lo(next_pos);
+        } else {
+            return Ok(next_pos);
+        }
+    }
+    write_span(tcx, remaining_span, Some(span_viewable), alt, layer, w)
+}
+
+fn write_coverage_gap<'tcx, W>(
+    tcx: TyCtxt<'tcx>,
+    lo: BytePos,
+    hi: BytePos,
+    w: &mut W,
+) -> io::Result<BytePos>
+where
+    W: Write,
+{
+    write_span(tcx, Span::with_root_ctxt(lo, hi), None, false, 0, w)
+}
+
+fn write_span<'tcx, W>(
+    tcx: TyCtxt<'tcx>,
+    span: Span,
+    span_viewable: Option<&SpanViewable>,
+    alt: bool,
+    layer: usize,
+    w: &mut W,
+) -> io::Result<BytePos>
+where
+    W: Write,
+{
+    let source_map = tcx.sess.source_map();
+    let snippet = source_map
+        .span_to_snippet(span)
+        .unwrap_or_else(|err| bug!("span_to_snippet error for span {:?}: {:?}", span, err));
+    let labeled_snippet = if let Some(SpanViewable { title, .. }) = span_viewable {
+        if span.is_empty() {
+            format!(r#"<span class="annotation">@{}</span>"#, title)
+        } else {
+            format!(r#"<span class="annotation">@{}:</span> {}"#, title, escape_html(&snippet))
+        }
+    } else {
+        snippet
+    };
+    let maybe_alt = if layer > 0 {
+        if alt { " odd" } else { " even" }
+    } else {
+        ""
+    };
+    let maybe_tooltip = if let Some(SpanViewable { tooltip, .. }) = span_viewable {
+        format!(" title=\"{}\"", escape_attr(tooltip))
+    } else {
+        "".to_owned()
+    };
+    if layer == 1 {
+        write!(w, "<span>")?;
+    }
+    for (i, line) in labeled_snippet.lines().enumerate() {
+        if i > 0 {
+            write!(w, "{}", NEW_LINE_SPAN)?;
+        }
+        write!(
+            w,
+            r#"<span class="code{}" style="--layer: {}"{}>{}</span>"#,
+            maybe_alt, layer, maybe_tooltip, line
+        )?;
+    }
+    if layer == 1 {
+        write!(w, "</span>")?;
+    }
+    Ok(span.hi())
+}
+
+fn tooltip<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    title: &str,
+    span: Span,
+    statements: Vec<Statement<'tcx>>,
+    terminator: &Option<Terminator<'tcx>>,
+) -> String {
+    let source_map = tcx.sess.source_map();
+    let mut text = Vec::new();
+    text.push(format!("{}: {}:", title, &source_map.span_to_string(span)));
+    for statement in statements {
+        let source_range = source_range_no_file(tcx, &statement.source_info.span);
+        text.push(format!(
+            "\n{}{}: {}: {}",
+            TOOLTIP_INDENT,
+            source_range,
+            statement_kind_name(&statement),
+            format!("{:?}", statement)
+        ));
+    }
+    if let Some(term) = terminator {
+        let source_range = source_range_no_file(tcx, &term.source_info.span);
+        text.push(format!(
+            "\n{}{}: {}: {:?}",
+            TOOLTIP_INDENT,
+            source_range,
+            terminator_kind_name(term),
+            term.kind
+        ));
+    }
+    text.join("")
+}
+
+fn fn_span<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Span {
+    let hir_id =
+        tcx.hir().local_def_id_to_hir_id(def_id.as_local().expect("expected DefId is local"));
+    tcx.hir().span(hir_id)
+}
+
+fn hir_body<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx rustc_hir::Body<'tcx> {
+    let hir_node = tcx.hir().get_if_local(def_id).expect("expected DefId is local");
+    let fn_body_id = hir::map::associated_body(hir_node).expect("HIR node is a function with body");
+    tcx.hir().body(fn_body_id)
+}
+
+fn escape_html(s: &str) -> String {
+    s.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
+}
+
+fn escape_attr(s: &str) -> String {
+    s.replace("&", "&amp;")
+        .replace("\"", "&quot;")
+        .replace("'", "&#39;")
+        .replace("<", "&lt;")
+        .replace(">", "&gt;")
+}
diff --git a/src/librustc_mir/util/storage.rs b/compiler/rustc_mir/src/util/storage.rs
index 0b7b1c29537..0b7b1c29537 100644
--- a/src/librustc_mir/util/storage.rs
+++ b/compiler/rustc_mir/src/util/storage.rs
diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml
new file mode 100644
index 00000000000..2dd894a67a6
--- /dev/null
+++ b/compiler/rustc_mir_build/Cargo.toml
@@ -0,0 +1,27 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_mir_build"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+rustc_arena = { path = "../rustc_arena" }
+tracing = "0.1"
+rustc_middle = { path = "../rustc_middle" }
+rustc_apfloat = { path = "../rustc_apfloat" }
+rustc_attr = { path = "../rustc_attr" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_index = { path = "../rustc_index" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_infer = { path = "../rustc_infer" }
+rustc_serialize = { path = "../rustc_serialize" }
+rustc_session = { path = "../rustc_session" }
+rustc_span = { path = "../rustc_span" }
+rustc_target = { path = "../rustc_target" }
+rustc_trait_selection = { path = "../rustc_trait_selection" }
+rustc_ast = { path = "../rustc_ast" }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_mir_build/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs
index d1cbf209b06..d1cbf209b06 100644
--- a/src/librustc_mir_build/build/block.rs
+++ b/compiler/rustc_mir_build/src/build/block.rs
diff --git a/src/librustc_mir_build/build/cfg.rs b/compiler/rustc_mir_build/src/build/cfg.rs
index 42e2b242d77..42e2b242d77 100644
--- a/src/librustc_mir_build/build/cfg.rs
+++ b/compiler/rustc_mir_build/src/build/cfg.rs
diff --git a/src/librustc_mir_build/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index 982aefcf604..982aefcf604 100644
--- a/src/librustc_mir_build/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
diff --git a/src/librustc_mir_build/build/expr/as_operand.rs b/compiler/rustc_mir_build/src/build/expr/as_operand.rs
index aac93f313f4..aac93f313f4 100644
--- a/src/librustc_mir_build/build/expr/as_operand.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs
diff --git a/src/librustc_mir_build/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
index 1e3e104c2ba..1e3e104c2ba 100644
--- a/src/librustc_mir_build/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
diff --git a/src/librustc_mir_build/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index 9c5fddc6b77..9c5fddc6b77 100644
--- a/src/librustc_mir_build/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
diff --git a/src/librustc_mir_build/build/expr/as_temp.rs b/compiler/rustc_mir_build/src/build/expr/as_temp.rs
index a9cc0cc2f24..a9cc0cc2f24 100644
--- a/src/librustc_mir_build/build/expr/as_temp.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_temp.rs
diff --git a/src/librustc_mir_build/build/expr/category.rs b/compiler/rustc_mir_build/src/build/expr/category.rs
index 9cabd186d84..9cabd186d84 100644
--- a/src/librustc_mir_build/build/expr/category.rs
+++ b/compiler/rustc_mir_build/src/build/expr/category.rs
diff --git a/src/librustc_mir_build/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index 3d623abfa6e..3d623abfa6e 100644
--- a/src/librustc_mir_build/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
diff --git a/src/librustc_mir_build/build/expr/mod.rs b/compiler/rustc_mir_build/src/build/expr/mod.rs
index ac8c7e725e1..ac8c7e725e1 100644
--- a/src/librustc_mir_build/build/expr/mod.rs
+++ b/compiler/rustc_mir_build/src/build/expr/mod.rs
diff --git a/src/librustc_mir_build/build/expr/stmt.rs b/compiler/rustc_mir_build/src/build/expr/stmt.rs
index f117689d940..f117689d940 100644
--- a/src/librustc_mir_build/build/expr/stmt.rs
+++ b/compiler/rustc_mir_build/src/build/expr/stmt.rs
diff --git a/src/librustc_mir_build/build/into.rs b/compiler/rustc_mir_build/src/build/into.rs
index 7264e495b84..7264e495b84 100644
--- a/src/librustc_mir_build/build/into.rs
+++ b/compiler/rustc_mir_build/src/build/into.rs
diff --git a/src/librustc_mir_build/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 3a525d10b08..3a525d10b08 100644
--- a/src/librustc_mir_build/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
diff --git a/src/librustc_mir_build/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs
index e584aeb9226..e584aeb9226 100644
--- a/src/librustc_mir_build/build/matches/simplify.rs
+++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs
diff --git a/src/librustc_mir_build/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index c4a87a554a3..c4a87a554a3 100644
--- a/src/librustc_mir_build/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
diff --git a/src/librustc_mir_build/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs
index c6d39947f7d..c6d39947f7d 100644
--- a/src/librustc_mir_build/build/matches/util.rs
+++ b/compiler/rustc_mir_build/src/build/matches/util.rs
diff --git a/src/librustc_mir_build/build/misc.rs b/compiler/rustc_mir_build/src/build/misc.rs
index 29651d9bc66..29651d9bc66 100644
--- a/src/librustc_mir_build/build/misc.rs
+++ b/compiler/rustc_mir_build/src/build/misc.rs
diff --git a/src/librustc_mir_build/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 249cce0ba19..249cce0ba19 100644
--- a/src/librustc_mir_build/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
diff --git a/src/librustc_mir_build/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs
index 2a03bb78c6b..2a03bb78c6b 100644
--- a/src/librustc_mir_build/build/scope.rs
+++ b/compiler/rustc_mir_build/src/build/scope.rs
diff --git a/src/librustc_mir_build/lib.rs b/compiler/rustc_mir_build/src/lib.rs
index 313bb979a51..313bb979a51 100644
--- a/src/librustc_mir_build/lib.rs
+++ b/compiler/rustc_mir_build/src/lib.rs
diff --git a/src/librustc_mir_build/lints.rs b/compiler/rustc_mir_build/src/lints.rs
index fd2d5a4abd4..fd2d5a4abd4 100644
--- a/src/librustc_mir_build/lints.rs
+++ b/compiler/rustc_mir_build/src/lints.rs
diff --git a/src/librustc_mir_build/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs
index dd5515d39b0..dd5515d39b0 100644
--- a/src/librustc_mir_build/thir/constant.rs
+++ b/compiler/rustc_mir_build/src/thir/constant.rs
diff --git a/src/librustc_mir_build/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs
index 980888df7fe..980888df7fe 100644
--- a/src/librustc_mir_build/thir/cx/block.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/block.rs
diff --git a/src/librustc_mir_build/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 066e46fec14..066e46fec14 100644
--- a/src/librustc_mir_build/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
diff --git a/src/librustc_mir_build/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index cf42fee873e..cf42fee873e 100644
--- a/src/librustc_mir_build/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
diff --git a/src/librustc_mir_build/thir/cx/to_ref.rs b/compiler/rustc_mir_build/src/thir/cx/to_ref.rs
index 53a988ebb79..53a988ebb79 100644
--- a/src/librustc_mir_build/thir/cx/to_ref.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/to_ref.rs
diff --git a/src/librustc_mir_build/thir/mod.rs b/compiler/rustc_mir_build/src/thir/mod.rs
index 2837bfa040f..2837bfa040f 100644
--- a/src/librustc_mir_build/thir/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/mod.rs
diff --git a/src/librustc_mir_build/thir/pattern/_match.rs b/compiler/rustc_mir_build/src/thir/pattern/_match.rs
index 3202f7d1b1b..3202f7d1b1b 100644
--- a/src/librustc_mir_build/thir/pattern/_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/_match.rs
diff --git a/src/librustc_mir_build/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index 4e7108667e1..4e7108667e1 100644
--- a/src/librustc_mir_build/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
diff --git a/src/librustc_mir_build/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index f6d3ccc1ae0..f6d3ccc1ae0 100644
--- a/src/librustc_mir_build/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
diff --git a/src/librustc_mir_build/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index c163cb0e60c..c163cb0e60c 100644
--- a/src/librustc_mir_build/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
diff --git a/src/librustc_mir_build/thir/util.rs b/compiler/rustc_mir_build/src/thir/util.rs
index 7de60ddda41..7de60ddda41 100644
--- a/src/librustc_mir_build/thir/util.rs
+++ b/compiler/rustc_mir_build/src/thir/util.rs
diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml
new file mode 100644
index 00000000000..52835e5c8a9
--- /dev/null
+++ b/compiler/rustc_parse/Cargo.toml
@@ -0,0 +1,22 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_parse"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+bitflags = "1.0"
+tracing = "0.1"
+rustc_ast_pretty = { path = "../rustc_ast_pretty" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_feature = { path = "../rustc_feature" }
+rustc_lexer = { path = "../rustc_lexer" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_session = { path = "../rustc_session" }
+rustc_span = { path = "../rustc_span" }
+rustc_ast = { path = "../rustc_ast" }
+unicode-normalization = "0.1.11"
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_parse/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index a65d3446819..034442b798b 100644
--- a/src/librustc_parse/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -1,5 +1,6 @@
 use rustc_ast::ast::AttrStyle;
 use rustc_ast::token::{self, CommentKind, Token, TokenKind};
+use rustc_ast::tokenstream::IsJoint;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{error_code, Applicability, DiagnosticBuilder, FatalError};
 use rustc_lexer::Base;
@@ -27,7 +28,7 @@ pub struct UnmatchedBrace {
     pub candidate_span: Option<Span>,
 }
 
-pub struct StringReader<'a> {
+crate struct StringReader<'a> {
     sess: &'a ParseSess,
     /// Initial position, read-only.
     start_pos: BytePos,
@@ -41,7 +42,7 @@ pub struct StringReader<'a> {
 }
 
 impl<'a> StringReader<'a> {
-    pub fn new(
+    crate fn new(
         sess: &'a ParseSess,
         source_file: Lrc<rustc_span::SourceFile>,
         override_span: Option<Span>,
@@ -65,42 +66,46 @@ impl<'a> StringReader<'a> {
         self.override_span.unwrap_or_else(|| Span::with_root_ctxt(lo, hi))
     }
 
-    /// Returns the next token, including trivia like whitespace or comments.
-    pub fn next_token(&mut self) -> Token {
+    /// Returns the next token, and info about preceding whitespace, if any.
+    fn next_token(&mut self) -> (IsJoint, Token) {
+        let mut is_joint = IsJoint::Joint;
+
+        // Skip `#!` at the start of the file
         let start_src_index = self.src_index(self.pos);
         let text: &str = &self.src[start_src_index..self.end_src_index];
-
-        if text.is_empty() {
-            let span = self.mk_sp(self.pos, self.pos);
-            return Token::new(token::Eof, span);
+        let is_beginning_of_file = self.pos == self.start_pos;
+        if is_beginning_of_file {
+            if let Some(shebang_len) = rustc_lexer::strip_shebang(text) {
+                self.pos = self.pos + BytePos::from_usize(shebang_len);
+                is_joint = IsJoint::NonJoint;
+            }
         }
 
-        {
-            let is_beginning_of_file = self.pos == self.start_pos;
-            if is_beginning_of_file {
-                if let Some(shebang_len) = rustc_lexer::strip_shebang(text) {
-                    let start = self.pos;
-                    self.pos = self.pos + BytePos::from_usize(shebang_len);
+        // Skip trivial (whitespace & comments) tokens
+        loop {
+            let start_src_index = self.src_index(self.pos);
+            let text: &str = &self.src[start_src_index..self.end_src_index];
 
-                    let sym = self.symbol_from(start + BytePos::from_usize("#!".len()));
-                    let kind = token::Shebang(sym);
-
-                    let span = self.mk_sp(start, self.pos);
-                    return Token::new(kind, span);
-                }
+            if text.is_empty() {
+                let span = self.mk_sp(self.pos, self.pos);
+                return (is_joint, Token::new(token::Eof, span));
             }
-        }
 
-        let token = rustc_lexer::first_token(text);
+            let token = rustc_lexer::first_token(text);
 
-        let start = self.pos;
-        self.pos = self.pos + BytePos::from_usize(token.len);
+            let start = self.pos;
+            self.pos = self.pos + BytePos::from_usize(token.len);
 
-        debug!("try_next_token: {:?}({:?})", token.kind, self.str_from(start));
+            debug!("next_token: {:?}({:?})", token.kind, self.str_from(start));
 
-        let kind = self.cook_lexer_token(token.kind, start);
-        let span = self.mk_sp(start, self.pos);
-        Token::new(kind, span)
+            match self.cook_lexer_token(token.kind, start) {
+                Some(kind) => {
+                    let span = self.mk_sp(start, self.pos);
+                    return (is_joint, Token::new(kind, span));
+                }
+                None => is_joint = IsJoint::NonJoint,
+            }
+        }
     }
 
     /// Report a fatal lexical error with a given span.
@@ -140,19 +145,16 @@ impl<'a> StringReader<'a> {
     /// Turns simple `rustc_lexer::TokenKind` enum into a rich
     /// `librustc_ast::TokenKind`. This turns strings into interned
     /// symbols and runs additional validation.
-    fn cook_lexer_token(&self, token: rustc_lexer::TokenKind, start: BytePos) -> TokenKind {
-        match token {
+    fn cook_lexer_token(&self, token: rustc_lexer::TokenKind, start: BytePos) -> Option<TokenKind> {
+        Some(match token {
             rustc_lexer::TokenKind::LineComment { doc_style } => {
-                match doc_style {
-                    Some(doc_style) => {
-                        // Opening delimiter of the length 3 is not included into the symbol.
-                        let content_start = start + BytePos(3);
-                        let content = self.str_from(content_start);
+                // Skip non-doc comments
+                let doc_style = doc_style?;
 
-                        self.cook_doc_comment(content_start, content, CommentKind::Line, doc_style)
-                    }
-                    None => token::Comment,
-                }
+                // Opening delimiter of the length 3 is not included into the symbol.
+                let content_start = start + BytePos(3);
+                let content = self.str_from(content_start);
+                self.cook_doc_comment(content_start, content, CommentKind::Line, doc_style)
             }
             rustc_lexer::TokenKind::BlockComment { doc_style, terminated } => {
                 if !terminated {
@@ -171,20 +173,18 @@ impl<'a> StringReader<'a> {
                         .emit();
                     FatalError.raise();
                 }
-                match doc_style {
-                    Some(doc_style) => {
-                        // Opening delimiter of the length 3 and closing delimiter of the length 2
-                        // are not included into the symbol.
-                        let content_start = start + BytePos(3);
-                        let content_end = self.pos - BytePos(if terminated { 2 } else { 0 });
-                        let content = self.str_from_to(content_start, content_end);
-
-                        self.cook_doc_comment(content_start, content, CommentKind::Block, doc_style)
-                    }
-                    None => token::Comment,
-                }
+
+                // Skip non-doc comments
+                let doc_style = doc_style?;
+
+                // Opening delimiter of the length 3 and closing delimiter of the length 2
+                // are not included into the symbol.
+                let content_start = start + BytePos(3);
+                let content_end = self.pos - BytePos(if terminated { 2 } else { 0 });
+                let content = self.str_from_to(content_start, content_end);
+                self.cook_doc_comment(content_start, content, CommentKind::Block, doc_style)
             }
-            rustc_lexer::TokenKind::Whitespace => token::Whitespace,
+            rustc_lexer::TokenKind::Whitespace => return None,
             rustc_lexer::TokenKind::Ident | rustc_lexer::TokenKind::RawIdent => {
                 let is_raw_ident = token == rustc_lexer::TokenKind::RawIdent;
                 let mut ident_start = start;
@@ -282,12 +282,11 @@ impl<'a> StringReader<'a> {
                 // this should be inside `rustc_lexer`. However, we should first remove compound
                 // tokens like `<<` from `rustc_lexer`, and then add fancier error recovery to it,
                 // as there will be less overall work to do this way.
-                let token = unicode_chars::check_for_substitution(self, start, c, &mut err)
-                    .unwrap_or_else(|| token::Unknown(self.symbol_from(start)));
+                let token = unicode_chars::check_for_substitution(self, start, c, &mut err);
                 err.emit();
-                token
+                token?
             }
-        }
+        })
     }
 
     fn cook_doc_comment(
@@ -439,10 +438,6 @@ impl<'a> StringReader<'a> {
         (lit_kind, id)
     }
 
-    pub fn pos(&self) -> BytePos {
-        self.pos
-    }
-
     #[inline]
     fn src_index(&self, pos: BytePos) -> usize {
         (pos - self.start_pos).to_usize()
@@ -454,12 +449,6 @@ impl<'a> StringReader<'a> {
         self.str_from_to(start, self.pos)
     }
 
-    /// Creates a Symbol from a given offset to the current offset.
-    fn symbol_from(&self, start: BytePos) -> Symbol {
-        debug!("taking an ident from {:?} to {:?}", start, self.pos);
-        Symbol::intern(self.str_from(start))
-    }
-
     /// As symbol_from, with an explicit endpoint.
     fn symbol_from_to(&self, start: BytePos, end: BytePos) -> Symbol {
         debug!("taking an ident from {:?} to {:?}", start, end);
diff --git a/src/librustc_parse/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs
index c08659ec9f6..d5977ca3c7d 100644
--- a/src/librustc_parse/lexer/tokentrees.rs
+++ b/compiler/rustc_parse/src/lexer/tokentrees.rs
@@ -16,7 +16,6 @@ impl<'a> StringReader<'a> {
         let mut tt_reader = TokenTreesReader {
             string_reader: self,
             token: Token::dummy(),
-            joint_to_prev: Joint,
             open_braces: Vec::new(),
             unmatched_braces: Vec::new(),
             matching_delim_spans: Vec::new(),
@@ -32,7 +31,6 @@ impl<'a> StringReader<'a> {
 struct TokenTreesReader<'a> {
     string_reader: StringReader<'a>,
     token: Token,
-    joint_to_prev: IsJoint,
     /// Stack of open delimiters and their spans. Used for error message.
     open_braces: Vec<(token::DelimToken, Span)>,
     unmatched_braces: Vec<UnmatchedBrace>,
@@ -53,7 +51,7 @@ impl<'a> TokenTreesReader<'a> {
     fn parse_all_token_trees(&mut self) -> PResult<'a, TokenStream> {
         let mut buf = TokenStreamBuilder::default();
 
-        self.real_token();
+        self.bump();
         while self.token != token::Eof {
             buf.push(self.parse_token_tree()?);
         }
@@ -126,7 +124,7 @@ impl<'a> TokenTreesReader<'a> {
 
                 // Parse the open delimiter.
                 self.open_braces.push((delim, self.token.span));
-                self.real_token();
+                self.bump();
 
                 // Parse the token trees within the delimiters.
                 // We stop at any delimiter so we can try to recover if the user
@@ -171,7 +169,7 @@ impl<'a> TokenTreesReader<'a> {
                             ));
                         }
                         // Parse the closing delimiter.
-                        self.real_token();
+                        self.bump();
                     }
                     // Incorrect delimiter.
                     token::CloseDelim(other) => {
@@ -217,7 +215,7 @@ impl<'a> TokenTreesReader<'a> {
                         //     bar(baz(
                         // }  // Incorrect delimiter but matches the earlier `{`
                         if !self.open_braces.iter().any(|&(b, _)| b == other) {
-                            self.real_token();
+                            self.bump();
                         }
                     }
                     token::Eof => {
@@ -264,27 +262,19 @@ impl<'a> TokenTreesReader<'a> {
             }
             _ => {
                 let tt = TokenTree::Token(self.token.take());
-                self.real_token();
-                let is_joint = self.joint_to_prev == Joint && self.token.is_op();
-                Ok((tt, if is_joint { Joint } else { NonJoint }))
+                let mut is_joint = self.bump();
+                if !self.token.is_op() {
+                    is_joint = NonJoint;
+                }
+                Ok((tt, is_joint))
             }
         }
     }
 
-    fn real_token(&mut self) {
-        self.joint_to_prev = Joint;
-        loop {
-            let token = self.string_reader.next_token();
-            match token.kind {
-                token::Whitespace | token::Comment | token::Shebang(_) | token::Unknown(_) => {
-                    self.joint_to_prev = NonJoint;
-                }
-                _ => {
-                    self.token = token;
-                    return;
-                }
-            }
-        }
+    fn bump(&mut self) -> IsJoint {
+        let (joint_to_prev, token) = self.string_reader.next_token();
+        self.token = token;
+        joint_to_prev
     }
 }
 
diff --git a/src/librustc_parse/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
index 6f249f491a6..6f249f491a6 100644
--- a/src/librustc_parse/lexer/unescape_error_reporting.rs
+++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
diff --git a/src/librustc_parse/lexer/unicode_chars.rs b/compiler/rustc_parse/src/lexer/unicode_chars.rs
index ac395f6cbc2..8dc0db01ecb 100644
--- a/src/librustc_parse/lexer/unicode_chars.rs
+++ b/compiler/rustc_parse/src/lexer/unicode_chars.rs
@@ -303,7 +303,7 @@ const UNICODE_ARRAY: &[(char, &str, char)] = &[
 // However, we should first remove compound tokens like `<<` from `rustc_lexer`, and then add
 // fancier error recovery to it, as there will be less overall work to do this way.
 const ASCII_ARRAY: &[(char, &str, Option<token::TokenKind>)] = &[
-    (' ', "Space", Some(token::Whitespace)),
+    (' ', "Space", None),
     ('_', "Underscore", Some(token::Ident(kw::Underscore, false))),
     ('-', "Minus/Hyphen", Some(token::BinOp(token::Minus))),
     (',', "Comma", Some(token::Comma)),
diff --git a/src/librustc_parse/lib.rs b/compiler/rustc_parse/src/lib.rs
index bc857c97742..462279b0a9e 100644
--- a/src/librustc_parse/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -348,9 +348,6 @@ pub fn tokenstream_probably_equal_for_proc_macro(
                 | token::CloseDelim(DelimToken::NoDelim)
                 // The pretty printer collapses many semicolons into one.
                 | token::Semi
-                // The pretty printer collapses whitespace arbitrarily and can
-                // introduce whitespace from `NoDelim`.
-                | token::Whitespace
                 // The pretty printer can turn `$crate` into `::crate_name`
                 | token::ModSep = token.kind {
                 return false;
@@ -506,8 +503,6 @@ fn token_probably_equal_for_proc_macro(first: &Token, other: &Token) -> bool {
         | (&Pound, &Pound)
         | (&Dollar, &Dollar)
         | (&Question, &Question)
-        | (&Whitespace, &Whitespace)
-        | (&Comment, &Comment)
         | (&Eof, &Eof) => true,
 
         (&BinOp(a), &BinOp(b)) | (&BinOpEq(a), &BinOpEq(b)) => a == b,
@@ -516,8 +511,6 @@ fn token_probably_equal_for_proc_macro(first: &Token, other: &Token) -> bool {
 
         (&DocComment(a1, a2, a3), &DocComment(b1, b2, b3)) => a1 == b1 && a2 == b2 && a3 == b3,
 
-        (&Shebang(a), &Shebang(b)) => a == b,
-
         (&Literal(a), &Literal(b)) => a == b,
 
         (&Lifetime(a), &Lifetime(b)) => a == b,
diff --git a/src/librustc_parse/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index 4e4429e461f..4e4429e461f 100644
--- a/src/librustc_parse/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
diff --git a/src/librustc_parse/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 12efe391fb9..12efe391fb9 100644
--- a/src/librustc_parse/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
diff --git a/src/librustc_parse/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index f022c628fe2..69d13b5cf53 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1480,7 +1480,7 @@ impl<'a> Parser<'a> {
 
     /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`).
     /// Keep this in sync with `Token::can_begin_literal_maybe_minus`.
-    pub(super) fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
+    pub fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
         maybe_whole_expr!(self);
 
         let lo = self.token.span;
diff --git a/src/librustc_parse/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index dd99a7587dd..dd99a7587dd 100644
--- a/src/librustc_parse/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
diff --git a/src/librustc_parse/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 9143af651df..9143af651df 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
diff --git a/src/librustc_parse/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index d67ed74bc99..84edfecad19 100644
--- a/src/librustc_parse/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -1014,7 +1014,8 @@ impl<'a> Parser<'a> {
     /// If the following element can't be a tuple (i.e., it's a function definition), then
     /// it's not a tuple struct field), and the contents within the parentheses isn't valid,
     /// so emit a proper diagnostic.
-    pub(crate) fn parse_visibility(&mut self, fbt: FollowedByType) -> PResult<'a, Visibility> {
+    // Public for rustfmt usage.
+    pub fn parse_visibility(&mut self, fbt: FollowedByType) -> PResult<'a, Visibility> {
         maybe_whole!(self, NtVis, |x| x);
 
         self.expected_tokens.push(TokenType::Keyword(kw::Crate));
@@ -1233,6 +1234,10 @@ impl<'a> Parser<'a> {
                 *t == token::OpenDelim(token::Brace) || *t == token::BinOp(token::Star)
             })
     }
+
+    pub fn clear_expected_tokens(&mut self) {
+        self.expected_tokens.clear();
+    }
 }
 
 crate fn make_unclosed_delims_error(
diff --git a/src/librustc_parse/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs
index f40cd1131d2..f40cd1131d2 100644
--- a/src/librustc_parse/parser/nonterminal.rs
+++ b/compiler/rustc_parse/src/parser/nonterminal.rs
diff --git a/src/librustc_parse/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 2c0133a24dc..2c0133a24dc 100644
--- a/src/librustc_parse/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
diff --git a/src/librustc_parse/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 54b4df8613f..54b4df8613f 100644
--- a/src/librustc_parse/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
diff --git a/src/librustc_parse/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index ac067cb0eab..947ca6b5bd5 100644
--- a/src/librustc_parse/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -10,7 +10,7 @@ use rustc_ast as ast;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, TokenKind};
 use rustc_ast::util::classify;
-use rustc_ast::{AttrStyle, AttrVec, Attribute, MacCall, MacStmtStyle};
+use rustc_ast::{AttrStyle, AttrVec, Attribute, MacCall, MacCallStmt, MacStmtStyle};
 use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt, StmtKind, DUMMY_NODE_ID};
 use rustc_errors::{Applicability, PResult};
 use rustc_span::source_map::{BytePos, Span};
@@ -21,7 +21,8 @@ use std::mem;
 impl<'a> Parser<'a> {
     /// Parses a statement. This stops just before trailing semicolons on everything but items.
     /// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed.
-    pub(super) fn parse_stmt(&mut self) -> PResult<'a, Option<Stmt>> {
+    // Public for rustfmt usage.
+    pub fn parse_stmt(&mut self) -> PResult<'a, Option<Stmt>> {
         Ok(self.parse_stmt_without_recovery().unwrap_or_else(|mut e| {
             e.emit();
             self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
@@ -106,7 +107,7 @@ impl<'a> Parser<'a> {
 
         let kind = if delim == token::Brace || self.token == token::Semi || self.token == token::Eof
         {
-            StmtKind::MacCall(P((mac, style, attrs)))
+            StmtKind::MacCall(P(MacCallStmt { mac, style, attrs }))
         } else {
             // Since none of the above applied, this is an expression statement macro.
             let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac), AttrVec::new());
diff --git a/src/librustc_parse/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 4356850818e..4356850818e 100644
--- a/src/librustc_parse/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
diff --git a/src/librustc_parse/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index f4bb9610940..f4bb9610940 100644
--- a/src/librustc_parse/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
diff --git a/compiler/rustc_parse_format/Cargo.toml b/compiler/rustc_parse_format/Cargo.toml
new file mode 100644
index 00000000000..c2317d91a6e
--- /dev/null
+++ b/compiler/rustc_parse_format/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_parse_format"
+version = "0.0.0"
+edition = "2018"
+
+[dependencies]
+rustc_span = { path = "../rustc_span" }
+rustc_lexer = { path = "../rustc_lexer" }
diff --git a/src/librustc_parse_format/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index e07b8b86aef..e07b8b86aef 100644
--- a/src/librustc_parse_format/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
diff --git a/src/librustc_parse_format/tests.rs b/compiler/rustc_parse_format/src/tests.rs
index 9fd0497fffe..9fd0497fffe 100644
--- a/src/librustc_parse_format/tests.rs
+++ b/compiler/rustc_parse_format/src/tests.rs
diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml
new file mode 100644
index 00000000000..4c3a96eed04
--- /dev/null
+++ b/compiler/rustc_passes/Cargo.toml
@@ -0,0 +1,19 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_passes"
+version = "0.0.0"
+edition = "2018"
+
+[dependencies]
+tracing = "0.1"
+rustc_middle = { path = "../rustc_middle" }
+rustc_attr = { path = "../rustc_attr" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_index = { path = "../rustc_index" }
+rustc_session = { path = "../rustc_session" }
+rustc_target = { path = "../rustc_target" }
+rustc_ast = { path = "../rustc_ast" }
+rustc_span = { path = "../rustc_span" }
+rustc_trait_selection = { path = "../rustc_trait_selection" }
diff --git a/src/librustc_passes/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 832cde86d0b..832cde86d0b 100644
--- a/src/librustc_passes/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
diff --git a/src/librustc_passes/check_const.rs b/compiler/rustc_passes/src/check_const.rs
index dd0bcbf208d..dd0bcbf208d 100644
--- a/src/librustc_passes/check_const.rs
+++ b/compiler/rustc_passes/src/check_const.rs
diff --git a/src/librustc_passes/dead.rs b/compiler/rustc_passes/src/dead.rs
index 01da33ddd2e..01da33ddd2e 100644
--- a/src/librustc_passes/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
diff --git a/src/librustc_passes/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs
index df0f9f157ae..df0f9f157ae 100644
--- a/src/librustc_passes/diagnostic_items.rs
+++ b/compiler/rustc_passes/src/diagnostic_items.rs
diff --git a/src/librustc_passes/entry.rs b/compiler/rustc_passes/src/entry.rs
index 8aa6e7936be..8aa6e7936be 100644
--- a/src/librustc_passes/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
diff --git a/src/librustc_passes/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs
index 2edbc29b7ef..2edbc29b7ef 100644
--- a/src/librustc_passes/hir_id_validator.rs
+++ b/compiler/rustc_passes/src/hir_id_validator.rs
diff --git a/src/librustc_passes/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs
index 9537321026e..9537321026e 100644
--- a/src/librustc_passes/hir_stats.rs
+++ b/compiler/rustc_passes/src/hir_stats.rs
diff --git a/src/librustc_passes/intrinsicck.rs b/compiler/rustc_passes/src/intrinsicck.rs
index ebe231009d3..ebe231009d3 100644
--- a/src/librustc_passes/intrinsicck.rs
+++ b/compiler/rustc_passes/src/intrinsicck.rs
diff --git a/src/librustc_passes/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs
index 0ae0c381a11..0ae0c381a11 100644
--- a/src/librustc_passes/lang_items.rs
+++ b/compiler/rustc_passes/src/lang_items.rs
diff --git a/src/librustc_passes/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs
index 504cbbfcb76..504cbbfcb76 100644
--- a/src/librustc_passes/layout_test.rs
+++ b/compiler/rustc_passes/src/layout_test.rs
diff --git a/src/librustc_passes/lib.rs b/compiler/rustc_passes/src/lib.rs
index be4c542ec3a..be4c542ec3a 100644
--- a/src/librustc_passes/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
diff --git a/src/librustc_passes/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs
index 7c62a234dba..7c62a234dba 100644
--- a/src/librustc_passes/lib_features.rs
+++ b/compiler/rustc_passes/src/lib_features.rs
diff --git a/src/librustc_passes/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index 55525586479..55525586479 100644
--- a/src/librustc_passes/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
diff --git a/src/librustc_passes/loops.rs b/compiler/rustc_passes/src/loops.rs
index 9b4da71e5e9..9b4da71e5e9 100644
--- a/src/librustc_passes/loops.rs
+++ b/compiler/rustc_passes/src/loops.rs
diff --git a/src/librustc_passes/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index 8d5c980609c..8d5c980609c 100644
--- a/src/librustc_passes/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
diff --git a/src/librustc_passes/region.rs b/compiler/rustc_passes/src/region.rs
index 1af79abe4b9..1af79abe4b9 100644
--- a/src/librustc_passes/region.rs
+++ b/compiler/rustc_passes/src/region.rs
diff --git a/src/librustc_passes/stability.rs b/compiler/rustc_passes/src/stability.rs
index 91edc7d9db7..91edc7d9db7 100644
--- a/src/librustc_passes/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
diff --git a/src/librustc_passes/upvars.rs b/compiler/rustc_passes/src/upvars.rs
index 91b8ae07637..91b8ae07637 100644
--- a/src/librustc_passes/upvars.rs
+++ b/compiler/rustc_passes/src/upvars.rs
diff --git a/src/librustc_passes/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs
index 6bc2110bfb3..6bc2110bfb3 100644
--- a/src/librustc_passes/weak_lang_items.rs
+++ b/compiler/rustc_passes/src/weak_lang_items.rs
diff --git a/compiler/rustc_plugin_impl/Cargo.toml b/compiler/rustc_plugin_impl/Cargo.toml
new file mode 100644
index 00000000000..500d13a8c16
--- /dev/null
+++ b/compiler/rustc_plugin_impl/Cargo.toml
@@ -0,0 +1,19 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_plugin_impl"
+version = "0.0.0"
+build = false
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+rustc_middle = { path = "../rustc_middle" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_lint = { path = "../rustc_lint" }
+rustc_metadata = { path = "../rustc_metadata" }
+rustc_ast = { path = "../rustc_ast" }
+rustc_session = { path = "../rustc_session" }
+rustc_span = { path = "../rustc_span" }
diff --git a/src/librustc_plugin_impl/build.rs b/compiler/rustc_plugin_impl/src/build.rs
index d16dd701a12..d16dd701a12 100644
--- a/src/librustc_plugin_impl/build.rs
+++ b/compiler/rustc_plugin_impl/src/build.rs
diff --git a/src/librustc_plugin_impl/lib.rs b/compiler/rustc_plugin_impl/src/lib.rs
index 1eb65dd96ba..1eb65dd96ba 100644
--- a/src/librustc_plugin_impl/lib.rs
+++ b/compiler/rustc_plugin_impl/src/lib.rs
diff --git a/src/librustc_plugin_impl/load.rs b/compiler/rustc_plugin_impl/src/load.rs
index 687f7db221f..687f7db221f 100644
--- a/src/librustc_plugin_impl/load.rs
+++ b/compiler/rustc_plugin_impl/src/load.rs
diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml
new file mode 100644
index 00000000000..ce83dc1de78
--- /dev/null
+++ b/compiler/rustc_privacy/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_privacy"
+version = "0.0.0"
+edition = "2018"
+
+[dependencies]
+rustc_middle = { path = "../rustc_middle" }
+rustc_attr = { path = "../rustc_attr" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_typeck = { path = "../rustc_typeck" }
+rustc_session = { path = "../rustc_session" }
+rustc_span = { path = "../rustc_span" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+tracing = "0.1"
diff --git a/src/librustc_privacy/lib.rs b/compiler/rustc_privacy/src/lib.rs
index deb4277cb38..deb4277cb38 100644
--- a/src/librustc_privacy/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml
new file mode 100644
index 00000000000..7defb00a881
--- /dev/null
+++ b/compiler/rustc_query_system/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_query_system"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+rustc_arena = { path = "../rustc_arena" }
+tracing = "0.1"
+rustc-rayon-core = "0.3.0"
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_macros = { path = "../rustc_macros" }
+rustc_index = { path = "../rustc_index" }
+rustc_serialize = { path = "../rustc_serialize" }
+rustc_span = { path = "../rustc_span" }
+parking_lot = "0.10"
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_query_system/cache.rs b/compiler/rustc_query_system/src/cache.rs
index be3d3607728..be3d3607728 100644
--- a/src/librustc_query_system/cache.rs
+++ b/compiler/rustc_query_system/src/cache.rs
diff --git a/src/librustc_query_system/dep_graph/README.md b/compiler/rustc_query_system/src/dep_graph/README.md
index b9d91cd35a8..b9d91cd35a8 100644
--- a/src/librustc_query_system/dep_graph/README.md
+++ b/compiler/rustc_query_system/src/dep_graph/README.md
diff --git a/src/librustc_query_system/dep_graph/debug.rs b/compiler/rustc_query_system/src/dep_graph/debug.rs
index 718a2f1039a..718a2f1039a 100644
--- a/src/librustc_query_system/dep_graph/debug.rs
+++ b/compiler/rustc_query_system/src/dep_graph/debug.rs
diff --git a/src/librustc_query_system/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs
index e302784cc3e..e302784cc3e 100644
--- a/src/librustc_query_system/dep_graph/dep_node.rs
+++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs
diff --git a/src/librustc_query_system/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index d70306b4869..d70306b4869 100644
--- a/src/librustc_query_system/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
diff --git a/src/librustc_query_system/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs
index e8d02692f37..e8d02692f37 100644
--- a/src/librustc_query_system/dep_graph/mod.rs
+++ b/compiler/rustc_query_system/src/dep_graph/mod.rs
diff --git a/src/librustc_query_system/dep_graph/prev.rs b/compiler/rustc_query_system/src/dep_graph/prev.rs
index 29357ce9449..29357ce9449 100644
--- a/src/librustc_query_system/dep_graph/prev.rs
+++ b/compiler/rustc_query_system/src/dep_graph/prev.rs
diff --git a/src/librustc_query_system/dep_graph/query.rs b/compiler/rustc_query_system/src/dep_graph/query.rs
index fb313d2658f..fb313d2658f 100644
--- a/src/librustc_query_system/dep_graph/query.rs
+++ b/compiler/rustc_query_system/src/dep_graph/query.rs
diff --git a/src/librustc_query_system/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs
index 932c6d2a2f1..932c6d2a2f1 100644
--- a/src/librustc_query_system/dep_graph/serialized.rs
+++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs
diff --git a/src/librustc_query_system/lib.rs b/compiler/rustc_query_system/src/lib.rs
index 26b76a9c006..26b76a9c006 100644
--- a/src/librustc_query_system/lib.rs
+++ b/compiler/rustc_query_system/src/lib.rs
diff --git a/src/librustc_query_system/query/README.md b/compiler/rustc_query_system/src/query/README.md
index 8ec07b9fdeb..8ec07b9fdeb 100644
--- a/src/librustc_query_system/query/README.md
+++ b/compiler/rustc_query_system/src/query/README.md
diff --git a/src/librustc_query_system/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs
index 1839e1af45e..1839e1af45e 100644
--- a/src/librustc_query_system/query/caches.rs
+++ b/compiler/rustc_query_system/src/query/caches.rs
diff --git a/src/librustc_query_system/query/config.rs b/compiler/rustc_query_system/src/query/config.rs
index 549056570f9..549056570f9 100644
--- a/src/librustc_query_system/query/config.rs
+++ b/compiler/rustc_query_system/src/query/config.rs
diff --git a/src/librustc_query_system/query/job.rs b/compiler/rustc_query_system/src/query/job.rs
index 190312bb330..190312bb330 100644
--- a/src/librustc_query_system/query/job.rs
+++ b/compiler/rustc_query_system/src/query/job.rs
diff --git a/src/librustc_query_system/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs
index 49097725bc9..49097725bc9 100644
--- a/src/librustc_query_system/query/mod.rs
+++ b/compiler/rustc_query_system/src/query/mod.rs
diff --git a/src/librustc_query_system/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index ae042cc8081..ae042cc8081 100644
--- a/src/librustc_query_system/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml
new file mode 100644
index 00000000000..821f9ea4738
--- /dev/null
+++ b/compiler/rustc_resolve/Cargo.toml
@@ -0,0 +1,29 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_resolve"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+test = false
+doctest = false
+
+[dependencies]
+bitflags = "1.2.1"
+tracing = "0.1"
+rustc_ast = { path = "../rustc_ast" }
+rustc_arena = { path = "../rustc_arena" }
+rustc_middle = { path = "../rustc_middle" }
+rustc_ast_lowering = { path = "../rustc_ast_lowering" }
+rustc_ast_pretty = { path = "../rustc_ast_pretty" }
+rustc_attr = { path = "../rustc_attr" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_expand = { path = "../rustc_expand" }
+rustc_feature = { path = "../rustc_feature" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_index = { path = "../rustc_index" }
+rustc_metadata = { path = "../rustc_metadata" }
+rustc_session = { path = "../rustc_session" }
+rustc_span = { path = "../rustc_span" }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 761724be57d..761724be57d 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
diff --git a/src/librustc_resolve/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs
index 5624a6b6acc..5624a6b6acc 100644
--- a/src/librustc_resolve/check_unused.rs
+++ b/compiler/rustc_resolve/src/check_unused.rs
diff --git a/src/librustc_resolve/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index 5d5088de31b..5d5088de31b 100644
--- a/src/librustc_resolve/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
diff --git a/src/librustc_resolve/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 48e1068b8da..48e1068b8da 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
diff --git a/src/librustc_resolve/imports.rs b/compiler/rustc_resolve/src/imports.rs
index b02fc427d60..b02fc427d60 100644
--- a/src/librustc_resolve/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
diff --git a/src/librustc_resolve/late.rs b/compiler/rustc_resolve/src/late.rs
index d113eb22aba..2b2123e295d 100644
--- a/src/librustc_resolve/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -378,6 +378,9 @@ struct DiagnosticMetadata<'ast> {
 
     /// Only used for better errors on `let <pat>: <expr, not type>;`.
     current_let_binding: Option<(Span, Option<Span>, Option<Span>)>,
+
+    /// Used to detect possible `if let` written without `let` and to provide structured suggestion.
+    in_if_condition: Option<&'ast Expr>,
 }
 
 struct LateResolutionVisitor<'a, 'b, 'ast> {
@@ -403,7 +406,7 @@ struct LateResolutionVisitor<'a, 'b, 'ast> {
     ///
     /// In particular, rustdoc uses this to avoid giving errors for `cfg()` items.
     /// In most cases this will be `None`, in which case errors will always be reported.
-    /// If it is `Some(_)`, then it will be updated when entering a nested function or trait body.
+    /// If it is `true`, then it will be updated when entering a nested function or trait body.
     in_func_body: bool,
 }
 
@@ -2199,7 +2202,9 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
 
             ExprKind::If(ref cond, ref then, ref opt_else) => {
                 self.with_rib(ValueNS, NormalRibKind, |this| {
+                    let old = this.diagnostic_metadata.in_if_condition.replace(cond);
                     this.visit_expr(cond);
+                    this.diagnostic_metadata.in_if_condition = old;
                     this.visit_block(then);
                 });
                 if let Some(expr) = opt_else {
diff --git a/src/librustc_resolve/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index d392967af38..8cb6b6553ff 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -176,6 +176,19 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
         let code = source.error_code(res.is_some());
         let mut err = self.r.session.struct_span_err_with_code(base_span, &base_msg, code);
 
+        match (source, self.diagnostic_metadata.in_if_condition) {
+            (PathSource::Expr(_), Some(Expr { span, kind: ExprKind::Assign(..), .. })) => {
+                err.span_suggestion_verbose(
+                    span.shrink_to_lo(),
+                    "you might have meant to use pattern matching",
+                    "let ".to_string(),
+                    Applicability::MaybeIncorrect,
+                );
+                self.r.session.if_let_suggestions.borrow_mut().insert(*span);
+            }
+            _ => {}
+        }
+
         let is_assoc_fn = self.self_type_is_available(span);
         // Emit help message for fake-self from other languages (e.g., `this` in Javascript).
         if ["this", "my"].contains(&&*item_str.as_str()) && is_assoc_fn {
diff --git a/src/librustc_resolve/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index 31360d47473..31360d47473 100644
--- a/src/librustc_resolve/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
diff --git a/src/librustc_resolve/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 5892edf7652..50729086ec6 100644
--- a/src/librustc_resolve/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -867,6 +867,12 @@ pub struct ExternPreludeEntry<'a> {
     pub introduced_by_item: bool,
 }
 
+/// Used for better errors for E0773
+enum BuiltinMacroState {
+    NotYetSeen(SyntaxExtension),
+    AlreadySeen(Span),
+}
+
 /// The main resolver class.
 ///
 /// This is the visitor that walks the whole crate.
@@ -960,7 +966,7 @@ pub struct Resolver<'a> {
 
     crate_loader: CrateLoader<'a>,
     macro_names: FxHashSet<Ident>,
-    builtin_macros: FxHashMap<Symbol, SyntaxExtension>,
+    builtin_macros: FxHashMap<Symbol, BuiltinMacroState>,
     registered_attrs: FxHashSet<Ident>,
     registered_tools: FxHashSet<Ident>,
     macro_use_prelude: FxHashMap<Symbol, &'a NameBinding<'a>>,
diff --git a/src/librustc_resolve/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 51518d63ae9..bea71389647 100644
--- a/src/librustc_resolve/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -3,7 +3,7 @@
 
 use crate::imports::ImportResolver;
 use crate::Namespace::*;
-use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy};
+use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BuiltinMacroState, Determinacy};
 use crate::{CrateLint, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Weak};
 use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding};
 use rustc_ast::{self as ast, NodeId};
@@ -11,6 +11,7 @@ use rustc_ast_lowering::ResolverAstLowering;
 use rustc_ast_pretty::pprust;
 use rustc_attr::StabilityLevel;
 use rustc_data_structures::fx::FxHashSet;
+use rustc_errors::struct_span_err;
 use rustc_expand::base::{Indeterminate, InvocationRes, ResolverExpand, SyntaxExtension};
 use rustc_expand::compile_declarative_macro;
 use rustc_expand::expand::{AstFragment, AstFragmentKind, Invocation, InvocationKind};
@@ -166,7 +167,7 @@ impl<'a> ResolverExpand for Resolver<'a> {
     }
 
     fn register_builtin_macro(&mut self, ident: Ident, ext: SyntaxExtension) {
-        if self.builtin_macros.insert(ident.name, ext).is_some() {
+        if self.builtin_macros.insert(ident.name, BuiltinMacroState::NotYetSeen(ext)).is_some() {
             self.session
                 .span_err(ident.span, &format!("built-in macro `{}` was already defined", ident));
         }
@@ -1076,10 +1077,23 @@ impl<'a> Resolver<'a> {
 
         if result.is_builtin {
             // The macro was marked with `#[rustc_builtin_macro]`.
-            if let Some(ext) = self.builtin_macros.remove(&item.ident.name) {
+            if let Some(builtin_macro) = self.builtin_macros.get_mut(&item.ident.name) {
                 // The macro is a built-in, replace its expander function
                 // while still taking everything else from the source code.
-                result.kind = ext.kind;
+                // If we already loaded this builtin macro, give a better error message than 'no such builtin macro'.
+                match mem::replace(builtin_macro, BuiltinMacroState::AlreadySeen(item.span)) {
+                    BuiltinMacroState::NotYetSeen(ext) => result.kind = ext.kind,
+                    BuiltinMacroState::AlreadySeen(span) => {
+                        struct_span_err!(
+                            self.session,
+                            item.span,
+                            E0773,
+                            "attempted to define built-in macro more than once"
+                        )
+                        .span_note(span, "previously defined here")
+                        .emit();
+                    }
+                }
             } else {
                 let msg = format!("cannot find a built-in macro with name `{}`", item.ident);
                 self.session.span_err(item.span, &msg);
diff --git a/compiler/rustc_save_analysis/Cargo.toml b/compiler/rustc_save_analysis/Cargo.toml
new file mode 100644
index 00000000000..da1bed37a96
--- /dev/null
+++ b/compiler/rustc_save_analysis/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_save_analysis"
+version = "0.0.0"
+edition = "2018"
+
+[dependencies]
+tracing = "0.1"
+rustc_middle = { path = "../rustc_middle" }
+rustc_ast = { path = "../rustc_ast" }
+rustc_ast_pretty = { path = "../rustc_ast_pretty" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_hir_pretty = { path = "../rustc_hir_pretty" }
+rustc_lexer = { path = "../rustc_lexer" }
+serde_json = "1"
+rustc_session = { path = "../rustc_session" }
+rustc_span = { path = "../rustc_span" }
+rls-data = "0.19"
+rls-span = "0.5"
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs
index ce484858cbb..ce484858cbb 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/compiler/rustc_save_analysis/src/dump_visitor.rs
diff --git a/src/librustc_save_analysis/dumper.rs b/compiler/rustc_save_analysis/src/dumper.rs
index 5a2628287d6..5a2628287d6 100644
--- a/src/librustc_save_analysis/dumper.rs
+++ b/compiler/rustc_save_analysis/src/dumper.rs
diff --git a/src/librustc_save_analysis/lib.rs b/compiler/rustc_save_analysis/src/lib.rs
index 629051c1820..629051c1820 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/compiler/rustc_save_analysis/src/lib.rs
diff --git a/src/librustc_save_analysis/sig.rs b/compiler/rustc_save_analysis/src/sig.rs
index 6dd7f89d594..6dd7f89d594 100644
--- a/src/librustc_save_analysis/sig.rs
+++ b/compiler/rustc_save_analysis/src/sig.rs
diff --git a/src/librustc_save_analysis/span_utils.rs b/compiler/rustc_save_analysis/src/span_utils.rs
index edcd4925773..edcd4925773 100644
--- a/src/librustc_save_analysis/span_utils.rs
+++ b/compiler/rustc_save_analysis/src/span_utils.rs
diff --git a/src/librustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml
index 939e6a59ba0..16c5dff7341 100644
--- a/src/librustc_serialize/Cargo.toml
+++ b/compiler/rustc_serialize/Cargo.toml
@@ -4,13 +4,9 @@ name = "rustc_serialize"
 version = "0.0.0"
 edition = "2018"
 
-[lib]
-name = "rustc_serialize"
-path = "lib.rs"
-
 [dependencies]
 indexmap = "1"
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 
 [dev-dependencies]
-rustc_macros = { path = "../librustc_macros" }
+rustc_macros = { path = "../rustc_macros" }
diff --git a/src/librustc_serialize/collection_impls.rs b/compiler/rustc_serialize/src/collection_impls.rs
index 3d274cb0150..3d274cb0150 100644
--- a/src/librustc_serialize/collection_impls.rs
+++ b/compiler/rustc_serialize/src/collection_impls.rs
diff --git a/src/librustc_serialize/json.rs b/compiler/rustc_serialize/src/json.rs
index 6c8965aa2e3..6c8965aa2e3 100644
--- a/src/librustc_serialize/json.rs
+++ b/compiler/rustc_serialize/src/json.rs
diff --git a/src/librustc_serialize/json/tests.rs b/compiler/rustc_serialize/src/json/tests.rs
index 01678fbf0b7..01678fbf0b7 100644
--- a/src/librustc_serialize/json/tests.rs
+++ b/compiler/rustc_serialize/src/json/tests.rs
diff --git a/src/librustc_serialize/leb128.rs b/compiler/rustc_serialize/src/leb128.rs
index 1fe6a309e96..1fe6a309e96 100644
--- a/src/librustc_serialize/leb128.rs
+++ b/compiler/rustc_serialize/src/leb128.rs
diff --git a/src/librustc_serialize/lib.rs b/compiler/rustc_serialize/src/lib.rs
index 265b3b95e95..265b3b95e95 100644
--- a/src/librustc_serialize/lib.rs
+++ b/compiler/rustc_serialize/src/lib.rs
diff --git a/src/librustc_serialize/opaque.rs b/compiler/rustc_serialize/src/opaque.rs
index fa4423e261d..fa4423e261d 100644
--- a/src/librustc_serialize/opaque.rs
+++ b/compiler/rustc_serialize/src/opaque.rs
diff --git a/src/librustc_serialize/serialize.rs b/compiler/rustc_serialize/src/serialize.rs
index c0e23b89a60..c0e23b89a60 100644
--- a/src/librustc_serialize/serialize.rs
+++ b/compiler/rustc_serialize/src/serialize.rs
diff --git a/src/librustc_serialize/tests/json.rs b/compiler/rustc_serialize/tests/json.rs
index e3a823127d9..e3a823127d9 100644
--- a/src/librustc_serialize/tests/json.rs
+++ b/compiler/rustc_serialize/tests/json.rs
diff --git a/src/librustc_serialize/tests/leb128.rs b/compiler/rustc_serialize/tests/leb128.rs
index b0f7e785b78..b0f7e785b78 100644
--- a/src/librustc_serialize/tests/leb128.rs
+++ b/compiler/rustc_serialize/tests/leb128.rs
diff --git a/src/librustc_serialize/tests/opaque.rs b/compiler/rustc_serialize/tests/opaque.rs
index 13b3676a56c..13b3676a56c 100644
--- a/src/librustc_serialize/tests/opaque.rs
+++ b/compiler/rustc_serialize/tests/opaque.rs
diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml
new file mode 100644
index 00000000000..cdff1662fdb
--- /dev/null
+++ b/compiler/rustc_session/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_session"
+version = "0.0.0"
+edition = "2018"
+
+[dependencies]
+bitflags = "1.2.1"
+getopts = "0.2"
+rustc_macros = { path = "../rustc_macros" }
+tracing = "0.1"
+rustc_errors = { path = "../rustc_errors" }
+rustc_feature = { path = "../rustc_feature" }
+rustc_target = { path = "../rustc_target" }
+rustc_serialize = { path = "../rustc_serialize" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_span = { path = "../rustc_span" }
+rustc_fs_util = { path = "../rustc_fs_util" }
+num_cpus = "1.0"
+rustc_ast = { path = "../rustc_ast" }
diff --git a/src/librustc_session/cgu_reuse_tracker.rs b/compiler/rustc_session/src/cgu_reuse_tracker.rs
index 0eec12aa03f..0eec12aa03f 100644
--- a/src/librustc_session/cgu_reuse_tracker.rs
+++ b/compiler/rustc_session/src/cgu_reuse_tracker.rs
diff --git a/src/librustc_session/code_stats.rs b/compiler/rustc_session/src/code_stats.rs
index c263da69c35..c263da69c35 100644
--- a/src/librustc_session/code_stats.rs
+++ b/compiler/rustc_session/src/code_stats.rs
diff --git a/src/librustc_session/config.rs b/compiler/rustc_session/src/config.rs
index 1808a0ca59b..6861314a88f 100644
--- a/src/librustc_session/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -163,6 +163,21 @@ pub enum LtoCli {
     Unspecified,
 }
 
+/// The different settings that the `-Z dump_mir_spanview` flag can have. `Statement` generates a
+/// document highlighting each span of every statement (including terminators). `Terminator` and
+/// `Block` highlight a single span per `BasicBlock`: the span of the block's `Terminator`, or a
+/// computed span for the block, representing the entire range, covering the block's terminator and
+/// all of its statements.
+#[derive(Clone, Copy, PartialEq, Hash, Debug)]
+pub enum MirSpanview {
+    /// Default `-Z dump_mir_spanview` or `-Z dump_mir_spanview=statement`
+    Statement,
+    /// `-Z dump_mir_spanview=terminator`
+    Terminator,
+    /// `-Z dump_mir_spanview=block`
+    Block,
+}
+
 #[derive(Clone, PartialEq, Hash)]
 pub enum LinkerPluginLto {
     LinkerPlugin(PathBuf),
@@ -1718,20 +1733,11 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
             );
         }
 
-        // `-Z instrument-coverage` implies:
-        //   * `-Z symbol-mangling-version=v0` - to ensure consistent and reversible name mangling.
-        //     Note, LLVM coverage tools can analyze coverage over multiple runs, including some
-        //     changes to source code; so mangled names must be consistent across compilations.
-        //   * `-C link-dead-code` - so unexecuted code is still counted as zero, rather than be
-        //     optimized out. Note that instrumenting dead code can be explicitly disabled with:
-        //         `-Z instrument-coverage -C link-dead-code=no`.
+        // `-Z instrument-coverage` implies `-Z symbol-mangling-version=v0` - to ensure consistent
+        // and reversible name mangling. Note, LLVM coverage tools can analyze coverage over
+        // multiple runs, including some changes to source code; so mangled names must be consistent
+        // across compilations.
         debugging_opts.symbol_mangling_version = SymbolManglingVersion::V0;
-        if cg.link_dead_code == None {
-            // FIXME(richkadel): Investigate if the `instrument-coverage` implementation can
-            // inject ["zero counters"](https://llvm.org/docs/CoverageMappingFormat.html#counter)
-            // in the coverage map when "dead code" is removed, rather than forcing `link-dead-code`.
-            cg.link_dead_code = Some(true);
-        }
     }
 
     if !cg.embed_bitcode {
diff --git a/src/librustc_session/filesearch.rs b/compiler/rustc_session/src/filesearch.rs
index 284fca652ec..284fca652ec 100644
--- a/src/librustc_session/filesearch.rs
+++ b/compiler/rustc_session/src/filesearch.rs
diff --git a/src/librustc_session/lib.rs b/compiler/rustc_session/src/lib.rs
index c2ea141a06f..a808261798d 100644
--- a/src/librustc_session/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -1,4 +1,5 @@
 #![feature(crate_visibility_modifier)]
+#![feature(once_cell)]
 #![feature(or_patterns)]
 
 #[macro_use]
diff --git a/src/librustc_session/lint.rs b/compiler/rustc_session/src/lint.rs
index 0dcbee08abe..0dcbee08abe 100644
--- a/src/librustc_session/lint.rs
+++ b/compiler/rustc_session/src/lint.rs
diff --git a/src/librustc_session/lint/builtin.rs b/compiler/rustc_session/src/lint/builtin.rs
index 2db4d2a7f51..2db4d2a7f51 100644
--- a/src/librustc_session/lint/builtin.rs
+++ b/compiler/rustc_session/src/lint/builtin.rs
diff --git a/src/librustc_session/options.rs b/compiler/rustc_session/src/options.rs
index d05f1a3f34b..a28c17917df 100644
--- a/src/librustc_session/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -255,6 +255,7 @@ macro_rules! options {
         pub const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`";
         pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavor::one_of();
         pub const parse_optimization_fuel: &str = "crate=integer";
+        pub const parse_mir_spanview: &str = "`statement` (default), `terminator`, or `block`";
         pub const parse_unpretty: &str = "`string` or `string=string`";
         pub const parse_treat_err_as_bug: &str = "either no value or a number bigger than 0";
         pub const parse_lto: &str =
@@ -551,6 +552,36 @@ macro_rules! options {
             }
         }
 
+        fn parse_mir_spanview(slot: &mut Option<MirSpanview>, v: Option<&str>) -> bool {
+            if v.is_some() {
+                let mut bool_arg = None;
+                if parse_opt_bool(&mut bool_arg, v) {
+                    *slot = if bool_arg.unwrap() {
+                        Some(MirSpanview::Statement)
+                    } else {
+                        None
+                    };
+                    return true
+                }
+            }
+
+            let v = match v {
+                None => {
+                    *slot = Some(MirSpanview::Statement);
+                    return true;
+                }
+                Some(v) => v,
+            };
+
+            *slot = Some(match v.trim_end_matches("s") {
+                "statement" | "stmt" => MirSpanview::Statement,
+                "terminator" | "term" => MirSpanview::Terminator,
+                "block" | "basicblock" => MirSpanview::Block,
+                _ => return false,
+            });
+            true
+        }
+
         fn parse_treat_err_as_bug(slot: &mut Option<usize>, v: Option<&str>) -> bool {
             match v {
                 Some(s) => { *slot = s.parse().ok().filter(|&x| x != 0); slot.unwrap_or(0) != 0 }
@@ -719,6 +750,9 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
         "extra arguments to append to the linker invocation (space separated)"),
     link_dead_code: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
         "keep dead code at link time (useful for code coverage) (default: no)"),
+    link_self_contained: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
+        "control whether to link Rust provided C objects/libraries or rely
+        on C toolchain installed in the system"),
     linker: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
         "system linker to link outputs with"),
     linker_flavor: Option<LinkerFlavor> = (None, parse_linker_flavor, [UNTRACKED],
@@ -849,6 +883,11 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         "exclude the pass number when dumping MIR (used in tests) (default: no)"),
     dump_mir_graphviz: bool = (false, parse_bool, [UNTRACKED],
         "in addition to `.mir` files, create graphviz `.dot` files (default: no)"),
+    dump_mir_spanview: Option<MirSpanview> = (None, parse_mir_spanview, [UNTRACKED],
+        "in addition to `.mir` files, create `.html` files to view spans for \
+        all `statement`s (including terminators), only `terminator` spans, or \
+        computed `block` spans (one span encompassing a block's terminator and \
+        all statements)."),
     emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED],
         "emit a section containing stack size metadata (default: no)"),
     fewer_names: bool = (false, parse_bool, [TRACKED],
@@ -885,18 +924,15 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         "instrument the generated code to support LLVM source-based code coverage \
         reports (note, the compiler build config must include `profiler = true`, \
         and is mutually exclusive with `-C profile-generate`/`-C profile-use`); \
-        implies `-C link-dead-code` (unless explicitly disabled)` and \
-        `-Z symbol-mangling-version=v0`; and disables/overrides some optimization \
-        options (default: no)"),
+        implies `-C link-dead-code` (unless targeting MSVC, or explicitly disabled) \
+        and `-Z symbol-mangling-version=v0`; disables/overrides some Rust \
+        optimizations (default: no)"),
     instrument_mcount: bool = (false, parse_bool, [TRACKED],
         "insert function instrument code for mcount-based tracing (default: no)"),
     keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED],
         "keep hygiene data after analysis (default: no)"),
     link_native_libraries: bool = (true, parse_bool, [UNTRACKED],
         "link native libraries in the linker invocation (default: yes)"),
-    link_self_contained: Option<bool> = (None, parse_opt_bool, [TRACKED],
-        "control whether to link Rust provided C objects/libraries or rely
-         on C toolchain installed in the system"),
     link_only: bool = (false, parse_bool, [TRACKED],
         "link the `.rlink` file generated by `-Z no-link` (default: no)"),
     llvm_time_trace: bool = (false, parse_bool, [UNTRACKED],
@@ -967,6 +1003,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         "print the result of the monomorphization collection pass"),
     print_type_sizes: bool = (false, parse_bool, [UNTRACKED],
         "print layout information for each type encountered (default: no)"),
+    proc_macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
+         "show backtraces for panics during proc-macro execution (default: no)"),
     profile: bool = (false, parse_bool, [TRACKED],
         "insert profiling code (default: no)"),
     profile_emit: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
diff --git a/src/librustc_session/output.rs b/compiler/rustc_session/src/output.rs
index bf9c96c6c94..bf9c96c6c94 100644
--- a/src/librustc_session/output.rs
+++ b/compiler/rustc_session/src/output.rs
diff --git a/src/librustc_session/parse.rs b/compiler/rustc_session/src/parse.rs
index 6f10d0c4b89..6f10d0c4b89 100644
--- a/src/librustc_session/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
diff --git a/src/librustc_session/search_paths.rs b/compiler/rustc_session/src/search_paths.rs
index e12364b7dac..e12364b7dac 100644
--- a/src/librustc_session/search_paths.rs
+++ b/compiler/rustc_session/src/search_paths.rs
diff --git a/src/librustc_session/session.rs b/compiler/rustc_session/src/session.rs
index c006e593e47..db2059251c0 100644
--- a/src/librustc_session/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -213,6 +213,9 @@ pub struct Session {
 
     known_attrs: Lock<MarkedAttrs>,
     used_attrs: Lock<MarkedAttrs>,
+
+    /// `Span`s for `if` conditions that we have suggested turning into `if let`.
+    pub if_let_suggestions: Lock<FxHashSet<Span>>,
 }
 
 pub struct PerfStats {
@@ -1021,6 +1024,40 @@ impl Session {
         || self.opts.debugging_opts.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::MEMORY)
     }
 
+    pub fn link_dead_code(&self) -> bool {
+        match self.opts.cg.link_dead_code {
+            Some(explicitly_set) => explicitly_set,
+            None => {
+                self.opts.debugging_opts.instrument_coverage
+                    && !self.target.target.options.is_like_msvc
+                // Issue #76038: (rustc `-Clink-dead-code` causes MSVC linker to produce invalid
+                // binaries when LLVM InstrProf counters are enabled). As described by this issue,
+                // the "link dead code" option produces incorrect binaries when compiled and linked
+                // under MSVC. The resulting Rust programs typically crash with a segmentation
+                // fault, or produce an empty "*.profraw" file (profiling counter results normally
+                // generated during program exit).
+                //
+                // If not targeting MSVC, `-Z instrument-coverage` implies `-C link-dead-code`, so
+                // unexecuted code is still counted as zero, rather than be optimized out. Note that
+                // instrumenting dead code can be explicitly disabled with:
+                //
+                //     `-Z instrument-coverage -C link-dead-code=no`.
+                //
+                // FIXME(richkadel): Investigate if `instrument-coverage` implementation can inject
+                // [zero counters](https://llvm.org/docs/CoverageMappingFormat.html#counter) in the
+                // coverage map when "dead code" is removed, rather than forcing `link-dead-code`.
+                // This may not be possible, however, if (as it seems to appear) the "dead code"
+                // that would otherwise not be linked is only identified as "dead" by the native
+                // linker. If that's the case, I believe it is too late for the Rust compiler to
+                // leverage any information it might be able to get from the linker regarding what
+                // code is dead, to be able to add those counters.
+                //
+                // On the other hand, if any Rust compiler passes are optimizing out dead code blocks
+                // we should inject "zero" counters for those code regions.
+            }
+        }
+    }
+
     pub fn mark_attr_known(&self, attr: &Attribute) {
         self.known_attrs.lock().mark(attr)
     }
@@ -1354,6 +1391,7 @@ pub fn build_session(
         target_features: FxHashSet::default(),
         known_attrs: Lock::new(MarkedAttrs::new()),
         used_attrs: Lock::new(MarkedAttrs::new()),
+        if_let_suggestions: Default::default(),
     };
 
     validate_commandline_args_with_session_available(&sess);
@@ -1428,20 +1466,6 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
         );
     }
 
-    // FIXME(richkadel): See `src/test/run-make-fulldeps/instrument-coverage/Makefile`. After
-    // compiling with `-Zinstrument-coverage`, the resulting binary generates a segfault during
-    // the program's exit process (likely while attempting to generate the coverage stats in
-    // the "*.profraw" file). An investigation to resolve the problem on Windows is ongoing,
-    // but until this is resolved, the option is disabled on Windows, and the test is skipped
-    // when targeting `MSVC`.
-    if sess.opts.debugging_opts.instrument_coverage && sess.target.target.options.is_like_msvc {
-        sess.warn(
-            "Rust source-based code coverage instrumentation (with `-Z instrument-coverage`) \
-            is not yet supported on Windows when targeting MSVC. The resulting binaries will \
-            still be instrumented for experimentation purposes, but may not execute correctly.",
-        );
-    }
-
     const ASAN_SUPPORTED_TARGETS: &[&str] = &[
         "aarch64-fuchsia",
         "aarch64-unknown-linux-gnu",
diff --git a/src/librustc_session/utils.rs b/compiler/rustc_session/src/utils.rs
index 15447c01d1e..15447c01d1e 100644
--- a/src/librustc_session/utils.rs
+++ b/compiler/rustc_session/src/utils.rs
diff --git a/compiler/rustc_span/Cargo.toml b/compiler/rustc_span/Cargo.toml
new file mode 100644
index 00000000000..1abfd50f003
--- /dev/null
+++ b/compiler/rustc_span/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_span"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+rustc_serialize = { path = "../rustc_serialize" }
+rustc_macros = { path = "../rustc_macros" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_index = { path = "../rustc_index" }
+rustc_arena = { path = "../rustc_arena" }
+scoped-tls = "1.0"
+unicode-width = "0.1.4"
+cfg-if = "0.1.2"
+tracing = "0.1"
+sha-1 = "0.8"
+md-5 = "0.8"
diff --git a/src/librustc_span/analyze_source_file.rs b/compiler/rustc_span/src/analyze_source_file.rs
index b4beb3dc376..b4beb3dc376 100644
--- a/src/librustc_span/analyze_source_file.rs
+++ b/compiler/rustc_span/src/analyze_source_file.rs
diff --git a/src/librustc_span/analyze_source_file/tests.rs b/compiler/rustc_span/src/analyze_source_file/tests.rs
index cb418a4bdaf..cb418a4bdaf 100644
--- a/src/librustc_span/analyze_source_file/tests.rs
+++ b/compiler/rustc_span/src/analyze_source_file/tests.rs
diff --git a/src/librustc_span/caching_source_map_view.rs b/compiler/rustc_span/src/caching_source_map_view.rs
index 68b0bd1a574..68b0bd1a574 100644
--- a/src/librustc_span/caching_source_map_view.rs
+++ b/compiler/rustc_span/src/caching_source_map_view.rs
diff --git a/src/librustc_span/def_id.rs b/compiler/rustc_span/src/def_id.rs
index aae778217d3..aae778217d3 100644
--- a/src/librustc_span/def_id.rs
+++ b/compiler/rustc_span/src/def_id.rs
diff --git a/src/librustc_span/edition.rs b/compiler/rustc_span/src/edition.rs
index 4d0c92f51d7..4d0c92f51d7 100644
--- a/src/librustc_span/edition.rs
+++ b/compiler/rustc_span/src/edition.rs
diff --git a/src/librustc_span/fatal_error.rs b/compiler/rustc_span/src/fatal_error.rs
index 718c0ddbc63..718c0ddbc63 100644
--- a/src/librustc_span/fatal_error.rs
+++ b/compiler/rustc_span/src/fatal_error.rs
diff --git a/src/librustc_span/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 942c6648340..942c6648340 100644
--- a/src/librustc_span/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
diff --git a/src/librustc_span/lib.rs b/compiler/rustc_span/src/lib.rs
index c654dade2ab..b478a1d15c5 100644
--- a/src/librustc_span/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -400,6 +400,13 @@ impl Span {
         span.with_lo(span.hi)
     }
 
+    #[inline]
+    /// Returns true if hi == lo
+    pub fn is_empty(&self) -> bool {
+        let span = self.data();
+        span.hi == span.lo
+    }
+
     /// Returns `self` if `self` is not the dummy span, and `other` otherwise.
     pub fn substitute_dummy(self, other: Span) -> Span {
         if self.is_dummy() { other } else { self }
diff --git a/src/librustc_span/source_map.rs b/compiler/rustc_span/src/source_map.rs
index 7c656db22ed..37596b8ef6f 100644
--- a/src/librustc_span/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -487,6 +487,15 @@ impl SourceMap {
         }
     }
 
+    /// Returns a new `Span` covering the start and end `BytePos`s of the file containing the given
+    /// `pos`. This can be used to quickly determine if another `BytePos` or `Span` is from the same
+    /// file.
+    pub fn lookup_file_span(&self, pos: BytePos) -> Span {
+        let idx = self.lookup_source_file_idx(pos);
+        let SourceFile { start_pos, end_pos, .. } = *(*self.files.borrow().source_files)[idx];
+        Span::with_root_ctxt(start_pos, end_pos)
+    }
+
     /// Returns `Some(span)`, a union of the LHS and RHS span. The LHS must precede the RHS. If
     /// there are gaps between LHS and RHS, the resulting union will cross these gaps.
     /// For this to work,
diff --git a/src/librustc_span/source_map/tests.rs b/compiler/rustc_span/src/source_map/tests.rs
index b8459eee4ec..b8459eee4ec 100644
--- a/src/librustc_span/source_map/tests.rs
+++ b/compiler/rustc_span/src/source_map/tests.rs
diff --git a/src/librustc_span/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs
index b05e01d666b..b05e01d666b 100644
--- a/src/librustc_span/span_encoding.rs
+++ b/compiler/rustc_span/src/span_encoding.rs
diff --git a/src/librustc_span/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 5092b945f72..5092b945f72 100644
--- a/src/librustc_span/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
diff --git a/src/librustc_span/symbol/tests.rs b/compiler/rustc_span/src/symbol/tests.rs
index 47da03424b7..47da03424b7 100644
--- a/src/librustc_span/symbol/tests.rs
+++ b/compiler/rustc_span/src/symbol/tests.rs
diff --git a/src/librustc_span/tests.rs b/compiler/rustc_span/src/tests.rs
index 3c8eb8bcd31..3c8eb8bcd31 100644
--- a/src/librustc_span/tests.rs
+++ b/compiler/rustc_span/src/tests.rs
diff --git a/compiler/rustc_symbol_mangling/Cargo.toml b/compiler/rustc_symbol_mangling/Cargo.toml
new file mode 100644
index 00000000000..c0dacd24c38
--- /dev/null
+++ b/compiler/rustc_symbol_mangling/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_symbol_mangling"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+tracing = "0.1"
+punycode = "0.4.0"
+rustc-demangle = "0.1.16"
+
+rustc_ast = { path = "../rustc_ast" }
+rustc_span = { path = "../rustc_span" }
+rustc_middle = { path = "../rustc_middle" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_target = { path = "../rustc_target" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_session = { path = "../rustc_session" }
diff --git a/src/librustc_symbol_mangling/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index 24356844baf..24356844baf 100644
--- a/src/librustc_symbol_mangling/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
diff --git a/src/librustc_symbol_mangling/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs
index 296b40c4e39..296b40c4e39 100644
--- a/src/librustc_symbol_mangling/lib.rs
+++ b/compiler/rustc_symbol_mangling/src/lib.rs
diff --git a/src/librustc_symbol_mangling/test.rs b/compiler/rustc_symbol_mangling/src/test.rs
index 24850a8a0d2..24850a8a0d2 100644
--- a/src/librustc_symbol_mangling/test.rs
+++ b/compiler/rustc_symbol_mangling/src/test.rs
diff --git a/src/librustc_symbol_mangling/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index f01c3da8b5f..f01c3da8b5f 100644
--- a/src/librustc_symbol_mangling/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
diff --git a/compiler/rustc_target/Cargo.toml b/compiler/rustc_target/Cargo.toml
new file mode 100644
index 00000000000..2d7d9f1d82d
--- /dev/null
+++ b/compiler/rustc_target/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_target"
+version = "0.0.0"
+edition = "2018"
+
+[dependencies]
+bitflags = "1.2.1"
+tracing = "0.1"
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_macros = { path = "../rustc_macros" }
+rustc_serialize = { path = "../rustc_serialize" }
+rustc_span = { path = "../rustc_span" }
+rustc_index = { path = "../rustc_index" }
diff --git a/src/librustc_target/README.md b/compiler/rustc_target/README.md
index ac1e03385d1..ac1e03385d1 100644
--- a/src/librustc_target/README.md
+++ b/compiler/rustc_target/README.md
diff --git a/src/librustc_target/abi/call/aarch64.rs b/compiler/rustc_target/src/abi/call/aarch64.rs
index 1ab7722edab..1ab7722edab 100644
--- a/src/librustc_target/abi/call/aarch64.rs
+++ b/compiler/rustc_target/src/abi/call/aarch64.rs
diff --git a/src/librustc_target/abi/call/amdgpu.rs b/compiler/rustc_target/src/abi/call/amdgpu.rs
index 0b4f279fece..0b4f279fece 100644
--- a/src/librustc_target/abi/call/amdgpu.rs
+++ b/compiler/rustc_target/src/abi/call/amdgpu.rs
diff --git a/src/librustc_target/abi/call/arm.rs b/compiler/rustc_target/src/abi/call/arm.rs
index 26fed3bae4e..26fed3bae4e 100644
--- a/src/librustc_target/abi/call/arm.rs
+++ b/compiler/rustc_target/src/abi/call/arm.rs
diff --git a/src/librustc_target/abi/call/avr.rs b/compiler/rustc_target/src/abi/call/avr.rs
index c1f7a1e3af5..c1f7a1e3af5 100644
--- a/src/librustc_target/abi/call/avr.rs
+++ b/compiler/rustc_target/src/abi/call/avr.rs
diff --git a/src/librustc_target/abi/call/hexagon.rs b/compiler/rustc_target/src/abi/call/hexagon.rs
index 8028443b8a6..8028443b8a6 100644
--- a/src/librustc_target/abi/call/hexagon.rs
+++ b/compiler/rustc_target/src/abi/call/hexagon.rs
diff --git a/src/librustc_target/abi/call/mips.rs b/compiler/rustc_target/src/abi/call/mips.rs
index 733a7328bd3..733a7328bd3 100644
--- a/src/librustc_target/abi/call/mips.rs
+++ b/compiler/rustc_target/src/abi/call/mips.rs
diff --git a/src/librustc_target/abi/call/mips64.rs b/compiler/rustc_target/src/abi/call/mips64.rs
index 917dd104d14..917dd104d14 100644
--- a/src/librustc_target/abi/call/mips64.rs
+++ b/compiler/rustc_target/src/abi/call/mips64.rs
diff --git a/src/librustc_target/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index 8f7e2bba5aa..8f7e2bba5aa 100644
--- a/src/librustc_target/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
diff --git a/src/librustc_target/abi/call/msp430.rs b/compiler/rustc_target/src/abi/call/msp430.rs
index 3004bb9ff5d..3004bb9ff5d 100644
--- a/src/librustc_target/abi/call/msp430.rs
+++ b/compiler/rustc_target/src/abi/call/msp430.rs
diff --git a/src/librustc_target/abi/call/nvptx.rs b/compiler/rustc_target/src/abi/call/nvptx.rs
index 693337f0e52..693337f0e52 100644
--- a/src/librustc_target/abi/call/nvptx.rs
+++ b/compiler/rustc_target/src/abi/call/nvptx.rs
diff --git a/src/librustc_target/abi/call/nvptx64.rs b/compiler/rustc_target/src/abi/call/nvptx64.rs
index b9c9296dbac..b9c9296dbac 100644
--- a/src/librustc_target/abi/call/nvptx64.rs
+++ b/compiler/rustc_target/src/abi/call/nvptx64.rs
diff --git a/src/librustc_target/abi/call/powerpc.rs b/compiler/rustc_target/src/abi/call/powerpc.rs
index 27a5c6d2fc6..27a5c6d2fc6 100644
--- a/src/librustc_target/abi/call/powerpc.rs
+++ b/compiler/rustc_target/src/abi/call/powerpc.rs
diff --git a/src/librustc_target/abi/call/powerpc64.rs b/compiler/rustc_target/src/abi/call/powerpc64.rs
index b740707320f..b740707320f 100644
--- a/src/librustc_target/abi/call/powerpc64.rs
+++ b/compiler/rustc_target/src/abi/call/powerpc64.rs
diff --git a/src/librustc_target/abi/call/riscv.rs b/compiler/rustc_target/src/abi/call/riscv.rs
index 2e10bed3bd4..2e10bed3bd4 100644
--- a/src/librustc_target/abi/call/riscv.rs
+++ b/compiler/rustc_target/src/abi/call/riscv.rs
diff --git a/src/librustc_target/abi/call/s390x.rs b/compiler/rustc_target/src/abi/call/s390x.rs
index 005dcc62dfd..005dcc62dfd 100644
--- a/src/librustc_target/abi/call/s390x.rs
+++ b/compiler/rustc_target/src/abi/call/s390x.rs
diff --git a/src/librustc_target/abi/call/sparc.rs b/compiler/rustc_target/src/abi/call/sparc.rs
index 733a7328bd3..733a7328bd3 100644
--- a/src/librustc_target/abi/call/sparc.rs
+++ b/compiler/rustc_target/src/abi/call/sparc.rs
diff --git a/src/librustc_target/abi/call/sparc64.rs b/compiler/rustc_target/src/abi/call/sparc64.rs
index a647675e073..a647675e073 100644
--- a/src/librustc_target/abi/call/sparc64.rs
+++ b/compiler/rustc_target/src/abi/call/sparc64.rs
diff --git a/src/librustc_target/abi/call/wasm32.rs b/compiler/rustc_target/src/abi/call/wasm32.rs
index 510f671a501..510f671a501 100644
--- a/src/librustc_target/abi/call/wasm32.rs
+++ b/compiler/rustc_target/src/abi/call/wasm32.rs
diff --git a/src/librustc_target/abi/call/wasm32_bindgen_compat.rs b/compiler/rustc_target/src/abi/call/wasm32_bindgen_compat.rs
index 59571fd9d48..59571fd9d48 100644
--- a/src/librustc_target/abi/call/wasm32_bindgen_compat.rs
+++ b/compiler/rustc_target/src/abi/call/wasm32_bindgen_compat.rs
diff --git a/src/librustc_target/abi/call/x86.rs b/compiler/rustc_target/src/abi/call/x86.rs
index df3dd5d9208..df3dd5d9208 100644
--- a/src/librustc_target/abi/call/x86.rs
+++ b/compiler/rustc_target/src/abi/call/x86.rs
diff --git a/src/librustc_target/abi/call/x86_64.rs b/compiler/rustc_target/src/abi/call/x86_64.rs
index 5f154dc1bc9..5f154dc1bc9 100644
--- a/src/librustc_target/abi/call/x86_64.rs
+++ b/compiler/rustc_target/src/abi/call/x86_64.rs
diff --git a/src/librustc_target/abi/call/x86_win64.rs b/compiler/rustc_target/src/abi/call/x86_win64.rs
index 2aad641b1ec..2aad641b1ec 100644
--- a/src/librustc_target/abi/call/x86_win64.rs
+++ b/compiler/rustc_target/src/abi/call/x86_win64.rs
diff --git a/src/librustc_target/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs
index 4b565dd246f..4b565dd246f 100644
--- a/src/librustc_target/abi/mod.rs
+++ b/compiler/rustc_target/src/abi/mod.rs
diff --git a/src/librustc_target/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs
index e7c9edea765..e7c9edea765 100644
--- a/src/librustc_target/asm/aarch64.rs
+++ b/compiler/rustc_target/src/asm/aarch64.rs
diff --git a/src/librustc_target/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs
index 85a136b94aa..85a136b94aa 100644
--- a/src/librustc_target/asm/arm.rs
+++ b/compiler/rustc_target/src/asm/arm.rs
diff --git a/src/librustc_target/asm/hexagon.rs b/compiler/rustc_target/src/asm/hexagon.rs
index d41941d0b4c..d41941d0b4c 100644
--- a/src/librustc_target/asm/hexagon.rs
+++ b/compiler/rustc_target/src/asm/hexagon.rs
diff --git a/src/librustc_target/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index c22644bf813..c22644bf813 100644
--- a/src/librustc_target/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
diff --git a/src/librustc_target/asm/nvptx.rs b/compiler/rustc_target/src/asm/nvptx.rs
index 43d16ae0f5d..43d16ae0f5d 100644
--- a/src/librustc_target/asm/nvptx.rs
+++ b/compiler/rustc_target/src/asm/nvptx.rs
diff --git a/src/librustc_target/asm/riscv.rs b/compiler/rustc_target/src/asm/riscv.rs
index ced7483b005..ced7483b005 100644
--- a/src/librustc_target/asm/riscv.rs
+++ b/compiler/rustc_target/src/asm/riscv.rs
diff --git a/src/librustc_target/asm/x86.rs b/compiler/rustc_target/src/asm/x86.rs
index 0f62c19e1a3..0f62c19e1a3 100644
--- a/src/librustc_target/asm/x86.rs
+++ b/compiler/rustc_target/src/asm/x86.rs
diff --git a/src/librustc_target/lib.rs b/compiler/rustc_target/src/lib.rs
index 5788e1e8385..5788e1e8385 100644
--- a/src/librustc_target/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
diff --git a/src/librustc_target/spec/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs
index 60daf10b36a..60daf10b36a 100644
--- a/src/librustc_target/spec/aarch64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs
diff --git a/src/librustc_target/spec/aarch64_apple_ios.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs
index 21dcec8d5e3..21dcec8d5e3 100644
--- a/src/librustc_target/spec/aarch64_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs
diff --git a/src/librustc_target/spec/aarch64_apple_tvos.rs b/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs
index 2b0cd6cabf8..2b0cd6cabf8 100644
--- a/src/librustc_target/spec/aarch64_apple_tvos.rs
+++ b/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs
diff --git a/src/librustc_target/spec/aarch64_fuchsia.rs b/compiler/rustc_target/src/spec/aarch64_fuchsia.rs
index aabfe458ca3..aabfe458ca3 100644
--- a/src/librustc_target/spec/aarch64_fuchsia.rs
+++ b/compiler/rustc_target/src/spec/aarch64_fuchsia.rs
diff --git a/src/librustc_target/spec/aarch64_linux_android.rs b/compiler/rustc_target/src/spec/aarch64_linux_android.rs
index e4ecc7ac2dc..e4ecc7ac2dc 100644
--- a/src/librustc_target/spec/aarch64_linux_android.rs
+++ b/compiler/rustc_target/src/spec/aarch64_linux_android.rs
diff --git a/src/librustc_target/spec/aarch64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs
index 8c03f1e8a7e..8c03f1e8a7e 100644
--- a/src/librustc_target/spec/aarch64_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs
diff --git a/src/librustc_target/spec/aarch64_unknown_cloudabi.rs b/compiler/rustc_target/src/spec/aarch64_unknown_cloudabi.rs
index 1278b89c7fd..1278b89c7fd 100644
--- a/src/librustc_target/spec/aarch64_unknown_cloudabi.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_cloudabi.rs
diff --git a/src/librustc_target/spec/aarch64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs
index 5ae592c5139..5ae592c5139 100644
--- a/src/librustc_target/spec/aarch64_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs
diff --git a/src/librustc_target/spec/aarch64_unknown_hermit.rs b/compiler/rustc_target/src/spec/aarch64_unknown_hermit.rs
index e07b8f7a756..e07b8f7a756 100644
--- a/src/librustc_target/spec/aarch64_unknown_hermit.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_hermit.rs
diff --git a/src/librustc_target/spec/aarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs
index 036162248c7..036162248c7 100644
--- a/src/librustc_target/spec/aarch64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs
diff --git a/src/librustc_target/spec/aarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs
index dc613f35d1d..dc613f35d1d 100644
--- a/src/librustc_target/spec/aarch64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs
diff --git a/src/librustc_target/spec/aarch64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/aarch64_unknown_netbsd.rs
index 8c2f6fcff73..8c2f6fcff73 100644
--- a/src/librustc_target/spec/aarch64_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_netbsd.rs
diff --git a/src/librustc_target/spec/aarch64_unknown_none.rs b/compiler/rustc_target/src/spec/aarch64_unknown_none.rs
index e012dce73fe..e012dce73fe 100644
--- a/src/librustc_target/spec/aarch64_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_none.rs
diff --git a/src/librustc_target/spec/aarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs
index e2aa6e3b8f5..e2aa6e3b8f5 100644
--- a/src/librustc_target/spec/aarch64_unknown_none_softfloat.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs
diff --git a/src/librustc_target/spec/aarch64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/aarch64_unknown_openbsd.rs
index fd726c70f49..fd726c70f49 100644
--- a/src/librustc_target/spec/aarch64_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_openbsd.rs
diff --git a/src/librustc_target/spec/aarch64_unknown_redox.rs b/compiler/rustc_target/src/spec/aarch64_unknown_redox.rs
index f347a2dba53..f347a2dba53 100644
--- a/src/librustc_target/spec/aarch64_unknown_redox.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_redox.rs
diff --git a/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs
index 6a8d148259a..6a8d148259a 100644
--- a/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs
diff --git a/src/librustc_target/spec/aarch64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/aarch64_wrs_vxworks.rs
index 05f5d7d3a8b..05f5d7d3a8b 100644
--- a/src/librustc_target/spec/aarch64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/aarch64_wrs_vxworks.rs
diff --git a/src/librustc_target/spec/abi.rs b/compiler/rustc_target/src/spec/abi.rs
index 1e45739ca22..1e45739ca22 100644
--- a/src/librustc_target/spec/abi.rs
+++ b/compiler/rustc_target/src/spec/abi.rs
diff --git a/src/librustc_target/spec/abi/tests.rs b/compiler/rustc_target/src/spec/abi/tests.rs
index 8bea5e5efe3..8bea5e5efe3 100644
--- a/src/librustc_target/spec/abi/tests.rs
+++ b/compiler/rustc_target/src/spec/abi/tests.rs
diff --git a/src/librustc_target/spec/android_base.rs b/compiler/rustc_target/src/spec/android_base.rs
index 0ea99af83a1..0ea99af83a1 100644
--- a/src/librustc_target/spec/android_base.rs
+++ b/compiler/rustc_target/src/spec/android_base.rs
diff --git a/src/librustc_target/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs
index e7b565ae9ca..e7b565ae9ca 100644
--- a/src/librustc_target/spec/apple_base.rs
+++ b/compiler/rustc_target/src/spec/apple_base.rs
diff --git a/src/librustc_target/spec/apple_sdk_base.rs b/compiler/rustc_target/src/spec/apple_sdk_base.rs
index 0d0a0da9d1c..0d0a0da9d1c 100644
--- a/src/librustc_target/spec/apple_sdk_base.rs
+++ b/compiler/rustc_target/src/spec/apple_sdk_base.rs
diff --git a/src/librustc_target/spec/arm_base.rs b/compiler/rustc_target/src/spec/arm_base.rs
index b74d80dc6bb..b74d80dc6bb 100644
--- a/src/librustc_target/spec/arm_base.rs
+++ b/compiler/rustc_target/src/spec/arm_base.rs
diff --git a/src/librustc_target/spec/arm_linux_androideabi.rs b/compiler/rustc_target/src/spec/arm_linux_androideabi.rs
index 7109d043f51..7109d043f51 100644
--- a/src/librustc_target/spec/arm_linux_androideabi.rs
+++ b/compiler/rustc_target/src/spec/arm_linux_androideabi.rs
diff --git a/src/librustc_target/spec/arm_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs
index 2e3bad83e25..2e3bad83e25 100644
--- a/src/librustc_target/spec/arm_unknown_linux_gnueabi.rs
+++ b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs
diff --git a/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs
index f8e357cce66..f8e357cce66 100644
--- a/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs
+++ b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs
diff --git a/src/librustc_target/spec/arm_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs
index 75753af9f30..75753af9f30 100644
--- a/src/librustc_target/spec/arm_unknown_linux_musleabi.rs
+++ b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs
diff --git a/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs
index c74c88e3612..c74c88e3612 100644
--- a/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs
+++ b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs
diff --git a/src/librustc_target/spec/armebv7r_none_eabi.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs
index e0d1f2653ce..e0d1f2653ce 100644
--- a/src/librustc_target/spec/armebv7r_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs
diff --git a/src/librustc_target/spec/armebv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs
index e2d37d45bf1..e2d37d45bf1 100644
--- a/src/librustc_target/spec/armebv7r_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs
diff --git a/src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs
index 2580e8b0f85..2580e8b0f85 100644
--- a/src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs
+++ b/compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs
diff --git a/src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs
index f28421dc775..f28421dc775 100644
--- a/src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs
+++ b/compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs
diff --git a/src/librustc_target/spec/armv5te_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs
index fe1fa88883d..fe1fa88883d 100644
--- a/src/librustc_target/spec/armv5te_unknown_linux_musleabi.rs
+++ b/compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs
diff --git a/src/librustc_target/spec/armv6_unknown_freebsd.rs b/compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs
index 1e06f837997..1e06f837997 100644
--- a/src/librustc_target/spec/armv6_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs
diff --git a/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs
index ef40085888c..ef40085888c 100644
--- a/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs
diff --git a/src/librustc_target/spec/armv7_apple_ios.rs b/compiler/rustc_target/src/spec/armv7_apple_ios.rs
index 393843526a8..393843526a8 100644
--- a/src/librustc_target/spec/armv7_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/armv7_apple_ios.rs
diff --git a/src/librustc_target/spec/armv7_linux_androideabi.rs b/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs
index 38c6c31bd10..38c6c31bd10 100644
--- a/src/librustc_target/spec/armv7_linux_androideabi.rs
+++ b/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs
diff --git a/src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_cloudabi_eabihf.rs
index e3f4fe0b2ef..e3f4fe0b2ef 100644
--- a/src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7_unknown_cloudabi_eabihf.rs
diff --git a/src/librustc_target/spec/armv7_unknown_freebsd.rs b/compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs
index 80a9e6d7e3c..80a9e6d7e3c 100644
--- a/src/librustc_target/spec/armv7_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs
diff --git a/src/librustc_target/spec/armv7_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs
index 0f175e9aef5..0f175e9aef5 100644
--- a/src/librustc_target/spec/armv7_unknown_linux_gnueabi.rs
+++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs
diff --git a/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs
index 27923457cd1..27923457cd1 100644
--- a/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs
diff --git a/src/librustc_target/spec/armv7_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs
index 3d1bf05237f..3d1bf05237f 100644
--- a/src/librustc_target/spec/armv7_unknown_linux_musleabi.rs
+++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs
diff --git a/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs
index 03d7d88b0d6..03d7d88b0d6 100644
--- a/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs
diff --git a/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs
index 18fc9ed2ec6..18fc9ed2ec6 100644
--- a/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs
diff --git a/src/librustc_target/spec/armv7_wrs_vxworks_eabihf.rs b/compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs
index 04d8702471a..04d8702471a 100644
--- a/src/librustc_target/spec/armv7_wrs_vxworks_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs
diff --git a/src/librustc_target/spec/armv7a_none_eabi.rs b/compiler/rustc_target/src/spec/armv7a_none_eabi.rs
index 1db279defff..1db279defff 100644
--- a/src/librustc_target/spec/armv7a_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/armv7a_none_eabi.rs
diff --git a/src/librustc_target/spec/armv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs
index 22c2b306b43..22c2b306b43 100644
--- a/src/librustc_target/spec/armv7a_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs
diff --git a/src/librustc_target/spec/armv7r_none_eabi.rs b/compiler/rustc_target/src/spec/armv7r_none_eabi.rs
index fed83997190..fed83997190 100644
--- a/src/librustc_target/spec/armv7r_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/armv7r_none_eabi.rs
diff --git a/src/librustc_target/spec/armv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs
index 769ac13e515..769ac13e515 100644
--- a/src/librustc_target/spec/armv7r_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs
diff --git a/src/librustc_target/spec/armv7s_apple_ios.rs b/compiler/rustc_target/src/spec/armv7s_apple_ios.rs
index 998a7b2e164..998a7b2e164 100644
--- a/src/librustc_target/spec/armv7s_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/armv7s_apple_ios.rs
diff --git a/src/librustc_target/spec/asmjs_unknown_emscripten.rs b/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs
index d3dbc39c99d..d3dbc39c99d 100644
--- a/src/librustc_target/spec/asmjs_unknown_emscripten.rs
+++ b/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs
diff --git a/src/librustc_target/spec/avr_gnu_base.rs b/compiler/rustc_target/src/spec/avr_gnu_base.rs
index ff559c2bfd6..ff559c2bfd6 100644
--- a/src/librustc_target/spec/avr_gnu_base.rs
+++ b/compiler/rustc_target/src/spec/avr_gnu_base.rs
diff --git a/src/librustc_target/spec/avr_unknown_gnu_atmega328.rs b/compiler/rustc_target/src/spec/avr_unknown_gnu_atmega328.rs
index 5d22598b57b..5d22598b57b 100644
--- a/src/librustc_target/spec/avr_unknown_gnu_atmega328.rs
+++ b/compiler/rustc_target/src/spec/avr_unknown_gnu_atmega328.rs
diff --git a/src/librustc_target/spec/cloudabi_base.rs b/compiler/rustc_target/src/spec/cloudabi_base.rs
index 39039435f58..39039435f58 100644
--- a/src/librustc_target/spec/cloudabi_base.rs
+++ b/compiler/rustc_target/src/spec/cloudabi_base.rs
diff --git a/src/librustc_target/spec/crt_objects.rs b/compiler/rustc_target/src/spec/crt_objects.rs
index 8991691a9a3..8991691a9a3 100644
--- a/src/librustc_target/spec/crt_objects.rs
+++ b/compiler/rustc_target/src/spec/crt_objects.rs
diff --git a/src/librustc_target/spec/dragonfly_base.rs b/compiler/rustc_target/src/spec/dragonfly_base.rs
index c7062e1ca51..c7062e1ca51 100644
--- a/src/librustc_target/spec/dragonfly_base.rs
+++ b/compiler/rustc_target/src/spec/dragonfly_base.rs
diff --git a/src/librustc_target/spec/freebsd_base.rs b/compiler/rustc_target/src/spec/freebsd_base.rs
index d2a087ab62f..d2a087ab62f 100644
--- a/src/librustc_target/spec/freebsd_base.rs
+++ b/compiler/rustc_target/src/spec/freebsd_base.rs
diff --git a/src/librustc_target/spec/fuchsia_base.rs b/compiler/rustc_target/src/spec/fuchsia_base.rs
index 6f432dc1171..6f432dc1171 100644
--- a/src/librustc_target/spec/fuchsia_base.rs
+++ b/compiler/rustc_target/src/spec/fuchsia_base.rs
diff --git a/src/librustc_target/spec/haiku_base.rs b/compiler/rustc_target/src/spec/haiku_base.rs
index 3d7ae6c302d..3d7ae6c302d 100644
--- a/src/librustc_target/spec/haiku_base.rs
+++ b/compiler/rustc_target/src/spec/haiku_base.rs
diff --git a/src/librustc_target/spec/hermit_base.rs b/compiler/rustc_target/src/spec/hermit_base.rs
index e063c94cf2c..e063c94cf2c 100644
--- a/src/librustc_target/spec/hermit_base.rs
+++ b/compiler/rustc_target/src/spec/hermit_base.rs
diff --git a/src/librustc_target/spec/hermit_kernel_base.rs b/compiler/rustc_target/src/spec/hermit_kernel_base.rs
index 01b9f75637f..01b9f75637f 100644
--- a/src/librustc_target/spec/hermit_kernel_base.rs
+++ b/compiler/rustc_target/src/spec/hermit_kernel_base.rs
diff --git a/src/librustc_target/spec/hexagon_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs
index 0976acb4fb0..0976acb4fb0 100644
--- a/src/librustc_target/spec/hexagon_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs
diff --git a/src/librustc_target/spec/i386_apple_ios.rs b/compiler/rustc_target/src/spec/i386_apple_ios.rs
index a121d49769d..a121d49769d 100644
--- a/src/librustc_target/spec/i386_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/i386_apple_ios.rs
diff --git a/src/librustc_target/spec/i586_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/i586_pc_windows_msvc.rs
index ba712aced84..ba712aced84 100644
--- a/src/librustc_target/spec/i586_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/i586_pc_windows_msvc.rs
diff --git a/src/librustc_target/spec/i586_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/i586_unknown_linux_gnu.rs
index 49f4f2cb6b9..49f4f2cb6b9 100644
--- a/src/librustc_target/spec/i586_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/i586_unknown_linux_gnu.rs
diff --git a/src/librustc_target/spec/i586_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/i586_unknown_linux_musl.rs
index 0f2ccebd6da..0f2ccebd6da 100644
--- a/src/librustc_target/spec/i586_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/i586_unknown_linux_musl.rs
diff --git a/src/librustc_target/spec/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/i686_apple_darwin.rs
index b7a34f9740a..b7a34f9740a 100644
--- a/src/librustc_target/spec/i686_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/i686_apple_darwin.rs
diff --git a/src/librustc_target/spec/i686_linux_android.rs b/compiler/rustc_target/src/spec/i686_linux_android.rs
index 79242f24026..79242f24026 100644
--- a/src/librustc_target/spec/i686_linux_android.rs
+++ b/compiler/rustc_target/src/spec/i686_linux_android.rs
diff --git a/src/librustc_target/spec/i686_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs
index 33c9008bb14..33c9008bb14 100644
--- a/src/librustc_target/spec/i686_pc_windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs
diff --git a/src/librustc_target/spec/i686_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs
index 9d0922b8ce5..9d0922b8ce5 100644
--- a/src/librustc_target/spec/i686_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs
diff --git a/src/librustc_target/spec/i686_unknown_cloudabi.rs b/compiler/rustc_target/src/spec/i686_unknown_cloudabi.rs
index 729b1f68e00..729b1f68e00 100644
--- a/src/librustc_target/spec/i686_unknown_cloudabi.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_cloudabi.rs
diff --git a/src/librustc_target/spec/i686_unknown_freebsd.rs b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs
index 60f2188514e..60f2188514e 100644
--- a/src/librustc_target/spec/i686_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs
diff --git a/src/librustc_target/spec/i686_unknown_haiku.rs b/compiler/rustc_target/src/spec/i686_unknown_haiku.rs
index 4dc27af30da..4dc27af30da 100644
--- a/src/librustc_target/spec/i686_unknown_haiku.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_haiku.rs
diff --git a/src/librustc_target/spec/i686_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs
index 0d578f22f98..0d578f22f98 100644
--- a/src/librustc_target/spec/i686_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs
diff --git a/src/librustc_target/spec/i686_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs
index 699a0ab45e8..699a0ab45e8 100644
--- a/src/librustc_target/spec/i686_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs
diff --git a/src/librustc_target/spec/i686_unknown_netbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs
index 88b1ae7d53c..88b1ae7d53c 100644
--- a/src/librustc_target/spec/i686_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs
diff --git a/src/librustc_target/spec/i686_unknown_openbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs
index 829cd1ac1a3..829cd1ac1a3 100644
--- a/src/librustc_target/spec/i686_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs
diff --git a/src/librustc_target/spec/i686_unknown_uefi.rs b/compiler/rustc_target/src/spec/i686_unknown_uefi.rs
index 221d5f0785c..221d5f0785c 100644
--- a/src/librustc_target/spec/i686_unknown_uefi.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_uefi.rs
diff --git a/src/librustc_target/spec/i686_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs
index 1c6d2e061bc..1c6d2e061bc 100644
--- a/src/librustc_target/spec/i686_uwp_windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs
diff --git a/src/librustc_target/spec/i686_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/i686_uwp_windows_msvc.rs
index ed2dba53589..ed2dba53589 100644
--- a/src/librustc_target/spec/i686_uwp_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/i686_uwp_windows_msvc.rs
diff --git a/src/librustc_target/spec/i686_wrs_vxworks.rs b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs
index f5f66cabb2c..f5f66cabb2c 100644
--- a/src/librustc_target/spec/i686_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs
diff --git a/src/librustc_target/spec/illumos_base.rs b/compiler/rustc_target/src/spec/illumos_base.rs
index 214142b88fc..214142b88fc 100644
--- a/src/librustc_target/spec/illumos_base.rs
+++ b/compiler/rustc_target/src/spec/illumos_base.rs
diff --git a/src/librustc_target/spec/l4re_base.rs b/compiler/rustc_target/src/spec/l4re_base.rs
index 5caad10161d..5caad10161d 100644
--- a/src/librustc_target/spec/l4re_base.rs
+++ b/compiler/rustc_target/src/spec/l4re_base.rs
diff --git a/src/librustc_target/spec/linux_base.rs b/compiler/rustc_target/src/spec/linux_base.rs
index 52892fc3592..52892fc3592 100644
--- a/src/librustc_target/spec/linux_base.rs
+++ b/compiler/rustc_target/src/spec/linux_base.rs
diff --git a/src/librustc_target/spec/linux_kernel_base.rs b/compiler/rustc_target/src/spec/linux_kernel_base.rs
index 6d929d12447..6d929d12447 100644
--- a/src/librustc_target/spec/linux_kernel_base.rs
+++ b/compiler/rustc_target/src/spec/linux_kernel_base.rs
diff --git a/src/librustc_target/spec/linux_musl_base.rs b/compiler/rustc_target/src/spec/linux_musl_base.rs
index b90e91d2901..b90e91d2901 100644
--- a/src/librustc_target/spec/linux_musl_base.rs
+++ b/compiler/rustc_target/src/spec/linux_musl_base.rs
diff --git a/src/librustc_target/spec/mips64_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs
index b2ea8a6f388..b2ea8a6f388 100644
--- a/src/librustc_target/spec/mips64_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs
diff --git a/src/librustc_target/spec/mips64_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs
index 17584de1144..17584de1144 100644
--- a/src/librustc_target/spec/mips64_unknown_linux_muslabi64.rs
+++ b/compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs
diff --git a/src/librustc_target/spec/mips64el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs
index 48aea4a39b0..48aea4a39b0 100644
--- a/src/librustc_target/spec/mips64el_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs
diff --git a/src/librustc_target/spec/mips64el_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/mips64el_unknown_linux_muslabi64.rs
index c7a849a1641..c7a849a1641 100644
--- a/src/librustc_target/spec/mips64el_unknown_linux_muslabi64.rs
+++ b/compiler/rustc_target/src/spec/mips64el_unknown_linux_muslabi64.rs
diff --git a/src/librustc_target/spec/mips_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs
index e360abdb38d..e360abdb38d 100644
--- a/src/librustc_target/spec/mips_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs
diff --git a/src/librustc_target/spec/mips_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/mips_unknown_linux_musl.rs
index c8d97e600d4..c8d97e600d4 100644
--- a/src/librustc_target/spec/mips_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/mips_unknown_linux_musl.rs
diff --git a/src/librustc_target/spec/mips_unknown_linux_uclibc.rs b/compiler/rustc_target/src/spec/mips_unknown_linux_uclibc.rs
index 8116b8c9cc8..8116b8c9cc8 100644
--- a/src/librustc_target/spec/mips_unknown_linux_uclibc.rs
+++ b/compiler/rustc_target/src/spec/mips_unknown_linux_uclibc.rs
diff --git a/src/librustc_target/spec/mipsel_sony_psp.rs b/compiler/rustc_target/src/spec/mipsel_sony_psp.rs
index b3bda97c8a5..b3bda97c8a5 100644
--- a/src/librustc_target/spec/mipsel_sony_psp.rs
+++ b/compiler/rustc_target/src/spec/mipsel_sony_psp.rs
diff --git a/src/librustc_target/spec/mipsel_sony_psp_linker_script.ld b/compiler/rustc_target/src/spec/mipsel_sony_psp_linker_script.ld
index 1bd436d6f94..1bd436d6f94 100644
--- a/src/librustc_target/spec/mipsel_sony_psp_linker_script.ld
+++ b/compiler/rustc_target/src/spec/mipsel_sony_psp_linker_script.ld
diff --git a/src/librustc_target/spec/mipsel_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/mipsel_unknown_linux_gnu.rs
index 7e9d8cd942a..7e9d8cd942a 100644
--- a/src/librustc_target/spec/mipsel_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/mipsel_unknown_linux_gnu.rs
diff --git a/src/librustc_target/spec/mipsel_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/mipsel_unknown_linux_musl.rs
index f70cc13224f..f70cc13224f 100644
--- a/src/librustc_target/spec/mipsel_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/mipsel_unknown_linux_musl.rs
diff --git a/src/librustc_target/spec/mipsel_unknown_linux_uclibc.rs b/compiler/rustc_target/src/spec/mipsel_unknown_linux_uclibc.rs
index a8152011efa..a8152011efa 100644
--- a/src/librustc_target/spec/mipsel_unknown_linux_uclibc.rs
+++ b/compiler/rustc_target/src/spec/mipsel_unknown_linux_uclibc.rs
diff --git a/src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/mipsisa32r6_unknown_linux_gnu.rs
index 36b83c63fca..36b83c63fca 100644
--- a/src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/mipsisa32r6_unknown_linux_gnu.rs
diff --git a/src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/mipsisa32r6el_unknown_linux_gnu.rs
index 717ae3f1d20..717ae3f1d20 100644
--- a/src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/mipsisa32r6el_unknown_linux_gnu.rs
diff --git a/src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs
index 3f7d233e55f..3f7d233e55f 100644
--- a/src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs
diff --git a/src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs
index 4f41b8323a9..4f41b8323a9 100644
--- a/src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs
diff --git a/src/librustc_target/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index d6e8b304380..d6e8b304380 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
diff --git a/src/librustc_target/spec/msp430_none_elf.rs b/compiler/rustc_target/src/spec/msp430_none_elf.rs
index f75697996ac..f75697996ac 100644
--- a/src/librustc_target/spec/msp430_none_elf.rs
+++ b/compiler/rustc_target/src/spec/msp430_none_elf.rs
diff --git a/src/librustc_target/spec/msvc_base.rs b/compiler/rustc_target/src/spec/msvc_base.rs
index f57ef87cf12..f57ef87cf12 100644
--- a/src/librustc_target/spec/msvc_base.rs
+++ b/compiler/rustc_target/src/spec/msvc_base.rs
diff --git a/src/librustc_target/spec/netbsd_base.rs b/compiler/rustc_target/src/spec/netbsd_base.rs
index 988346af2d7..988346af2d7 100644
--- a/src/librustc_target/spec/netbsd_base.rs
+++ b/compiler/rustc_target/src/spec/netbsd_base.rs
diff --git a/src/librustc_target/spec/nvptx64_nvidia_cuda.rs b/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs
index 0c8f2a34301..0c8f2a34301 100644
--- a/src/librustc_target/spec/nvptx64_nvidia_cuda.rs
+++ b/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs
diff --git a/src/librustc_target/spec/openbsd_base.rs b/compiler/rustc_target/src/spec/openbsd_base.rs
index cadd14df693..cadd14df693 100644
--- a/src/librustc_target/spec/openbsd_base.rs
+++ b/compiler/rustc_target/src/spec/openbsd_base.rs
diff --git a/src/librustc_target/spec/powerpc64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs
index 60c15d6b7d2..60c15d6b7d2 100644
--- a/src/librustc_target/spec/powerpc64_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs
diff --git a/src/librustc_target/spec/powerpc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs
index 5306d905c5d..5306d905c5d 100644
--- a/src/librustc_target/spec/powerpc64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs
diff --git a/src/librustc_target/spec/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs
index c3b956effae..c3b956effae 100644
--- a/src/librustc_target/spec/powerpc64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs
diff --git a/src/librustc_target/spec/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs
index e00a927c3a4..e00a927c3a4 100644
--- a/src/librustc_target/spec/powerpc64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs
diff --git a/src/librustc_target/spec/powerpc64le_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs
index 90737994612..90737994612 100644
--- a/src/librustc_target/spec/powerpc64le_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs
diff --git a/src/librustc_target/spec/powerpc64le_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs
index 1a1fccfab02..1a1fccfab02 100644
--- a/src/librustc_target/spec/powerpc64le_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs
diff --git a/src/librustc_target/spec/powerpc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs
index 2d4c5986637..2d4c5986637 100644
--- a/src/librustc_target/spec/powerpc_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs
diff --git a/src/librustc_target/spec/powerpc_unknown_linux_gnuspe.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs
index fabc4313bee..fabc4313bee 100644
--- a/src/librustc_target/spec/powerpc_unknown_linux_gnuspe.rs
+++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs
diff --git a/src/librustc_target/spec/powerpc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs
index 240cbcbfe6e..240cbcbfe6e 100644
--- a/src/librustc_target/spec/powerpc_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs
diff --git a/src/librustc_target/spec/powerpc_unknown_netbsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs
index 6ca7053ced5..6ca7053ced5 100644
--- a/src/librustc_target/spec/powerpc_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs
diff --git a/src/librustc_target/spec/powerpc_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs
index 2211dc29a5d..2211dc29a5d 100644
--- a/src/librustc_target/spec/powerpc_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs
diff --git a/src/librustc_target/spec/powerpc_wrs_vxworks_spe.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs
index b10182c09ad..b10182c09ad 100644
--- a/src/librustc_target/spec/powerpc_wrs_vxworks_spe.rs
+++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs
diff --git a/src/librustc_target/spec/redox_base.rs b/compiler/rustc_target/src/spec/redox_base.rs
index 18cafe654d1..18cafe654d1 100644
--- a/src/librustc_target/spec/redox_base.rs
+++ b/compiler/rustc_target/src/spec/redox_base.rs
diff --git a/src/librustc_target/spec/riscv32i_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv32i_unknown_none_elf.rs
index 5b5e342000b..5b5e342000b 100644
--- a/src/librustc_target/spec/riscv32i_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/riscv32i_unknown_none_elf.rs
diff --git a/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv32imac_unknown_none_elf.rs
index 4cef5c42d8d..4cef5c42d8d 100644
--- a/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/riscv32imac_unknown_none_elf.rs
diff --git a/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv32imc_unknown_none_elf.rs
index 8ad563e441d..8ad563e441d 100644
--- a/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/riscv32imc_unknown_none_elf.rs
diff --git a/src/librustc_target/spec/riscv64gc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs
index f7a93c916d1..f7a93c916d1 100644
--- a/src/librustc_target/spec/riscv64gc_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs
diff --git a/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs
index 3aeb3f3ca72..3aeb3f3ca72 100644
--- a/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs
diff --git a/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs
index d8144964dc9..d8144964dc9 100644
--- a/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs
diff --git a/src/librustc_target/spec/riscv_base.rs b/compiler/rustc_target/src/spec/riscv_base.rs
index 64cf890037e..64cf890037e 100644
--- a/src/librustc_target/spec/riscv_base.rs
+++ b/compiler/rustc_target/src/spec/riscv_base.rs
diff --git a/src/librustc_target/spec/s390x_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs
index f259787e1d5..f259787e1d5 100644
--- a/src/librustc_target/spec/s390x_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs
diff --git a/src/librustc_target/spec/solaris_base.rs b/compiler/rustc_target/src/spec/solaris_base.rs
index 3d7f0034b8b..3d7f0034b8b 100644
--- a/src/librustc_target/spec/solaris_base.rs
+++ b/compiler/rustc_target/src/spec/solaris_base.rs
diff --git a/src/librustc_target/spec/sparc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/sparc64_unknown_linux_gnu.rs
index c842b22d4e1..c842b22d4e1 100644
--- a/src/librustc_target/spec/sparc64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/sparc64_unknown_linux_gnu.rs
diff --git a/src/librustc_target/spec/sparc64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs
index aad85e852f0..aad85e852f0 100644
--- a/src/librustc_target/spec/sparc64_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs
diff --git a/src/librustc_target/spec/sparc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs
index 229e0621e0d..229e0621e0d 100644
--- a/src/librustc_target/spec/sparc64_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs
diff --git a/src/librustc_target/spec/sparc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs
index 162cd311a38..162cd311a38 100644
--- a/src/librustc_target/spec/sparc_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs
diff --git a/src/librustc_target/spec/sparcv9_sun_solaris.rs b/compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs
index acc03fd0d79..acc03fd0d79 100644
--- a/src/librustc_target/spec/sparcv9_sun_solaris.rs
+++ b/compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs
diff --git a/src/librustc_target/spec/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs
index b2c2b8254d8..b2c2b8254d8 100644
--- a/src/librustc_target/spec/tests/tests_impl.rs
+++ b/compiler/rustc_target/src/spec/tests/tests_impl.rs
diff --git a/src/librustc_target/spec/thumb_base.rs b/compiler/rustc_target/src/spec/thumb_base.rs
index 2f7d15d5856..2f7d15d5856 100644
--- a/src/librustc_target/spec/thumb_base.rs
+++ b/compiler/rustc_target/src/spec/thumb_base.rs
diff --git a/src/librustc_target/spec/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs
index a8c78f057fc..a8c78f057fc 100644
--- a/src/librustc_target/spec/thumbv4t_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs
diff --git a/src/librustc_target/spec/thumbv6m_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs
index 953d60fcc22..953d60fcc22 100644
--- a/src/librustc_target/spec/thumbv6m_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs
diff --git a/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs
index 37828026fe1..37828026fe1 100644
--- a/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs
diff --git a/src/librustc_target/spec/thumbv7a_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/thumbv7a_uwp_windows_msvc.rs
index 29a4a9875e5..29a4a9875e5 100644
--- a/src/librustc_target/spec/thumbv7a_uwp_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/thumbv7a_uwp_windows_msvc.rs
diff --git a/src/librustc_target/spec/thumbv7em_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv7em_none_eabi.rs
index 9e085381953..9e085381953 100644
--- a/src/librustc_target/spec/thumbv7em_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv7em_none_eabi.rs
diff --git a/src/librustc_target/spec/thumbv7em_none_eabihf.rs b/compiler/rustc_target/src/spec/thumbv7em_none_eabihf.rs
index 95b9b9d5b56..95b9b9d5b56 100644
--- a/src/librustc_target/spec/thumbv7em_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/thumbv7em_none_eabihf.rs
diff --git a/src/librustc_target/spec/thumbv7m_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv7m_none_eabi.rs
index 528359ffad3..528359ffad3 100644
--- a/src/librustc_target/spec/thumbv7m_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv7m_none_eabi.rs
diff --git a/src/librustc_target/spec/thumbv7neon_linux_androideabi.rs b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs
index c52f077f6f1..c52f077f6f1 100644
--- a/src/librustc_target/spec/thumbv7neon_linux_androideabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs
diff --git a/src/librustc_target/spec/thumbv7neon_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs
index 78936948e64..78936948e64 100644
--- a/src/librustc_target/spec/thumbv7neon_unknown_linux_gnueabihf.rs
+++ b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs
diff --git a/src/librustc_target/spec/thumbv7neon_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs
index f759c3eeb01..f759c3eeb01 100644
--- a/src/librustc_target/spec/thumbv7neon_unknown_linux_musleabihf.rs
+++ b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs
diff --git a/src/librustc_target/spec/thumbv8m_base_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv8m_base_none_eabi.rs
index 3f67c67b7bc..3f67c67b7bc 100644
--- a/src/librustc_target/spec/thumbv8m_base_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv8m_base_none_eabi.rs
diff --git a/src/librustc_target/spec/thumbv8m_main_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv8m_main_none_eabi.rs
index 2f8103f0c70..2f8103f0c70 100644
--- a/src/librustc_target/spec/thumbv8m_main_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv8m_main_none_eabi.rs
diff --git a/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs b/compiler/rustc_target/src/spec/thumbv8m_main_none_eabihf.rs
index 53a340230d6..53a340230d6 100644
--- a/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/thumbv8m_main_none_eabihf.rs
diff --git a/src/librustc_target/spec/uefi_msvc_base.rs b/compiler/rustc_target/src/spec/uefi_msvc_base.rs
index 3f7c78c8e7d..3f7c78c8e7d 100644
--- a/src/librustc_target/spec/uefi_msvc_base.rs
+++ b/compiler/rustc_target/src/spec/uefi_msvc_base.rs
diff --git a/src/librustc_target/spec/vxworks_base.rs b/compiler/rustc_target/src/spec/vxworks_base.rs
index 777bb58d7db..777bb58d7db 100644
--- a/src/librustc_target/spec/vxworks_base.rs
+++ b/compiler/rustc_target/src/spec/vxworks_base.rs
diff --git a/src/librustc_target/spec/wasm32_base.rs b/compiler/rustc_target/src/spec/wasm32_base.rs
index 62fc8f06183..62fc8f06183 100644
--- a/src/librustc_target/spec/wasm32_base.rs
+++ b/compiler/rustc_target/src/spec/wasm32_base.rs
diff --git a/src/librustc_target/spec/wasm32_unknown_emscripten.rs b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs
index 1916639170e..1916639170e 100644
--- a/src/librustc_target/spec/wasm32_unknown_emscripten.rs
+++ b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs
diff --git a/src/librustc_target/spec/wasm32_unknown_unknown.rs b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs
index ded95a34d55..ded95a34d55 100644
--- a/src/librustc_target/spec/wasm32_unknown_unknown.rs
+++ b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs
diff --git a/src/librustc_target/spec/wasm32_wasi.rs b/compiler/rustc_target/src/spec/wasm32_wasi.rs
index 0bba7bdd473..0bba7bdd473 100644
--- a/src/librustc_target/spec/wasm32_wasi.rs
+++ b/compiler/rustc_target/src/spec/wasm32_wasi.rs
diff --git a/src/librustc_target/spec/windows_gnu_base.rs b/compiler/rustc_target/src/spec/windows_gnu_base.rs
index a864918655f..a864918655f 100644
--- a/src/librustc_target/spec/windows_gnu_base.rs
+++ b/compiler/rustc_target/src/spec/windows_gnu_base.rs
diff --git a/src/librustc_target/spec/windows_msvc_base.rs b/compiler/rustc_target/src/spec/windows_msvc_base.rs
index 77171f8672e..77171f8672e 100644
--- a/src/librustc_target/spec/windows_msvc_base.rs
+++ b/compiler/rustc_target/src/spec/windows_msvc_base.rs
diff --git a/src/librustc_target/spec/windows_uwp_gnu_base.rs b/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs
index fd55a0fc6a1..fd55a0fc6a1 100644
--- a/src/librustc_target/spec/windows_uwp_gnu_base.rs
+++ b/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs
diff --git a/src/librustc_target/spec/windows_uwp_msvc_base.rs b/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs
index 04ffa1a0add..04ffa1a0add 100644
--- a/src/librustc_target/spec/windows_uwp_msvc_base.rs
+++ b/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs
diff --git a/src/librustc_target/spec/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
index 909aebec70b..909aebec70b 100644
--- a/src/librustc_target/spec/x86_64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
diff --git a/src/librustc_target/spec/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs
index cfcf856836b..cfcf856836b 100644
--- a/src/librustc_target/spec/x86_64_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs
diff --git a/src/librustc_target/spec/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs
index c42d0911725..c42d0911725 100644
--- a/src/librustc_target/spec/x86_64_apple_ios_macabi.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs
diff --git a/src/librustc_target/spec/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs
index a56062c0b2b..a56062c0b2b 100644
--- a/src/librustc_target/spec/x86_64_apple_tvos.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs
diff --git a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs
index 3b5233a3e67..3b5233a3e67 100644
--- a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs
+++ b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs
diff --git a/src/librustc_target/spec/x86_64_fuchsia.rs b/compiler/rustc_target/src/spec/x86_64_fuchsia.rs
index 37b6d57366c..37b6d57366c 100644
--- a/src/librustc_target/spec/x86_64_fuchsia.rs
+++ b/compiler/rustc_target/src/spec/x86_64_fuchsia.rs
diff --git a/src/librustc_target/spec/x86_64_linux_android.rs b/compiler/rustc_target/src/spec/x86_64_linux_android.rs
index 74097f5bf6f..74097f5bf6f 100644
--- a/src/librustc_target/spec/x86_64_linux_android.rs
+++ b/compiler/rustc_target/src/spec/x86_64_linux_android.rs
diff --git a/src/librustc_target/spec/x86_64_linux_kernel.rs b/compiler/rustc_target/src/spec/x86_64_linux_kernel.rs
index 65bb97d84aa..65bb97d84aa 100644
--- a/src/librustc_target/spec/x86_64_linux_kernel.rs
+++ b/compiler/rustc_target/src/spec/x86_64_linux_kernel.rs
diff --git a/src/librustc_target/spec/x86_64_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs
index 99af483f1d4..99af483f1d4 100644
--- a/src/librustc_target/spec/x86_64_pc_windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs
diff --git a/src/librustc_target/spec/x86_64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/x86_64_pc_windows_msvc.rs
index 75ff6b97a2e..75ff6b97a2e 100644
--- a/src/librustc_target/spec/x86_64_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/x86_64_pc_windows_msvc.rs
diff --git a/src/librustc_target/spec/x86_64_rumprun_netbsd.rs b/compiler/rustc_target/src/spec/x86_64_rumprun_netbsd.rs
index fbade02c556..fbade02c556 100644
--- a/src/librustc_target/spec/x86_64_rumprun_netbsd.rs
+++ b/compiler/rustc_target/src/spec/x86_64_rumprun_netbsd.rs
diff --git a/src/librustc_target/spec/x86_64_sun_solaris.rs b/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs
index 53f4df96518..53f4df96518 100644
--- a/src/librustc_target/spec/x86_64_sun_solaris.rs
+++ b/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs
diff --git a/src/librustc_target/spec/x86_64_unknown_cloudabi.rs b/compiler/rustc_target/src/spec/x86_64_unknown_cloudabi.rs
index dbc5f965020..dbc5f965020 100644
--- a/src/librustc_target/spec/x86_64_unknown_cloudabi.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_cloudabi.rs
diff --git a/src/librustc_target/spec/x86_64_unknown_dragonfly.rs b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs
index fd1871b1a57..fd1871b1a57 100644
--- a/src/librustc_target/spec/x86_64_unknown_dragonfly.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs
diff --git a/src/librustc_target/spec/x86_64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs
index a124f582bf3..a124f582bf3 100644
--- a/src/librustc_target/spec/x86_64_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs
diff --git a/src/librustc_target/spec/x86_64_unknown_haiku.rs b/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs
index 51237697714..51237697714 100644
--- a/src/librustc_target/spec/x86_64_unknown_haiku.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs
diff --git a/src/librustc_target/spec/x86_64_unknown_hermit.rs b/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs
index 4a526f90ed5..4a526f90ed5 100644
--- a/src/librustc_target/spec/x86_64_unknown_hermit.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs
diff --git a/src/librustc_target/spec/x86_64_unknown_hermit_kernel.rs b/compiler/rustc_target/src/spec/x86_64_unknown_hermit_kernel.rs
index c25cd0809ee..c25cd0809ee 100644
--- a/src/librustc_target/spec/x86_64_unknown_hermit_kernel.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_hermit_kernel.rs
diff --git a/src/librustc_target/spec/x86_64_unknown_illumos.rs b/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs
index 2567ca47ef9..2567ca47ef9 100644
--- a/src/librustc_target/spec/x86_64_unknown_illumos.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs
diff --git a/src/librustc_target/spec/x86_64_unknown_l4re_uclibc.rs b/compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs
index cab19f149a7..cab19f149a7 100644
--- a/src/librustc_target/spec/x86_64_unknown_l4re_uclibc.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs
diff --git a/src/librustc_target/spec/x86_64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs
index 29cbb777db5..29cbb777db5 100644
--- a/src/librustc_target/spec/x86_64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs
diff --git a/src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs
index 0a37399e2fa..0a37399e2fa 100644
--- a/src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs
diff --git a/src/librustc_target/spec/x86_64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs
index 3a22290da68..3a22290da68 100644
--- a/src/librustc_target/spec/x86_64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs
diff --git a/src/librustc_target/spec/x86_64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs
index adf09c89c42..adf09c89c42 100644
--- a/src/librustc_target/spec/x86_64_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs
diff --git a/src/librustc_target/spec/x86_64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs
index dbd163db36b..dbd163db36b 100644
--- a/src/librustc_target/spec/x86_64_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs
diff --git a/src/librustc_target/spec/x86_64_unknown_redox.rs b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs
index 3d40bafbe1f..3d40bafbe1f 100644
--- a/src/librustc_target/spec/x86_64_unknown_redox.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs
diff --git a/src/librustc_target/spec/x86_64_unknown_uefi.rs b/compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs
index 849227a574a..849227a574a 100644
--- a/src/librustc_target/spec/x86_64_unknown_uefi.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs
diff --git a/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs
index 3bd18f23f6f..3bd18f23f6f 100644
--- a/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs
diff --git a/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/x86_64_uwp_windows_msvc.rs
index 258df010aae..258df010aae 100644
--- a/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/x86_64_uwp_windows_msvc.rs
diff --git a/src/librustc_target/spec/x86_64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs
index f1e27f4d8be..f1e27f4d8be 100644
--- a/src/librustc_target/spec/x86_64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs
diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml
new file mode 100644
index 00000000000..a72c172918b
--- /dev/null
+++ b/compiler/rustc_trait_selection/Cargo.toml
@@ -0,0 +1,25 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_trait_selection"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+doctest = false
+
+[dependencies]
+rustc_parse_format = { path = "../rustc_parse_format" }
+tracing = "0.1"
+rustc_attr = { path = "../rustc_attr" }
+rustc_middle = { path = "../rustc_middle" }
+rustc_ast = { path = "../rustc_ast" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_index = { path = "../rustc_index" }
+rustc_infer = { path = "../rustc_infer" }
+rustc_macros = { path = "../rustc_macros" }
+rustc_session = { path = "../rustc_session" }
+rustc_span = { path = "../rustc_span" }
+rustc_target = { path = "../rustc_target" }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_trait_selection/autoderef.rs b/compiler/rustc_trait_selection/src/autoderef.rs
index 02eefe56223..02eefe56223 100644
--- a/src/librustc_trait_selection/autoderef.rs
+++ b/compiler/rustc_trait_selection/src/autoderef.rs
diff --git a/src/librustc_trait_selection/infer.rs b/compiler/rustc_trait_selection/src/infer.rs
index 4ec1b29bca4..4ec1b29bca4 100644
--- a/src/librustc_trait_selection/infer.rs
+++ b/compiler/rustc_trait_selection/src/infer.rs
diff --git a/src/librustc_trait_selection/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index b5882df4729..b5882df4729 100644
--- a/src/librustc_trait_selection/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
diff --git a/src/librustc_trait_selection/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs
index 379c976df69..379c976df69 100644
--- a/src/librustc_trait_selection/opaque_types.rs
+++ b/compiler/rustc_trait_selection/src/opaque_types.rs
diff --git a/src/librustc_trait_selection/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index fa3d0241998..fa3d0241998 100644
--- a/src/librustc_trait_selection/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
diff --git a/src/librustc_trait_selection/traits/chalk_fulfill.rs b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs
index 0097097707f..0097097707f 100644
--- a/src/librustc_trait_selection/traits/chalk_fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs
diff --git a/src/librustc_trait_selection/traits/codegen/mod.rs b/compiler/rustc_trait_selection/src/traits/codegen/mod.rs
index dd7ea55cc10..dd7ea55cc10 100644
--- a/src/librustc_trait_selection/traits/codegen/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/codegen/mod.rs
diff --git a/src/librustc_trait_selection/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index b06cf4411d0..b06cf4411d0 100644
--- a/src/librustc_trait_selection/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
diff --git a/src/librustc_trait_selection/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs
index 4d477886979..4d477886979 100644
--- a/src/librustc_trait_selection/traits/engine.rs
+++ b/compiler/rustc_trait_selection/src/traits/engine.rs
diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 28542d4b12e..28542d4b12e 100644
--- a/src/librustc_trait_selection/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
diff --git a/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
index d2b9f84af33..d2b9f84af33 100644
--- a/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 138293c9533..138293c9533 100644
--- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
diff --git a/src/librustc_trait_selection/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index a5c6dc042ab..a5c6dc042ab 100644
--- a/src/librustc_trait_selection/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
diff --git a/src/librustc_trait_selection/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs
index 61567aeb57c..61567aeb57c 100644
--- a/src/librustc_trait_selection/traits/misc.rs
+++ b/compiler/rustc_trait_selection/src/traits/misc.rs
diff --git a/src/librustc_trait_selection/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index fe406e88c52..fe406e88c52 100644
--- a/src/librustc_trait_selection/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
diff --git a/src/librustc_trait_selection/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index c003e4f8068..c003e4f8068 100644
--- a/src/librustc_trait_selection/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
diff --git a/src/librustc_trait_selection/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
index 75822eadb2a..75822eadb2a 100644
--- a/src/librustc_trait_selection/traits/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
diff --git a/src/librustc_trait_selection/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index c788e4f5c90..c788e4f5c90 100644
--- a/src/librustc_trait_selection/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
diff --git a/src/librustc_trait_selection/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
index d07c95270e0..d07c95270e0 100644
--- a/src/librustc_trait_selection/traits/query/dropck_outlives.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
diff --git a/src/librustc_trait_selection/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
index 0569f6217da..0569f6217da 100644
--- a/src/librustc_trait_selection/traits/query/evaluate_obligation.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
diff --git a/src/librustc_trait_selection/traits/query/method_autoderef.rs b/compiler/rustc_trait_selection/src/traits/query/method_autoderef.rs
index 3c0ebec9335..3c0ebec9335 100644
--- a/src/librustc_trait_selection/traits/query/method_autoderef.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/method_autoderef.rs
diff --git a/src/librustc_trait_selection/traits/query/mod.rs b/compiler/rustc_trait_selection/src/traits/query/mod.rs
index 01f4f09e238..01f4f09e238 100644
--- a/src/librustc_trait_selection/traits/query/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/mod.rs
diff --git a/src/librustc_trait_selection/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index 93652329305..93652329305 100644
--- a/src/librustc_trait_selection/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
diff --git a/src/librustc_trait_selection/traits/query/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/outlives_bounds.rs
index a42409515db..a42409515db 100644
--- a/src/librustc_trait_selection/traits/query/outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/outlives_bounds.rs
diff --git a/src/librustc_trait_selection/traits/query/type_op/ascribe_user_type.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs
index 86b015767f0..86b015767f0 100644
--- a/src/librustc_trait_selection/traits/query/type_op/ascribe_user_type.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs
diff --git a/src/librustc_trait_selection/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs
index 915e8ae4a7a..915e8ae4a7a 100644
--- a/src/librustc_trait_selection/traits/query/type_op/custom.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs
diff --git a/src/librustc_trait_selection/traits/query/type_op/eq.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs
index 490114aacd1..490114aacd1 100644
--- a/src/librustc_trait_selection/traits/query/type_op/eq.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs
diff --git a/src/librustc_trait_selection/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
index cf7f0a553c7..cf7f0a553c7 100644
--- a/src/librustc_trait_selection/traits/query/type_op/implied_outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
diff --git a/src/librustc_trait_selection/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
index ed6c6d0cc0a..ed6c6d0cc0a 100644
--- a/src/librustc_trait_selection/traits/query/type_op/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
diff --git a/src/librustc_trait_selection/traits/query/type_op/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs
index 729b66ac21c..729b66ac21c 100644
--- a/src/librustc_trait_selection/traits/query/type_op/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs
diff --git a/src/librustc_trait_selection/traits/query/type_op/outlives.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs
index 5a27e57860e..5a27e57860e 100644
--- a/src/librustc_trait_selection/traits/query/type_op/outlives.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs
diff --git a/src/librustc_trait_selection/traits/query/type_op/prove_predicate.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs
index 93ddcb68554..93ddcb68554 100644
--- a/src/librustc_trait_selection/traits/query/type_op/prove_predicate.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs
diff --git a/src/librustc_trait_selection/traits/query/type_op/subtype.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs
index 57290b66914..57290b66914 100644
--- a/src/librustc_trait_selection/traits/query/type_op/subtype.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs
diff --git a/src/librustc_trait_selection/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 1d5441b8eff..1d5441b8eff 100644
--- a/src/librustc_trait_selection/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
diff --git a/src/librustc_trait_selection/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 3d6eb845136..3d6eb845136 100644
--- a/src/librustc_trait_selection/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
diff --git a/src/librustc_trait_selection/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 82f476b463d..82f476b463d 100644
--- a/src/librustc_trait_selection/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
diff --git a/src/librustc_trait_selection/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 4d81a3baa0e..4d81a3baa0e 100644
--- a/src/librustc_trait_selection/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
diff --git a/src/librustc_trait_selection/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
index 56b8354d68c..56b8354d68c 100644
--- a/src/librustc_trait_selection/traits/specialize/specialization_graph.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
diff --git a/src/librustc_trait_selection/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs
index 78186a5e8a5..78186a5e8a5 100644
--- a/src/librustc_trait_selection/traits/structural_match.rs
+++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs
diff --git a/src/librustc_trait_selection/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index f626bb0b7e3..f626bb0b7e3 100644
--- a/src/librustc_trait_selection/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
diff --git a/src/librustc_trait_selection/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 0ac3c6ffe62..0ac3c6ffe62 100644
--- a/src/librustc_trait_selection/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
diff --git a/compiler/rustc_traits/Cargo.toml b/compiler/rustc_traits/Cargo.toml
new file mode 100644
index 00000000000..2d63fc51220
--- /dev/null
+++ b/compiler/rustc_traits/Cargo.toml
@@ -0,0 +1,19 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_traits"
+version = "0.0.0"
+edition = "2018"
+
+[dependencies]
+tracing = "0.1"
+rustc_middle = { path = "../rustc_middle" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_index = { path = "../rustc_index" }
+rustc_ast = { path = "../rustc_ast" }
+rustc_span = { path = "../rustc_span" }
+chalk-ir = "0.14.0"
+chalk-solve = "0.14.0"
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
+rustc_infer = { path = "../rustc_infer" }
+rustc_trait_selection = { path = "../rustc_trait_selection" }
diff --git a/src/librustc_traits/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs
index 4c8be8eb610..4c8be8eb610 100644
--- a/src/librustc_traits/chalk/db.rs
+++ b/compiler/rustc_traits/src/chalk/db.rs
diff --git a/src/librustc_traits/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs
index a043fa3f4c8..a043fa3f4c8 100644
--- a/src/librustc_traits/chalk/lowering.rs
+++ b/compiler/rustc_traits/src/chalk/lowering.rs
diff --git a/src/librustc_traits/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs
index f18b4ca65f6..f18b4ca65f6 100644
--- a/src/librustc_traits/chalk/mod.rs
+++ b/compiler/rustc_traits/src/chalk/mod.rs
diff --git a/src/librustc_traits/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs
index ce00060b9b1..ce00060b9b1 100644
--- a/src/librustc_traits/dropck_outlives.rs
+++ b/compiler/rustc_traits/src/dropck_outlives.rs
diff --git a/src/librustc_traits/evaluate_obligation.rs b/compiler/rustc_traits/src/evaluate_obligation.rs
index 2404b7ff4b5..2404b7ff4b5 100644
--- a/src/librustc_traits/evaluate_obligation.rs
+++ b/compiler/rustc_traits/src/evaluate_obligation.rs
diff --git a/src/librustc_traits/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs
index de3096eac9b..de3096eac9b 100644
--- a/src/librustc_traits/implied_outlives_bounds.rs
+++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs
diff --git a/src/librustc_traits/lib.rs b/compiler/rustc_traits/src/lib.rs
index 6fea4732dda..6fea4732dda 100644
--- a/src/librustc_traits/lib.rs
+++ b/compiler/rustc_traits/src/lib.rs
diff --git a/src/librustc_traits/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs
index 83aee31a39f..83aee31a39f 100644
--- a/src/librustc_traits/normalize_erasing_regions.rs
+++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs
diff --git a/src/librustc_traits/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs
index a8e376838e2..a8e376838e2 100644
--- a/src/librustc_traits/normalize_projection_ty.rs
+++ b/compiler/rustc_traits/src/normalize_projection_ty.rs
diff --git a/src/librustc_traits/type_op.rs b/compiler/rustc_traits/src/type_op.rs
index 139ed6dcd35..139ed6dcd35 100644
--- a/src/librustc_traits/type_op.rs
+++ b/compiler/rustc_traits/src/type_op.rs
diff --git a/compiler/rustc_ty/Cargo.toml b/compiler/rustc_ty/Cargo.toml
new file mode 100644
index 00000000000..acb011b2dc0
--- /dev/null
+++ b/compiler/rustc_ty/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_ty"
+version = "0.0.0"
+edition = "2018"
+
+[dependencies]
+tracing = "0.1"
+rustc_middle = { path = "../rustc_middle" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_infer = { path = "../rustc_infer" }
+rustc_span = { path = "../rustc_span" }
+rustc_session = { path = "../rustc_session" }
+rustc_target = { path = "../rustc_target" }
+rustc_trait_selection = { path = "../rustc_trait_selection" }
diff --git a/src/librustc_ty/common_traits.rs b/compiler/rustc_ty/src/common_traits.rs
index 24ba0717866..24ba0717866 100644
--- a/src/librustc_ty/common_traits.rs
+++ b/compiler/rustc_ty/src/common_traits.rs
diff --git a/src/librustc_ty/instance.rs b/compiler/rustc_ty/src/instance.rs
index d0bd88af1ff..d0bd88af1ff 100644
--- a/src/librustc_ty/instance.rs
+++ b/compiler/rustc_ty/src/instance.rs
diff --git a/src/librustc_ty/lib.rs b/compiler/rustc_ty/src/lib.rs
index 6e9042d1ba7..6e9042d1ba7 100644
--- a/src/librustc_ty/lib.rs
+++ b/compiler/rustc_ty/src/lib.rs
diff --git a/src/librustc_ty/needs_drop.rs b/compiler/rustc_ty/src/needs_drop.rs
index c4af95205fe..c4af95205fe 100644
--- a/src/librustc_ty/needs_drop.rs
+++ b/compiler/rustc_ty/src/needs_drop.rs
diff --git a/src/librustc_ty/ty.rs b/compiler/rustc_ty/src/ty.rs
index 0f1dee7e2e0..0f1dee7e2e0 100644
--- a/src/librustc_ty/ty.rs
+++ b/compiler/rustc_ty/src/ty.rs
diff --git a/compiler/rustc_typeck/Cargo.toml b/compiler/rustc_typeck/Cargo.toml
new file mode 100644
index 00000000000..0a6bfaef431
--- /dev/null
+++ b/compiler/rustc_typeck/Cargo.toml
@@ -0,0 +1,27 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_typeck"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+test = false
+doctest = false
+
+[dependencies]
+rustc_arena = { path = "../rustc_arena" }
+tracing = "0.1"
+rustc_middle = { path = "../rustc_middle" }
+rustc_attr = { path = "../rustc_attr" }
+rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_hir = { path = "../rustc_hir" }
+rustc_hir_pretty = { path = "../rustc_hir_pretty" }
+rustc_target = { path = "../rustc_target" }
+rustc_session = { path = "../rustc_session" }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
+rustc_ast = { path = "../rustc_ast" }
+rustc_span = { path = "../rustc_span" }
+rustc_index = { path = "../rustc_index" }
+rustc_infer = { path = "../rustc_infer" }
+rustc_trait_selection = { path = "../rustc_trait_selection" }
diff --git a/src/librustc_typeck/README.md b/compiler/rustc_typeck/README.md
index b61dbd8c964..b61dbd8c964 100644
--- a/src/librustc_typeck/README.md
+++ b/compiler/rustc_typeck/README.md
diff --git a/src/librustc_typeck/astconv/errors.rs b/compiler/rustc_typeck/src/astconv/errors.rs
index 685243f54cb..685243f54cb 100644
--- a/src/librustc_typeck/astconv/errors.rs
+++ b/compiler/rustc_typeck/src/astconv/errors.rs
diff --git a/src/librustc_typeck/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs
index 84dab6de958..84dab6de958 100644
--- a/src/librustc_typeck/astconv/generics.rs
+++ b/compiler/rustc_typeck/src/astconv/generics.rs
diff --git a/src/librustc_typeck/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 80dd26e9154..80dd26e9154 100644
--- a/src/librustc_typeck/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
diff --git a/src/librustc_typeck/bounds.rs b/compiler/rustc_typeck/src/bounds.rs
index 63295f5faac..63295f5faac 100644
--- a/src/librustc_typeck/bounds.rs
+++ b/compiler/rustc_typeck/src/bounds.rs
diff --git a/src/librustc_typeck/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs
index afd4413069e..afd4413069e 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/compiler/rustc_typeck/src/check/_match.rs
diff --git a/src/librustc_typeck/check/autoderef.rs b/compiler/rustc_typeck/src/check/autoderef.rs
index 97d2b3e5a8e..97d2b3e5a8e 100644
--- a/src/librustc_typeck/check/autoderef.rs
+++ b/compiler/rustc_typeck/src/check/autoderef.rs
diff --git a/src/librustc_typeck/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs
index 4ba64035ca4..4ba64035ca4 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/compiler/rustc_typeck/src/check/callee.rs
diff --git a/src/librustc_typeck/check/cast.rs b/compiler/rustc_typeck/src/check/cast.rs
index e41314e8ab0..e41314e8ab0 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/compiler/rustc_typeck/src/check/cast.rs
diff --git a/src/librustc_typeck/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs
index 97f7e4537ce..97f7e4537ce 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/compiler/rustc_typeck/src/check/closure.rs
diff --git a/src/librustc_typeck/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs
index f0802c45ae0..f0802c45ae0 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/compiler/rustc_typeck/src/check/coercion.rs
diff --git a/src/librustc_typeck/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs
index 7adcd7b472e..7adcd7b472e 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/compiler/rustc_typeck/src/check/compare_method.rs
diff --git a/src/librustc_typeck/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs
index 5dc5480c335..5dc5480c335 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/compiler/rustc_typeck/src/check/demand.rs
diff --git a/src/librustc_typeck/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs
index 434886538fb..434886538fb 100644
--- a/src/librustc_typeck/check/dropck.rs
+++ b/compiler/rustc_typeck/src/check/dropck.rs
diff --git a/src/librustc_typeck/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 1573fb96791..cc8a6953f13 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -764,9 +764,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         rhs: &'tcx hir::Expr<'tcx>,
         span: &Span,
     ) -> Ty<'tcx> {
-        let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
-        let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty, Some(lhs));
-
         let expected_ty = expected.coercion_target_type(self, expr.span);
         if expected_ty == self.tcx.types.bool {
             // The expected type is `bool` but this will result in `()` so we can reasonably
@@ -774,20 +771,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // The likely cause of this is `if foo = bar { .. }`.
             let actual_ty = self.tcx.mk_unit();
             let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap();
-            let msg = "try comparing for equality";
-            let left = self.tcx.sess.source_map().span_to_snippet(lhs.span);
-            let right = self.tcx.sess.source_map().span_to_snippet(rhs.span);
-            if let (Ok(left), Ok(right)) = (left, right) {
-                let help = format!("{} == {}", left, right);
-                err.span_suggestion(expr.span, msg, help, Applicability::MaybeIncorrect);
+            let lhs_ty = self.check_expr(&lhs);
+            let rhs_ty = self.check_expr(&rhs);
+            if self.can_coerce(lhs_ty, rhs_ty) {
+                if !lhs.is_syntactic_place_expr() {
+                    // Do not suggest `if let x = y` as `==` is way more likely to be the intention.
+                    if let hir::Node::Expr(hir::Expr {
+                        kind: ExprKind::Match(_, _, hir::MatchSource::IfDesugar { .. }),
+                        ..
+                    }) = self.tcx.hir().get(
+                        self.tcx.hir().get_parent_node(self.tcx.hir().get_parent_node(expr.hir_id)),
+                    ) {
+                        // Likely `if let` intended.
+                        err.span_suggestion_verbose(
+                            expr.span.shrink_to_lo(),
+                            "you might have meant to use pattern matching",
+                            "let ".to_string(),
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                }
+                err.span_suggestion_verbose(
+                    *span,
+                    "you might have meant to compare for equality",
+                    "==".to_string(),
+                    Applicability::MaybeIncorrect,
+                );
             } else {
-                err.help(msg);
+                // Do this to cause extra errors about the assignment.
+                let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
+                let _ = self.check_expr_coercable_to_type(&rhs, lhs_ty, Some(lhs));
             }
-            err.emit();
-        } else {
-            self.check_lhs_assignable(lhs, "E0070", span);
+
+            if self.sess().if_let_suggestions.borrow().get(&expr.span).is_some() {
+                // We already emitted an `if let` suggestion due to an identifier not found.
+                err.delay_as_bug();
+            } else {
+                err.emit();
+            }
+            return self.tcx.ty_error();
         }
 
+        self.check_lhs_assignable(lhs, "E0070", span);
+
+        let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
+        let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty, Some(lhs));
+
         self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
 
         if lhs_ty.references_error() || rhs_ty.references_error() {
diff --git a/src/librustc_typeck/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs
index 93fdf93e9e3..93fdf93e9e3 100644
--- a/src/librustc_typeck/check/generator_interior.rs
+++ b/compiler/rustc_typeck/src/check/generator_interior.rs
diff --git a/src/librustc_typeck/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs
index 47cea8649ef..47cea8649ef 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/compiler/rustc_typeck/src/check/intrinsic.rs
diff --git a/src/librustc_typeck/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs
index 41e37ee9752..41e37ee9752 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/compiler/rustc_typeck/src/check/method/confirm.rs
diff --git a/src/librustc_typeck/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs
index c9a4df0317a..c9a4df0317a 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/compiler/rustc_typeck/src/check/method/mod.rs
diff --git a/src/librustc_typeck/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs
index 7ac6681be1a..7ac6681be1a 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/compiler/rustc_typeck/src/check/method/probe.rs
diff --git a/src/librustc_typeck/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index 5cae66bc5da..5cae66bc5da 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
diff --git a/src/librustc_typeck/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs
index 031d48f8a60..031d48f8a60 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/compiler/rustc_typeck/src/check/mod.rs
diff --git a/src/librustc_typeck/check/op.rs b/compiler/rustc_typeck/src/check/op.rs
index 66fb01a54f5..66fb01a54f5 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/compiler/rustc_typeck/src/check/op.rs
diff --git a/src/librustc_typeck/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs
index d1864ee2b35..d1864ee2b35 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/compiler/rustc_typeck/src/check/pat.rs
diff --git a/src/librustc_typeck/check/place_op.rs b/compiler/rustc_typeck/src/check/place_op.rs
index 4bef9aecd2e..4bef9aecd2e 100644
--- a/src/librustc_typeck/check/place_op.rs
+++ b/compiler/rustc_typeck/src/check/place_op.rs
diff --git a/src/librustc_typeck/check/regionck.rs b/compiler/rustc_typeck/src/check/regionck.rs
index 484961dbdb8..484961dbdb8 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/compiler/rustc_typeck/src/check/regionck.rs
diff --git a/src/librustc_typeck/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs
index 9bb84c07868..9bb84c07868 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/compiler/rustc_typeck/src/check/upvar.rs
diff --git a/src/librustc_typeck/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index 9c692edaa7f..9c692edaa7f 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
diff --git a/src/librustc_typeck/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs
index 67f67e64dd4..67f67e64dd4 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/compiler/rustc_typeck/src/check/writeback.rs
diff --git a/src/librustc_typeck/check_unused.rs b/compiler/rustc_typeck/src/check_unused.rs
index 4fda8932e21..4fda8932e21 100644
--- a/src/librustc_typeck/check_unused.rs
+++ b/compiler/rustc_typeck/src/check_unused.rs
diff --git a/src/librustc_typeck/coherence/builtin.rs b/compiler/rustc_typeck/src/coherence/builtin.rs
index 0d3cac7f7f3..0d3cac7f7f3 100644
--- a/src/librustc_typeck/coherence/builtin.rs
+++ b/compiler/rustc_typeck/src/coherence/builtin.rs
diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/compiler/rustc_typeck/src/coherence/inherent_impls.rs
index 859d510dcbe..859d510dcbe 100644
--- a/src/librustc_typeck/coherence/inherent_impls.rs
+++ b/compiler/rustc_typeck/src/coherence/inherent_impls.rs
diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs
index be77d049cae..be77d049cae 100644
--- a/src/librustc_typeck/coherence/inherent_impls_overlap.rs
+++ b/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs
diff --git a/src/librustc_typeck/coherence/mod.rs b/compiler/rustc_typeck/src/coherence/mod.rs
index 1483244717b..1483244717b 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/compiler/rustc_typeck/src/coherence/mod.rs
diff --git a/src/librustc_typeck/coherence/orphan.rs b/compiler/rustc_typeck/src/coherence/orphan.rs
index 71469770f2a..71469770f2a 100644
--- a/src/librustc_typeck/coherence/orphan.rs
+++ b/compiler/rustc_typeck/src/coherence/orphan.rs
diff --git a/src/librustc_typeck/coherence/unsafety.rs b/compiler/rustc_typeck/src/coherence/unsafety.rs
index b281092ea63..b281092ea63 100644
--- a/src/librustc_typeck/coherence/unsafety.rs
+++ b/compiler/rustc_typeck/src/coherence/unsafety.rs
diff --git a/src/librustc_typeck/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 7a3f7ec56a2..7a3f7ec56a2 100644
--- a/src/librustc_typeck/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
diff --git a/src/librustc_typeck/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index 70ed92c5614..70ed92c5614 100644
--- a/src/librustc_typeck/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
diff --git a/src/librustc_typeck/constrained_generic_params.rs b/compiler/rustc_typeck/src/constrained_generic_params.rs
index 7c80315ee19..7c80315ee19 100644
--- a/src/librustc_typeck/constrained_generic_params.rs
+++ b/compiler/rustc_typeck/src/constrained_generic_params.rs
diff --git a/src/librustc_typeck/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs
index e774f2d095d..e774f2d095d 100644
--- a/src/librustc_typeck/expr_use_visitor.rs
+++ b/compiler/rustc_typeck/src/expr_use_visitor.rs
diff --git a/src/librustc_typeck/impl_wf_check.rs b/compiler/rustc_typeck/src/impl_wf_check.rs
index 891e482b431..891e482b431 100644
--- a/src/librustc_typeck/impl_wf_check.rs
+++ b/compiler/rustc_typeck/src/impl_wf_check.rs
diff --git a/src/librustc_typeck/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
index 3746e5778aa..3746e5778aa 100644
--- a/src/librustc_typeck/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
diff --git a/src/librustc_typeck/lib.rs b/compiler/rustc_typeck/src/lib.rs
index 62f92fe7ffa..62f92fe7ffa 100644
--- a/src/librustc_typeck/lib.rs
+++ b/compiler/rustc_typeck/src/lib.rs
diff --git a/src/librustc_typeck/mem_categorization.rs b/compiler/rustc_typeck/src/mem_categorization.rs
index 8a6fe620af7..8a6fe620af7 100644
--- a/src/librustc_typeck/mem_categorization.rs
+++ b/compiler/rustc_typeck/src/mem_categorization.rs
diff --git a/src/librustc_typeck/outlives/explicit.rs b/compiler/rustc_typeck/src/outlives/explicit.rs
index 135960a4c11..135960a4c11 100644
--- a/src/librustc_typeck/outlives/explicit.rs
+++ b/compiler/rustc_typeck/src/outlives/explicit.rs
diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/compiler/rustc_typeck/src/outlives/implicit_infer.rs
index 762d4216f70..762d4216f70 100644
--- a/src/librustc_typeck/outlives/implicit_infer.rs
+++ b/compiler/rustc_typeck/src/outlives/implicit_infer.rs
diff --git a/src/librustc_typeck/outlives/mod.rs b/compiler/rustc_typeck/src/outlives/mod.rs
index 94926f480e2..94926f480e2 100644
--- a/src/librustc_typeck/outlives/mod.rs
+++ b/compiler/rustc_typeck/src/outlives/mod.rs
diff --git a/src/librustc_typeck/outlives/test.rs b/compiler/rustc_typeck/src/outlives/test.rs
index abe9319d71c..abe9319d71c 100644
--- a/src/librustc_typeck/outlives/test.rs
+++ b/compiler/rustc_typeck/src/outlives/test.rs
diff --git a/src/librustc_typeck/outlives/utils.rs b/compiler/rustc_typeck/src/outlives/utils.rs
index 8b069678796..8b069678796 100644
--- a/src/librustc_typeck/outlives/utils.rs
+++ b/compiler/rustc_typeck/src/outlives/utils.rs
diff --git a/src/librustc_typeck/structured_errors.rs b/compiler/rustc_typeck/src/structured_errors.rs
index 83125a3e2fe..83125a3e2fe 100644
--- a/src/librustc_typeck/structured_errors.rs
+++ b/compiler/rustc_typeck/src/structured_errors.rs
diff --git a/src/librustc_typeck/variance/constraints.rs b/compiler/rustc_typeck/src/variance/constraints.rs
index 535530a2ed4..535530a2ed4 100644
--- a/src/librustc_typeck/variance/constraints.rs
+++ b/compiler/rustc_typeck/src/variance/constraints.rs
diff --git a/src/librustc_typeck/variance/mod.rs b/compiler/rustc_typeck/src/variance/mod.rs
index a893f69c48a..a893f69c48a 100644
--- a/src/librustc_typeck/variance/mod.rs
+++ b/compiler/rustc_typeck/src/variance/mod.rs
diff --git a/src/librustc_typeck/variance/solve.rs b/compiler/rustc_typeck/src/variance/solve.rs
index 7402117a7eb..7402117a7eb 100644
--- a/src/librustc_typeck/variance/solve.rs
+++ b/compiler/rustc_typeck/src/variance/solve.rs
diff --git a/src/librustc_typeck/variance/terms.rs b/compiler/rustc_typeck/src/variance/terms.rs
index f61a783de69..f61a783de69 100644
--- a/src/librustc_typeck/variance/terms.rs
+++ b/compiler/rustc_typeck/src/variance/terms.rs
diff --git a/src/librustc_typeck/variance/test.rs b/compiler/rustc_typeck/src/variance/test.rs
index 1aab89310c6..1aab89310c6 100644
--- a/src/librustc_typeck/variance/test.rs
+++ b/compiler/rustc_typeck/src/variance/test.rs
diff --git a/src/librustc_typeck/variance/xform.rs b/compiler/rustc_typeck/src/variance/xform.rs
index 027f0859fcd..027f0859fcd 100644
--- a/src/librustc_typeck/variance/xform.rs
+++ b/compiler/rustc_typeck/src/variance/xform.rs
diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs
index 51c233a21f1..e7260f3956c 100644
--- a/library/alloc/src/borrow.rs
+++ b/library/alloc/src/borrow.rs
@@ -217,7 +217,7 @@ impl<B: ?Sized + ToOwned> Cow<'_, B> {
     /// assert!(!bull.is_borrowed());
     /// ```
     #[unstable(feature = "cow_is_borrowed", issue = "65143")]
-    pub fn is_borrowed(&self) -> bool {
+    pub const fn is_borrowed(&self) -> bool {
         match *self {
             Borrowed(_) => true,
             Owned(_) => false,
@@ -239,7 +239,7 @@ impl<B: ?Sized + ToOwned> Cow<'_, B> {
     /// assert!(!bull.is_owned());
     /// ```
     #[unstable(feature = "cow_is_borrowed", issue = "65143")]
-    pub fn is_owned(&self) -> bool {
+    pub const fn is_owned(&self) -> bool {
         !self.is_borrowed()
     }
 
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index 05211e2037b..5c8c2c5a5a8 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -217,7 +217,7 @@ impl<T> Box<T> {
     /// assert_eq!(*zero, 0)
     /// ```
     ///
-    /// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed
+    /// [zeroed]: mem::MaybeUninit::zeroed
     #[unstable(feature = "new_uninit", issue = "63291")]
     pub fn new_zeroed() -> Box<mem::MaybeUninit<T>> {
         let layout = alloc::Layout::new::<mem::MaybeUninit<T>>();
@@ -289,7 +289,7 @@ impl<T> Box<[T]> {
     /// assert_eq!(*values, [0, 0, 0])
     /// ```
     ///
-    /// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed
+    /// [zeroed]: mem::MaybeUninit::zeroed
     #[unstable(feature = "new_uninit", issue = "63291")]
     pub fn new_zeroed_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
         unsafe { RawVec::with_capacity_zeroed(len).into_box(len) }
@@ -307,7 +307,7 @@ impl<T> Box<mem::MaybeUninit<T>> {
     /// Calling this when the content is not yet fully initialized
     /// causes immediate undefined behavior.
     ///
-    /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+    /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init
     ///
     /// # Examples
     ///
@@ -343,7 +343,7 @@ impl<T> Box<[mem::MaybeUninit<T>]> {
     /// Calling this when the content is not yet fully initialized
     /// causes immediate undefined behavior.
     ///
-    /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+    /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init
     ///
     /// # Examples
     ///
diff --git a/library/alloc/src/collections/vec_deque.rs b/library/alloc/src/collections/vec_deque.rs
index d3c6d493d6d..52b9f73ba88 100644
--- a/library/alloc/src/collections/vec_deque.rs
+++ b/library/alloc/src/collections/vec_deque.rs
@@ -47,10 +47,17 @@ const MAXIMUM_ZST_CAPACITY: usize = 1 << (64 - 1); // Largest possible power of
 /// push onto the back in this manner, and iterating over `VecDeque` goes front
 /// to back.
 ///
+/// Since `VecDeque` is a ring buffer, its elements are not necessarily contiguous
+/// in memory. If you want to access the elements as a single slice, such as for
+/// efficient sorting, you can use [`make_contiguous`]. It rotates the `VecDeque`
+/// so that its elements do not wrap, and returns a mutable slice to the
+/// now-contiguous element sequence.
+///
 /// [`push_back`]: #method.push_back
 /// [`pop_front`]: #method.pop_front
 /// [`extend`]: #method.extend
 /// [`append`]: #method.append
+/// [`make_contiguous`]: #method.make_contiguous
 #[cfg_attr(not(test), rustc_diagnostic_item = "vecdeque_type")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct VecDeque<T> {
@@ -678,7 +685,7 @@ impl<T> VecDeque<T> {
     }
 
     /// Tries to reserve the minimum capacity for exactly `additional` more elements to
-    /// be inserted in the given `VecDeque<T>`. After calling `reserve_exact`,
+    /// be inserted in the given `VecDeque<T>`. After calling `try_reserve_exact`,
     /// capacity will be greater than or equal to `self.len() + additional`.
     /// Does nothing if the capacity is already sufficient.
     ///
@@ -720,7 +727,7 @@ impl<T> VecDeque<T> {
 
     /// Tries to reserve capacity for at least `additional` more elements to be inserted
     /// in the given `VecDeque<T>`. The collection may reserve more space to avoid
-    /// frequent reallocations. After calling `reserve`, capacity will be
+    /// frequent reallocations. After calling `try_reserve`, capacity will be
     /// greater than or equal to `self.len() + additional`. Does nothing if
     /// capacity is already sufficient.
     ///
@@ -2188,8 +2195,6 @@ impl<T> VecDeque<T> {
     /// Sorting the content of a deque.
     ///
     /// ```
-    /// #![feature(deque_make_contiguous)]
-    ///
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::with_capacity(15);
@@ -2210,8 +2215,6 @@ impl<T> VecDeque<T> {
     /// Getting immutable access to the contiguous slice.
     ///
     /// ```rust
-    /// #![feature(deque_make_contiguous)]
-    ///
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
@@ -2228,7 +2231,7 @@ impl<T> VecDeque<T> {
     ///     assert_eq!(slice, &[3, 2, 1] as &[_]);
     /// }
     /// ```
-    #[unstable(feature = "deque_make_contiguous", issue = "70929")]
+    #[stable(feature = "deque_make_contiguous", since = "1.48.0")]
     pub fn make_contiguous(&mut self) -> &mut [T] {
         if self.is_contiguous() {
             let tail = self.tail;
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 1046397f4be..2f0a374015a 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -376,7 +376,7 @@ impl<T> Rc<T> {
     /// assert_eq!(*zero, 0)
     /// ```
     ///
-    /// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed
+    /// [zeroed]: mem::MaybeUninit::zeroed
     #[unstable(feature = "new_uninit", issue = "63291")]
     pub fn new_zeroed() -> Rc<mem::MaybeUninit<T>> {
         unsafe {
@@ -484,7 +484,7 @@ impl<T> Rc<[T]> {
     /// assert_eq!(*values, [0, 0, 0])
     /// ```
     ///
-    /// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed
+    /// [zeroed]: mem::MaybeUninit::zeroed
     #[unstable(feature = "new_uninit", issue = "63291")]
     pub fn new_zeroed_slice(len: usize) -> Rc<[mem::MaybeUninit<T>]> {
         unsafe {
@@ -511,7 +511,7 @@ impl<T> Rc<mem::MaybeUninit<T>> {
     /// Calling this when the content is not yet fully initialized
     /// causes immediate undefined behavior.
     ///
-    /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+    /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init
     ///
     /// # Examples
     ///
@@ -550,7 +550,7 @@ impl<T> Rc<[mem::MaybeUninit<T>]> {
     /// Calling this when the content is not yet fully initialized
     /// causes immediate undefined behavior.
     ///
-    /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+    /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init
     ///
     /// # Examples
     ///
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 73d2fe74826..6a240fbb42a 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -111,7 +111,7 @@ macro_rules! acquire {
 ///
 /// # Cloning references
 ///
-/// Creating a new reference from an existing reference counted pointer is done using the
+/// Creating a new reference from an existing reference-counted pointer is done using the
 /// `Clone` trait implemented for [`Arc<T>`][Arc] and [`Weak<T>`][Weak].
 ///
 /// ```
@@ -152,7 +152,7 @@ macro_rules! acquire {
 /// [upgrade]: Weak::upgrade
 /// [`RefCell<T>`]: core::cell::RefCell
 /// [`std::sync`]: ../../std/sync/index.html
-/// [`Arc::clone(&from)`]: #method.clone
+/// [`Arc::clone(&from)`]: Arc::clone
 ///
 /// # Examples
 ///
@@ -201,7 +201,7 @@ macro_rules! acquire {
 /// See the [`rc` documentation][rc_examples] for more examples of reference
 /// counting in general.
 ///
-/// [rc_examples]: ../../std/rc/index.html#examples
+/// [rc_examples]: crate::rc#examples
 #[cfg_attr(not(test), rustc_diagnostic_item = "Arc")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Arc<T: ?Sized> {
diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs
index 61e1245f073..27eefb05842 100644
--- a/library/alloc/src/vec.rs
+++ b/library/alloc/src/vec.rs
@@ -114,8 +114,9 @@ use crate::raw_vec::RawVec;
 /// assert_eq!(vec, [0, 0, 0, 0, 0]);
 ///
 /// // The following is equivalent, but potentially slower:
-/// let mut vec1 = Vec::with_capacity(5);
-/// vec1.resize(5, 0);
+/// let mut vec = Vec::with_capacity(5);
+/// vec.resize(5, 0);
+/// assert_eq!(vec, [0, 0, 0, 0, 0]);
 /// ```
 ///
 /// Use a `Vec<T>` as an efficient stack:
@@ -522,7 +523,7 @@ impl<T> Vec<T> {
 
     /// Tries to reserve capacity for at least `additional` more elements to be inserted
     /// in the given `Vec<T>`. The collection may reserve more space to avoid
-    /// frequent reallocations. After calling `reserve`, capacity will be
+    /// frequent reallocations. After calling `try_reserve`, capacity will be
     /// greater than or equal to `self.len() + additional`. Does nothing if
     /// capacity is already sufficient.
     ///
@@ -558,7 +559,7 @@ impl<T> Vec<T> {
     }
 
     /// Tries to reserves the minimum capacity for exactly `additional` more elements to
-    /// be inserted in the given `Vec<T>`. After calling `reserve_exact`,
+    /// be inserted in the given `Vec<T>`. After calling `try_reserve_exact`,
     /// capacity will be greater than or equal to `self.len() + additional`.
     /// Does nothing if the capacity is already sufficient.
     ///
@@ -581,7 +582,7 @@ impl<T> Vec<T> {
     ///     let mut output = Vec::new();
     ///
     ///     // Pre-reserve the memory, exiting if we can't
-    ///     output.try_reserve(data.len())?;
+    ///     output.try_reserve_exact(data.len())?;
     ///
     ///     // Now we know this can't OOM in the middle of our complex work
     ///     output.extend(data.iter().map(|&val| {
@@ -1565,7 +1566,7 @@ impl<T: Clone> Vec<T> {
     /// This method requires `T` to implement [`Clone`],
     /// in order to be able to clone the passed value.
     /// If you need more flexibility (or want to rely on [`Default`] instead of
-    /// [`Clone`]), use [`resize_with`].
+    /// [`Clone`]), use [`Vec::resize_with`].
     ///
     /// # Examples
     ///
@@ -1578,8 +1579,6 @@ impl<T: Clone> Vec<T> {
     /// vec.resize(2, 0);
     /// assert_eq!(vec, [1, 2]);
     /// ```
-    ///
-    /// [`resize_with`]: Vec::resize_with
     #[stable(feature = "vec_resize", since = "1.5.0")]
     pub fn resize(&mut self, new_len: usize, value: T) {
         let len = self.len();
@@ -1609,7 +1608,7 @@ impl<T: Clone> Vec<T> {
     /// assert_eq!(vec, [1, 2, 3, 4]);
     /// ```
     ///
-    /// [`extend`]: #method.extend
+    /// [`extend`]: Vec::extend
     #[stable(feature = "vec_extend_from_slice", since = "1.6.0")]
     pub fn extend_from_slice(&mut self, other: &[T]) {
         self.spec_extend(other.iter())
@@ -3024,7 +3023,10 @@ impl<T> Drain<'_, T> {
     }
 }
 
-/// An iterator produced by calling `drain_filter` on Vec.
+/// An iterator which uses a closure to determine if an element should be removed.
+///
+/// This struct is created by [`Vec::drain_filter`].
+/// See its documentation for more.
 #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")]
 #[derive(Debug)]
 pub struct DrainFilter<'a, T, F>
diff --git a/library/core/benches/num/flt2dec/strategy/dragon.rs b/library/core/benches/num/flt2dec/strategy/dragon.rs
index 4e1fd8bf753..319b9773e49 100644
--- a/library/core/benches/num/flt2dec/strategy/dragon.rs
+++ b/library/core/benches/num/flt2dec/strategy/dragon.rs
@@ -1,59 +1,76 @@
 use super::super::*;
 use core::num::flt2dec::strategy::dragon::*;
+use std::mem::MaybeUninit;
 use test::Bencher;
 
 #[bench]
 fn bench_small_shortest(b: &mut Bencher) {
     let decoded = decode_finite(3.141592f64);
-    let mut buf = [0; MAX_SIG_DIGITS];
-    b.iter(|| format_shortest(&decoded, &mut buf));
+    let mut buf = [MaybeUninit::new(0); MAX_SIG_DIGITS];
+    b.iter(|| {
+        format_shortest(&decoded, &mut buf);
+    });
 }
 
 #[bench]
 fn bench_big_shortest(b: &mut Bencher) {
     let decoded = decode_finite(f64::MAX);
-    let mut buf = [0; MAX_SIG_DIGITS];
-    b.iter(|| format_shortest(&decoded, &mut buf));
+    let mut buf = [MaybeUninit::new(0); MAX_SIG_DIGITS];
+    b.iter(|| {
+        format_shortest(&decoded, &mut buf);
+    });
 }
 
 #[bench]
 fn bench_small_exact_3(b: &mut Bencher) {
     let decoded = decode_finite(3.141592f64);
-    let mut buf = [0; 3];
-    b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+    let mut buf = [MaybeUninit::new(0); 3];
+    b.iter(|| {
+        format_exact(&decoded, &mut buf, i16::MIN);
+    });
 }
 
 #[bench]
 fn bench_big_exact_3(b: &mut Bencher) {
     let decoded = decode_finite(f64::MAX);
-    let mut buf = [0; 3];
-    b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+    let mut buf = [MaybeUninit::new(0); 3];
+    b.iter(|| {
+        format_exact(&decoded, &mut buf, i16::MIN);
+    });
 }
 
 #[bench]
 fn bench_small_exact_12(b: &mut Bencher) {
     let decoded = decode_finite(3.141592f64);
-    let mut buf = [0; 12];
-    b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+    let mut buf = [MaybeUninit::new(0); 12];
+    b.iter(|| {
+        format_exact(&decoded, &mut buf, i16::MIN);
+    });
 }
 
 #[bench]
 fn bench_big_exact_12(b: &mut Bencher) {
     let decoded = decode_finite(f64::MAX);
-    let mut buf = [0; 12];
-    b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+    let mut buf = [MaybeUninit::new(0); 12];
+    b.iter(|| {
+        format_exact(&decoded, &mut buf, i16::MIN);
+    });
 }
 
 #[bench]
 fn bench_small_exact_inf(b: &mut Bencher) {
     let decoded = decode_finite(3.141592f64);
-    let mut buf = [0; 1024];
-    b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+    let mut buf = [MaybeUninit::new(0); 1024];
+    b.iter(|| {
+        format_exact(&decoded, &mut buf, i16::MIN);
+    });
 }
 
 #[bench]
 fn bench_big_exact_inf(b: &mut Bencher) {
     let decoded = decode_finite(f64::MAX);
-    let mut buf = [0; 1024];
-    b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+    let mut buf = [MaybeUninit::new(0); 1024];
+    b.iter(|| {
+        format_exact(&decoded, &mut buf, i16::MIN);
+    });
 }
diff --git a/library/core/benches/num/flt2dec/strategy/grisu.rs b/library/core/benches/num/flt2dec/strategy/grisu.rs
index 77ca901a90a..76425731e1d 100644
--- a/library/core/benches/num/flt2dec/strategy/grisu.rs
+++ b/library/core/benches/num/flt2dec/strategy/grisu.rs
@@ -1,5 +1,6 @@
 use super::super::*;
 use core::num::flt2dec::strategy::grisu::*;
+use std::mem::MaybeUninit;
 use test::Bencher;
 
 pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
@@ -12,55 +13,71 @@ pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
 #[bench]
 fn bench_small_shortest(b: &mut Bencher) {
     let decoded = decode_finite(3.141592f64);
-    let mut buf = [0; MAX_SIG_DIGITS];
-    b.iter(|| format_shortest(&decoded, &mut buf));
+    let mut buf = [MaybeUninit::new(0); MAX_SIG_DIGITS];
+    b.iter(|| {
+        format_shortest(&decoded, &mut buf);
+    });
 }
 
 #[bench]
 fn bench_big_shortest(b: &mut Bencher) {
     let decoded = decode_finite(f64::MAX);
-    let mut buf = [0; MAX_SIG_DIGITS];
-    b.iter(|| format_shortest(&decoded, &mut buf));
+    let mut buf = [MaybeUninit::new(0); MAX_SIG_DIGITS];
+    b.iter(|| {
+        format_shortest(&decoded, &mut buf);
+    });
 }
 
 #[bench]
 fn bench_small_exact_3(b: &mut Bencher) {
     let decoded = decode_finite(3.141592f64);
-    let mut buf = [0; 3];
-    b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+    let mut buf = [MaybeUninit::new(0); 3];
+    b.iter(|| {
+        format_exact(&decoded, &mut buf, i16::MIN);
+    });
 }
 
 #[bench]
 fn bench_big_exact_3(b: &mut Bencher) {
     let decoded = decode_finite(f64::MAX);
-    let mut buf = [0; 3];
-    b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+    let mut buf = [MaybeUninit::new(0); 3];
+    b.iter(|| {
+        format_exact(&decoded, &mut buf, i16::MIN);
+    });
 }
 
 #[bench]
 fn bench_small_exact_12(b: &mut Bencher) {
     let decoded = decode_finite(3.141592f64);
-    let mut buf = [0; 12];
-    b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+    let mut buf = [MaybeUninit::new(0); 12];
+    b.iter(|| {
+        format_exact(&decoded, &mut buf, i16::MIN);
+    });
 }
 
 #[bench]
 fn bench_big_exact_12(b: &mut Bencher) {
     let decoded = decode_finite(f64::MAX);
-    let mut buf = [0; 12];
-    b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+    let mut buf = [MaybeUninit::new(0); 12];
+    b.iter(|| {
+        format_exact(&decoded, &mut buf, i16::MIN);
+    });
 }
 
 #[bench]
 fn bench_small_exact_inf(b: &mut Bencher) {
     let decoded = decode_finite(3.141592f64);
-    let mut buf = [0; 1024];
-    b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+    let mut buf = [MaybeUninit::new(0); 1024];
+    b.iter(|| {
+        format_exact(&decoded, &mut buf, i16::MIN);
+    });
 }
 
 #[bench]
 fn bench_big_exact_inf(b: &mut Bencher) {
     let decoded = decode_finite(f64::MAX);
-    let mut buf = [0; 1024];
-    b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+    let mut buf = [MaybeUninit::new(0); 1024];
+    b.iter(|| {
+        format_exact(&decoded, &mut buf, i16::MIN);
+    });
 }
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index f85be5584e3..f45c99c285c 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -422,4 +422,17 @@ impl<T, const N: usize> [T; N] {
         // and we just need to cast it to the correct type.
         unsafe { crate::mem::transmute_copy::<_, [U; N]>(&dst) }
     }
+
+    /// Returns a slice containing the entire array. Equivalent to `&s[..]`.
+    #[unstable(feature = "array_methods", issue = "76118")]
+    pub fn as_slice(&self) -> &[T] {
+        self
+    }
+
+    /// Returns a mutable slice containing the entire array. Equivalent to
+    /// `&mut s[..]`.
+    #[unstable(feature = "array_methods", issue = "76118")]
+    pub fn as_mut_slice(&mut self) -> &mut [T] {
+        self
+    }
 }
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index 7784ec687ea..a953a3a4182 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -7,11 +7,9 @@
 //! contain owned boxes or implement [`Drop`]), so the compiler considers
 //! them cheap and safe to copy. For other types copies must be made
 //! explicitly, by convention implementing the [`Clone`] trait and calling
-//! the [`clone`][clone] method.
+//! the [`clone`] method.
 //!
-//! [`Clone`]: trait.Clone.html
-//! [clone]: trait.Clone.html#tymethod.clone
-//! [`Drop`]: ../../std/ops/trait.Drop.html
+//! [`clone`]: Clone::clone
 //!
 //! Basic usage example:
 //!
@@ -51,7 +49,9 @@
 /// ## Derivable
 ///
 /// This trait can be used with `#[derive]` if all fields are `Clone`. The `derive`d
-/// implementation of [`clone`] calls [`clone`] on each field.
+/// implementation of [`Clone`] calls [`clone`] on each field.
+///
+/// [`clone`]: Clone::clone
 ///
 /// For a generic struct, `#[derive]` implements `Clone` conditionally by adding bound `Clone` on
 /// generic parameters.
@@ -74,9 +74,6 @@
 /// An example is a generic struct holding a function pointer. In this case, the
 /// implementation of `Clone` cannot be `derive`d, but can be implemented as:
 ///
-/// [`Copy`]: ../../std/marker/trait.Copy.html
-/// [`clone`]: trait.Clone.html#tymethod.clone
-///
 /// ```
 /// struct Generate<T>(fn() -> T);
 ///
diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs
index 5f10a2eb023..2bfeb49b5fa 100644
--- a/library/core/src/convert/mod.rs
+++ b/library/core/src/convert/mod.rs
@@ -31,13 +31,6 @@
 //!   `into` themselves and `from` themselves
 //!
 //! See each trait for usage examples.
-//!
-//! [`Into`]: trait.Into.html
-//! [`From`]: trait.From.html
-//! [`TryFrom`]: trait.TryFrom.html
-//! [`TryInto`]: trait.TryInto.html
-//! [`AsRef`]: trait.AsRef.html
-//! [`AsMut`]: trait.AsMut.html
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -141,13 +134,11 @@ pub const fn identity<T>(x: T) -> T {
 /// want to accept all references that can be converted to [`&str`] as an argument.
 /// Since both [`String`] and [`&str`] implement `AsRef<str>` we can accept both as input argument.
 ///
-/// [`Option<T>`]: ../../std/option/enum.Option.html
-/// [`Result<T, E>`]: ../../std/result/enum.Result.html
-/// [`Borrow`]: ../../std/borrow/trait.Borrow.html
-/// [`Hash`]: ../../std/hash/trait.Hash.html
-/// [`Eq`]: ../../std/cmp/trait.Eq.html
-/// [`Ord`]: ../../std/cmp/trait.Ord.html
-/// [`&str`]: ../../std/primitive.str.html
+/// [`Option<T>`]: Option
+/// [`Result<T, E>`]: Result
+/// [`Borrow`]: crate::borrow::Borrow
+/// [`Eq`]: crate::cmp::Eq
+/// [`Ord`]: crate::cmp::Ord
 /// [`String`]: ../../std/string/struct.String.html
 ///
 /// ```
@@ -177,8 +168,8 @@ pub trait AsRef<T: ?Sized> {
 /// **Note: This trait must not fail**. If the conversion can fail, use a
 /// dedicated method which returns an [`Option<T>`] or a [`Result<T, E>`].
 ///
-/// [`Option<T>`]: ../../std/option/enum.Option.html
-/// [`Result<T, E>`]: ../../std/result/enum.Result.html
+/// [`Option<T>`]: Option
+/// [`Result<T, E>`]: Result
 ///
 /// # Generic Implementations
 ///
@@ -278,12 +269,9 @@ pub trait AsMut<T: ?Sized> {
 /// is_hello(s);
 /// ```
 ///
-/// [`TryInto`]: trait.TryInto.html
-/// [`Option<T>`]: ../../std/option/enum.Option.html
-/// [`Result<T, E>`]: ../../std/result/enum.Result.html
+/// [`Option<T>`]: Option
+/// [`Result<T, E>`]: Result
 /// [`String`]: ../../std/string/struct.String.html
-/// [`From`]: trait.From.html
-/// [`Into`]: trait.Into.html
 /// [`Vec`]: ../../std/vec/struct.Vec.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Into<T>: Sized {
@@ -370,12 +358,10 @@ pub trait Into<T>: Sized {
 /// }
 /// ```
 ///
-/// [`TryFrom`]: trait.TryFrom.html
-/// [`Option<T>`]: ../../std/option/enum.Option.html
-/// [`Result<T, E>`]: ../../std/result/enum.Result.html
+/// [`Option<T>`]: Option
+/// [`Result<T, E>`]: Result
 /// [`String`]: ../../std/string/struct.String.html
-/// [`Into`]: trait.Into.html
-/// [`from`]: trait.From.html#tymethod.from
+/// [`from`]: From::from
 /// [book]: ../../book/ch09-00-error-handling.html
 #[rustc_diagnostic_item = "from_trait"]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -404,9 +390,6 @@ pub trait From<T>: Sized {
 ///
 /// This suffers the same restrictions and reasoning as implementing
 /// [`Into`], see there for details.
-///
-/// [`TryFrom`]: trait.TryFrom.html
-/// [`Into`]: trait.Into.html
 #[stable(feature = "try_from", since = "1.34.0")]
 pub trait TryInto<T>: Sized {
     /// The type returned in the event of a conversion error.
@@ -485,11 +468,9 @@ pub trait TryInto<T>: Sized {
 /// assert!(try_successful_smaller_number.is_ok());
 /// ```
 ///
-/// [`try_from`]: trait.TryFrom.html#tymethod.try_from
-/// [`TryInto`]: trait.TryInto.html
-/// [`i32::MAX`]: ../../std/i32/constant.MAX.html
+/// [`i32::MAX`]: crate::i32::MAX
+/// [`try_from`]: TryFrom::try_from
 /// [`!`]: ../../std/primitive.never.html
-/// [`Infallible`]: enum.Infallible.html
 #[stable(feature = "try_from", since = "1.34.0")]
 pub trait TryFrom<T>: Sized {
     /// The type returned in the event of a conversion error.
@@ -676,7 +657,6 @@ impl AsRef<str> for str {
 ///
 /// … and eventually deprecate `Infallible`.
 ///
-///
 /// However there is one case where `!` syntax can be used
 /// before `!` is stabilized as a full-fledged type: in the position of a function’s return type.
 /// Specifically, it is possible implementations for two different function pointer types:
@@ -692,10 +672,6 @@ impl AsRef<str> for str {
 /// the two `impl`s will start to overlap
 /// and therefore will be disallowed by the language’s trait coherence rules.
 ///
-/// [`Ok`]: ../result/enum.Result.html#variant.Ok
-/// [`Result`]: ../result/enum.Result.html
-/// [`TryFrom`]: trait.TryFrom.html
-/// [`Into`]: trait.Into.html
 /// [never]: ../../std/primitive.never.html
 #[stable(feature = "convert_infallible", since = "1.34.0")]
 #[derive(Copy)]
diff --git a/library/core/src/fmt/float.rs b/library/core/src/fmt/float.rs
index 52d8349bc9a..5908da477e1 100644
--- a/library/core/src/fmt/float.rs
+++ b/library/core/src/fmt/float.rs
@@ -14,25 +14,17 @@ fn float_to_decimal_common_exact<T>(
 where
     T: flt2dec::DecodableFloat,
 {
-    // SAFETY: Possible undefined behavior, see FIXME(#53491)
-    unsafe {
-        let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64
-        let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 4]>::uninit();
-        // FIXME(#53491): This is calling `get_mut` on an uninitialized
-        // `MaybeUninit` (here and elsewhere in this file). Revisit this once
-        // we decided whether that is valid or not.
-        // We can do this only because we are libstd and coupled to the compiler.
-        // (FWIW, using `freeze` would not be enough; `flt2dec::Part` is an enum!)
-        let formatted = flt2dec::to_exact_fixed_str(
-            flt2dec::strategy::grisu::format_exact,
-            *num,
-            sign,
-            precision,
-            buf.get_mut(),
-            parts.get_mut(),
-        );
-        fmt.pad_formatted_parts(&formatted)
-    }
+    let mut buf: [MaybeUninit<u8>; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64
+    let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 4] = MaybeUninit::uninit_array();
+    let formatted = flt2dec::to_exact_fixed_str(
+        flt2dec::strategy::grisu::format_exact,
+        *num,
+        sign,
+        precision,
+        &mut buf,
+        &mut parts,
+    );
+    fmt.pad_formatted_parts(&formatted)
 }
 
 // Don't inline this so callers that call both this and the above won't wind
@@ -47,22 +39,18 @@ fn float_to_decimal_common_shortest<T>(
 where
     T: flt2dec::DecodableFloat,
 {
-    // SAFETY: Possible undefined behavior, see FIXME(#53491)
-    unsafe {
-        // enough for f32 and f64
-        let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninit();
-        let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 4]>::uninit();
-        // FIXME(#53491)
-        let formatted = flt2dec::to_shortest_str(
-            flt2dec::strategy::grisu::format_shortest,
-            *num,
-            sign,
-            precision,
-            buf.get_mut(),
-            parts.get_mut(),
-        );
-        fmt.pad_formatted_parts(&formatted)
-    }
+    // enough for f32 and f64
+    let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array();
+    let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 4] = MaybeUninit::uninit_array();
+    let formatted = flt2dec::to_shortest_str(
+        flt2dec::strategy::grisu::format_shortest,
+        *num,
+        sign,
+        precision,
+        &mut buf,
+        &mut parts,
+    );
+    fmt.pad_formatted_parts(&formatted)
 }
 
 // Common code of floating point Debug and Display.
@@ -103,22 +91,18 @@ fn float_to_exponential_common_exact<T>(
 where
     T: flt2dec::DecodableFloat,
 {
-    // SAFETY: Possible undefined behavior, see FIXME(#53491)
-    unsafe {
-        let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64
-        let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 6]>::uninit();
-        // FIXME(#53491)
-        let formatted = flt2dec::to_exact_exp_str(
-            flt2dec::strategy::grisu::format_exact,
-            *num,
-            sign,
-            precision,
-            upper,
-            buf.get_mut(),
-            parts.get_mut(),
-        );
-        fmt.pad_formatted_parts(&formatted)
-    }
+    let mut buf: [MaybeUninit<u8>; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64
+    let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 6] = MaybeUninit::uninit_array();
+    let formatted = flt2dec::to_exact_exp_str(
+        flt2dec::strategy::grisu::format_exact,
+        *num,
+        sign,
+        precision,
+        upper,
+        &mut buf,
+        &mut parts,
+    );
+    fmt.pad_formatted_parts(&formatted)
 }
 
 // Don't inline this so callers that call both this and the above won't wind
@@ -133,23 +117,19 @@ fn float_to_exponential_common_shortest<T>(
 where
     T: flt2dec::DecodableFloat,
 {
-    // SAFETY: Possible undefined behavior, see FIXME(#53491)
-    unsafe {
-        // enough for f32 and f64
-        let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninit();
-        let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 6]>::uninit();
-        // FIXME(#53491)
-        let formatted = flt2dec::to_shortest_exp_str(
-            flt2dec::strategy::grisu::format_shortest,
-            *num,
-            sign,
-            (0, 0),
-            upper,
-            buf.get_mut(),
-            parts.get_mut(),
-        );
-        fmt.pad_formatted_parts(&formatted)
-    }
+    // enough for f32 and f64
+    let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array();
+    let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 6] = MaybeUninit::uninit_array();
+    let formatted = flt2dec::to_shortest_exp_str(
+        flt2dec::strategy::grisu::format_shortest,
+        *num,
+        sign,
+        (0, 0),
+        upper,
+        &mut buf,
+        &mut parts,
+    );
+    fmt.pad_formatted_parts(&formatted)
 }
 
 // Common code of floating point LowerExp and UpperExp.
diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs
index 9fcd137e1a6..f32c3963abe 100644
--- a/library/core/src/iter/adapters/mod.rs
+++ b/library/core/src/iter/adapters/mod.rs
@@ -1,9 +1,9 @@
 use crate::cmp;
 use crate::fmt;
 use crate::intrinsics;
-use crate::ops::{Add, AddAssign, Try};
+use crate::ops::{Add, AddAssign, ControlFlow, Try};
 
-use super::{from_fn, LoopState};
+use super::from_fn;
 use super::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator, TrustedLen};
 
 mod chain;
@@ -1164,10 +1164,10 @@ where
         #[inline]
         fn find<T, B>(
             f: &mut impl FnMut(T) -> Option<B>,
-        ) -> impl FnMut((), T) -> LoopState<(), B> + '_ {
+        ) -> impl FnMut((), T) -> ControlFlow<(), B> + '_ {
             move |(), x| match f(x) {
-                Some(x) => LoopState::Break(x),
-                None => LoopState::Continue(()),
+                Some(x) => ControlFlow::Break(x),
+                None => ControlFlow::Continue(()),
             }
         }
 
@@ -1864,13 +1864,13 @@ where
             flag: &'a mut bool,
             p: &'a mut impl FnMut(&T) -> bool,
             mut fold: impl FnMut(Acc, T) -> R + 'a,
-        ) -> impl FnMut(Acc, T) -> LoopState<Acc, R> + 'a {
+        ) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a {
             move |acc, x| {
                 if p(&x) {
-                    LoopState::from_try(fold(acc, x))
+                    ControlFlow::from_try(fold(acc, x))
                 } else {
                     *flag = true;
-                    LoopState::Break(Try::from_ok(acc))
+                    ControlFlow::Break(Try::from_ok(acc))
                 }
             }
         }
@@ -1963,8 +1963,8 @@ where
     {
         let Self { iter, predicate } = self;
         iter.try_fold(init, |acc, x| match predicate(x) {
-            Some(item) => LoopState::from_try(fold(acc, item)),
-            None => LoopState::Break(Try::from_ok(acc)),
+            Some(item) => ControlFlow::from_try(fold(acc, item)),
+            None => ControlFlow::Break(Try::from_ok(acc)),
         })
         .into_try()
     }
@@ -2135,11 +2135,11 @@ where
         fn check<T, Acc, R: Try<Ok = Acc>>(
             mut n: usize,
             mut fold: impl FnMut(Acc, T) -> R,
-        ) -> impl FnMut(Acc, T) -> LoopState<Acc, R> {
+        ) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> {
             move |acc, x| {
                 n -= 1;
                 let r = fold(acc, x);
-                if n == 0 { LoopState::Break(r) } else { LoopState::from_try(r) }
+                if n == 0 { ControlFlow::Break(r) } else { ControlFlow::from_try(r) }
             }
         }
 
@@ -2246,11 +2246,11 @@ where
         fn check<'a, T, Acc, R: Try<Ok = Acc>>(
             n: &'a mut usize,
             mut fold: impl FnMut(Acc, T) -> R + 'a,
-        ) -> impl FnMut(Acc, T) -> LoopState<Acc, R> + 'a {
+        ) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a {
             move |acc, x| {
                 *n -= 1;
                 let r = fold(acc, x);
-                if *n == 0 { LoopState::Break(r) } else { LoopState::from_try(r) }
+                if *n == 0 { ControlFlow::Break(r) } else { ControlFlow::from_try(r) }
             }
         }
 
@@ -2414,10 +2414,10 @@ where
             state: &'a mut St,
             f: &'a mut impl FnMut(&mut St, T) -> Option<B>,
             mut fold: impl FnMut(Acc, B) -> R + 'a,
-        ) -> impl FnMut(Acc, T) -> LoopState<Acc, R> + 'a {
+        ) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a {
             move |acc, x| match f(state, x) {
-                None => LoopState::Break(Try::from_ok(acc)),
-                Some(x) => LoopState::from_try(fold(acc, x)),
+                None => ControlFlow::Break(Try::from_ok(acc)),
+                Some(x) => ControlFlow::from_try(fold(acc, x)),
             }
         }
 
@@ -2638,10 +2638,10 @@ where
         let error = &mut *self.error;
         self.iter
             .try_fold(init, |acc, x| match x {
-                Ok(x) => LoopState::from_try(f(acc, x)),
+                Ok(x) => ControlFlow::from_try(f(acc, x)),
                 Err(e) => {
                     *error = Err(e);
-                    LoopState::Break(Try::from_ok(acc))
+                    ControlFlow::Break(Try::from_ok(acc))
                 }
             })
             .into_try()
diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs
index 9b528cdbe30..bab8dda2915 100644
--- a/library/core/src/iter/mod.rs
+++ b/library/core/src/iter/mod.rs
@@ -54,8 +54,7 @@
 //! below for more details.
 //!
 //! [`Some(Item)`]: Some
-//! [`Iterator`]: trait.Iterator.html
-//! [`next`]: trait.Iterator.html#tymethod.next
+//! [`next`]: Iterator::next
 //! [`TryIter`]: ../../std/sync/mpsc/struct.TryIter.html
 //!
 //! # The three forms of iteration
@@ -136,7 +135,7 @@
 //! methods like `nth` and `fold` if an iterator can compute them more efficiently without calling
 //! `next`.
 //!
-//! # for Loops and IntoIterator
+//! # `for` loops and `IntoIterator`
 //!
 //! Rust's `for` loop syntax is actually sugar for iterators. Here's a basic
 //! example of `for`:
@@ -159,8 +158,7 @@
 //! Let's take a look at that `for` loop again, and what the compiler converts
 //! it into:
 //!
-//! [`IntoIterator`]: trait.IntoIterator.html
-//! [`into_iter`]: trait.IntoIterator.html#tymethod.into_iter
+//! [`into_iter`]: IntoIterator::into_iter
 //!
 //! ```
 //! let values = vec![1, 2, 3, 4, 5];
@@ -222,9 +220,9 @@
 //! across versions of Rust, so you should avoid relying on the exact values
 //! returned by an iterator which panicked.
 //!
-//! [`map`]: trait.Iterator.html#method.map
-//! [`take`]: trait.Iterator.html#method.take
-//! [`filter`]: trait.Iterator.html#method.filter
+//! [`map`]: Iterator::map
+//! [`take`]: Iterator::take
+//! [`filter`]: Iterator::filter
 //!
 //! # Laziness
 //!
@@ -261,13 +259,13 @@
 //! }
 //! ```
 //!
-//! [`map`]: trait.Iterator.html#method.map
-//! [`for_each`]: trait.Iterator.html#method.for_each
+//! [`map`]: Iterator::map
+//! [`for_each`]: Iterator::for_each
 //!
 //! Another common way to evaluate an iterator is to use the [`collect`]
 //! method to produce a new collection.
 //!
-//! [`collect`]: trait.Iterator.html#method.collect
+//! [`collect`]: Iterator::collect
 //!
 //! # Infinity
 //!
@@ -305,13 +303,11 @@
 //! println!("The smallest number one is {}.", least);
 //! ```
 //!
-//! [`take`]: trait.Iterator.html#method.take
-//! [`min`]: trait.Iterator.html#method.min
+//! [`take`]: Iterator::take
+//! [`min`]: Iterator::min
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use crate::ops::Try;
-
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::traits::Iterator;
 
@@ -369,57 +365,3 @@ mod adapters;
 mod range;
 mod sources;
 mod traits;
-
-/// Used to make try_fold closures more like normal loops
-#[derive(PartialEq)]
-enum LoopState<C, B> {
-    Continue(C),
-    Break(B),
-}
-
-impl<C, B> Try for LoopState<C, B> {
-    type Ok = C;
-    type Error = B;
-    #[inline]
-    fn into_result(self) -> Result<Self::Ok, Self::Error> {
-        match self {
-            LoopState::Continue(y) => Ok(y),
-            LoopState::Break(x) => Err(x),
-        }
-    }
-    #[inline]
-    fn from_error(v: Self::Error) -> Self {
-        LoopState::Break(v)
-    }
-    #[inline]
-    fn from_ok(v: Self::Ok) -> Self {
-        LoopState::Continue(v)
-    }
-}
-
-impl<C, B> LoopState<C, B> {
-    #[inline]
-    fn break_value(self) -> Option<B> {
-        match self {
-            LoopState::Continue(..) => None,
-            LoopState::Break(x) => Some(x),
-        }
-    }
-}
-
-impl<R: Try> LoopState<R::Ok, R> {
-    #[inline]
-    fn from_try(r: R) -> Self {
-        match Try::into_result(r) {
-            Ok(v) => LoopState::Continue(v),
-            Err(v) => LoopState::Break(Try::from_error(v)),
-        }
-    }
-    #[inline]
-    fn into_try(self) -> R {
-        match self {
-            LoopState::Continue(v) => Try::from_ok(v),
-            LoopState::Break(v) => v,
-        }
-    }
-}
diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs
index 323fdbb45f3..f50807116bd 100644
--- a/library/core/src/iter/traits/double_ended.rs
+++ b/library/core/src/iter/traits/double_ended.rs
@@ -1,5 +1,4 @@
-use crate::iter::LoopState;
-use crate::ops::Try;
+use crate::ops::{ControlFlow, Try};
 
 /// An iterator able to yield elements from both ends.
 ///
@@ -309,9 +308,9 @@ pub trait DoubleEndedIterator: Iterator {
         #[inline]
         fn check<T>(
             mut predicate: impl FnMut(&T) -> bool,
-        ) -> impl FnMut((), T) -> LoopState<(), T> {
+        ) -> impl FnMut((), T) -> ControlFlow<(), T> {
             move |(), x| {
-                if predicate(&x) { LoopState::Break(x) } else { LoopState::Continue(()) }
+                if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::Continue(()) }
             }
         }
 
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index a1d11b597a1..46ef12cd938 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -3,9 +3,8 @@
 // can't split that into multiple files.
 
 use crate::cmp::{self, Ordering};
-use crate::ops::{Add, Try};
+use crate::ops::{Add, ControlFlow, Try};
 
-use super::super::LoopState;
 use super::super::TrustedRandomAccess;
 use super::super::{Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse};
 use super::super::{FlatMap, Flatten};
@@ -22,8 +21,8 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
 /// generally, please see the [module-level documentation]. In particular, you
 /// may want to know how to [implement `Iterator`][impl].
 ///
-/// [module-level documentation]: index.html
-/// [impl]: index.html#implementing-iterator
+/// [module-level documentation]: crate::iter
+/// [impl]: crate::iter#implementing-iterator
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_on_unimplemented(
     on(
@@ -212,7 +211,7 @@ pub trait Iterator {
     /// returning the number of times it saw [`Some`]. Note that [`next`] has to be
     /// called at least once even if the iterator does not have any elements.
     ///
-    /// [`next`]: #tymethod.next
+    /// [`next`]: Iterator::next
     ///
     /// # Overflow Behavior
     ///
@@ -449,9 +448,7 @@ pub trait Iterator {
     /// }
     /// ```
     ///
-    /// [`once`]: fn.once.html
-    /// [`Iterator`]: trait.Iterator.html
-    /// [`IntoIterator`]: trait.IntoIterator.html
+    /// [`once`]: crate::iter::once
     /// [`OsStr`]: ../../std/ffi/struct.OsStr.html
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -496,9 +493,6 @@ pub trait Iterator {
     /// [`Iterator`] itself. For example, slices (`&[T]`) implement
     /// [`IntoIterator`], and so can be passed to `zip()` directly:
     ///
-    /// [`IntoIterator`]: trait.IntoIterator.html
-    /// [`Iterator`]: trait.Iterator.html
-    ///
     /// ```
     /// let s1 = &[1, 2, 3];
     /// let s2 = &[4, 5, 6];
@@ -530,8 +524,8 @@ pub trait Iterator {
     /// assert_eq!((2, 'o'), zipper[2]);
     /// ```
     ///
-    /// [`enumerate`]: #method.enumerate
-    /// [`next`]: #tymethod.next
+    /// [`enumerate`]: Iterator::enumerate
+    /// [`next`]: Iterator::next
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter>
@@ -734,8 +728,8 @@ pub trait Iterator {
     /// Why `filter_map` and not just [`filter`] and [`map`]? The key is in this
     /// part:
     ///
-    /// [`filter`]: #method.filter
-    /// [`map`]: #method.map
+    /// [`filter`]: Iterator::filter
+    /// [`map`]: Iterator::map
     ///
     /// > If the closure returns [`Some(element)`][`Some`], then that element is returned.
     ///
@@ -802,7 +796,7 @@ pub trait Iterator {
     ///
     /// [`usize`]: type@usize
     /// [`usize::MAX`]: crate::usize::MAX
-    /// [`zip`]: #method.zip
+    /// [`zip`]: Iterator::zip
     ///
     /// # Examples
     ///
@@ -837,8 +831,8 @@ pub trait Iterator {
     /// anything other than fetching the next value) of the [`next`] method
     /// will occur.
     ///
-    /// [`peek`]: crate::iter::Peekable::peek
-    /// [`next`]: #tymethod.next
+    /// [`peek`]: Peekable::peek
+    /// [`next`]: Iterator::next
     ///
     /// # Examples
     ///
@@ -876,7 +870,7 @@ pub trait Iterator {
 
     /// Creates an iterator that [`skip`]s elements based on a predicate.
     ///
-    /// [`skip`]: #method.skip
+    /// [`skip`]: Iterator::skip
     ///
     /// `skip_while()` takes a closure as an argument. It will call this
     /// closure on each element of the iterator, and ignore elements
@@ -1043,8 +1037,8 @@ pub trait Iterator {
     ///
     /// Here's the same example, but with [`take_while`] and [`map`]:
     ///
-    /// [`take_while`]: #method.take_while
-    /// [`map`]: #method.map
+    /// [`take_while`]: Iterator::take_while
+    /// [`map`]: Iterator::map
     ///
     /// ```
     /// let a = [-1i32, 4, 0, 1];
@@ -1104,7 +1098,7 @@ pub trait Iterator {
     /// It is also not specified what this iterator returns after the first` None` is returned.
     /// If you need fused iterator, use [`fuse`].
     ///
-    /// [`fuse`]: #method.fuse
+    /// [`fuse`]: Iterator::fuse
     #[inline]
     #[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
     fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
@@ -1190,7 +1184,7 @@ pub trait Iterator {
     /// An iterator adaptor similar to [`fold`] that holds internal state and
     /// produces a new iterator.
     ///
-    /// [`fold`]: #method.fold
+    /// [`fold`]: Iterator::fold
     ///
     /// `scan()` takes two arguments: an initial value which seeds the internal
     /// state, and a closure with two arguments, the first being a mutable
@@ -1246,8 +1240,8 @@ pub trait Iterator {
     /// one item for each element, and `flat_map()`'s closure returns an
     /// iterator for each element.
     ///
-    /// [`map`]: #method.map
-    /// [`flatten`]: #method.flatten
+    /// [`map`]: Iterator::map
+    /// [`flatten`]: Iterator::flatten
     ///
     /// # Examples
     ///
@@ -1333,7 +1327,7 @@ pub trait Iterator {
     /// two-dimensional and not one-dimensional. To get a one-dimensional
     /// structure, you have to `flatten()` again.
     ///
-    /// [`flat_map()`]: #method.flat_map
+    /// [`flat_map()`]: Iterator::flat_map
     #[inline]
     #[stable(feature = "iterator_flatten", since = "1.29.0")]
     fn flatten(self) -> Flatten<Self>
@@ -1640,7 +1634,7 @@ pub trait Iterator {
     /// assert_eq!(Ok(vec![1, 3]), result);
     /// ```
     ///
-    /// [`iter`]: #tymethod.next
+    /// [`iter`]: Iterator::next
     /// [`String`]: ../../std/string/struct.String.html
     /// [`char`]: type@char
     #[inline]
@@ -1661,8 +1655,8 @@ pub trait Iterator {
     ///
     /// See also [`is_partitioned()`] and [`partition_in_place()`].
     ///
-    /// [`is_partitioned()`]: #method.is_partitioned
-    /// [`partition_in_place()`]: #method.partition_in_place
+    /// [`is_partitioned()`]: Iterator::is_partitioned
+    /// [`partition_in_place()`]: Iterator::partition_in_place
     ///
     /// # Examples
     ///
@@ -1716,8 +1710,8 @@ pub trait Iterator {
     ///
     /// See also [`is_partitioned()`] and [`partition()`].
     ///
-    /// [`is_partitioned()`]: #method.is_partitioned
-    /// [`partition()`]: #method.partition
+    /// [`is_partitioned()`]: Iterator::is_partitioned
+    /// [`partition()`]: Iterator::partition
     ///
     /// # Examples
     ///
@@ -1779,8 +1773,8 @@ pub trait Iterator {
     ///
     /// See also [`partition()`] and [`partition_in_place()`].
     ///
-    /// [`partition()`]: #method.partition
-    /// [`partition_in_place()`]: #method.partition_in_place
+    /// [`partition()`]: Iterator::partition
+    /// [`partition_in_place()`]: Iterator::partition_in_place
     ///
     /// # Examples
     ///
@@ -1879,8 +1873,8 @@ pub trait Iterator {
     /// This can also be thought of as the fallible form of [`for_each()`]
     /// or as the stateless version of [`try_fold()`].
     ///
-    /// [`for_each()`]: #method.for_each
-    /// [`try_fold()`]: #method.try_fold
+    /// [`for_each()`]: Iterator::for_each
+    /// [`try_fold()`]: Iterator::try_fold
     ///
     /// # Examples
     ///
@@ -2006,11 +2000,13 @@ pub trait Iterator {
         accum
     }
 
-    /// The same as [`fold()`](#method.fold), but uses the first element in the
+    /// The same as [`fold()`], but uses the first element in the
     /// iterator as the initial value, folding every subsequent element into it.
     /// If the iterator is empty, return `None`; otherwise, return the result
     /// of the fold.
     ///
+    /// [`fold()`]: Iterator::fold
+    ///
     /// # Example
     ///
     /// Find the maximum value:
@@ -2088,12 +2084,12 @@ pub trait Iterator {
         F: FnMut(Self::Item) -> bool,
     {
         #[inline]
-        fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> LoopState<(), ()> {
+        fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> {
             move |(), x| {
-                if f(x) { LoopState::Continue(()) } else { LoopState::Break(()) }
+                if f(x) { ControlFlow::Continue(()) } else { ControlFlow::Break(()) }
             }
         }
-        self.try_fold((), check(f)) == LoopState::Continue(())
+        self.try_fold((), check(f)) == ControlFlow::Continue(())
     }
 
     /// Tests if any element of the iterator matches a predicate.
@@ -2141,13 +2137,13 @@ pub trait Iterator {
         F: FnMut(Self::Item) -> bool,
     {
         #[inline]
-        fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> LoopState<(), ()> {
+        fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> {
             move |(), x| {
-                if f(x) { LoopState::Break(()) } else { LoopState::Continue(()) }
+                if f(x) { ControlFlow::Break(()) } else { ControlFlow::Continue(()) }
             }
         }
 
-        self.try_fold((), check(f)) == LoopState::Break(())
+        self.try_fold((), check(f)) == ControlFlow::Break(())
     }
 
     /// Searches for an element of an iterator that satisfies a predicate.
@@ -2203,9 +2199,9 @@ pub trait Iterator {
         #[inline]
         fn check<T>(
             mut predicate: impl FnMut(&T) -> bool,
-        ) -> impl FnMut((), T) -> LoopState<(), T> {
+        ) -> impl FnMut((), T) -> ControlFlow<(), T> {
             move |(), x| {
-                if predicate(&x) { LoopState::Break(x) } else { LoopState::Continue(()) }
+                if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::Continue(()) }
             }
         }
 
@@ -2235,10 +2231,12 @@ pub trait Iterator {
         F: FnMut(Self::Item) -> Option<B>,
     {
         #[inline]
-        fn check<T, B>(mut f: impl FnMut(T) -> Option<B>) -> impl FnMut((), T) -> LoopState<(), B> {
+        fn check<T, B>(
+            mut f: impl FnMut(T) -> Option<B>,
+        ) -> impl FnMut((), T) -> ControlFlow<(), B> {
             move |(), x| match f(x) {
-                Some(x) => LoopState::Break(x),
-                None => LoopState::Continue(()),
+                Some(x) => ControlFlow::Break(x),
+                None => ControlFlow::Continue(()),
             }
         }
 
@@ -2274,15 +2272,15 @@ pub trait Iterator {
         R: Try<Ok = bool>,
     {
         #[inline]
-        fn check<F, T, R>(mut f: F) -> impl FnMut((), T) -> LoopState<(), Result<T, R::Error>>
+        fn check<F, T, R>(mut f: F) -> impl FnMut((), T) -> ControlFlow<(), Result<T, R::Error>>
         where
             F: FnMut(&T) -> R,
             R: Try<Ok = bool>,
         {
             move |(), x| match f(&x).into_result() {
-                Ok(false) => LoopState::Continue(()),
-                Ok(true) => LoopState::Break(Ok(x)),
-                Err(x) => LoopState::Break(Err(x)),
+                Ok(false) => ControlFlow::Continue(()),
+                Ok(true) => ControlFlow::Break(Ok(x)),
+                Err(x) => ControlFlow::Break(Err(x)),
             }
         }
 
@@ -2352,10 +2350,14 @@ pub trait Iterator {
         #[inline]
         fn check<T>(
             mut predicate: impl FnMut(T) -> bool,
-        ) -> impl FnMut(usize, T) -> LoopState<usize, usize> {
+        ) -> impl FnMut(usize, T) -> ControlFlow<usize, usize> {
             // The addition might panic on overflow
             move |i, x| {
-                if predicate(x) { LoopState::Break(i) } else { LoopState::Continue(Add::add(i, 1)) }
+                if predicate(x) {
+                    ControlFlow::Break(i)
+                } else {
+                    ControlFlow::Continue(Add::add(i, 1))
+                }
             }
         }
 
@@ -2411,10 +2413,10 @@ pub trait Iterator {
         #[inline]
         fn check<T>(
             mut predicate: impl FnMut(T) -> bool,
-        ) -> impl FnMut(usize, T) -> LoopState<usize, usize> {
+        ) -> impl FnMut(usize, T) -> ControlFlow<usize, usize> {
             move |i, x| {
                 let i = i - 1;
-                if predicate(x) { LoopState::Break(i) } else { LoopState::Continue(i) }
+                if predicate(x) { ControlFlow::Break(i) } else { ControlFlow::Continue(i) }
             }
         }
 
@@ -2602,8 +2604,6 @@ pub trait Iterator {
     /// This is only possible if the iterator has an end, so `rev()` only
     /// works on [`DoubleEndedIterator`]s.
     ///
-    /// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html
-    ///
     /// # Examples
     ///
     /// ```
@@ -2634,7 +2634,7 @@ pub trait Iterator {
     ///
     /// This function is, in some sense, the opposite of [`zip`].
     ///
-    /// [`zip`]: #method.zip
+    /// [`zip`]: Iterator::zip
     ///
     /// # Examples
     ///
@@ -3078,6 +3078,7 @@ pub trait Iterator {
     /// assert_eq!([1].iter().lt([1].iter()), false);
     /// assert_eq!([1].iter().lt([1, 2].iter()), true);
     /// assert_eq!([1, 2].iter().lt([1].iter()), false);
+    /// assert_eq!([1, 2].iter().lt([1, 2].iter()), false);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
     fn lt<I>(self, other: I) -> bool
@@ -3098,6 +3099,7 @@ pub trait Iterator {
     /// assert_eq!([1].iter().le([1].iter()), true);
     /// assert_eq!([1].iter().le([1, 2].iter()), true);
     /// assert_eq!([1, 2].iter().le([1].iter()), false);
+    /// assert_eq!([1, 2].iter().le([1, 2].iter()), true);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
     fn le<I>(self, other: I) -> bool
@@ -3118,6 +3120,7 @@ pub trait Iterator {
     /// assert_eq!([1].iter().gt([1].iter()), false);
     /// assert_eq!([1].iter().gt([1, 2].iter()), false);
     /// assert_eq!([1, 2].iter().gt([1].iter()), true);
+    /// assert_eq!([1, 2].iter().gt([1, 2].iter()), false);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
     fn gt<I>(self, other: I) -> bool
@@ -3138,6 +3141,7 @@ pub trait Iterator {
     /// assert_eq!([1].iter().ge([1].iter()), true);
     /// assert_eq!([1].iter().ge([1, 2].iter()), false);
     /// assert_eq!([1, 2].iter().ge([1].iter()), true);
+    /// assert_eq!([1, 2].iter().ge([1, 2].iter()), true);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
     fn ge<I>(self, other: I) -> bool
@@ -3197,7 +3201,7 @@ pub trait Iterator {
     /// assert!(![0.0, 1.0, f32::NAN].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
     /// ```
     ///
-    /// [`is_sorted`]: #method.is_sorted
+    /// [`is_sorted`]: Iterator::is_sorted
     #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
     fn is_sorted_by<F>(mut self, mut compare: F) -> bool
     where
@@ -3226,7 +3230,7 @@ pub trait Iterator {
     /// the elements, as determined by `f`. Apart from that, it's equivalent to [`is_sorted`]; see
     /// its documentation for more information.
     ///
-    /// [`is_sorted`]: #method.is_sorted
+    /// [`is_sorted`]: Iterator::is_sorted
     ///
     /// # Examples
     ///
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 4e0da1fc4a6..a1b0821004b 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -242,7 +242,7 @@ macro_rules! debug_assert_ne {
 #[macro_export]
 #[stable(feature = "matches_macro", since = "1.42.0")]
 macro_rules! matches {
-    ($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )?) => {
+    ($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )? $(,)?) => {
         match $expression {
             $( $pattern )|+ $( if $guard )? => true,
             _ => false
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index a02ee9c5ba9..9340b591ebd 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -111,13 +111,13 @@ pub trait Sized {
 ///   - `T` is not part of the type of any other fields
 ///   - `Bar<T>: Unsize<Bar<U>>`, if the last field of `Foo` has type `Bar<T>`
 ///
-/// `Unsize` is used along with [`ops::CoerceUnsized`][coerceunsized] to allow
-/// "user-defined" containers such as [`rc::Rc`][rc] to contain dynamically-sized
+/// `Unsize` is used along with [`ops::CoerceUnsized`] to allow
+/// "user-defined" containers such as [`Rc`] to contain dynamically-sized
 /// types. See the [DST coercion RFC][RFC982] and [the nomicon entry on coercion][nomicon-coerce]
 /// for more details.
 ///
-/// [coerceunsized]: ../ops/trait.CoerceUnsized.html
-/// [rc]: ../../std/rc/struct.Rc.html
+/// [`ops::CoerceUnsized`]: crate::ops::CoerceUnsized
+/// [`Rc`]: ../../std/rc/struct.Rc.html
 /// [RFC982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
 /// [nomicon-coerce]: ../../nomicon/coercions.html
 #[unstable(feature = "unsize", issue = "27732")]
@@ -368,11 +368,7 @@ pub trait StructuralEq {
 ///
 /// [`Vec<T>`]: ../../std/vec/struct.Vec.html
 /// [`String`]: ../../std/string/struct.String.html
-/// [`Drop`]: ../../std/ops/trait.Drop.html
-/// [`size_of::<T>`]: ../../std/mem/fn.size_of.html
-/// [`Clone`]: ../clone/trait.Clone.html
-/// [`String`]: ../../std/string/struct.String.html
-/// [`i32`]: ../../std/primitive.i32.html
+/// [`size_of::<T>`]: crate::mem::size_of
 /// [impls]: #implementors
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang = "copy"]
@@ -400,18 +396,18 @@ pub macro Copy($item:item) {
 /// This trait is automatically implemented when the compiler determines
 /// it's appropriate.
 ///
-/// The precise definition is: a type `T` is `Sync` if and only if `&T` is
-/// [`Send`][send]. In other words, if there is no possibility of
+/// The precise definition is: a type `T` is [`Sync`] if and only if `&T` is
+/// [`Send`]. In other words, if there is no possibility of
 /// [undefined behavior][ub] (including data races) when passing
 /// `&T` references between threads.
 ///
-/// As one would expect, primitive types like [`u8`][u8] and [`f64`][f64]
-/// are all `Sync`, and so are simple aggregate types containing them,
-/// like tuples, structs and enums. More examples of basic `Sync`
+/// As one would expect, primitive types like [`u8`] and [`f64`]
+/// are all [`Sync`], and so are simple aggregate types containing them,
+/// like tuples, structs and enums. More examples of basic [`Sync`]
 /// types include "immutable" types like `&T`, and those with simple
 /// inherited mutability, such as [`Box<T>`][box], [`Vec<T>`][vec] and
-/// most other collection types. (Generic parameters need to be `Sync`
-/// for their container to be `Sync`.)
+/// most other collection types. (Generic parameters need to be [`Sync`]
+/// for their container to be [`Sync`].)
 ///
 /// A somewhat surprising consequence of the definition is that `&mut T`
 /// is `Sync` (if `T` is `Sync`) even though it seems like that might
@@ -421,15 +417,15 @@ pub macro Copy($item:item) {
 /// of a data race.
 ///
 /// Types that are not `Sync` are those that have "interior
-/// mutability" in a non-thread-safe form, such as [`cell::Cell`][cell]
-/// and [`cell::RefCell`][refcell]. These types allow for mutation of
+/// mutability" in a non-thread-safe form, such as [`Cell`][cell]
+/// and [`RefCell`][refcell]. These types allow for mutation of
 /// their contents even through an immutable, shared reference. For
 /// example the `set` method on [`Cell<T>`][cell] takes `&self`, so it requires
 /// only a shared reference [`&Cell<T>`][cell]. The method performs no
 /// synchronization, thus [`Cell`][cell] cannot be `Sync`.
 ///
 /// Another example of a non-`Sync` type is the reference-counting
-/// pointer [`rc::Rc`][rc]. Given any reference [`&Rc<T>`][rc], you can clone
+/// pointer [`Rc`][rc]. Given any reference [`&Rc<T>`][rc], you can clone
 /// a new [`Rc<T>`][rc], modifying the reference counts in a non-atomic way.
 ///
 /// For cases when one does need thread-safe interior mutability,
@@ -445,24 +441,21 @@ pub macro Copy($item:item) {
 /// [undefined behavior][ub]. For example, [`transmute`][transmute]-ing
 /// from `&T` to `&mut T` is invalid.
 ///
-/// See [the Nomicon](../../nomicon/send-and-sync.html) for more
-/// details about `Sync`.
+/// See [the Nomicon][nomicon-send-and-sync] for more details about `Sync`.
 ///
-/// [send]: trait.Send.html
-/// [u8]: ../../std/primitive.u8.html
-/// [f64]: ../../std/primitive.f64.html
 /// [box]: ../../std/boxed/struct.Box.html
 /// [vec]: ../../std/vec/struct.Vec.html
-/// [cell]: ../cell/struct.Cell.html
-/// [refcell]: ../cell/struct.RefCell.html
+/// [cell]: crate::cell::Cell
+/// [refcell]: crate::cell::RefCell
 /// [rc]: ../../std/rc/struct.Rc.html
 /// [arc]: ../../std/sync/struct.Arc.html
-/// [atomic data types]: ../sync/atomic/index.html
+/// [atomic data types]: crate::sync::atomic
 /// [mutex]: ../../std/sync/struct.Mutex.html
 /// [rwlock]: ../../std/sync/struct.RwLock.html
-/// [unsafecell]: ../cell/struct.UnsafeCell.html
+/// [unsafecell]: crate::cell::UnsafeCell
 /// [ub]: ../../reference/behavior-considered-undefined.html
-/// [transmute]: ../../std/mem/fn.transmute.html
+/// [transmute]: crate::mem::transmute
+/// [nomicon-send-and-sync]: ../../nomicon/send-and-sync.html
 #[stable(feature = "rust1", since = "1.0.0")]
 #[cfg_attr(not(test), rustc_diagnostic_item = "sync_trait")]
 #[lang = "sync"]
@@ -698,7 +691,7 @@ mod impls {
 /// guarantees to [`mem::Discriminant`]. It is **undefined behavior** to transmute
 /// between `DiscriminantKind::Discriminant` and `mem::Discriminant`.
 ///
-/// [`mem::Discriminant`]: https://doc.rust-lang.org/stable/core/mem/struct.Discriminant.html
+/// [`mem::Discriminant`]: crate::mem::Discriminant
 #[unstable(
     feature = "discriminant_kind",
     issue = "none",
@@ -733,7 +726,7 @@ unsafe impl<T: ?Sized> Freeze for &mut T {}
 ///
 /// The [`Pin`][Pin] type is used instead to prevent moves through the type
 /// system. Pointers `P<T>` wrapped in the [`Pin<P<T>>`][Pin] wrapper can't be
-/// moved out of. See the [`pin module`] documentation for more information on
+/// moved out of. See the [`pin` module] documentation for more information on
 /// pinning.
 ///
 /// Implementing the `Unpin` trait for `T` lifts the restrictions of pinning off
@@ -764,9 +757,9 @@ unsafe impl<T: ?Sized> Freeze for &mut T {}
 ///
 /// This trait is automatically implemented for almost every type.
 ///
-/// [`mem::replace`]: ../../std/mem/fn.replace.html
+/// [`mem::replace`]: crate::mem::replace
 /// [Pin]: crate::pin::Pin
-/// [`pin module`]: crate::pin
+/// [`pin` module]: crate::pin
 #[stable(feature = "pin", since = "1.33.0")]
 #[rustc_on_unimplemented(
     on(_Self = "std::future::Future", note = "consider using `Box::pin`",),
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index d2d65fd2fa5..a79d9e25f34 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -369,7 +369,7 @@ impl<T> MaybeUninit<T> {
     pub fn write(&mut self, val: T) -> &mut T {
         unsafe {
             self.value = ManuallyDrop::new(val);
-            self.get_mut()
+            self.assume_init_mut()
         }
     }
 
@@ -601,7 +601,7 @@ impl<T> MaybeUninit<T> {
     /// // create a shared reference to it:
     /// let x: &Vec<u32> = unsafe {
     ///     // Safety: `x` has been initialized.
-    ///     x.get_ref()
+    ///     x.assume_init_ref()
     /// };
     /// assert_eq!(x, &vec![1, 2, 3]);
     /// ```
@@ -613,7 +613,7 @@ impl<T> MaybeUninit<T> {
     /// use std::mem::MaybeUninit;
     ///
     /// let x = MaybeUninit::<Vec<u32>>::uninit();
-    /// let x_vec: &Vec<u32> = unsafe { x.get_ref() };
+    /// let x_vec: &Vec<u32> = unsafe { x.assume_init_ref() };
     /// // We have created a reference to an uninitialized vector! This is undefined behavior. ⚠️
     /// ```
     ///
@@ -624,14 +624,14 @@ impl<T> MaybeUninit<T> {
     /// let b = MaybeUninit::<Cell<bool>>::uninit();
     /// // Initialize the `MaybeUninit` using `Cell::set`:
     /// unsafe {
-    ///     b.get_ref().set(true);
-    ///  // ^^^^^^^^^^^
-    ///  // Reference to an uninitialized `Cell<bool>`: UB!
+    ///     b.assume_init_ref().set(true);
+    ///    // ^^^^^^^^^^^^^^^
+    ///    // Reference to an uninitialized `Cell<bool>`: UB!
     /// }
     /// ```
     #[unstable(feature = "maybe_uninit_ref", issue = "63568")]
     #[inline(always)]
-    pub unsafe fn get_ref(&self) -> &T {
+    pub unsafe fn assume_init_ref(&self) -> &T {
         // SAFETY: the caller must guarantee that `self` is initialized.
         // This also means that `self` must be a `value` variant.
         unsafe {
@@ -650,7 +650,7 @@ impl<T> MaybeUninit<T> {
     ///
     /// Calling this when the content is not yet fully initialized causes undefined
     /// behavior: it is up to the caller to guarantee that the `MaybeUninit<T>` really
-    /// is in an initialized state. For instance, `.get_mut()` cannot be used to
+    /// is in an initialized state. For instance, `.assume_init_mut()` cannot be used to
     /// initialize a `MaybeUninit`.
     ///
     /// # Examples
@@ -678,7 +678,7 @@ impl<T> MaybeUninit<T> {
     /// // the `&mut MaybeUninit<[u8; 2048]>` to a `&mut [u8; 2048]`:
     /// let buf: &mut [u8; 2048] = unsafe {
     ///     // Safety: `buf` has been initialized.
-    ///     buf.get_mut()
+    ///     buf.assume_init_mut()
     /// };
     ///
     /// // Now we can use `buf` as a normal slice:
@@ -691,7 +691,7 @@ impl<T> MaybeUninit<T> {
     ///
     /// ### *Incorrect* usages of this method:
     ///
-    /// You cannot use `.get_mut()` to initialize a value:
+    /// You cannot use `.assume_init_mut()` to initialize a value:
     ///
     /// ```rust,no_run
     /// #![feature(maybe_uninit_ref)]
@@ -699,7 +699,7 @@ impl<T> MaybeUninit<T> {
     ///
     /// let mut b = MaybeUninit::<bool>::uninit();
     /// unsafe {
-    ///     *b.get_mut() = true;
+    ///     *b.assume_init_mut() = true;
     ///     // We have created a (mutable) reference to an uninitialized `bool`!
     ///     // This is undefined behavior. ⚠️
     /// }
@@ -716,8 +716,8 @@ impl<T> MaybeUninit<T> {
     /// fn read_chunk (reader: &'_ mut dyn io::Read) -> io::Result<[u8; 64]>
     /// {
     ///     let mut buffer = MaybeUninit::<[u8; 64]>::uninit();
-    ///     reader.read_exact(unsafe { buffer.get_mut() })?;
-    ///                             // ^^^^^^^^^^^^^^^^
+    ///     reader.read_exact(unsafe { buffer.assume_init_mut() })?;
+    ///                             // ^^^^^^^^^^^^^^^^^^^^^^^^
     ///                             // (mutable) reference to uninitialized memory!
     ///                             // This is undefined behavior.
     ///     Ok(unsafe { buffer.assume_init() })
@@ -737,23 +737,23 @@ impl<T> MaybeUninit<T> {
     ///
     /// let foo: Foo = unsafe {
     ///     let mut foo = MaybeUninit::<Foo>::uninit();
-    ///     ptr::write(&mut foo.get_mut().a as *mut u32, 1337);
-    ///                  // ^^^^^^^^^^^^^
+    ///     ptr::write(&mut foo.assume_init_mut().a as *mut u32, 1337);
+    ///                  // ^^^^^^^^^^^^^^^^^^^^^
     ///                  // (mutable) reference to uninitialized memory!
     ///                  // This is undefined behavior.
-    ///     ptr::write(&mut foo.get_mut().b as *mut u8, 42);
-    ///                  // ^^^^^^^^^^^^^
+    ///     ptr::write(&mut foo.assume_init_mut().b as *mut u8, 42);
+    ///                  // ^^^^^^^^^^^^^^^^^^^^^
     ///                  // (mutable) reference to uninitialized memory!
     ///                  // This is undefined behavior.
     ///     foo.assume_init()
     /// };
     /// ```
-    // FIXME(#53491): We currently rely on the above being incorrect, i.e., we have references
+    // FIXME(#76092): We currently rely on the above being incorrect, i.e., we have references
     // to uninitialized data (e.g., in `libcore/fmt/float.rs`).  We should make
     // a final decision about the rules before stabilization.
     #[unstable(feature = "maybe_uninit_ref", issue = "63568")]
     #[inline(always)]
-    pub unsafe fn get_mut(&mut self) -> &mut T {
+    pub unsafe fn assume_init_mut(&mut self) -> &mut T {
         // SAFETY: the caller must guarantee that `self` is initialized.
         // This also means that `self` must be a `value` variant.
         unsafe {
diff --git a/library/core/src/num/flt2dec/mod.rs b/library/core/src/num/flt2dec/mod.rs
index 9bf56e93d89..1f28edb4128 100644
--- a/library/core/src/num/flt2dec/mod.rs
+++ b/library/core/src/num/flt2dec/mod.rs
@@ -124,6 +124,8 @@ functions.
 
 pub use self::decoder::{decode, DecodableFloat, Decoded, FullDecoded};
 
+use crate::mem::MaybeUninit;
+
 pub mod decoder;
 pub mod estimator;
 
@@ -140,23 +142,23 @@ pub mod strategy {
 /// The exact formula is `ceil(# bits in mantissa * log_10 2 + 1)`.
 pub const MAX_SIG_DIGITS: usize = 17;
 
-/// When `d[..n]` contains decimal digits, increase the last digit and propagate carry.
-/// Returns a next digit when it causes the length change.
+/// When `d` contains decimal digits, increase the last digit and propagate carry.
+/// Returns a next digit when it causes the length to change.
 #[doc(hidden)]
-pub fn round_up(d: &mut [u8], n: usize) -> Option<u8> {
-    match d[..n].iter().rposition(|&c| c != b'9') {
+pub fn round_up(d: &mut [u8]) -> Option<u8> {
+    match d.iter().rposition(|&c| c != b'9') {
         Some(i) => {
             // d[i+1..n] is all nines
             d[i] += 1;
-            for j in i + 1..n {
+            for j in i + 1..d.len() {
                 d[j] = b'0';
             }
             None
         }
-        None if n > 0 => {
+        None if d.len() > 0 => {
             // 999..999 rounds to 1000..000 with an increased exponent
             d[0] = b'1';
-            for j in 1..n {
+            for j in 1..d.len() {
                 d[j] = b'0';
             }
             Some(b'0')
@@ -281,7 +283,7 @@ fn digits_to_dec_str<'a>(
     buf: &'a [u8],
     exp: i16,
     frac_digits: usize,
-    parts: &'a mut [Part<'a>],
+    parts: &'a mut [MaybeUninit<Part<'a>>],
 ) -> &'a [Part<'a>] {
     assert!(!buf.is_empty());
     assert!(buf[0] > b'0');
@@ -303,38 +305,44 @@ fn digits_to_dec_str<'a>(
     if exp <= 0 {
         // the decimal point is before rendered digits: [0.][000...000][1234][____]
         let minus_exp = -(exp as i32) as usize;
-        parts[0] = Part::Copy(b"0.");
-        parts[1] = Part::Zero(minus_exp);
-        parts[2] = Part::Copy(buf);
+        parts[0] = MaybeUninit::new(Part::Copy(b"0."));
+        parts[1] = MaybeUninit::new(Part::Zero(minus_exp));
+        parts[2] = MaybeUninit::new(Part::Copy(buf));
         if frac_digits > buf.len() && frac_digits - buf.len() > minus_exp {
-            parts[3] = Part::Zero((frac_digits - buf.len()) - minus_exp);
-            &parts[..4]
+            parts[3] = MaybeUninit::new(Part::Zero((frac_digits - buf.len()) - minus_exp));
+            // SAFETY: we just initialized the elements `..4`.
+            unsafe { MaybeUninit::slice_get_ref(&parts[..4]) }
         } else {
-            &parts[..3]
+            // SAFETY: we just initialized the elements `..3`.
+            unsafe { MaybeUninit::slice_get_ref(&parts[..3]) }
         }
     } else {
         let exp = exp as usize;
         if exp < buf.len() {
             // the decimal point is inside rendered digits: [12][.][34][____]
-            parts[0] = Part::Copy(&buf[..exp]);
-            parts[1] = Part::Copy(b".");
-            parts[2] = Part::Copy(&buf[exp..]);
+            parts[0] = MaybeUninit::new(Part::Copy(&buf[..exp]));
+            parts[1] = MaybeUninit::new(Part::Copy(b"."));
+            parts[2] = MaybeUninit::new(Part::Copy(&buf[exp..]));
             if frac_digits > buf.len() - exp {
-                parts[3] = Part::Zero(frac_digits - (buf.len() - exp));
-                &parts[..4]
+                parts[3] = MaybeUninit::new(Part::Zero(frac_digits - (buf.len() - exp)));
+                // SAFETY: we just initialized the elements `..4`.
+                unsafe { MaybeUninit::slice_get_ref(&parts[..4]) }
             } else {
-                &parts[..3]
+                // SAFETY: we just initialized the elements `..3`.
+                unsafe { MaybeUninit::slice_get_ref(&parts[..3]) }
             }
         } else {
             // the decimal point is after rendered digits: [1234][____0000] or [1234][__][.][__].
-            parts[0] = Part::Copy(buf);
-            parts[1] = Part::Zero(exp - buf.len());
+            parts[0] = MaybeUninit::new(Part::Copy(buf));
+            parts[1] = MaybeUninit::new(Part::Zero(exp - buf.len()));
             if frac_digits > 0 {
-                parts[2] = Part::Copy(b".");
-                parts[3] = Part::Zero(frac_digits);
-                &parts[..4]
+                parts[2] = MaybeUninit::new(Part::Copy(b"."));
+                parts[3] = MaybeUninit::new(Part::Zero(frac_digits));
+                // SAFETY: we just initialized the elements `..4`.
+                unsafe { MaybeUninit::slice_get_ref(&parts[..4]) }
             } else {
-                &parts[..2]
+                // SAFETY: we just initialized the elements `..2`.
+                unsafe { MaybeUninit::slice_get_ref(&parts[..2]) }
             }
         }
     }
@@ -354,7 +362,7 @@ fn digits_to_exp_str<'a>(
     exp: i16,
     min_ndigits: usize,
     upper: bool,
-    parts: &'a mut [Part<'a>],
+    parts: &'a mut [MaybeUninit<Part<'a>>],
 ) -> &'a [Part<'a>] {
     assert!(!buf.is_empty());
     assert!(buf[0] > b'0');
@@ -362,15 +370,15 @@ fn digits_to_exp_str<'a>(
 
     let mut n = 0;
 
-    parts[n] = Part::Copy(&buf[..1]);
+    parts[n] = MaybeUninit::new(Part::Copy(&buf[..1]));
     n += 1;
 
     if buf.len() > 1 || min_ndigits > 1 {
-        parts[n] = Part::Copy(b".");
-        parts[n + 1] = Part::Copy(&buf[1..]);
+        parts[n] = MaybeUninit::new(Part::Copy(b"."));
+        parts[n + 1] = MaybeUninit::new(Part::Copy(&buf[1..]));
         n += 2;
         if min_ndigits > buf.len() {
-            parts[n] = Part::Zero(min_ndigits - buf.len());
+            parts[n] = MaybeUninit::new(Part::Zero(min_ndigits - buf.len()));
             n += 1;
         }
     }
@@ -378,13 +386,14 @@ fn digits_to_exp_str<'a>(
     // 0.1234 x 10^exp = 1.234 x 10^(exp-1)
     let exp = exp as i32 - 1; // avoid underflow when exp is i16::MIN
     if exp < 0 {
-        parts[n] = Part::Copy(if upper { b"E-" } else { b"e-" });
-        parts[n + 1] = Part::Num(-exp as u16);
+        parts[n] = MaybeUninit::new(Part::Copy(if upper { b"E-" } else { b"e-" }));
+        parts[n + 1] = MaybeUninit::new(Part::Num(-exp as u16));
     } else {
-        parts[n] = Part::Copy(if upper { b"E" } else { b"e" });
-        parts[n + 1] = Part::Num(exp as u16);
+        parts[n] = MaybeUninit::new(Part::Copy(if upper { b"E" } else { b"e" }));
+        parts[n + 1] = MaybeUninit::new(Part::Num(exp as u16));
     }
-    &parts[..n + 2]
+    // SAFETY: we just initialized the elements `..n + 2`.
+    unsafe { MaybeUninit::slice_get_ref(&parts[..n + 2]) }
 }
 
 /// Sign formatting options.
@@ -446,6 +455,7 @@ fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static
 /// (which can be an empty string if no sign is rendered).
 ///
 /// `format_shortest` should be the underlying digit-generation function.
+/// It should return the part of the buffer that it initialized.
 /// You probably would want `strategy::grisu::format_shortest` for this.
 ///
 /// `frac_digits` can be less than the number of actual fractional digits in `v`;
@@ -461,12 +471,12 @@ pub fn to_shortest_str<'a, T, F>(
     v: T,
     sign: Sign,
     frac_digits: usize,
-    buf: &'a mut [u8],
-    parts: &'a mut [Part<'a>],
+    buf: &'a mut [MaybeUninit<u8>],
+    parts: &'a mut [MaybeUninit<Part<'a>>],
 ) -> Formatted<'a>
 where
     T: DecodableFloat,
-    F: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+    F: FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
 {
     assert!(parts.len() >= 4);
     assert!(buf.len() >= MAX_SIG_DIGITS);
@@ -475,27 +485,31 @@ where
     let sign = determine_sign(sign, &full_decoded, negative);
     match full_decoded {
         FullDecoded::Nan => {
-            parts[0] = Part::Copy(b"NaN");
-            Formatted { sign, parts: &parts[..1] }
+            parts[0] = MaybeUninit::new(Part::Copy(b"NaN"));
+            // SAFETY: we just initialized the elements `..1`.
+            Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
         }
         FullDecoded::Infinite => {
-            parts[0] = Part::Copy(b"inf");
-            Formatted { sign, parts: &parts[..1] }
+            parts[0] = MaybeUninit::new(Part::Copy(b"inf"));
+            // SAFETY: we just initialized the elements `..1`.
+            Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
         }
         FullDecoded::Zero => {
             if frac_digits > 0 {
                 // [0.][0000]
-                parts[0] = Part::Copy(b"0.");
-                parts[1] = Part::Zero(frac_digits);
-                Formatted { sign, parts: &parts[..2] }
+                parts[0] = MaybeUninit::new(Part::Copy(b"0."));
+                parts[1] = MaybeUninit::new(Part::Zero(frac_digits));
+                // SAFETY: we just initialized the elements `..2`.
+                Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..2]) } }
             } else {
-                parts[0] = Part::Copy(b"0");
-                Formatted { sign, parts: &parts[..1] }
+                parts[0] = MaybeUninit::new(Part::Copy(b"0"));
+                // SAFETY: we just initialized the elements `..1`.
+                Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
             }
         }
         FullDecoded::Finite(ref decoded) => {
-            let (len, exp) = format_shortest(decoded, buf);
-            Formatted { sign, parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) }
+            let (buf, exp) = format_shortest(decoded, buf);
+            Formatted { sign, parts: digits_to_dec_str(buf, exp, frac_digits, parts) }
         }
     }
 }
@@ -509,6 +523,7 @@ where
 /// an empty string if no sign is rendered).
 ///
 /// `format_shortest` should be the underlying digit-generation function.
+/// It should return the part of the buffer that it initialized.
 /// You probably would want `strategy::grisu::format_shortest` for this.
 ///
 /// The `dec_bounds` is a tuple `(lo, hi)` such that the number is formatted
@@ -525,12 +540,12 @@ pub fn to_shortest_exp_str<'a, T, F>(
     sign: Sign,
     dec_bounds: (i16, i16),
     upper: bool,
-    buf: &'a mut [u8],
-    parts: &'a mut [Part<'a>],
+    buf: &'a mut [MaybeUninit<u8>],
+    parts: &'a mut [MaybeUninit<Part<'a>>],
 ) -> Formatted<'a>
 where
     T: DecodableFloat,
-    F: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+    F: FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
 {
     assert!(parts.len() >= 6);
     assert!(buf.len() >= MAX_SIG_DIGITS);
@@ -540,28 +555,31 @@ where
     let sign = determine_sign(sign, &full_decoded, negative);
     match full_decoded {
         FullDecoded::Nan => {
-            parts[0] = Part::Copy(b"NaN");
-            Formatted { sign, parts: &parts[..1] }
+            parts[0] = MaybeUninit::new(Part::Copy(b"NaN"));
+            // SAFETY: we just initialized the elements `..1`.
+            Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
         }
         FullDecoded::Infinite => {
-            parts[0] = Part::Copy(b"inf");
-            Formatted { sign, parts: &parts[..1] }
+            parts[0] = MaybeUninit::new(Part::Copy(b"inf"));
+            // SAFETY: we just initialized the elements `..1`.
+            Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
         }
         FullDecoded::Zero => {
             parts[0] = if dec_bounds.0 <= 0 && 0 < dec_bounds.1 {
-                Part::Copy(b"0")
+                MaybeUninit::new(Part::Copy(b"0"))
             } else {
-                Part::Copy(if upper { b"0E0" } else { b"0e0" })
+                MaybeUninit::new(Part::Copy(if upper { b"0E0" } else { b"0e0" }))
             };
-            Formatted { sign, parts: &parts[..1] }
+            // SAFETY: we just initialized the elements `..1`.
+            Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
         }
         FullDecoded::Finite(ref decoded) => {
-            let (len, exp) = format_shortest(decoded, buf);
+            let (buf, exp) = format_shortest(decoded, buf);
             let vis_exp = exp as i32 - 1;
             let parts = if dec_bounds.0 as i32 <= vis_exp && vis_exp < dec_bounds.1 as i32 {
-                digits_to_dec_str(&buf[..len], exp, 0, parts)
+                digits_to_dec_str(buf, exp, 0, parts)
             } else {
-                digits_to_exp_str(&buf[..len], exp, 0, upper, parts)
+                digits_to_exp_str(buf, exp, 0, upper, parts)
             };
             Formatted { sign, parts }
         }
@@ -600,6 +618,7 @@ fn estimate_max_buf_len(exp: i16) -> usize {
 /// an empty string if no sign is rendered).
 ///
 /// `format_exact` should be the underlying digit-generation function.
+/// It should return the part of the buffer that it initialized.
 /// You probably would want `strategy::grisu::format_exact` for this.
 ///
 /// The byte buffer should be at least `ndigits` bytes long unless `ndigits` is
@@ -613,12 +632,12 @@ pub fn to_exact_exp_str<'a, T, F>(
     sign: Sign,
     ndigits: usize,
     upper: bool,
-    buf: &'a mut [u8],
-    parts: &'a mut [Part<'a>],
+    buf: &'a mut [MaybeUninit<u8>],
+    parts: &'a mut [MaybeUninit<Part<'a>>],
 ) -> Formatted<'a>
 where
     T: DecodableFloat,
-    F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16),
+    F: FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
 {
     assert!(parts.len() >= 6);
     assert!(ndigits > 0);
@@ -627,23 +646,27 @@ where
     let sign = determine_sign(sign, &full_decoded, negative);
     match full_decoded {
         FullDecoded::Nan => {
-            parts[0] = Part::Copy(b"NaN");
-            Formatted { sign, parts: &parts[..1] }
+            parts[0] = MaybeUninit::new(Part::Copy(b"NaN"));
+            // SAFETY: we just initialized the elements `..1`.
+            Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
         }
         FullDecoded::Infinite => {
-            parts[0] = Part::Copy(b"inf");
-            Formatted { sign, parts: &parts[..1] }
+            parts[0] = MaybeUninit::new(Part::Copy(b"inf"));
+            // SAFETY: we just initialized the elements `..1`.
+            Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
         }
         FullDecoded::Zero => {
             if ndigits > 1 {
                 // [0.][0000][e0]
-                parts[0] = Part::Copy(b"0.");
-                parts[1] = Part::Zero(ndigits - 1);
-                parts[2] = Part::Copy(if upper { b"E0" } else { b"e0" });
-                Formatted { sign, parts: &parts[..3] }
+                parts[0] = MaybeUninit::new(Part::Copy(b"0."));
+                parts[1] = MaybeUninit::new(Part::Zero(ndigits - 1));
+                parts[2] = MaybeUninit::new(Part::Copy(if upper { b"E0" } else { b"e0" }));
+                // SAFETY: we just initialized the elements `..3`.
+                Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..3]) } }
             } else {
-                parts[0] = Part::Copy(if upper { b"0E0" } else { b"0e0" });
-                Formatted { sign, parts: &parts[..1] }
+                parts[0] = MaybeUninit::new(Part::Copy(if upper { b"0E0" } else { b"0e0" }));
+                // SAFETY: we just initialized the elements `..1`.
+                Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
             }
         }
         FullDecoded::Finite(ref decoded) => {
@@ -651,8 +674,8 @@ where
             assert!(buf.len() >= ndigits || buf.len() >= maxlen);
 
             let trunc = if ndigits < maxlen { ndigits } else { maxlen };
-            let (len, exp) = format_exact(decoded, &mut buf[..trunc], i16::MIN);
-            Formatted { sign, parts: digits_to_exp_str(&buf[..len], exp, ndigits, upper, parts) }
+            let (buf, exp) = format_exact(decoded, &mut buf[..trunc], i16::MIN);
+            Formatted { sign, parts: digits_to_exp_str(buf, exp, ndigits, upper, parts) }
         }
     }
 }
@@ -665,6 +688,7 @@ where
 /// (which can be an empty string if no sign is rendered).
 ///
 /// `format_exact` should be the underlying digit-generation function.
+/// It should return the part of the buffer that it initialized.
 /// You probably would want `strategy::grisu::format_exact` for this.
 ///
 /// The byte buffer should be enough for the output unless `frac_digits` is
@@ -677,12 +701,12 @@ pub fn to_exact_fixed_str<'a, T, F>(
     v: T,
     sign: Sign,
     frac_digits: usize,
-    buf: &'a mut [u8],
-    parts: &'a mut [Part<'a>],
+    buf: &'a mut [MaybeUninit<u8>],
+    parts: &'a mut [MaybeUninit<Part<'a>>],
 ) -> Formatted<'a>
 where
     T: DecodableFloat,
-    F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16),
+    F: FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
 {
     assert!(parts.len() >= 4);
 
@@ -690,22 +714,26 @@ where
     let sign = determine_sign(sign, &full_decoded, negative);
     match full_decoded {
         FullDecoded::Nan => {
-            parts[0] = Part::Copy(b"NaN");
-            Formatted { sign, parts: &parts[..1] }
+            parts[0] = MaybeUninit::new(Part::Copy(b"NaN"));
+            // SAFETY: we just initialized the elements `..1`.
+            Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
         }
         FullDecoded::Infinite => {
-            parts[0] = Part::Copy(b"inf");
-            Formatted { sign, parts: &parts[..1] }
+            parts[0] = MaybeUninit::new(Part::Copy(b"inf"));
+            // SAFETY: we just initialized the elements `..1`.
+            Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
         }
         FullDecoded::Zero => {
             if frac_digits > 0 {
                 // [0.][0000]
-                parts[0] = Part::Copy(b"0.");
-                parts[1] = Part::Zero(frac_digits);
-                Formatted { sign, parts: &parts[..2] }
+                parts[0] = MaybeUninit::new(Part::Copy(b"0."));
+                parts[1] = MaybeUninit::new(Part::Zero(frac_digits));
+                // SAFETY: we just initialized the elements `..2`.
+                Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..2]) } }
             } else {
-                parts[0] = Part::Copy(b"0");
-                Formatted { sign, parts: &parts[..1] }
+                parts[0] = MaybeUninit::new(Part::Copy(b"0"));
+                // SAFETY: we just initialized the elements `..1`.
+                Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
             }
         }
         FullDecoded::Finite(ref decoded) => {
@@ -716,23 +744,25 @@ where
             // `format_exact` will end rendering digits much earlier in this case,
             // because we are strictly limited by `maxlen`.
             let limit = if frac_digits < 0x8000 { -(frac_digits as i16) } else { i16::MIN };
-            let (len, exp) = format_exact(decoded, &mut buf[..maxlen], limit);
+            let (buf, exp) = format_exact(decoded, &mut buf[..maxlen], limit);
             if exp <= limit {
                 // the restriction couldn't been met, so this should render like zero no matter
                 // `exp` was. this does not include the case that the restriction has been met
                 // only after the final rounding-up; it's a regular case with `exp = limit + 1`.
-                debug_assert_eq!(len, 0);
+                debug_assert_eq!(buf.len(), 0);
                 if frac_digits > 0 {
                     // [0.][0000]
-                    parts[0] = Part::Copy(b"0.");
-                    parts[1] = Part::Zero(frac_digits);
-                    Formatted { sign, parts: &parts[..2] }
+                    parts[0] = MaybeUninit::new(Part::Copy(b"0."));
+                    parts[1] = MaybeUninit::new(Part::Zero(frac_digits));
+                    // SAFETY: we just initialized the elements `..2`.
+                    Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..2]) } }
                 } else {
-                    parts[0] = Part::Copy(b"0");
-                    Formatted { sign, parts: &parts[..1] }
+                    parts[0] = MaybeUninit::new(Part::Copy(b"0"));
+                    // SAFETY: we just initialized the elements `..1`.
+                    Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } }
                 }
             } else {
-                Formatted { sign, parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) }
+                Formatted { sign, parts: digits_to_dec_str(buf, exp, frac_digits, parts) }
             }
         }
     }
diff --git a/library/core/src/num/flt2dec/strategy/dragon.rs b/library/core/src/num/flt2dec/strategy/dragon.rs
index c8de0004352..8cb6763cdbe 100644
--- a/library/core/src/num/flt2dec/strategy/dragon.rs
+++ b/library/core/src/num/flt2dec/strategy/dragon.rs
@@ -5,6 +5,7 @@
 //!   quickly and accurately. SIGPLAN Not. 31, 5 (May. 1996), 108-116.
 
 use crate::cmp::Ordering;
+use crate::mem::MaybeUninit;
 
 use crate::num::bignum::Big32x40 as Big;
 use crate::num::bignum::Digit32 as Digit;
@@ -97,7 +98,10 @@ fn div_rem_upto_16<'a>(
 }
 
 /// The shortest mode implementation for Dragon.
-pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp*/ i16) {
+pub fn format_shortest<'a>(
+    d: &Decoded,
+    buf: &'a mut [MaybeUninit<u8>],
+) -> (/*digits*/ &'a [u8], /*exp*/ i16) {
     // the number `v` to format is known to be:
     // - equal to `mant * 2^exp`;
     // - preceded by `(mant - 2 * minus) * 2^exp` in the original type; and
@@ -186,7 +190,7 @@ pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp
         // generate one digit: `d[n] = floor(mant / scale) < 10`.
         let (d, _) = div_rem_upto_16(&mut mant, &scale, &scale2, &scale4, &scale8);
         debug_assert!(d < 10);
-        buf[i] = b'0' + d;
+        buf[i] = MaybeUninit::new(b'0' + d);
         i += 1;
 
         // this is a simplified description of the modified Dragon algorithm.
@@ -241,18 +245,24 @@ pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp
         // if rounding up changes the length, the exponent should also change.
         // it seems that this condition is very hard to satisfy (possibly impossible),
         // but we are just being safe and consistent here.
-        if let Some(c) = round_up(buf, i) {
-            buf[i] = c;
+        // SAFETY: we initialized that memory above.
+        if let Some(c) = round_up(unsafe { MaybeUninit::slice_get_mut(&mut buf[..i]) }) {
+            buf[i] = MaybeUninit::new(c);
             i += 1;
             k += 1;
         }
     }
 
-    (i, k)
+    // SAFETY: we initialized that memory above.
+    (unsafe { MaybeUninit::slice_get_ref(&buf[..i]) }, k)
 }
 
 /// The exact and fixed mode implementation for Dragon.
-pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usize, /*exp*/ i16) {
+pub fn format_exact<'a>(
+    d: &Decoded,
+    buf: &'a mut [MaybeUninit<u8>],
+    limit: i16,
+) -> (/*digits*/ &'a [u8], /*exp*/ i16) {
     assert!(d.mant > 0);
     assert!(d.minus > 0);
     assert!(d.plus > 0);
@@ -319,9 +329,10 @@ pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usi
                 // following digits are all zeroes, we stop here
                 // do *not* try to perform rounding! rather, fill remaining digits.
                 for c in &mut buf[i..len] {
-                    *c = b'0';
+                    *c = MaybeUninit::new(b'0');
                 }
-                return (len, k);
+                // SAFETY: we initialized that memory above.
+                return (unsafe { MaybeUninit::slice_get_ref(&buf[..len]) }, k);
             }
 
             let mut d = 0;
@@ -343,7 +354,7 @@ pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usi
             }
             debug_assert!(mant < scale);
             debug_assert!(d < 10);
-            buf[i] = b'0' + d;
+            buf[i] = MaybeUninit::new(b'0' + d);
             mant.mul_small(10);
         }
     }
@@ -353,21 +364,25 @@ pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usi
     // round to even (i.e., avoid rounding up when the prior digit is even).
     let order = mant.cmp(scale.mul_small(5));
     if order == Ordering::Greater
-        || (order == Ordering::Equal && (len == 0 || buf[len - 1] & 1 == 1))
+        || (order == Ordering::Equal
+            // SAFETY: `buf[len-1]` is initialized.
+            && (len == 0 || unsafe { buf[len - 1].assume_init() } & 1 == 1))
     {
         // if rounding up changes the length, the exponent should also change.
         // but we've been requested a fixed number of digits, so do not alter the buffer...
-        if let Some(c) = round_up(buf, len) {
+        // SAFETY: we initialized that memory above.
+        if let Some(c) = round_up(unsafe { MaybeUninit::slice_get_mut(&mut buf[..len]) }) {
             // ...unless we've been requested the fixed precision instead.
             // we also need to check that, if the original buffer was empty,
             // the additional digit can only be added when `k == limit` (edge case).
             k += 1;
             if k > limit && len < buf.len() {
-                buf[len] = c;
+                buf[len] = MaybeUninit::new(c);
                 len += 1;
             }
         }
     }
 
-    (len, k)
+    // SAFETY: we initialized that memory above.
+    (unsafe { MaybeUninit::slice_get_ref(&buf[..len]) }, k)
 }
diff --git a/library/core/src/num/flt2dec/strategy/grisu.rs b/library/core/src/num/flt2dec/strategy/grisu.rs
index 1e2db212dd0..ed1dd654a3a 100644
--- a/library/core/src/num/flt2dec/strategy/grisu.rs
+++ b/library/core/src/num/flt2dec/strategy/grisu.rs
@@ -5,6 +5,7 @@
 //! [^1]: Florian Loitsch. 2010. Printing floating-point numbers quickly and
 //!   accurately with integers. SIGPLAN Not. 45, 6 (June 2010), 233-243.
 
+use crate::mem::MaybeUninit;
 use crate::num::diy_float::Fp;
 use crate::num::flt2dec::{round_up, Decoded, MAX_SIG_DIGITS};
 
@@ -161,10 +162,10 @@ pub fn max_pow10_no_more_than(x: u32) -> (u8, u32) {
 /// The shortest mode implementation for Grisu.
 ///
 /// It returns `None` when it would return an inexact representation otherwise.
-pub fn format_shortest_opt(
+pub fn format_shortest_opt<'a>(
     d: &Decoded,
-    buf: &mut [u8],
-) -> Option<(/*#digits*/ usize, /*exp*/ i16)> {
+    buf: &'a mut [MaybeUninit<u8>],
+) -> Option<(/*digits*/ &'a [u8], /*exp*/ i16)> {
     assert!(d.mant > 0);
     assert!(d.minus > 0);
     assert!(d.plus > 0);
@@ -266,14 +267,23 @@ pub fn format_shortest_opt(
         let q = remainder / ten_kappa;
         let r = remainder % ten_kappa;
         debug_assert!(q < 10);
-        buf[i] = b'0' + q as u8;
+        buf[i] = MaybeUninit::new(b'0' + q as u8);
         i += 1;
 
         let plus1rem = ((r as u64) << e) + plus1frac; // == (plus1 % 10^kappa) * 2^e
         if plus1rem < delta1 {
             // `plus1 % 10^kappa < delta1 = plus1 - minus1`; we've found the correct `kappa`.
             let ten_kappa = (ten_kappa as u64) << e; // scale 10^kappa back to the shared exponent
-            return round_and_weed(&mut buf[..i], exp, plus1rem, delta1, plus1 - v.f, ten_kappa, 1);
+            return round_and_weed(
+                // SAFETY: we initialized that memory above.
+                unsafe { MaybeUninit::slice_get_mut(&mut buf[..i]) },
+                exp,
+                plus1rem,
+                delta1,
+                plus1 - v.f,
+                ten_kappa,
+                1,
+            );
         }
 
         // break the loop when we have rendered all integral digits.
@@ -310,13 +320,14 @@ pub fn format_shortest_opt(
         let q = remainder >> e;
         let r = remainder & ((1 << e) - 1);
         debug_assert!(q < 10);
-        buf[i] = b'0' + q as u8;
+        buf[i] = MaybeUninit::new(b'0' + q as u8);
         i += 1;
 
         if r < threshold {
             let ten_kappa = 1 << e; // implicit divisor
             return round_and_weed(
-                &mut buf[..i],
+                // SAFETY: we initialized that memory above.
+                unsafe { MaybeUninit::slice_get_mut(&mut buf[..i]) },
                 exp,
                 r,
                 threshold,
@@ -355,7 +366,7 @@ pub fn format_shortest_opt(
         plus1v: u64,
         ten_kappa: u64,
         ulp: u64,
-    ) -> Option<(usize, i16)> {
+    ) -> Option<(&[u8], i16)> {
         assert!(!buf.is_empty());
 
         // produce two approximations to `v` (actually `plus1 - v`) within 1.5 ulps.
@@ -437,20 +448,22 @@ pub fn format_shortest_opt(
         // this is too liberal, though, so we reject any `w(n)` not between `plus0` and `minus0`,
         // i.e., `plus1 - plus1w(n) <= minus0` or `plus1 - plus1w(n) >= plus0`. we utilize the facts
         // that `threshold = plus1 - minus1` and `plus1 - plus0 = minus0 - minus1 = 2 ulp`.
-        if 2 * ulp <= plus1w && plus1w <= threshold - 4 * ulp {
-            Some((buf.len(), exp))
-        } else {
-            None
-        }
+        if 2 * ulp <= plus1w && plus1w <= threshold - 4 * ulp { Some((buf, exp)) } else { None }
     }
 }
 
 /// The shortest mode implementation for Grisu with Dragon fallback.
 ///
 /// This should be used for most cases.
-pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp*/ i16) {
+pub fn format_shortest<'a>(
+    d: &Decoded,
+    buf: &'a mut [MaybeUninit<u8>],
+) -> (/*digits*/ &'a [u8], /*exp*/ i16) {
     use crate::num::flt2dec::strategy::dragon::format_shortest as fallback;
-    match format_shortest_opt(d, buf) {
+    // SAFETY: The borrow checker is not smart enough to let us use `buf`
+    // in the second branch, so we launder the lifetime here. But we only re-use
+    // `buf` if `format_shortest_opt` returned `None` so this is okay.
+    match format_shortest_opt(d, unsafe { &mut *(buf as *mut _) }) {
         Some(ret) => ret,
         None => fallback(d, buf),
     }
@@ -459,11 +472,11 @@ pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp
 /// The exact and fixed mode implementation for Grisu.
 ///
 /// It returns `None` when it would return an inexact representation otherwise.
-pub fn format_exact_opt(
+pub fn format_exact_opt<'a>(
     d: &Decoded,
-    buf: &mut [u8],
+    buf: &'a mut [MaybeUninit<u8>],
     limit: i16,
-) -> Option<(/*#digits*/ usize, /*exp*/ i16)> {
+) -> Option<(/*digits*/ &'a [u8], /*exp*/ i16)> {
     assert!(d.mant > 0);
     assert!(d.mant < (1 << 61)); // we need at least three bits of additional precision
     assert!(!buf.is_empty());
@@ -510,7 +523,11 @@ pub fn format_exact_opt(
         // thus we are being sloppy here and widen the error range by a factor of 10.
         // this will increase the false negative rate, but only very, *very* slightly;
         // it can only matter noticeably when the mantissa is bigger than 60 bits.
-        return possibly_round(buf, 0, exp, limit, v.f / 10, (max_ten_kappa as u64) << e, err << e);
+        //
+        // SAFETY: `len=0`, so the obligation of having initialized this memory is trivial.
+        return unsafe {
+            possibly_round(buf, 0, exp, limit, v.f / 10, (max_ten_kappa as u64) << e, err << e)
+        };
     } else if ((exp as i32 - limit as i32) as usize) < buf.len() {
         (exp - limit) as usize
     } else {
@@ -534,13 +551,16 @@ pub fn format_exact_opt(
         let q = remainder / ten_kappa;
         let r = remainder % ten_kappa;
         debug_assert!(q < 10);
-        buf[i] = b'0' + q as u8;
+        buf[i] = MaybeUninit::new(b'0' + q as u8);
         i += 1;
 
         // is the buffer full? run the rounding pass with the remainder.
         if i == len {
             let vrem = ((r as u64) << e) + vfrac; // == (v % 10^kappa) * 2^e
-            return possibly_round(buf, len, exp, limit, vrem, (ten_kappa as u64) << e, err << e);
+            // SAFETY: we have initialized `len` many bytes.
+            return unsafe {
+                possibly_round(buf, len, exp, limit, vrem, (ten_kappa as u64) << e, err << e)
+            };
         }
 
         // break the loop when we have rendered all integral digits.
@@ -585,12 +605,13 @@ pub fn format_exact_opt(
         let q = remainder >> e;
         let r = remainder & ((1 << e) - 1);
         debug_assert!(q < 10);
-        buf[i] = b'0' + q as u8;
+        buf[i] = MaybeUninit::new(b'0' + q as u8);
         i += 1;
 
         // is the buffer full? run the rounding pass with the remainder.
         if i == len {
-            return possibly_round(buf, len, exp, limit, r, 1 << e, err);
+            // SAFETY: we have initialized `len` many bytes.
+            return unsafe { possibly_round(buf, len, exp, limit, r, 1 << e, err) };
         }
 
         // restore invariants
@@ -610,15 +631,17 @@ pub fn format_exact_opt(
     // - `remainder = (v % 10^kappa) * k`
     // - `ten_kappa = 10^kappa * k`
     // - `ulp = 2^-e * k`
-    fn possibly_round(
-        buf: &mut [u8],
+    //
+    // SAFETY: the first `len` bytes of `buf` must be initialized.
+    unsafe fn possibly_round(
+        buf: &mut [MaybeUninit<u8>],
         mut len: usize,
         mut exp: i16,
         limit: i16,
         remainder: u64,
         ten_kappa: u64,
         ulp: u64,
-    ) -> Option<(usize, i16)> {
+    ) -> Option<(&[u8], i16)> {
         debug_assert!(remainder < ten_kappa);
 
         //           10^kappa
@@ -677,7 +700,8 @@ pub fn format_exact_opt(
         // we've already verified that `ulp < 10^kappa / 2`, so as long as
         // `10^kappa` did not overflow after all, the second check is fine.
         if ten_kappa - remainder > remainder && ten_kappa - 2 * remainder >= 2 * ulp {
-            return Some((len, exp));
+            // SAFETY: our caller initialized that memory.
+            return Some((unsafe { MaybeUninit::slice_get_ref(&buf[..len]) }, exp));
         }
 
         //   :<------- remainder ------>|   :
@@ -698,17 +722,19 @@ pub fn format_exact_opt(
         // as `10^kappa` is never zero). also note that `remainder - ulp <= 10^kappa`,
         // so the second check does not overflow.
         if remainder > ulp && ten_kappa - (remainder - ulp) <= remainder - ulp {
-            if let Some(c) = round_up(buf, len) {
+            // SAFETY: our caller must have initialized that memory.
+            if let Some(c) = round_up(unsafe { MaybeUninit::slice_get_mut(&mut buf[..len]) }) {
                 // only add an additional digit when we've been requested the fixed precision.
                 // we also need to check that, if the original buffer was empty,
                 // the additional digit can only be added when `exp == limit` (edge case).
                 exp += 1;
                 if exp > limit && len < buf.len() {
-                    buf[len] = c;
+                    buf[len] = MaybeUninit::new(c);
                     len += 1;
                 }
             }
-            return Some((len, exp));
+            // SAFETY: we and our caller initialized that memory.
+            return Some((unsafe { MaybeUninit::slice_get_ref(&buf[..len]) }, exp));
         }
 
         // otherwise we are doomed (i.e., some values between `v - 1 ulp` and `v + 1 ulp` are
@@ -720,9 +746,16 @@ pub fn format_exact_opt(
 /// The exact and fixed mode implementation for Grisu with Dragon fallback.
 ///
 /// This should be used for most cases.
-pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usize, /*exp*/ i16) {
+pub fn format_exact<'a>(
+    d: &Decoded,
+    buf: &'a mut [MaybeUninit<u8>],
+    limit: i16,
+) -> (/*digits*/ &'a [u8], /*exp*/ i16) {
     use crate::num::flt2dec::strategy::dragon::format_exact as fallback;
-    match format_exact_opt(d, buf, limit) {
+    // SAFETY: The borrow checker is not smart enough to let us use `buf`
+    // in the second branch, so we launder the lifetime here. But we only re-use
+    // `buf` if `format_exact_opt` returned `None` so this is okay.
+    match format_exact_opt(d, unsafe { &mut *(buf as *mut _) }, limit) {
         Some(ret) => ret,
         None => fallback(d, buf, limit),
     }
diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs
new file mode 100644
index 00000000000..687d423dcb6
--- /dev/null
+++ b/library/core/src/ops/control_flow.rs
@@ -0,0 +1,67 @@
+use crate::ops::Try;
+
+/// Used to make try_fold closures more like normal loops
+#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+#[derive(Debug, Clone, Copy, PartialEq)]
+pub enum ControlFlow<C, B> {
+    /// Continue in the loop, using the given value for the next iteration
+    Continue(C),
+    /// Exit the loop, yielding the given value
+    Break(B),
+}
+
+#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+impl<C, B> Try for ControlFlow<C, B> {
+    type Ok = C;
+    type Error = B;
+    #[inline]
+    fn into_result(self) -> Result<Self::Ok, Self::Error> {
+        match self {
+            ControlFlow::Continue(y) => Ok(y),
+            ControlFlow::Break(x) => Err(x),
+        }
+    }
+    #[inline]
+    fn from_error(v: Self::Error) -> Self {
+        ControlFlow::Break(v)
+    }
+    #[inline]
+    fn from_ok(v: Self::Ok) -> Self {
+        ControlFlow::Continue(v)
+    }
+}
+
+impl<C, B> ControlFlow<C, B> {
+    /// Converts the `ControlFlow` into an `Option` which is `Some` if the
+    /// `ControlFlow` was `Break` and `None` otherwise.
+    #[inline]
+    #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+    pub fn break_value(self) -> Option<B> {
+        match self {
+            ControlFlow::Continue(..) => None,
+            ControlFlow::Break(x) => Some(x),
+        }
+    }
+}
+
+impl<R: Try> ControlFlow<R::Ok, R> {
+    /// Create a `ControlFlow` from any type implementing `Try`.
+    #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+    #[inline]
+    pub fn from_try(r: R) -> Self {
+        match Try::into_result(r) {
+            Ok(v) => ControlFlow::Continue(v),
+            Err(v) => ControlFlow::Break(Try::from_error(v)),
+        }
+    }
+
+    /// Convert a `ControlFlow` into any type implementing `Try`;
+    #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+    #[inline]
+    pub fn into_try(self) -> R {
+        match self {
+            ControlFlow::Continue(v) => Try::from_ok(v),
+            ControlFlow::Break(v) => v,
+        }
+    }
+}
diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs
index c19bd6e441e..2a4186f9d5d 100644
--- a/library/core/src/ops/mod.rs
+++ b/library/core/src/ops/mod.rs
@@ -140,6 +140,7 @@
 
 mod arith;
 mod bit;
+mod control_flow;
 mod deref;
 mod drop;
 mod function;
@@ -191,3 +192,6 @@ pub use self::unsize::CoerceUnsized;
 
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
 pub use self::unsize::DispatchFromDyn;
+
+#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+pub use self::control_flow::ControlFlow;
diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs
index 316ecafe572..25ee73c626e 100644
--- a/library/core/src/panic.rs
+++ b/library/core/src/panic.rs
@@ -92,8 +92,6 @@ impl<'a> PanicInfo<'a> {
     /// If the `panic!` macro from the `core` crate (not from `std`)
     /// was used with a formatting string and some additional arguments,
     /// returns that message ready to be used for example with [`fmt::write`]
-    ///
-    /// [`fmt::write`]: ../fmt/fn.write.html
     #[unstable(feature = "panic_info_message", issue = "66745")]
     pub fn message(&self) -> Option<&fmt::Arguments<'_>> {
         self.message
@@ -105,8 +103,6 @@ impl<'a> PanicInfo<'a> {
     /// This method will currently always return [`Some`], but this may change
     /// in future versions.
     ///
-    /// [`Some`]: ../../std/option/enum.Option.html#variant.Some
-    ///
     /// # Examples
     ///
     /// ```should_panic
@@ -153,10 +149,7 @@ impl fmt::Display for PanicInfo<'_> {
 
 /// A struct containing information about the location of a panic.
 ///
-/// This structure is created by the [`location`] method of [`PanicInfo`].
-///
-/// [`location`]: ../../std/panic/struct.PanicInfo.html#method.location
-/// [`PanicInfo`]: ../../std/panic/struct.PanicInfo.html
+/// This structure is created by [`PanicInfo::location()`].
 ///
 /// # Examples
 ///
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index 8f60c4787d4..a12a22fa26d 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -661,7 +661,7 @@ impl<'a, T: ?Sized> Pin<&'a T> {
     /// because it is one of the fields of that value), and also that you do
     /// not move out of the argument you receive to the interior function.
     ///
-    /// [`pin` module]: ../../std/pin/index.html#projections-and-structural-pinning
+    /// [`pin` module]: self#projections-and-structural-pinning
     #[stable(feature = "pin", since = "1.33.0")]
     pub unsafe fn map_unchecked<U, F>(self, func: F) -> Pin<&'a U>
     where
@@ -692,7 +692,7 @@ impl<'a, T: ?Sized> Pin<&'a T> {
     /// the `Pin` itself. This method allows turning the `Pin` into a reference
     /// with the same lifetime as the original `Pin`.
     ///
-    /// ["pinning projections"]: ../../std/pin/index.html#projections-and-structural-pinning
+    /// ["pinning projections"]: self#projections-and-structural-pinning
     #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
     pub fn get_ref(self) -> &'a T {
@@ -756,7 +756,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
     /// because it is one of the fields of that value), and also that you do
     /// not move out of the argument you receive to the interior function.
     ///
-    /// [`pin` module]: ../../std/pin/index.html#projections-and-structural-pinning
+    /// [`pin` module]: self#projections-and-structural-pinning
     #[stable(feature = "pin", since = "1.33.0")]
     pub unsafe fn map_unchecked_mut<U, F>(self, func: F) -> Pin<&'a mut U>
     where
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 4dcb91d63c9..503f015e76a 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -288,10 +288,12 @@ impl<T> [T] {
     /// Returns a reference to an element or subslice, without doing bounds
     /// checking.
     ///
-    /// This is generally not recommended, use with caution!
+    /// For a safe alternative see [`get`].
+    ///
+    /// # Safety
+    ///
     /// Calling this method with an out-of-bounds index is *[undefined behavior]*
     /// even if the resulting reference is not used.
-    /// For a safe alternative see [`get`].
     ///
     /// [`get`]: #method.get
     /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
@@ -320,10 +322,12 @@ impl<T> [T] {
     /// Returns a mutable reference to an element or subslice, without doing
     /// bounds checking.
     ///
-    /// This is generally not recommended, use with caution!
+    /// For a safe alternative see [`get_mut`].
+    ///
+    /// # Safety
+    ///
     /// Calling this method with an out-of-bounds index is *[undefined behavior]*
     /// even if the resulting reference is not used.
-    /// For a safe alternative see [`get_mut`].
     ///
     /// [`get_mut`]: #method.get_mut
     /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
@@ -865,8 +869,9 @@ impl<T> [T] {
     pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> {
         assert_ne!(chunk_size, 0);
         let rem = self.len() % chunk_size;
-        let len = self.len() - rem;
-        let (fst, snd) = self.split_at(len);
+        let fst_len = self.len() - rem;
+        // SAFETY: 0 <= fst_len <= self.len() by construction above
+        let (fst, snd) = unsafe { self.split_at_unchecked(fst_len) };
         ChunksExact { v: fst, rem: snd, chunk_size }
     }
 
@@ -910,8 +915,9 @@ impl<T> [T] {
     pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T> {
         assert_ne!(chunk_size, 0);
         let rem = self.len() % chunk_size;
-        let len = self.len() - rem;
-        let (fst, snd) = self.split_at_mut(len);
+        let fst_len = self.len() - rem;
+        // SAFETY: 0 <= fst_len <= self.len() by construction above
+        let (fst, snd) = unsafe { self.split_at_mut_unchecked(fst_len) };
         ChunksExactMut { v: fst, rem: snd, chunk_size }
     }
 
@@ -1063,7 +1069,8 @@ impl<T> [T] {
     pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T> {
         assert!(chunk_size != 0);
         let rem = self.len() % chunk_size;
-        let (fst, snd) = self.split_at(rem);
+        // SAFETY: 0 <= rem <= self.len() by construction above
+        let (fst, snd) = unsafe { self.split_at_unchecked(rem) };
         RChunksExact { v: snd, rem: fst, chunk_size }
     }
 
@@ -1108,7 +1115,8 @@ impl<T> [T] {
     pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T> {
         assert!(chunk_size != 0);
         let rem = self.len() % chunk_size;
-        let (fst, snd) = self.split_at_mut(rem);
+        // SAFETY: 0 <= rem <= self.len() by construction above
+        let (fst, snd) = unsafe { self.split_at_mut_unchecked(rem) };
         RChunksExactMut { v: snd, rem: fst, chunk_size }
     }
 
@@ -1129,26 +1137,29 @@ impl<T> [T] {
     ///
     /// {
     ///    let (left, right) = v.split_at(0);
-    ///    assert!(left == []);
-    ///    assert!(right == [1, 2, 3, 4, 5, 6]);
+    ///    assert_eq!(left, []);
+    ///    assert_eq!(right, [1, 2, 3, 4, 5, 6]);
     /// }
     ///
     /// {
     ///     let (left, right) = v.split_at(2);
-    ///     assert!(left == [1, 2]);
-    ///     assert!(right == [3, 4, 5, 6]);
+    ///     assert_eq!(left, [1, 2]);
+    ///     assert_eq!(right, [3, 4, 5, 6]);
     /// }
     ///
     /// {
     ///     let (left, right) = v.split_at(6);
-    ///     assert!(left == [1, 2, 3, 4, 5, 6]);
-    ///     assert!(right == []);
+    ///     assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    ///     assert_eq!(right, []);
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn split_at(&self, mid: usize) -> (&[T], &[T]) {
-        (&self[..mid], &self[mid..])
+        assert!(mid <= self.len());
+        // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
+        // fulfills the requirements of `from_raw_parts_mut`.
+        unsafe { self.split_at_unchecked(mid) }
     }
 
     /// Divides one mutable slice into two at an index.
@@ -1168,26 +1179,115 @@ impl<T> [T] {
     /// // scoped to restrict the lifetime of the borrows
     /// {
     ///     let (left, right) = v.split_at_mut(2);
-    ///     assert!(left == [1, 0]);
-    ///     assert!(right == [3, 0, 5, 6]);
+    ///     assert_eq!(left, [1, 0]);
+    ///     assert_eq!(right, [3, 0, 5, 6]);
     ///     left[1] = 2;
     ///     right[1] = 4;
     /// }
-    /// assert!(v == [1, 2, 3, 4, 5, 6]);
+    /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
-        let len = self.len();
-        let ptr = self.as_mut_ptr();
-
+        assert!(mid <= self.len());
         // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
         // fulfills the requirements of `from_raw_parts_mut`.
-        unsafe {
-            assert!(mid <= len);
+        unsafe { self.split_at_mut_unchecked(mid) }
+    }
 
-            (from_raw_parts_mut(ptr, mid), from_raw_parts_mut(ptr.add(mid), len - mid))
-        }
+    /// Divides one slice into two at an index, without doing bounds checking.
+    ///
+    /// The first will contain all indices from `[0, mid)` (excluding
+    /// the index `mid` itself) and the second will contain all
+    /// indices from `[mid, len)` (excluding the index `len` itself).
+    ///
+    /// For a safe alternative see [`split_at`].
+    ///
+    /// # Safety
+    ///
+    /// Calling this method with an out-of-bounds index is *[undefined behavior]*
+    /// even if the resulting reference is not used. The caller has to ensure that
+    /// `0 <= mid <= self.len()`.
+    ///
+    /// [`split_at`]: #method.split_at
+    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
+    ///
+    /// # Examples
+    ///
+    /// ```compile_fail
+    /// #![feature(slice_split_at_unchecked)]
+    ///
+    /// let v = [1, 2, 3, 4, 5, 6];
+    ///
+    /// unsafe {
+    ///    let (left, right) = v.split_at_unchecked(0);
+    ///    assert_eq!(left, []);
+    ///    assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+    /// }
+    ///
+    /// unsafe {
+    ///     let (left, right) = v.split_at_unchecked(2);
+    ///     assert_eq!(left, [1, 2]);
+    ///     assert_eq!(right, [3, 4, 5, 6]);
+    /// }
+    ///
+    /// unsafe {
+    ///     let (left, right) = v.split_at_unchecked(6);
+    ///     assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    ///     assert_eq!(right, []);
+    /// }
+    /// ```
+    #[unstable(feature = "slice_split_at_unchecked", reason = "new API", issue = "76014")]
+    #[inline]
+    unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T]) {
+        // SAFETY: Caller has to check that `0 <= mid <= self.len()`
+        unsafe { (self.get_unchecked(..mid), self.get_unchecked(mid..)) }
+    }
+
+    /// Divides one mutable slice into two at an index, without doing bounds checking.
+    ///
+    /// The first will contain all indices from `[0, mid)` (excluding
+    /// the index `mid` itself) and the second will contain all
+    /// indices from `[mid, len)` (excluding the index `len` itself).
+    ///
+    /// For a safe alternative see [`split_at_mut`].
+    ///
+    /// # Safety
+    ///
+    /// Calling this method with an out-of-bounds index is *[undefined behavior]*
+    /// even if the resulting reference is not used. The caller has to ensure that
+    /// `0 <= mid <= self.len()`.
+    ///
+    /// [`split_at_mut`]: #method.split_at_mut
+    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
+    ///
+    /// # Examples
+    ///
+    /// ```compile_fail
+    /// #![feature(slice_split_at_unchecked)]
+    ///
+    /// let mut v = [1, 0, 3, 0, 5, 6];
+    /// // scoped to restrict the lifetime of the borrows
+    /// unsafe {
+    ///     let (left, right) = v.split_at_mut_unchecked(2);
+    ///     assert_eq!(left, [1, 0]);
+    ///     assert_eq!(right, [3, 0, 5, 6]);
+    ///     left[1] = 2;
+    ///     right[1] = 4;
+    /// }
+    /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+    /// ```
+    #[unstable(feature = "slice_split_at_unchecked", reason = "new API", issue = "76014")]
+    #[inline]
+    unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
+        let len = self.len();
+        let ptr = self.as_mut_ptr();
+
+        // SAFETY: Caller has to check that `0 <= mid <= self.len()`.
+        //
+        // `[ptr; mid]` and `[mid; len]` are not overlapping, so returning a mutable reference
+        // is fine.
+        unsafe { (from_raw_parts_mut(ptr, mid), from_raw_parts_mut(ptr.add(mid), len - mid)) }
     }
 
     /// Returns an iterator over subslices separated by elements that match
@@ -5390,7 +5490,7 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {
 /// This struct is created by the [`chunks_exact`] method on [slices].
 ///
 /// [`chunks_exact`]: ../../std/primitive.slice.html#method.chunks_exact
-/// [`remainder`]: ../../std/slice/struct.ChunksExact.html#method.remainder
+/// [`remainder`]: ChunksExact::remainder
 /// [slices]: ../../std/primitive.slice.html
 #[derive(Debug)]
 #[stable(feature = "chunks_exact", since = "1.31.0")]
@@ -5530,7 +5630,7 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> {
 /// This struct is created by the [`chunks_exact_mut`] method on [slices].
 ///
 /// [`chunks_exact_mut`]: ../../std/primitive.slice.html#method.chunks_exact_mut
-/// [`into_remainder`]: ../../std/slice/struct.ChunksExactMut.html#method.into_remainder
+/// [`into_remainder`]: ChunksExactMut::into_remainder
 /// [slices]: ../../std/primitive.slice.html
 #[derive(Debug)]
 #[stable(feature = "chunks_exact", since = "1.31.0")]
@@ -5667,7 +5767,7 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
 /// This struct is created by the [`array_chunks`] method on [slices].
 ///
 /// [`array_chunks`]: ../../std/primitive.slice.html#method.array_chunks
-/// [`remainder`]: ../../std/slice/struct.ArrayChunks.html#method.remainder
+/// [`remainder`]: ArrayChunks::remainder
 /// [slices]: ../../std/primitive.slice.html
 #[derive(Debug)]
 #[unstable(feature = "array_chunks", issue = "74985")]
@@ -6072,7 +6172,7 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> {
 /// This struct is created by the [`rchunks_exact`] method on [slices].
 ///
 /// [`rchunks_exact`]: ../../std/primitive.slice.html#method.rchunks_exact
-/// [`remainder`]: ../../std/slice/struct.ChunksExact.html#method.remainder
+/// [`remainder`]: ChunksExact::remainder
 /// [slices]: ../../std/primitive.slice.html
 #[derive(Debug)]
 #[stable(feature = "rchunks", since = "1.31.0")]
@@ -6217,7 +6317,7 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> {
 /// This struct is created by the [`rchunks_exact_mut`] method on [slices].
 ///
 /// [`rchunks_exact_mut`]: ../../std/primitive.slice.html#method.rchunks_exact_mut
-/// [`into_remainder`]: ../../std/slice/struct.ChunksExactMut.html#method.into_remainder
+/// [`into_remainder`]: ChunksExactMut::into_remainder
 /// [slices]: ../../std/primitive.slice.html
 #[derive(Debug)]
 #[stable(feature = "rchunks", since = "1.31.0")]
@@ -6427,8 +6527,8 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
 /// }
 /// ```
 ///
-/// [valid]: ../../std/ptr/index.html#safety
-/// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling
+/// [valid]: ptr#safety
+/// [`NonNull::dangling()`]: ptr::NonNull::dangling
 /// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -6467,10 +6567,9 @@ pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
 /// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
 ///   See the safety documentation of [`pointer::offset`].
 ///
-/// [valid]: ../../std/ptr/index.html#safety
-/// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling
+/// [valid]: ptr#safety
+/// [`NonNull::dangling()`]: ptr::NonNull::dangling
 /// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
-/// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 81e621318e1..4a651e5aa0e 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -1,5 +1,6 @@
 #![feature(alloc_layout_extra)]
 #![feature(array_chunks)]
+#![feature(array_methods)]
 #![feature(array_map)]
 #![feature(bool_to_option)]
 #![feature(bound_cloned)]
diff --git a/library/core/tests/num/flt2dec/mod.rs b/library/core/tests/num/flt2dec/mod.rs
index ae892e3b0bf..8e95249a79d 100644
--- a/library/core/tests/num/flt2dec/mod.rs
+++ b/library/core/tests/num/flt2dec/mod.rs
@@ -1,3 +1,4 @@
+use std::mem::MaybeUninit;
 use std::{fmt, str};
 
 use core::num::flt2dec::{decode, DecodableFloat, Decoded, FullDecoded};
@@ -36,20 +37,20 @@ macro_rules! check_shortest {
     );
 
     ($f:ident($v:expr) => $buf:expr, $exp:expr; $fmt:expr, $($key:ident = $val:expr),*) => ({
-        let mut buf = [b'_'; MAX_SIG_DIGITS];
-        let (len, k) = $f(&decode_finite($v), &mut buf);
-        assert!((&buf[..len], k) == ($buf, $exp),
-                $fmt, actual = (str::from_utf8(&buf[..len]).unwrap(), k),
+        let mut buf = [MaybeUninit::new(b'_'); MAX_SIG_DIGITS];
+        let (buf, k) = $f(&decode_finite($v), &mut buf);
+        assert!((buf, k) == ($buf, $exp),
+                $fmt, actual = (str::from_utf8(buf).unwrap(), k),
                       expected = (str::from_utf8($buf).unwrap(), $exp),
                       $($key = $val),*);
     });
 
     ($f:ident{$($k:ident: $v:expr),+} => $buf:expr, $exp:expr;
                                          $fmt:expr, $($key:ident = $val:expr),*) => ({
-        let mut buf = [b'_'; MAX_SIG_DIGITS];
-        let (len, k) = $f(&Decoded { $($k: $v),+ }, &mut buf);
-        assert!((&buf[..len], k) == ($buf, $exp),
-                $fmt, actual = (str::from_utf8(&buf[..len]).unwrap(), k),
+        let mut buf = [MaybeUninit::new(b'_'); MAX_SIG_DIGITS];
+        let (buf, k) = $f(&Decoded { $($k: $v),+ }, &mut buf);
+        assert!((buf, k) == ($buf, $exp),
+                $fmt, actual = (str::from_utf8(buf).unwrap(), k),
                       expected = (str::from_utf8($buf).unwrap(), $exp),
                       $($key = $val),*);
     })
@@ -58,9 +59,9 @@ macro_rules! check_shortest {
 macro_rules! try_exact {
     ($f:ident($decoded:expr) => $buf:expr, $expected:expr, $expectedk:expr;
                                 $fmt:expr, $($key:ident = $val:expr),*) => ({
-        let (len, k) = $f($decoded, &mut $buf[..$expected.len()], i16::MIN);
-        assert!((&$buf[..len], k) == ($expected, $expectedk),
-                $fmt, actual = (str::from_utf8(&$buf[..len]).unwrap(), k),
+        let (buf, k) = $f($decoded, &mut $buf[..$expected.len()], i16::MIN);
+        assert!((buf, k) == ($expected, $expectedk),
+                $fmt, actual = (str::from_utf8(buf).unwrap(), k),
                       expected = (str::from_utf8($expected).unwrap(), $expectedk),
                       $($key = $val),*);
     })
@@ -69,9 +70,9 @@ macro_rules! try_exact {
 macro_rules! try_fixed {
     ($f:ident($decoded:expr) => $buf:expr, $request:expr, $expected:expr, $expectedk:expr;
                                 $fmt:expr, $($key:ident = $val:expr),*) => ({
-        let (len, k) = $f($decoded, &mut $buf[..], $request);
-        assert!((&$buf[..len], k) == ($expected, $expectedk),
-                $fmt, actual = (str::from_utf8(&$buf[..len]).unwrap(), k),
+        let (buf, k) = $f($decoded, &mut $buf[..], $request);
+        assert!((buf, k) == ($expected, $expectedk),
+                $fmt, actual = (str::from_utf8(buf).unwrap(), k),
                       expected = (str::from_utf8($expected).unwrap(), $expectedk),
                       $($key = $val),*);
     })
@@ -93,10 +94,10 @@ fn ldexp_f64(a: f64, b: i32) -> f64 {
 fn check_exact<F, T>(mut f: F, v: T, vstr: &str, expected: &[u8], expectedk: i16)
 where
     T: DecodableFloat,
-    F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16),
+    F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
 {
     // use a large enough buffer
-    let mut buf = [b'_'; 1024];
+    let mut buf = [MaybeUninit::new(b'_'); 1024];
     let mut expected_ = [b'_'; 1024];
 
     let decoded = decode_finite(v);
@@ -118,7 +119,7 @@ where
                 // we should always return `100..00` (`i` digits) instead, since that's
                 // what we can came up with `i` digits anyway. `round_up` assumes that
                 // the adjustment to the length is done by caller, which we simply ignore.
-                if let Some(_) = round_up(&mut expected_, i) {
+                if let Some(_) = round_up(&mut expected_[..i]) {
                     expectedk_ += 1;
                 }
             }
@@ -193,10 +194,10 @@ impl TestableFloat for f64 {
 fn check_exact_one<F, T>(mut f: F, x: i64, e: isize, tstr: &str, expected: &[u8], expectedk: i16)
 where
     T: TestableFloat,
-    F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16),
+    F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
 {
     // use a large enough buffer
-    let mut buf = [b'_'; 1024];
+    let mut buf = [MaybeUninit::new(b'_'); 1024];
     let v: T = TestableFloat::ldexpi(x, e);
     let decoded = decode_finite(v);
 
@@ -230,7 +231,7 @@ macro_rules! check_exact_one {
 
 pub fn f32_shortest_sanity_test<F>(mut f: F)
 where
-    F: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+    F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
 {
     // 0.0999999940395355224609375
     // 0.100000001490116119384765625
@@ -277,7 +278,7 @@ where
 
 pub fn f32_exact_sanity_test<F>(mut f: F)
 where
-    F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16),
+    F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
 {
     let minf32 = ldexp_f32(1.0, -149);
 
@@ -321,7 +322,7 @@ where
 
 pub fn f64_shortest_sanity_test<F>(mut f: F)
 where
-    F: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+    F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
 {
     // 0.0999999999999999777955395074968691915273...
     // 0.1000000000000000055511151231257827021181...
@@ -387,7 +388,7 @@ where
 
 pub fn f64_exact_sanity_test<F>(mut f: F)
 where
-    F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16),
+    F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
 {
     let minf64 = ldexp_f64(1.0, -1074);
 
@@ -474,7 +475,7 @@ where
 
 pub fn more_shortest_sanity_test<F>(mut f: F)
 where
-    F: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+    F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
 {
     check_shortest!(f{mant: 99_999_999_999_999_999, minus: 1, plus: 1,
                       exp: 0, inclusive: true} => b"1", 18);
@@ -484,10 +485,10 @@ where
 
 fn to_string_with_parts<F>(mut f: F) -> String
 where
-    F: for<'a> FnMut(&'a mut [u8], &'a mut [Part<'a>]) -> Formatted<'a>,
+    F: for<'a> FnMut(&'a mut [MaybeUninit<u8>], &'a mut [MaybeUninit<Part<'a>>]) -> Formatted<'a>,
 {
-    let mut buf = [0; 1024];
-    let mut parts = [Part::Zero(0); 16];
+    let mut buf = [MaybeUninit::new(0); 1024];
+    let mut parts = [MaybeUninit::new(Part::Zero(0)); 16];
     let formatted = f(&mut buf, &mut parts);
     let mut ret = vec![0; formatted.len()];
     assert_eq!(formatted.write(&mut ret), Some(ret.len()));
@@ -496,14 +497,14 @@ where
 
 pub fn to_shortest_str_test<F>(mut f_: F)
 where
-    F: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+    F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
 {
     use core::num::flt2dec::Sign::*;
 
     fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize) -> String
     where
         T: DecodableFloat,
-        F: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+        F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
     {
         to_string_with_parts(|buf, parts| {
             to_shortest_str(|d, b| f(d, b), v, sign, frac_digits, buf, parts)
@@ -597,14 +598,14 @@ where
 
 pub fn to_shortest_exp_str_test<F>(mut f_: F)
 where
-    F: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+    F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
 {
     use core::num::flt2dec::Sign::*;
 
     fn to_string<T, F>(f: &mut F, v: T, sign: Sign, exp_bounds: (i16, i16), upper: bool) -> String
     where
         T: DecodableFloat,
-        F: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+        F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
     {
         to_string_with_parts(|buf, parts| {
             to_shortest_exp_str(|d, b| f(d, b), v, sign, exp_bounds, upper, buf, parts)
@@ -716,14 +717,14 @@ where
 
 pub fn to_exact_exp_str_test<F>(mut f_: F)
 where
-    F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16),
+    F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
 {
     use core::num::flt2dec::Sign::*;
 
     fn to_string<T, F>(f: &mut F, v: T, sign: Sign, ndigits: usize, upper: bool) -> String
     where
         T: DecodableFloat,
-        F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16),
+        F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
     {
         to_string_with_parts(|buf, parts| {
             to_exact_exp_str(|d, b, l| f(d, b, l), v, sign, ndigits, upper, buf, parts)
@@ -989,14 +990,14 @@ where
 
 pub fn to_exact_fixed_str_test<F>(mut f_: F)
 where
-    F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16),
+    F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
 {
     use core::num::flt2dec::Sign::*;
 
     fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize) -> String
     where
         T: DecodableFloat,
-        F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16),
+        F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
     {
         to_string_with_parts(|buf, parts| {
             to_exact_fixed_str(|d, b, l| f(d, b, l), v, sign, frac_digits, buf, parts)
diff --git a/library/core/tests/num/flt2dec/random.rs b/library/core/tests/num/flt2dec/random.rs
index e5656eb204c..57b3dcf8e1e 100644
--- a/library/core/tests/num/flt2dec/random.rs
+++ b/library/core/tests/num/flt2dec/random.rs
@@ -1,5 +1,6 @@
 #![cfg(not(target_arch = "wasm32"))]
 
+use std::mem::MaybeUninit;
 use std::str;
 
 use core::num::flt2dec::strategy::grisu::format_exact_opt;
@@ -20,8 +21,8 @@ pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
 
 fn iterate<F, G, V>(func: &str, k: usize, n: usize, mut f: F, mut g: G, mut v: V) -> (usize, usize)
 where
-    F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
-    G: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+    F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> Option<(&'a [u8], i16)>,
+    G: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
     V: FnMut(usize) -> Decoded,
 {
     assert!(k <= 1024);
@@ -42,11 +43,11 @@ where
         }
 
         let decoded = v(i);
-        let mut buf1 = [0; 1024];
-        if let Some((len1, e1)) = f(&decoded, &mut buf1[..k]) {
-            let mut buf2 = [0; 1024];
-            let (len2, e2) = g(&decoded, &mut buf2[..k]);
-            if e1 == e2 && &buf1[..len1] == &buf2[..len2] {
+        let mut buf1 = [MaybeUninit::new(0); 1024];
+        if let Some((buf1, e1)) = f(&decoded, &mut buf1[..k]) {
+            let mut buf2 = [MaybeUninit::new(0); 1024];
+            let (buf2, e2) = g(&decoded, &mut buf2[..k]);
+            if e1 == e2 && buf1 == buf2 {
                 npassed += 1;
             } else {
                 println!(
@@ -54,9 +55,9 @@ where
                     i,
                     n,
                     decoded,
-                    str::from_utf8(&buf1[..len1]).unwrap(),
+                    str::from_utf8(buf1).unwrap(),
                     e1,
-                    str::from_utf8(&buf2[..len2]).unwrap(),
+                    str::from_utf8(buf2).unwrap(),
                     e2
                 );
             }
@@ -85,8 +86,8 @@ where
 
 pub fn f32_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
 where
-    F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
-    G: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+    F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> Option<(&'a [u8], i16)>,
+    G: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
 {
     if cfg!(target_os = "emscripten") {
         return; // using rng pulls in i128 support, which doesn't work
@@ -101,8 +102,8 @@ where
 
 pub fn f64_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
 where
-    F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
-    G: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+    F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> Option<(&'a [u8], i16)>,
+    G: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
 {
     if cfg!(target_os = "emscripten") {
         return; // using rng pulls in i128 support, which doesn't work
@@ -117,8 +118,8 @@ where
 
 pub fn f32_exhaustive_equivalence_test<F, G>(f: F, g: G, k: usize)
 where
-    F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
-    G: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+    F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> Option<(&'a [u8], i16)>,
+    G: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
 {
     // we have only 2^23 * (2^8 - 1) - 1 = 2,139,095,039 positive finite f32 values,
     // so why not simply testing all of them?
diff --git a/library/core/tests/option.rs b/library/core/tests/option.rs
index fa308160fc2..b46bcfd16d2 100644
--- a/library/core/tests/option.rs
+++ b/library/core/tests/option.rs
@@ -1,4 +1,3 @@
-use core::array::FixedSizeArray;
 use core::clone::Clone;
 use core::mem;
 use core::ops::DerefMut;
diff --git a/library/core/tests/result.rs b/library/core/tests/result.rs
index caa2d916cd7..35598295a95 100644
--- a/library/core/tests/result.rs
+++ b/library/core/tests/result.rs
@@ -1,4 +1,3 @@
-use core::array::FixedSizeArray;
 use core::ops::DerefMut;
 use core::option::*;
 
diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs
index c00e07388b8..3d9016293b8 100644
--- a/library/proc_macro/src/bridge/client.rs
+++ b/library/proc_macro/src/bridge/client.rs
@@ -311,11 +311,13 @@ impl Bridge<'_> {
         HIDE_PANICS_DURING_EXPANSION.call_once(|| {
             let prev = panic::take_hook();
             panic::set_hook(Box::new(move |info| {
-                let hide = BridgeState::with(|state| match state {
-                    BridgeState::NotConnected => false,
-                    BridgeState::Connected(_) | BridgeState::InUse => true,
+                let show = BridgeState::with(|state| match state {
+                    BridgeState::NotConnected => true,
+                    // Something weird is going on, so don't suppress any backtraces
+                    BridgeState::InUse => true,
+                    BridgeState::Connected(bridge) => bridge.force_show_panics,
                 });
-                if !hide {
+                if show {
                     prev(info)
                 }
             }));
diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs
index 324be9f4701..c898d483a8b 100644
--- a/library/proc_macro/src/bridge/mod.rs
+++ b/library/proc_macro/src/bridge/mod.rs
@@ -220,6 +220,9 @@ pub struct Bridge<'a> {
 
     /// Server-side function that the client uses to make requests.
     dispatch: closure::Closure<'a, Buffer<u8>, Buffer<u8>>,
+
+    /// If 'true', always invoke the default panic hook
+    force_show_panics: bool,
 }
 
 impl<'a> !Sync for Bridge<'a> {}
diff --git a/library/proc_macro/src/bridge/server.rs b/library/proc_macro/src/bridge/server.rs
index eb39025e4c2..1b3ccf4c18e 100644
--- a/library/proc_macro/src/bridge/server.rs
+++ b/library/proc_macro/src/bridge/server.rs
@@ -135,6 +135,7 @@ pub trait ExecutionStrategy {
         input: Buffer<u8>,
         run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>,
         client_data: D,
+        force_show_panics: bool,
     ) -> Buffer<u8>;
 }
 
@@ -147,10 +148,14 @@ impl ExecutionStrategy for SameThread {
         input: Buffer<u8>,
         run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>,
         client_data: D,
+        force_show_panics: bool,
     ) -> Buffer<u8> {
         let mut dispatch = |b| dispatcher.dispatch(b);
 
-        run_client(Bridge { cached_buffer: input, dispatch: (&mut dispatch).into() }, client_data)
+        run_client(
+            Bridge { cached_buffer: input, dispatch: (&mut dispatch).into(), force_show_panics },
+            client_data,
+        )
     }
 }
 
@@ -166,6 +171,7 @@ impl ExecutionStrategy for CrossThread1 {
         input: Buffer<u8>,
         run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>,
         client_data: D,
+        force_show_panics: bool,
     ) -> Buffer<u8> {
         use std::sync::mpsc::channel;
 
@@ -179,7 +185,11 @@ impl ExecutionStrategy for CrossThread1 {
             };
 
             run_client(
-                Bridge { cached_buffer: input, dispatch: (&mut dispatch).into() },
+                Bridge {
+                    cached_buffer: input,
+                    dispatch: (&mut dispatch).into(),
+                    force_show_panics,
+                },
                 client_data,
             )
         });
@@ -201,6 +211,7 @@ impl ExecutionStrategy for CrossThread2 {
         input: Buffer<u8>,
         run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>,
         client_data: D,
+        force_show_panics: bool,
     ) -> Buffer<u8> {
         use std::sync::{Arc, Mutex};
 
@@ -226,7 +237,11 @@ impl ExecutionStrategy for CrossThread2 {
             };
 
             let r = run_client(
-                Bridge { cached_buffer: input, dispatch: (&mut dispatch).into() },
+                Bridge {
+                    cached_buffer: input,
+                    dispatch: (&mut dispatch).into(),
+                    force_show_panics,
+                },
                 client_data,
             );
 
@@ -265,6 +280,7 @@ fn run_server<
     input: I,
     run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>,
     client_data: D,
+    force_show_panics: bool,
 ) -> Result<O, PanicMessage> {
     let mut dispatcher =
         Dispatcher { handle_store: HandleStore::new(handle_counters), server: MarkedTypes(server) };
@@ -272,7 +288,13 @@ fn run_server<
     let mut b = Buffer::new();
     input.encode(&mut b, &mut dispatcher.handle_store);
 
-    b = strategy.run_bridge_and_client(&mut dispatcher, b, run_client, client_data);
+    b = strategy.run_bridge_and_client(
+        &mut dispatcher,
+        b,
+        run_client,
+        client_data,
+        force_show_panics,
+    );
 
     Result::decode(&mut &b[..], &mut dispatcher.handle_store)
 }
@@ -283,6 +305,7 @@ impl client::Client<fn(crate::TokenStream) -> crate::TokenStream> {
         strategy: &impl ExecutionStrategy,
         server: S,
         input: S::TokenStream,
+        force_show_panics: bool,
     ) -> Result<S::TokenStream, PanicMessage> {
         let client::Client { get_handle_counters, run, f } = *self;
         run_server(
@@ -292,6 +315,7 @@ impl client::Client<fn(crate::TokenStream) -> crate::TokenStream> {
             <MarkedTypes<S> as Types>::TokenStream::mark(input),
             run,
             f,
+            force_show_panics,
         )
         .map(<MarkedTypes<S> as Types>::TokenStream::unmark)
     }
@@ -304,6 +328,7 @@ impl client::Client<fn(crate::TokenStream, crate::TokenStream) -> crate::TokenSt
         server: S,
         input: S::TokenStream,
         input2: S::TokenStream,
+        force_show_panics: bool,
     ) -> Result<S::TokenStream, PanicMessage> {
         let client::Client { get_handle_counters, run, f } = *self;
         run_server(
@@ -316,6 +341,7 @@ impl client::Client<fn(crate::TokenStream, crate::TokenStream) -> crate::TokenSt
             ),
             run,
             f,
+            force_show_panics,
         )
         .map(<MarkedTypes<S> as Types>::TokenStream::unmark)
     }
diff --git a/library/std/src/ascii.rs b/library/std/src/ascii.rs
index c9106136d34..035cd9f243b 100644
--- a/library/std/src/ascii.rs
+++ b/library/std/src/ascii.rs
@@ -70,7 +70,6 @@ pub trait AsciiExt {
     /// inherent methods on `u8`, `char`, `[u8]` and `str`.
     ///
     /// [`make_ascii_uppercase`]: AsciiExt::make_ascii_uppercase
-    /// [`str::to_uppercase`]: ../primitive.str.html#method.to_uppercase
     #[stable(feature = "rust1", since = "1.0.0")]
     #[allow(deprecated)]
     fn to_ascii_uppercase(&self) -> Self::Owned;
@@ -91,7 +90,6 @@ pub trait AsciiExt {
     /// inherent methods on `u8`, `char`, `[u8]` and `str`.
     ///
     /// [`make_ascii_lowercase`]: AsciiExt::make_ascii_lowercase
-    /// [`str::to_lowercase`]: ../primitive.str.html#method.to_lowercase
     #[stable(feature = "rust1", since = "1.0.0")]
     #[allow(deprecated)]
     fn to_ascii_lowercase(&self) -> Self::Owned;
diff --git a/library/std/src/backtrace.rs b/library/std/src/backtrace.rs
index 09f83ea5fca..cc29e1c0b05 100644
--- a/library/std/src/backtrace.rs
+++ b/library/std/src/backtrace.rs
@@ -66,6 +66,9 @@
 
 #![unstable(feature = "backtrace", issue = "53487")]
 
+#[cfg(test)]
+mod tests;
+
 // NB: A note on resolution of a backtrace:
 //
 // Backtraces primarily happen in two steps, one is where we actually capture
@@ -438,55 +441,3 @@ impl RawFrame {
         }
     }
 }
-
-#[test]
-fn test_debug() {
-    let backtrace = Backtrace {
-        inner: Inner::Captured(Mutex::new(Capture {
-            actual_start: 1,
-            resolved: true,
-            frames: vec![
-                BacktraceFrame {
-                    frame: RawFrame::Fake,
-                    symbols: vec![BacktraceSymbol {
-                        name: Some(b"std::backtrace::Backtrace::create".to_vec()),
-                        filename: Some(BytesOrWide::Bytes(b"rust/backtrace.rs".to_vec())),
-                        lineno: Some(100),
-                    }],
-                },
-                BacktraceFrame {
-                    frame: RawFrame::Fake,
-                    symbols: vec![BacktraceSymbol {
-                        name: Some(b"__rust_maybe_catch_panic".to_vec()),
-                        filename: None,
-                        lineno: None,
-                    }],
-                },
-                BacktraceFrame {
-                    frame: RawFrame::Fake,
-                    symbols: vec![
-                        BacktraceSymbol {
-                            name: Some(b"std::rt::lang_start_internal".to_vec()),
-                            filename: Some(BytesOrWide::Bytes(b"rust/rt.rs".to_vec())),
-                            lineno: Some(300),
-                        },
-                        BacktraceSymbol {
-                            name: Some(b"std::rt::lang_start".to_vec()),
-                            filename: Some(BytesOrWide::Bytes(b"rust/rt.rs".to_vec())),
-                            lineno: Some(400),
-                        },
-                    ],
-                },
-            ],
-        })),
-    };
-
-    #[rustfmt::skip]
-    let expected = "Backtrace [\
-    \n    { fn: \"__rust_maybe_catch_panic\" },\
-    \n    { fn: \"std::rt::lang_start_internal\", file: \"rust/rt.rs\", line: 300 },\
-    \n    { fn: \"std::rt::lang_start\", file: \"rust/rt.rs\", line: 400 },\
-    \n]";
-
-    assert_eq!(format!("{:#?}", backtrace), expected);
-}
diff --git a/library/std/src/backtrace/tests.rs b/library/std/src/backtrace/tests.rs
new file mode 100644
index 00000000000..287359cd545
--- /dev/null
+++ b/library/std/src/backtrace/tests.rs
@@ -0,0 +1,53 @@
+use super::*;
+
+#[test]
+fn test_debug() {
+    let backtrace = Backtrace {
+        inner: Inner::Captured(Mutex::new(Capture {
+            actual_start: 1,
+            resolved: true,
+            frames: vec![
+                BacktraceFrame {
+                    frame: RawFrame::Fake,
+                    symbols: vec![BacktraceSymbol {
+                        name: Some(b"std::backtrace::Backtrace::create".to_vec()),
+                        filename: Some(BytesOrWide::Bytes(b"rust/backtrace.rs".to_vec())),
+                        lineno: Some(100),
+                    }],
+                },
+                BacktraceFrame {
+                    frame: RawFrame::Fake,
+                    symbols: vec![BacktraceSymbol {
+                        name: Some(b"__rust_maybe_catch_panic".to_vec()),
+                        filename: None,
+                        lineno: None,
+                    }],
+                },
+                BacktraceFrame {
+                    frame: RawFrame::Fake,
+                    symbols: vec![
+                        BacktraceSymbol {
+                            name: Some(b"std::rt::lang_start_internal".to_vec()),
+                            filename: Some(BytesOrWide::Bytes(b"rust/rt.rs".to_vec())),
+                            lineno: Some(300),
+                        },
+                        BacktraceSymbol {
+                            name: Some(b"std::rt::lang_start".to_vec()),
+                            filename: Some(BytesOrWide::Bytes(b"rust/rt.rs".to_vec())),
+                            lineno: Some(400),
+                        },
+                    ],
+                },
+            ],
+        })),
+    };
+
+    #[rustfmt::skip]
+    let expected = "Backtrace [\
+    \n    { fn: \"__rust_maybe_catch_panic\" },\
+    \n    { fn: \"std::rt::lang_start_internal\", file: \"rust/rt.rs\", line: 300 },\
+    \n    { fn: \"std::rt::lang_start\", file: \"rust/rt.rs\", line: 400 },\
+    \n]";
+
+    assert_eq!(format!("{:#?}", backtrace), expected);
+}
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 70f7214e2f1..77cc5b93dbb 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -1,4 +1,5 @@
-// ignore-tidy-filelength
+#[cfg(test)]
+mod tests;
 
 use self::Entry::*;
 
@@ -2754,933 +2755,3 @@ fn assert_covariance() {
         d
     }
 }
-
-#[cfg(test)]
-mod test_map {
-    use super::Entry::{Occupied, Vacant};
-    use super::HashMap;
-    use super::RandomState;
-    use crate::cell::RefCell;
-    use rand::{thread_rng, Rng};
-    use realstd::collections::TryReserveError::*;
-
-    // https://github.com/rust-lang/rust/issues/62301
-    fn _assert_hashmap_is_unwind_safe() {
-        fn assert_unwind_safe<T: crate::panic::UnwindSafe>() {}
-        assert_unwind_safe::<HashMap<(), crate::cell::UnsafeCell<()>>>();
-    }
-
-    #[test]
-    fn test_zero_capacities() {
-        type HM = HashMap<i32, i32>;
-
-        let m = HM::new();
-        assert_eq!(m.capacity(), 0);
-
-        let m = HM::default();
-        assert_eq!(m.capacity(), 0);
-
-        let m = HM::with_hasher(RandomState::new());
-        assert_eq!(m.capacity(), 0);
-
-        let m = HM::with_capacity(0);
-        assert_eq!(m.capacity(), 0);
-
-        let m = HM::with_capacity_and_hasher(0, RandomState::new());
-        assert_eq!(m.capacity(), 0);
-
-        let mut m = HM::new();
-        m.insert(1, 1);
-        m.insert(2, 2);
-        m.remove(&1);
-        m.remove(&2);
-        m.shrink_to_fit();
-        assert_eq!(m.capacity(), 0);
-
-        let mut m = HM::new();
-        m.reserve(0);
-        assert_eq!(m.capacity(), 0);
-    }
-
-    #[test]
-    fn test_create_capacity_zero() {
-        let mut m = HashMap::with_capacity(0);
-
-        assert!(m.insert(1, 1).is_none());
-
-        assert!(m.contains_key(&1));
-        assert!(!m.contains_key(&0));
-    }
-
-    #[test]
-    fn test_insert() {
-        let mut m = HashMap::new();
-        assert_eq!(m.len(), 0);
-        assert!(m.insert(1, 2).is_none());
-        assert_eq!(m.len(), 1);
-        assert!(m.insert(2, 4).is_none());
-        assert_eq!(m.len(), 2);
-        assert_eq!(*m.get(&1).unwrap(), 2);
-        assert_eq!(*m.get(&2).unwrap(), 4);
-    }
-
-    #[test]
-    fn test_clone() {
-        let mut m = HashMap::new();
-        assert_eq!(m.len(), 0);
-        assert!(m.insert(1, 2).is_none());
-        assert_eq!(m.len(), 1);
-        assert!(m.insert(2, 4).is_none());
-        assert_eq!(m.len(), 2);
-        let m2 = m.clone();
-        assert_eq!(*m2.get(&1).unwrap(), 2);
-        assert_eq!(*m2.get(&2).unwrap(), 4);
-        assert_eq!(m2.len(), 2);
-    }
-
-    thread_local! { static DROP_VECTOR: RefCell<Vec<i32>> = RefCell::new(Vec::new()) }
-
-    #[derive(Hash, PartialEq, Eq)]
-    struct Droppable {
-        k: usize,
-    }
-
-    impl Droppable {
-        fn new(k: usize) -> Droppable {
-            DROP_VECTOR.with(|slot| {
-                slot.borrow_mut()[k] += 1;
-            });
-
-            Droppable { k }
-        }
-    }
-
-    impl Drop for Droppable {
-        fn drop(&mut self) {
-            DROP_VECTOR.with(|slot| {
-                slot.borrow_mut()[self.k] -= 1;
-            });
-        }
-    }
-
-    impl Clone for Droppable {
-        fn clone(&self) -> Droppable {
-            Droppable::new(self.k)
-        }
-    }
-
-    #[test]
-    fn test_drops() {
-        DROP_VECTOR.with(|slot| {
-            *slot.borrow_mut() = vec![0; 200];
-        });
-
-        {
-            let mut m = HashMap::new();
-
-            DROP_VECTOR.with(|v| {
-                for i in 0..200 {
-                    assert_eq!(v.borrow()[i], 0);
-                }
-            });
-
-            for i in 0..100 {
-                let d1 = Droppable::new(i);
-                let d2 = Droppable::new(i + 100);
-                m.insert(d1, d2);
-            }
-
-            DROP_VECTOR.with(|v| {
-                for i in 0..200 {
-                    assert_eq!(v.borrow()[i], 1);
-                }
-            });
-
-            for i in 0..50 {
-                let k = Droppable::new(i);
-                let v = m.remove(&k);
-
-                assert!(v.is_some());
-
-                DROP_VECTOR.with(|v| {
-                    assert_eq!(v.borrow()[i], 1);
-                    assert_eq!(v.borrow()[i + 100], 1);
-                });
-            }
-
-            DROP_VECTOR.with(|v| {
-                for i in 0..50 {
-                    assert_eq!(v.borrow()[i], 0);
-                    assert_eq!(v.borrow()[i + 100], 0);
-                }
-
-                for i in 50..100 {
-                    assert_eq!(v.borrow()[i], 1);
-                    assert_eq!(v.borrow()[i + 100], 1);
-                }
-            });
-        }
-
-        DROP_VECTOR.with(|v| {
-            for i in 0..200 {
-                assert_eq!(v.borrow()[i], 0);
-            }
-        });
-    }
-
-    #[test]
-    fn test_into_iter_drops() {
-        DROP_VECTOR.with(|v| {
-            *v.borrow_mut() = vec![0; 200];
-        });
-
-        let hm = {
-            let mut hm = HashMap::new();
-
-            DROP_VECTOR.with(|v| {
-                for i in 0..200 {
-                    assert_eq!(v.borrow()[i], 0);
-                }
-            });
-
-            for i in 0..100 {
-                let d1 = Droppable::new(i);
-                let d2 = Droppable::new(i + 100);
-                hm.insert(d1, d2);
-            }
-
-            DROP_VECTOR.with(|v| {
-                for i in 0..200 {
-                    assert_eq!(v.borrow()[i], 1);
-                }
-            });
-
-            hm
-        };
-
-        // By the way, ensure that cloning doesn't screw up the dropping.
-        drop(hm.clone());
-
-        {
-            let mut half = hm.into_iter().take(50);
-
-            DROP_VECTOR.with(|v| {
-                for i in 0..200 {
-                    assert_eq!(v.borrow()[i], 1);
-                }
-            });
-
-            for _ in half.by_ref() {}
-
-            DROP_VECTOR.with(|v| {
-                let nk = (0..100).filter(|&i| v.borrow()[i] == 1).count();
-
-                let nv = (0..100).filter(|&i| v.borrow()[i + 100] == 1).count();
-
-                assert_eq!(nk, 50);
-                assert_eq!(nv, 50);
-            });
-        };
-
-        DROP_VECTOR.with(|v| {
-            for i in 0..200 {
-                assert_eq!(v.borrow()[i], 0);
-            }
-        });
-    }
-
-    #[test]
-    fn test_empty_remove() {
-        let mut m: HashMap<i32, bool> = HashMap::new();
-        assert_eq!(m.remove(&0), None);
-    }
-
-    #[test]
-    fn test_empty_entry() {
-        let mut m: HashMap<i32, bool> = HashMap::new();
-        match m.entry(0) {
-            Occupied(_) => panic!(),
-            Vacant(_) => {}
-        }
-        assert!(*m.entry(0).or_insert(true));
-        assert_eq!(m.len(), 1);
-    }
-
-    #[test]
-    fn test_empty_iter() {
-        let mut m: HashMap<i32, bool> = HashMap::new();
-        assert_eq!(m.drain().next(), None);
-        assert_eq!(m.keys().next(), None);
-        assert_eq!(m.values().next(), None);
-        assert_eq!(m.values_mut().next(), None);
-        assert_eq!(m.iter().next(), None);
-        assert_eq!(m.iter_mut().next(), None);
-        assert_eq!(m.len(), 0);
-        assert!(m.is_empty());
-        assert_eq!(m.into_iter().next(), None);
-    }
-
-    #[test]
-    fn test_lots_of_insertions() {
-        let mut m = HashMap::new();
-
-        // Try this a few times to make sure we never screw up the hashmap's
-        // internal state.
-        for _ in 0..10 {
-            assert!(m.is_empty());
-
-            for i in 1..1001 {
-                assert!(m.insert(i, i).is_none());
-
-                for j in 1..=i {
-                    let r = m.get(&j);
-                    assert_eq!(r, Some(&j));
-                }
-
-                for j in i + 1..1001 {
-                    let r = m.get(&j);
-                    assert_eq!(r, None);
-                }
-            }
-
-            for i in 1001..2001 {
-                assert!(!m.contains_key(&i));
-            }
-
-            // remove forwards
-            for i in 1..1001 {
-                assert!(m.remove(&i).is_some());
-
-                for j in 1..=i {
-                    assert!(!m.contains_key(&j));
-                }
-
-                for j in i + 1..1001 {
-                    assert!(m.contains_key(&j));
-                }
-            }
-
-            for i in 1..1001 {
-                assert!(!m.contains_key(&i));
-            }
-
-            for i in 1..1001 {
-                assert!(m.insert(i, i).is_none());
-            }
-
-            // remove backwards
-            for i in (1..1001).rev() {
-                assert!(m.remove(&i).is_some());
-
-                for j in i..1001 {
-                    assert!(!m.contains_key(&j));
-                }
-
-                for j in 1..i {
-                    assert!(m.contains_key(&j));
-                }
-            }
-        }
-    }
-
-    #[test]
-    fn test_find_mut() {
-        let mut m = HashMap::new();
-        assert!(m.insert(1, 12).is_none());
-        assert!(m.insert(2, 8).is_none());
-        assert!(m.insert(5, 14).is_none());
-        let new = 100;
-        match m.get_mut(&5) {
-            None => panic!(),
-            Some(x) => *x = new,
-        }
-        assert_eq!(m.get(&5), Some(&new));
-    }
-
-    #[test]
-    fn test_insert_overwrite() {
-        let mut m = HashMap::new();
-        assert!(m.insert(1, 2).is_none());
-        assert_eq!(*m.get(&1).unwrap(), 2);
-        assert!(!m.insert(1, 3).is_none());
-        assert_eq!(*m.get(&1).unwrap(), 3);
-    }
-
-    #[test]
-    fn test_insert_conflicts() {
-        let mut m = HashMap::with_capacity(4);
-        assert!(m.insert(1, 2).is_none());
-        assert!(m.insert(5, 3).is_none());
-        assert!(m.insert(9, 4).is_none());
-        assert_eq!(*m.get(&9).unwrap(), 4);
-        assert_eq!(*m.get(&5).unwrap(), 3);
-        assert_eq!(*m.get(&1).unwrap(), 2);
-    }
-
-    #[test]
-    fn test_conflict_remove() {
-        let mut m = HashMap::with_capacity(4);
-        assert!(m.insert(1, 2).is_none());
-        assert_eq!(*m.get(&1).unwrap(), 2);
-        assert!(m.insert(5, 3).is_none());
-        assert_eq!(*m.get(&1).unwrap(), 2);
-        assert_eq!(*m.get(&5).unwrap(), 3);
-        assert!(m.insert(9, 4).is_none());
-        assert_eq!(*m.get(&1).unwrap(), 2);
-        assert_eq!(*m.get(&5).unwrap(), 3);
-        assert_eq!(*m.get(&9).unwrap(), 4);
-        assert!(m.remove(&1).is_some());
-        assert_eq!(*m.get(&9).unwrap(), 4);
-        assert_eq!(*m.get(&5).unwrap(), 3);
-    }
-
-    #[test]
-    fn test_is_empty() {
-        let mut m = HashMap::with_capacity(4);
-        assert!(m.insert(1, 2).is_none());
-        assert!(!m.is_empty());
-        assert!(m.remove(&1).is_some());
-        assert!(m.is_empty());
-    }
-
-    #[test]
-    fn test_remove() {
-        let mut m = HashMap::new();
-        m.insert(1, 2);
-        assert_eq!(m.remove(&1), Some(2));
-        assert_eq!(m.remove(&1), None);
-    }
-
-    #[test]
-    fn test_remove_entry() {
-        let mut m = HashMap::new();
-        m.insert(1, 2);
-        assert_eq!(m.remove_entry(&1), Some((1, 2)));
-        assert_eq!(m.remove(&1), None);
-    }
-
-    #[test]
-    fn test_iterate() {
-        let mut m = HashMap::with_capacity(4);
-        for i in 0..32 {
-            assert!(m.insert(i, i * 2).is_none());
-        }
-        assert_eq!(m.len(), 32);
-
-        let mut observed: u32 = 0;
-
-        for (k, v) in &m {
-            assert_eq!(*v, *k * 2);
-            observed |= 1 << *k;
-        }
-        assert_eq!(observed, 0xFFFF_FFFF);
-    }
-
-    #[test]
-    fn test_keys() {
-        let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
-        let map: HashMap<_, _> = vec.into_iter().collect();
-        let keys: Vec<_> = map.keys().cloned().collect();
-        assert_eq!(keys.len(), 3);
-        assert!(keys.contains(&1));
-        assert!(keys.contains(&2));
-        assert!(keys.contains(&3));
-    }
-
-    #[test]
-    fn test_values() {
-        let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
-        let map: HashMap<_, _> = vec.into_iter().collect();
-        let values: Vec<_> = map.values().cloned().collect();
-        assert_eq!(values.len(), 3);
-        assert!(values.contains(&'a'));
-        assert!(values.contains(&'b'));
-        assert!(values.contains(&'c'));
-    }
-
-    #[test]
-    fn test_values_mut() {
-        let vec = vec![(1, 1), (2, 2), (3, 3)];
-        let mut map: HashMap<_, _> = vec.into_iter().collect();
-        for value in map.values_mut() {
-            *value = (*value) * 2
-        }
-        let values: Vec<_> = map.values().cloned().collect();
-        assert_eq!(values.len(), 3);
-        assert!(values.contains(&2));
-        assert!(values.contains(&4));
-        assert!(values.contains(&6));
-    }
-
-    #[test]
-    fn test_into_keys() {
-        let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
-        let map: HashMap<_, _> = vec.into_iter().collect();
-        let keys: Vec<_> = map.into_keys().collect();
-
-        assert_eq!(keys.len(), 3);
-        assert!(keys.contains(&1));
-        assert!(keys.contains(&2));
-        assert!(keys.contains(&3));
-    }
-
-    #[test]
-    fn test_into_values() {
-        let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
-        let map: HashMap<_, _> = vec.into_iter().collect();
-        let values: Vec<_> = map.into_values().collect();
-
-        assert_eq!(values.len(), 3);
-        assert!(values.contains(&'a'));
-        assert!(values.contains(&'b'));
-        assert!(values.contains(&'c'));
-    }
-
-    #[test]
-    fn test_find() {
-        let mut m = HashMap::new();
-        assert!(m.get(&1).is_none());
-        m.insert(1, 2);
-        match m.get(&1) {
-            None => panic!(),
-            Some(v) => assert_eq!(*v, 2),
-        }
-    }
-
-    #[test]
-    fn test_eq() {
-        let mut m1 = HashMap::new();
-        m1.insert(1, 2);
-        m1.insert(2, 3);
-        m1.insert(3, 4);
-
-        let mut m2 = HashMap::new();
-        m2.insert(1, 2);
-        m2.insert(2, 3);
-
-        assert!(m1 != m2);
-
-        m2.insert(3, 4);
-
-        assert_eq!(m1, m2);
-    }
-
-    #[test]
-    fn test_show() {
-        let mut map = HashMap::new();
-        let empty: HashMap<i32, i32> = HashMap::new();
-
-        map.insert(1, 2);
-        map.insert(3, 4);
-
-        let map_str = format!("{:?}", map);
-
-        assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
-        assert_eq!(format!("{:?}", empty), "{}");
-    }
-
-    #[test]
-    fn test_reserve_shrink_to_fit() {
-        let mut m = HashMap::new();
-        m.insert(0, 0);
-        m.remove(&0);
-        assert!(m.capacity() >= m.len());
-        for i in 0..128 {
-            m.insert(i, i);
-        }
-        m.reserve(256);
-
-        let usable_cap = m.capacity();
-        for i in 128..(128 + 256) {
-            m.insert(i, i);
-            assert_eq!(m.capacity(), usable_cap);
-        }
-
-        for i in 100..(128 + 256) {
-            assert_eq!(m.remove(&i), Some(i));
-        }
-        m.shrink_to_fit();
-
-        assert_eq!(m.len(), 100);
-        assert!(!m.is_empty());
-        assert!(m.capacity() >= m.len());
-
-        for i in 0..100 {
-            assert_eq!(m.remove(&i), Some(i));
-        }
-        m.shrink_to_fit();
-        m.insert(0, 0);
-
-        assert_eq!(m.len(), 1);
-        assert!(m.capacity() >= m.len());
-        assert_eq!(m.remove(&0), Some(0));
-    }
-
-    #[test]
-    fn test_from_iter() {
-        let xs = [(1, 1), (2, 2), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
-        let map: HashMap<_, _> = xs.iter().cloned().collect();
-
-        for &(k, v) in &xs {
-            assert_eq!(map.get(&k), Some(&v));
-        }
-
-        assert_eq!(map.iter().len(), xs.len() - 1);
-    }
-
-    #[test]
-    fn test_size_hint() {
-        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
-        let map: HashMap<_, _> = xs.iter().cloned().collect();
-
-        let mut iter = map.iter();
-
-        for _ in iter.by_ref().take(3) {}
-
-        assert_eq!(iter.size_hint(), (3, Some(3)));
-    }
-
-    #[test]
-    fn test_iter_len() {
-        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
-        let map: HashMap<_, _> = xs.iter().cloned().collect();
-
-        let mut iter = map.iter();
-
-        for _ in iter.by_ref().take(3) {}
-
-        assert_eq!(iter.len(), 3);
-    }
-
-    #[test]
-    fn test_mut_size_hint() {
-        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
-        let mut map: HashMap<_, _> = xs.iter().cloned().collect();
-
-        let mut iter = map.iter_mut();
-
-        for _ in iter.by_ref().take(3) {}
-
-        assert_eq!(iter.size_hint(), (3, Some(3)));
-    }
-
-    #[test]
-    fn test_iter_mut_len() {
-        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
-        let mut map: HashMap<_, _> = xs.iter().cloned().collect();
-
-        let mut iter = map.iter_mut();
-
-        for _ in iter.by_ref().take(3) {}
-
-        assert_eq!(iter.len(), 3);
-    }
-
-    #[test]
-    fn test_index() {
-        let mut map = HashMap::new();
-
-        map.insert(1, 2);
-        map.insert(2, 1);
-        map.insert(3, 4);
-
-        assert_eq!(map[&2], 1);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_index_nonexistent() {
-        let mut map = HashMap::new();
-
-        map.insert(1, 2);
-        map.insert(2, 1);
-        map.insert(3, 4);
-
-        map[&4];
-    }
-
-    #[test]
-    fn test_entry() {
-        let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
-
-        let mut map: HashMap<_, _> = xs.iter().cloned().collect();
-
-        // Existing key (insert)
-        match map.entry(1) {
-            Vacant(_) => unreachable!(),
-            Occupied(mut view) => {
-                assert_eq!(view.get(), &10);
-                assert_eq!(view.insert(100), 10);
-            }
-        }
-        assert_eq!(map.get(&1).unwrap(), &100);
-        assert_eq!(map.len(), 6);
-
-        // Existing key (update)
-        match map.entry(2) {
-            Vacant(_) => unreachable!(),
-            Occupied(mut view) => {
-                let v = view.get_mut();
-                let new_v = (*v) * 10;
-                *v = new_v;
-            }
-        }
-        assert_eq!(map.get(&2).unwrap(), &200);
-        assert_eq!(map.len(), 6);
-
-        // Existing key (take)
-        match map.entry(3) {
-            Vacant(_) => unreachable!(),
-            Occupied(view) => {
-                assert_eq!(view.remove(), 30);
-            }
-        }
-        assert_eq!(map.get(&3), None);
-        assert_eq!(map.len(), 5);
-
-        // Inexistent key (insert)
-        match map.entry(10) {
-            Occupied(_) => unreachable!(),
-            Vacant(view) => {
-                assert_eq!(*view.insert(1000), 1000);
-            }
-        }
-        assert_eq!(map.get(&10).unwrap(), &1000);
-        assert_eq!(map.len(), 6);
-    }
-
-    #[test]
-    fn test_entry_take_doesnt_corrupt() {
-        #![allow(deprecated)] //rand
-        // Test for #19292
-        fn check(m: &HashMap<i32, ()>) {
-            for k in m.keys() {
-                assert!(m.contains_key(k), "{} is in keys() but not in the map?", k);
-            }
-        }
-
-        let mut m = HashMap::new();
-        let mut rng = thread_rng();
-
-        // Populate the map with some items.
-        for _ in 0..50 {
-            let x = rng.gen_range(-10, 10);
-            m.insert(x, ());
-        }
-
-        for _ in 0..1000 {
-            let x = rng.gen_range(-10, 10);
-            match m.entry(x) {
-                Vacant(_) => {}
-                Occupied(e) => {
-                    e.remove();
-                }
-            }
-
-            check(&m);
-        }
-    }
-
-    #[test]
-    fn test_extend_ref() {
-        let mut a = HashMap::new();
-        a.insert(1, "one");
-        let mut b = HashMap::new();
-        b.insert(2, "two");
-        b.insert(3, "three");
-
-        a.extend(&b);
-
-        assert_eq!(a.len(), 3);
-        assert_eq!(a[&1], "one");
-        assert_eq!(a[&2], "two");
-        assert_eq!(a[&3], "three");
-    }
-
-    #[test]
-    fn test_capacity_not_less_than_len() {
-        let mut a = HashMap::new();
-        let mut item = 0;
-
-        for _ in 0..116 {
-            a.insert(item, 0);
-            item += 1;
-        }
-
-        assert!(a.capacity() > a.len());
-
-        let free = a.capacity() - a.len();
-        for _ in 0..free {
-            a.insert(item, 0);
-            item += 1;
-        }
-
-        assert_eq!(a.len(), a.capacity());
-
-        // Insert at capacity should cause allocation.
-        a.insert(item, 0);
-        assert!(a.capacity() > a.len());
-    }
-
-    #[test]
-    fn test_occupied_entry_key() {
-        let mut a = HashMap::new();
-        let key = "hello there";
-        let value = "value goes here";
-        assert!(a.is_empty());
-        a.insert(key.clone(), value.clone());
-        assert_eq!(a.len(), 1);
-        assert_eq!(a[key], value);
-
-        match a.entry(key.clone()) {
-            Vacant(_) => panic!(),
-            Occupied(e) => assert_eq!(key, *e.key()),
-        }
-        assert_eq!(a.len(), 1);
-        assert_eq!(a[key], value);
-    }
-
-    #[test]
-    fn test_vacant_entry_key() {
-        let mut a = HashMap::new();
-        let key = "hello there";
-        let value = "value goes here";
-
-        assert!(a.is_empty());
-        match a.entry(key.clone()) {
-            Occupied(_) => panic!(),
-            Vacant(e) => {
-                assert_eq!(key, *e.key());
-                e.insert(value.clone());
-            }
-        }
-        assert_eq!(a.len(), 1);
-        assert_eq!(a[key], value);
-    }
-
-    #[test]
-    fn test_retain() {
-        let mut map: HashMap<i32, i32> = (0..100).map(|x| (x, x * 10)).collect();
-
-        map.retain(|&k, _| k % 2 == 0);
-        assert_eq!(map.len(), 50);
-        assert_eq!(map[&2], 20);
-        assert_eq!(map[&4], 40);
-        assert_eq!(map[&6], 60);
-    }
-
-    #[test]
-    fn test_try_reserve() {
-        let mut empty_bytes: HashMap<u8, u8> = HashMap::new();
-
-        const MAX_USIZE: usize = usize::MAX;
-
-        if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_USIZE) {
-        } else {
-            panic!("usize::MAX should trigger an overflow!");
-        }
-
-        if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_USIZE / 8) {
-        } else {
-            panic!("usize::MAX / 8 should trigger an OOM!")
-        }
-    }
-
-    #[test]
-    fn test_raw_entry() {
-        use super::RawEntryMut::{Occupied, Vacant};
-
-        let xs = [(1i32, 10i32), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
-
-        let mut map: HashMap<_, _> = xs.iter().cloned().collect();
-
-        let compute_hash = |map: &HashMap<i32, i32>, k: i32| -> u64 {
-            use core::hash::{BuildHasher, Hash, Hasher};
-
-            let mut hasher = map.hasher().build_hasher();
-            k.hash(&mut hasher);
-            hasher.finish()
-        };
-
-        // Existing key (insert)
-        match map.raw_entry_mut().from_key(&1) {
-            Vacant(_) => unreachable!(),
-            Occupied(mut view) => {
-                assert_eq!(view.get(), &10);
-                assert_eq!(view.insert(100), 10);
-            }
-        }
-        let hash1 = compute_hash(&map, 1);
-        assert_eq!(map.raw_entry().from_key(&1).unwrap(), (&1, &100));
-        assert_eq!(map.raw_entry().from_hash(hash1, |k| *k == 1).unwrap(), (&1, &100));
-        assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash1, &1).unwrap(), (&1, &100));
-        assert_eq!(map.len(), 6);
-
-        // Existing key (update)
-        match map.raw_entry_mut().from_key(&2) {
-            Vacant(_) => unreachable!(),
-            Occupied(mut view) => {
-                let v = view.get_mut();
-                let new_v = (*v) * 10;
-                *v = new_v;
-            }
-        }
-        let hash2 = compute_hash(&map, 2);
-        assert_eq!(map.raw_entry().from_key(&2).unwrap(), (&2, &200));
-        assert_eq!(map.raw_entry().from_hash(hash2, |k| *k == 2).unwrap(), (&2, &200));
-        assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash2, &2).unwrap(), (&2, &200));
-        assert_eq!(map.len(), 6);
-
-        // Existing key (take)
-        let hash3 = compute_hash(&map, 3);
-        match map.raw_entry_mut().from_key_hashed_nocheck(hash3, &3) {
-            Vacant(_) => unreachable!(),
-            Occupied(view) => {
-                assert_eq!(view.remove_entry(), (3, 30));
-            }
-        }
-        assert_eq!(map.raw_entry().from_key(&3), None);
-        assert_eq!(map.raw_entry().from_hash(hash3, |k| *k == 3), None);
-        assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash3, &3), None);
-        assert_eq!(map.len(), 5);
-
-        // Nonexistent key (insert)
-        match map.raw_entry_mut().from_key(&10) {
-            Occupied(_) => unreachable!(),
-            Vacant(view) => {
-                assert_eq!(view.insert(10, 1000), (&mut 10, &mut 1000));
-            }
-        }
-        assert_eq!(map.raw_entry().from_key(&10).unwrap(), (&10, &1000));
-        assert_eq!(map.len(), 6);
-
-        // Ensure all lookup methods produce equivalent results.
-        for k in 0..12 {
-            let hash = compute_hash(&map, k);
-            let v = map.get(&k).cloned();
-            let kv = v.as_ref().map(|v| (&k, v));
-
-            assert_eq!(map.raw_entry().from_key(&k), kv);
-            assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv);
-            assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv);
-
-            match map.raw_entry_mut().from_key(&k) {
-                Occupied(mut o) => assert_eq!(Some(o.get_key_value()), kv),
-                Vacant(_) => assert_eq!(v, None),
-            }
-            match map.raw_entry_mut().from_key_hashed_nocheck(hash, &k) {
-                Occupied(mut o) => assert_eq!(Some(o.get_key_value()), kv),
-                Vacant(_) => assert_eq!(v, None),
-            }
-            match map.raw_entry_mut().from_hash(hash, |q| *q == k) {
-                Occupied(mut o) => assert_eq!(Some(o.get_key_value()), kv),
-                Vacant(_) => assert_eq!(v, None),
-            }
-        }
-    }
-}
diff --git a/library/std/src/collections/hash/map/tests.rs b/library/std/src/collections/hash/map/tests.rs
new file mode 100644
index 00000000000..4283d80b78e
--- /dev/null
+++ b/library/std/src/collections/hash/map/tests.rs
@@ -0,0 +1,926 @@
+use super::Entry::{Occupied, Vacant};
+use super::HashMap;
+use super::RandomState;
+use crate::cell::RefCell;
+use rand::{thread_rng, Rng};
+use realstd::collections::TryReserveError::*;
+
+// https://github.com/rust-lang/rust/issues/62301
+fn _assert_hashmap_is_unwind_safe() {
+    fn assert_unwind_safe<T: crate::panic::UnwindSafe>() {}
+    assert_unwind_safe::<HashMap<(), crate::cell::UnsafeCell<()>>>();
+}
+
+#[test]
+fn test_zero_capacities() {
+    type HM = HashMap<i32, i32>;
+
+    let m = HM::new();
+    assert_eq!(m.capacity(), 0);
+
+    let m = HM::default();
+    assert_eq!(m.capacity(), 0);
+
+    let m = HM::with_hasher(RandomState::new());
+    assert_eq!(m.capacity(), 0);
+
+    let m = HM::with_capacity(0);
+    assert_eq!(m.capacity(), 0);
+
+    let m = HM::with_capacity_and_hasher(0, RandomState::new());
+    assert_eq!(m.capacity(), 0);
+
+    let mut m = HM::new();
+    m.insert(1, 1);
+    m.insert(2, 2);
+    m.remove(&1);
+    m.remove(&2);
+    m.shrink_to_fit();
+    assert_eq!(m.capacity(), 0);
+
+    let mut m = HM::new();
+    m.reserve(0);
+    assert_eq!(m.capacity(), 0);
+}
+
+#[test]
+fn test_create_capacity_zero() {
+    let mut m = HashMap::with_capacity(0);
+
+    assert!(m.insert(1, 1).is_none());
+
+    assert!(m.contains_key(&1));
+    assert!(!m.contains_key(&0));
+}
+
+#[test]
+fn test_insert() {
+    let mut m = HashMap::new();
+    assert_eq!(m.len(), 0);
+    assert!(m.insert(1, 2).is_none());
+    assert_eq!(m.len(), 1);
+    assert!(m.insert(2, 4).is_none());
+    assert_eq!(m.len(), 2);
+    assert_eq!(*m.get(&1).unwrap(), 2);
+    assert_eq!(*m.get(&2).unwrap(), 4);
+}
+
+#[test]
+fn test_clone() {
+    let mut m = HashMap::new();
+    assert_eq!(m.len(), 0);
+    assert!(m.insert(1, 2).is_none());
+    assert_eq!(m.len(), 1);
+    assert!(m.insert(2, 4).is_none());
+    assert_eq!(m.len(), 2);
+    let m2 = m.clone();
+    assert_eq!(*m2.get(&1).unwrap(), 2);
+    assert_eq!(*m2.get(&2).unwrap(), 4);
+    assert_eq!(m2.len(), 2);
+}
+
+thread_local! { static DROP_VECTOR: RefCell<Vec<i32>> = RefCell::new(Vec::new()) }
+
+#[derive(Hash, PartialEq, Eq)]
+struct Droppable {
+    k: usize,
+}
+
+impl Droppable {
+    fn new(k: usize) -> Droppable {
+        DROP_VECTOR.with(|slot| {
+            slot.borrow_mut()[k] += 1;
+        });
+
+        Droppable { k }
+    }
+}
+
+impl Drop for Droppable {
+    fn drop(&mut self) {
+        DROP_VECTOR.with(|slot| {
+            slot.borrow_mut()[self.k] -= 1;
+        });
+    }
+}
+
+impl Clone for Droppable {
+    fn clone(&self) -> Droppable {
+        Droppable::new(self.k)
+    }
+}
+
+#[test]
+fn test_drops() {
+    DROP_VECTOR.with(|slot| {
+        *slot.borrow_mut() = vec![0; 200];
+    });
+
+    {
+        let mut m = HashMap::new();
+
+        DROP_VECTOR.with(|v| {
+            for i in 0..200 {
+                assert_eq!(v.borrow()[i], 0);
+            }
+        });
+
+        for i in 0..100 {
+            let d1 = Droppable::new(i);
+            let d2 = Droppable::new(i + 100);
+            m.insert(d1, d2);
+        }
+
+        DROP_VECTOR.with(|v| {
+            for i in 0..200 {
+                assert_eq!(v.borrow()[i], 1);
+            }
+        });
+
+        for i in 0..50 {
+            let k = Droppable::new(i);
+            let v = m.remove(&k);
+
+            assert!(v.is_some());
+
+            DROP_VECTOR.with(|v| {
+                assert_eq!(v.borrow()[i], 1);
+                assert_eq!(v.borrow()[i + 100], 1);
+            });
+        }
+
+        DROP_VECTOR.with(|v| {
+            for i in 0..50 {
+                assert_eq!(v.borrow()[i], 0);
+                assert_eq!(v.borrow()[i + 100], 0);
+            }
+
+            for i in 50..100 {
+                assert_eq!(v.borrow()[i], 1);
+                assert_eq!(v.borrow()[i + 100], 1);
+            }
+        });
+    }
+
+    DROP_VECTOR.with(|v| {
+        for i in 0..200 {
+            assert_eq!(v.borrow()[i], 0);
+        }
+    });
+}
+
+#[test]
+fn test_into_iter_drops() {
+    DROP_VECTOR.with(|v| {
+        *v.borrow_mut() = vec![0; 200];
+    });
+
+    let hm = {
+        let mut hm = HashMap::new();
+
+        DROP_VECTOR.with(|v| {
+            for i in 0..200 {
+                assert_eq!(v.borrow()[i], 0);
+            }
+        });
+
+        for i in 0..100 {
+            let d1 = Droppable::new(i);
+            let d2 = Droppable::new(i + 100);
+            hm.insert(d1, d2);
+        }
+
+        DROP_VECTOR.with(|v| {
+            for i in 0..200 {
+                assert_eq!(v.borrow()[i], 1);
+            }
+        });
+
+        hm
+    };
+
+    // By the way, ensure that cloning doesn't screw up the dropping.
+    drop(hm.clone());
+
+    {
+        let mut half = hm.into_iter().take(50);
+
+        DROP_VECTOR.with(|v| {
+            for i in 0..200 {
+                assert_eq!(v.borrow()[i], 1);
+            }
+        });
+
+        for _ in half.by_ref() {}
+
+        DROP_VECTOR.with(|v| {
+            let nk = (0..100).filter(|&i| v.borrow()[i] == 1).count();
+
+            let nv = (0..100).filter(|&i| v.borrow()[i + 100] == 1).count();
+
+            assert_eq!(nk, 50);
+            assert_eq!(nv, 50);
+        });
+    };
+
+    DROP_VECTOR.with(|v| {
+        for i in 0..200 {
+            assert_eq!(v.borrow()[i], 0);
+        }
+    });
+}
+
+#[test]
+fn test_empty_remove() {
+    let mut m: HashMap<i32, bool> = HashMap::new();
+    assert_eq!(m.remove(&0), None);
+}
+
+#[test]
+fn test_empty_entry() {
+    let mut m: HashMap<i32, bool> = HashMap::new();
+    match m.entry(0) {
+        Occupied(_) => panic!(),
+        Vacant(_) => {}
+    }
+    assert!(*m.entry(0).or_insert(true));
+    assert_eq!(m.len(), 1);
+}
+
+#[test]
+fn test_empty_iter() {
+    let mut m: HashMap<i32, bool> = HashMap::new();
+    assert_eq!(m.drain().next(), None);
+    assert_eq!(m.keys().next(), None);
+    assert_eq!(m.values().next(), None);
+    assert_eq!(m.values_mut().next(), None);
+    assert_eq!(m.iter().next(), None);
+    assert_eq!(m.iter_mut().next(), None);
+    assert_eq!(m.len(), 0);
+    assert!(m.is_empty());
+    assert_eq!(m.into_iter().next(), None);
+}
+
+#[test]
+fn test_lots_of_insertions() {
+    let mut m = HashMap::new();
+
+    // Try this a few times to make sure we never screw up the hashmap's
+    // internal state.
+    for _ in 0..10 {
+        assert!(m.is_empty());
+
+        for i in 1..1001 {
+            assert!(m.insert(i, i).is_none());
+
+            for j in 1..=i {
+                let r = m.get(&j);
+                assert_eq!(r, Some(&j));
+            }
+
+            for j in i + 1..1001 {
+                let r = m.get(&j);
+                assert_eq!(r, None);
+            }
+        }
+
+        for i in 1001..2001 {
+            assert!(!m.contains_key(&i));
+        }
+
+        // remove forwards
+        for i in 1..1001 {
+            assert!(m.remove(&i).is_some());
+
+            for j in 1..=i {
+                assert!(!m.contains_key(&j));
+            }
+
+            for j in i + 1..1001 {
+                assert!(m.contains_key(&j));
+            }
+        }
+
+        for i in 1..1001 {
+            assert!(!m.contains_key(&i));
+        }
+
+        for i in 1..1001 {
+            assert!(m.insert(i, i).is_none());
+        }
+
+        // remove backwards
+        for i in (1..1001).rev() {
+            assert!(m.remove(&i).is_some());
+
+            for j in i..1001 {
+                assert!(!m.contains_key(&j));
+            }
+
+            for j in 1..i {
+                assert!(m.contains_key(&j));
+            }
+        }
+    }
+}
+
+#[test]
+fn test_find_mut() {
+    let mut m = HashMap::new();
+    assert!(m.insert(1, 12).is_none());
+    assert!(m.insert(2, 8).is_none());
+    assert!(m.insert(5, 14).is_none());
+    let new = 100;
+    match m.get_mut(&5) {
+        None => panic!(),
+        Some(x) => *x = new,
+    }
+    assert_eq!(m.get(&5), Some(&new));
+}
+
+#[test]
+fn test_insert_overwrite() {
+    let mut m = HashMap::new();
+    assert!(m.insert(1, 2).is_none());
+    assert_eq!(*m.get(&1).unwrap(), 2);
+    assert!(!m.insert(1, 3).is_none());
+    assert_eq!(*m.get(&1).unwrap(), 3);
+}
+
+#[test]
+fn test_insert_conflicts() {
+    let mut m = HashMap::with_capacity(4);
+    assert!(m.insert(1, 2).is_none());
+    assert!(m.insert(5, 3).is_none());
+    assert!(m.insert(9, 4).is_none());
+    assert_eq!(*m.get(&9).unwrap(), 4);
+    assert_eq!(*m.get(&5).unwrap(), 3);
+    assert_eq!(*m.get(&1).unwrap(), 2);
+}
+
+#[test]
+fn test_conflict_remove() {
+    let mut m = HashMap::with_capacity(4);
+    assert!(m.insert(1, 2).is_none());
+    assert_eq!(*m.get(&1).unwrap(), 2);
+    assert!(m.insert(5, 3).is_none());
+    assert_eq!(*m.get(&1).unwrap(), 2);
+    assert_eq!(*m.get(&5).unwrap(), 3);
+    assert!(m.insert(9, 4).is_none());
+    assert_eq!(*m.get(&1).unwrap(), 2);
+    assert_eq!(*m.get(&5).unwrap(), 3);
+    assert_eq!(*m.get(&9).unwrap(), 4);
+    assert!(m.remove(&1).is_some());
+    assert_eq!(*m.get(&9).unwrap(), 4);
+    assert_eq!(*m.get(&5).unwrap(), 3);
+}
+
+#[test]
+fn test_is_empty() {
+    let mut m = HashMap::with_capacity(4);
+    assert!(m.insert(1, 2).is_none());
+    assert!(!m.is_empty());
+    assert!(m.remove(&1).is_some());
+    assert!(m.is_empty());
+}
+
+#[test]
+fn test_remove() {
+    let mut m = HashMap::new();
+    m.insert(1, 2);
+    assert_eq!(m.remove(&1), Some(2));
+    assert_eq!(m.remove(&1), None);
+}
+
+#[test]
+fn test_remove_entry() {
+    let mut m = HashMap::new();
+    m.insert(1, 2);
+    assert_eq!(m.remove_entry(&1), Some((1, 2)));
+    assert_eq!(m.remove(&1), None);
+}
+
+#[test]
+fn test_iterate() {
+    let mut m = HashMap::with_capacity(4);
+    for i in 0..32 {
+        assert!(m.insert(i, i * 2).is_none());
+    }
+    assert_eq!(m.len(), 32);
+
+    let mut observed: u32 = 0;
+
+    for (k, v) in &m {
+        assert_eq!(*v, *k * 2);
+        observed |= 1 << *k;
+    }
+    assert_eq!(observed, 0xFFFF_FFFF);
+}
+
+#[test]
+fn test_keys() {
+    let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
+    let map: HashMap<_, _> = vec.into_iter().collect();
+    let keys: Vec<_> = map.keys().cloned().collect();
+    assert_eq!(keys.len(), 3);
+    assert!(keys.contains(&1));
+    assert!(keys.contains(&2));
+    assert!(keys.contains(&3));
+}
+
+#[test]
+fn test_values() {
+    let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
+    let map: HashMap<_, _> = vec.into_iter().collect();
+    let values: Vec<_> = map.values().cloned().collect();
+    assert_eq!(values.len(), 3);
+    assert!(values.contains(&'a'));
+    assert!(values.contains(&'b'));
+    assert!(values.contains(&'c'));
+}
+
+#[test]
+fn test_values_mut() {
+    let vec = vec![(1, 1), (2, 2), (3, 3)];
+    let mut map: HashMap<_, _> = vec.into_iter().collect();
+    for value in map.values_mut() {
+        *value = (*value) * 2
+    }
+    let values: Vec<_> = map.values().cloned().collect();
+    assert_eq!(values.len(), 3);
+    assert!(values.contains(&2));
+    assert!(values.contains(&4));
+    assert!(values.contains(&6));
+}
+
+#[test]
+fn test_into_keys() {
+    let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
+    let map: HashMap<_, _> = vec.into_iter().collect();
+    let keys: Vec<_> = map.into_keys().collect();
+
+    assert_eq!(keys.len(), 3);
+    assert!(keys.contains(&1));
+    assert!(keys.contains(&2));
+    assert!(keys.contains(&3));
+}
+
+#[test]
+fn test_into_values() {
+    let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
+    let map: HashMap<_, _> = vec.into_iter().collect();
+    let values: Vec<_> = map.into_values().collect();
+
+    assert_eq!(values.len(), 3);
+    assert!(values.contains(&'a'));
+    assert!(values.contains(&'b'));
+    assert!(values.contains(&'c'));
+}
+
+#[test]
+fn test_find() {
+    let mut m = HashMap::new();
+    assert!(m.get(&1).is_none());
+    m.insert(1, 2);
+    match m.get(&1) {
+        None => panic!(),
+        Some(v) => assert_eq!(*v, 2),
+    }
+}
+
+#[test]
+fn test_eq() {
+    let mut m1 = HashMap::new();
+    m1.insert(1, 2);
+    m1.insert(2, 3);
+    m1.insert(3, 4);
+
+    let mut m2 = HashMap::new();
+    m2.insert(1, 2);
+    m2.insert(2, 3);
+
+    assert!(m1 != m2);
+
+    m2.insert(3, 4);
+
+    assert_eq!(m1, m2);
+}
+
+#[test]
+fn test_show() {
+    let mut map = HashMap::new();
+    let empty: HashMap<i32, i32> = HashMap::new();
+
+    map.insert(1, 2);
+    map.insert(3, 4);
+
+    let map_str = format!("{:?}", map);
+
+    assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
+    assert_eq!(format!("{:?}", empty), "{}");
+}
+
+#[test]
+fn test_reserve_shrink_to_fit() {
+    let mut m = HashMap::new();
+    m.insert(0, 0);
+    m.remove(&0);
+    assert!(m.capacity() >= m.len());
+    for i in 0..128 {
+        m.insert(i, i);
+    }
+    m.reserve(256);
+
+    let usable_cap = m.capacity();
+    for i in 128..(128 + 256) {
+        m.insert(i, i);
+        assert_eq!(m.capacity(), usable_cap);
+    }
+
+    for i in 100..(128 + 256) {
+        assert_eq!(m.remove(&i), Some(i));
+    }
+    m.shrink_to_fit();
+
+    assert_eq!(m.len(), 100);
+    assert!(!m.is_empty());
+    assert!(m.capacity() >= m.len());
+
+    for i in 0..100 {
+        assert_eq!(m.remove(&i), Some(i));
+    }
+    m.shrink_to_fit();
+    m.insert(0, 0);
+
+    assert_eq!(m.len(), 1);
+    assert!(m.capacity() >= m.len());
+    assert_eq!(m.remove(&0), Some(0));
+}
+
+#[test]
+fn test_from_iter() {
+    let xs = [(1, 1), (2, 2), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+    let map: HashMap<_, _> = xs.iter().cloned().collect();
+
+    for &(k, v) in &xs {
+        assert_eq!(map.get(&k), Some(&v));
+    }
+
+    assert_eq!(map.iter().len(), xs.len() - 1);
+}
+
+#[test]
+fn test_size_hint() {
+    let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+    let map: HashMap<_, _> = xs.iter().cloned().collect();
+
+    let mut iter = map.iter();
+
+    for _ in iter.by_ref().take(3) {}
+
+    assert_eq!(iter.size_hint(), (3, Some(3)));
+}
+
+#[test]
+fn test_iter_len() {
+    let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+    let map: HashMap<_, _> = xs.iter().cloned().collect();
+
+    let mut iter = map.iter();
+
+    for _ in iter.by_ref().take(3) {}
+
+    assert_eq!(iter.len(), 3);
+}
+
+#[test]
+fn test_mut_size_hint() {
+    let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+    let mut map: HashMap<_, _> = xs.iter().cloned().collect();
+
+    let mut iter = map.iter_mut();
+
+    for _ in iter.by_ref().take(3) {}
+
+    assert_eq!(iter.size_hint(), (3, Some(3)));
+}
+
+#[test]
+fn test_iter_mut_len() {
+    let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+    let mut map: HashMap<_, _> = xs.iter().cloned().collect();
+
+    let mut iter = map.iter_mut();
+
+    for _ in iter.by_ref().take(3) {}
+
+    assert_eq!(iter.len(), 3);
+}
+
+#[test]
+fn test_index() {
+    let mut map = HashMap::new();
+
+    map.insert(1, 2);
+    map.insert(2, 1);
+    map.insert(3, 4);
+
+    assert_eq!(map[&2], 1);
+}
+
+#[test]
+#[should_panic]
+fn test_index_nonexistent() {
+    let mut map = HashMap::new();
+
+    map.insert(1, 2);
+    map.insert(2, 1);
+    map.insert(3, 4);
+
+    map[&4];
+}
+
+#[test]
+fn test_entry() {
+    let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
+
+    let mut map: HashMap<_, _> = xs.iter().cloned().collect();
+
+    // Existing key (insert)
+    match map.entry(1) {
+        Vacant(_) => unreachable!(),
+        Occupied(mut view) => {
+            assert_eq!(view.get(), &10);
+            assert_eq!(view.insert(100), 10);
+        }
+    }
+    assert_eq!(map.get(&1).unwrap(), &100);
+    assert_eq!(map.len(), 6);
+
+    // Existing key (update)
+    match map.entry(2) {
+        Vacant(_) => unreachable!(),
+        Occupied(mut view) => {
+            let v = view.get_mut();
+            let new_v = (*v) * 10;
+            *v = new_v;
+        }
+    }
+    assert_eq!(map.get(&2).unwrap(), &200);
+    assert_eq!(map.len(), 6);
+
+    // Existing key (take)
+    match map.entry(3) {
+        Vacant(_) => unreachable!(),
+        Occupied(view) => {
+            assert_eq!(view.remove(), 30);
+        }
+    }
+    assert_eq!(map.get(&3), None);
+    assert_eq!(map.len(), 5);
+
+    // Inexistent key (insert)
+    match map.entry(10) {
+        Occupied(_) => unreachable!(),
+        Vacant(view) => {
+            assert_eq!(*view.insert(1000), 1000);
+        }
+    }
+    assert_eq!(map.get(&10).unwrap(), &1000);
+    assert_eq!(map.len(), 6);
+}
+
+#[test]
+fn test_entry_take_doesnt_corrupt() {
+    #![allow(deprecated)] //rand
+    // Test for #19292
+    fn check(m: &HashMap<i32, ()>) {
+        for k in m.keys() {
+            assert!(m.contains_key(k), "{} is in keys() but not in the map?", k);
+        }
+    }
+
+    let mut m = HashMap::new();
+    let mut rng = thread_rng();
+
+    // Populate the map with some items.
+    for _ in 0..50 {
+        let x = rng.gen_range(-10, 10);
+        m.insert(x, ());
+    }
+
+    for _ in 0..1000 {
+        let x = rng.gen_range(-10, 10);
+        match m.entry(x) {
+            Vacant(_) => {}
+            Occupied(e) => {
+                e.remove();
+            }
+        }
+
+        check(&m);
+    }
+}
+
+#[test]
+fn test_extend_ref() {
+    let mut a = HashMap::new();
+    a.insert(1, "one");
+    let mut b = HashMap::new();
+    b.insert(2, "two");
+    b.insert(3, "three");
+
+    a.extend(&b);
+
+    assert_eq!(a.len(), 3);
+    assert_eq!(a[&1], "one");
+    assert_eq!(a[&2], "two");
+    assert_eq!(a[&3], "three");
+}
+
+#[test]
+fn test_capacity_not_less_than_len() {
+    let mut a = HashMap::new();
+    let mut item = 0;
+
+    for _ in 0..116 {
+        a.insert(item, 0);
+        item += 1;
+    }
+
+    assert!(a.capacity() > a.len());
+
+    let free = a.capacity() - a.len();
+    for _ in 0..free {
+        a.insert(item, 0);
+        item += 1;
+    }
+
+    assert_eq!(a.len(), a.capacity());
+
+    // Insert at capacity should cause allocation.
+    a.insert(item, 0);
+    assert!(a.capacity() > a.len());
+}
+
+#[test]
+fn test_occupied_entry_key() {
+    let mut a = HashMap::new();
+    let key = "hello there";
+    let value = "value goes here";
+    assert!(a.is_empty());
+    a.insert(key.clone(), value.clone());
+    assert_eq!(a.len(), 1);
+    assert_eq!(a[key], value);
+
+    match a.entry(key.clone()) {
+        Vacant(_) => panic!(),
+        Occupied(e) => assert_eq!(key, *e.key()),
+    }
+    assert_eq!(a.len(), 1);
+    assert_eq!(a[key], value);
+}
+
+#[test]
+fn test_vacant_entry_key() {
+    let mut a = HashMap::new();
+    let key = "hello there";
+    let value = "value goes here";
+
+    assert!(a.is_empty());
+    match a.entry(key.clone()) {
+        Occupied(_) => panic!(),
+        Vacant(e) => {
+            assert_eq!(key, *e.key());
+            e.insert(value.clone());
+        }
+    }
+    assert_eq!(a.len(), 1);
+    assert_eq!(a[key], value);
+}
+
+#[test]
+fn test_retain() {
+    let mut map: HashMap<i32, i32> = (0..100).map(|x| (x, x * 10)).collect();
+
+    map.retain(|&k, _| k % 2 == 0);
+    assert_eq!(map.len(), 50);
+    assert_eq!(map[&2], 20);
+    assert_eq!(map[&4], 40);
+    assert_eq!(map[&6], 60);
+}
+
+#[test]
+fn test_try_reserve() {
+    let mut empty_bytes: HashMap<u8, u8> = HashMap::new();
+
+    const MAX_USIZE: usize = usize::MAX;
+
+    if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_USIZE) {
+    } else {
+        panic!("usize::MAX should trigger an overflow!");
+    }
+
+    if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_USIZE / 8) {
+    } else {
+        panic!("usize::MAX / 8 should trigger an OOM!")
+    }
+}
+
+#[test]
+fn test_raw_entry() {
+    use super::RawEntryMut::{Occupied, Vacant};
+
+    let xs = [(1i32, 10i32), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
+
+    let mut map: HashMap<_, _> = xs.iter().cloned().collect();
+
+    let compute_hash = |map: &HashMap<i32, i32>, k: i32| -> u64 {
+        use core::hash::{BuildHasher, Hash, Hasher};
+
+        let mut hasher = map.hasher().build_hasher();
+        k.hash(&mut hasher);
+        hasher.finish()
+    };
+
+    // Existing key (insert)
+    match map.raw_entry_mut().from_key(&1) {
+        Vacant(_) => unreachable!(),
+        Occupied(mut view) => {
+            assert_eq!(view.get(), &10);
+            assert_eq!(view.insert(100), 10);
+        }
+    }
+    let hash1 = compute_hash(&map, 1);
+    assert_eq!(map.raw_entry().from_key(&1).unwrap(), (&1, &100));
+    assert_eq!(map.raw_entry().from_hash(hash1, |k| *k == 1).unwrap(), (&1, &100));
+    assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash1, &1).unwrap(), (&1, &100));
+    assert_eq!(map.len(), 6);
+
+    // Existing key (update)
+    match map.raw_entry_mut().from_key(&2) {
+        Vacant(_) => unreachable!(),
+        Occupied(mut view) => {
+            let v = view.get_mut();
+            let new_v = (*v) * 10;
+            *v = new_v;
+        }
+    }
+    let hash2 = compute_hash(&map, 2);
+    assert_eq!(map.raw_entry().from_key(&2).unwrap(), (&2, &200));
+    assert_eq!(map.raw_entry().from_hash(hash2, |k| *k == 2).unwrap(), (&2, &200));
+    assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash2, &2).unwrap(), (&2, &200));
+    assert_eq!(map.len(), 6);
+
+    // Existing key (take)
+    let hash3 = compute_hash(&map, 3);
+    match map.raw_entry_mut().from_key_hashed_nocheck(hash3, &3) {
+        Vacant(_) => unreachable!(),
+        Occupied(view) => {
+            assert_eq!(view.remove_entry(), (3, 30));
+        }
+    }
+    assert_eq!(map.raw_entry().from_key(&3), None);
+    assert_eq!(map.raw_entry().from_hash(hash3, |k| *k == 3), None);
+    assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash3, &3), None);
+    assert_eq!(map.len(), 5);
+
+    // Nonexistent key (insert)
+    match map.raw_entry_mut().from_key(&10) {
+        Occupied(_) => unreachable!(),
+        Vacant(view) => {
+            assert_eq!(view.insert(10, 1000), (&mut 10, &mut 1000));
+        }
+    }
+    assert_eq!(map.raw_entry().from_key(&10).unwrap(), (&10, &1000));
+    assert_eq!(map.len(), 6);
+
+    // Ensure all lookup methods produce equivalent results.
+    for k in 0..12 {
+        let hash = compute_hash(&map, k);
+        let v = map.get(&k).cloned();
+        let kv = v.as_ref().map(|v| (&k, v));
+
+        assert_eq!(map.raw_entry().from_key(&k), kv);
+        assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv);
+        assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv);
+
+        match map.raw_entry_mut().from_key(&k) {
+            Occupied(mut o) => assert_eq!(Some(o.get_key_value()), kv),
+            Vacant(_) => assert_eq!(v, None),
+        }
+        match map.raw_entry_mut().from_key_hashed_nocheck(hash, &k) {
+            Occupied(mut o) => assert_eq!(Some(o.get_key_value()), kv),
+            Vacant(_) => assert_eq!(v, None),
+        }
+        match map.raw_entry_mut().from_hash(hash, |q| *q == k) {
+            Occupied(mut o) => assert_eq!(Some(o.get_key_value()), kv),
+            Vacant(_) => assert_eq!(v, None),
+        }
+    }
+}
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index 10bf917daea..8c39725ef35 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -1,3 +1,6 @@
+#[cfg(test)]
+mod tests;
+
 use crate::borrow::Borrow;
 use crate::collections::TryReserveError;
 use crate::fmt;
@@ -1579,422 +1582,3 @@ fn assert_covariance() {
         d
     }
 }
-
-#[cfg(test)]
-mod test_set {
-    use super::super::map::RandomState;
-    use super::HashSet;
-
-    #[test]
-    fn test_zero_capacities() {
-        type HS = HashSet<i32>;
-
-        let s = HS::new();
-        assert_eq!(s.capacity(), 0);
-
-        let s = HS::default();
-        assert_eq!(s.capacity(), 0);
-
-        let s = HS::with_hasher(RandomState::new());
-        assert_eq!(s.capacity(), 0);
-
-        let s = HS::with_capacity(0);
-        assert_eq!(s.capacity(), 0);
-
-        let s = HS::with_capacity_and_hasher(0, RandomState::new());
-        assert_eq!(s.capacity(), 0);
-
-        let mut s = HS::new();
-        s.insert(1);
-        s.insert(2);
-        s.remove(&1);
-        s.remove(&2);
-        s.shrink_to_fit();
-        assert_eq!(s.capacity(), 0);
-
-        let mut s = HS::new();
-        s.reserve(0);
-        assert_eq!(s.capacity(), 0);
-    }
-
-    #[test]
-    fn test_disjoint() {
-        let mut xs = HashSet::new();
-        let mut ys = HashSet::new();
-        assert!(xs.is_disjoint(&ys));
-        assert!(ys.is_disjoint(&xs));
-        assert!(xs.insert(5));
-        assert!(ys.insert(11));
-        assert!(xs.is_disjoint(&ys));
-        assert!(ys.is_disjoint(&xs));
-        assert!(xs.insert(7));
-        assert!(xs.insert(19));
-        assert!(xs.insert(4));
-        assert!(ys.insert(2));
-        assert!(ys.insert(-11));
-        assert!(xs.is_disjoint(&ys));
-        assert!(ys.is_disjoint(&xs));
-        assert!(ys.insert(7));
-        assert!(!xs.is_disjoint(&ys));
-        assert!(!ys.is_disjoint(&xs));
-    }
-
-    #[test]
-    fn test_subset_and_superset() {
-        let mut a = HashSet::new();
-        assert!(a.insert(0));
-        assert!(a.insert(5));
-        assert!(a.insert(11));
-        assert!(a.insert(7));
-
-        let mut b = HashSet::new();
-        assert!(b.insert(0));
-        assert!(b.insert(7));
-        assert!(b.insert(19));
-        assert!(b.insert(250));
-        assert!(b.insert(11));
-        assert!(b.insert(200));
-
-        assert!(!a.is_subset(&b));
-        assert!(!a.is_superset(&b));
-        assert!(!b.is_subset(&a));
-        assert!(!b.is_superset(&a));
-
-        assert!(b.insert(5));
-
-        assert!(a.is_subset(&b));
-        assert!(!a.is_superset(&b));
-        assert!(!b.is_subset(&a));
-        assert!(b.is_superset(&a));
-    }
-
-    #[test]
-    fn test_iterate() {
-        let mut a = HashSet::new();
-        for i in 0..32 {
-            assert!(a.insert(i));
-        }
-        let mut observed: u32 = 0;
-        for k in &a {
-            observed |= 1 << *k;
-        }
-        assert_eq!(observed, 0xFFFF_FFFF);
-    }
-
-    #[test]
-    fn test_intersection() {
-        let mut a = HashSet::new();
-        let mut b = HashSet::new();
-        assert!(a.intersection(&b).next().is_none());
-
-        assert!(a.insert(11));
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(77));
-        assert!(a.insert(103));
-        assert!(a.insert(5));
-        assert!(a.insert(-5));
-
-        assert!(b.insert(2));
-        assert!(b.insert(11));
-        assert!(b.insert(77));
-        assert!(b.insert(-9));
-        assert!(b.insert(-42));
-        assert!(b.insert(5));
-        assert!(b.insert(3));
-
-        let mut i = 0;
-        let expected = [3, 5, 11, 77];
-        for x in a.intersection(&b) {
-            assert!(expected.contains(x));
-            i += 1
-        }
-        assert_eq!(i, expected.len());
-
-        assert!(a.insert(9)); // make a bigger than b
-
-        i = 0;
-        for x in a.intersection(&b) {
-            assert!(expected.contains(x));
-            i += 1
-        }
-        assert_eq!(i, expected.len());
-
-        i = 0;
-        for x in b.intersection(&a) {
-            assert!(expected.contains(x));
-            i += 1
-        }
-        assert_eq!(i, expected.len());
-    }
-
-    #[test]
-    fn test_difference() {
-        let mut a = HashSet::new();
-        let mut b = HashSet::new();
-
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(5));
-        assert!(a.insert(9));
-        assert!(a.insert(11));
-
-        assert!(b.insert(3));
-        assert!(b.insert(9));
-
-        let mut i = 0;
-        let expected = [1, 5, 11];
-        for x in a.difference(&b) {
-            assert!(expected.contains(x));
-            i += 1
-        }
-        assert_eq!(i, expected.len());
-    }
-
-    #[test]
-    fn test_symmetric_difference() {
-        let mut a = HashSet::new();
-        let mut b = HashSet::new();
-
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(5));
-        assert!(a.insert(9));
-        assert!(a.insert(11));
-
-        assert!(b.insert(-2));
-        assert!(b.insert(3));
-        assert!(b.insert(9));
-        assert!(b.insert(14));
-        assert!(b.insert(22));
-
-        let mut i = 0;
-        let expected = [-2, 1, 5, 11, 14, 22];
-        for x in a.symmetric_difference(&b) {
-            assert!(expected.contains(x));
-            i += 1
-        }
-        assert_eq!(i, expected.len());
-    }
-
-    #[test]
-    fn test_union() {
-        let mut a = HashSet::new();
-        let mut b = HashSet::new();
-        assert!(a.union(&b).next().is_none());
-        assert!(b.union(&a).next().is_none());
-
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(11));
-        assert!(a.insert(16));
-        assert!(a.insert(19));
-        assert!(a.insert(24));
-
-        assert!(b.insert(-2));
-        assert!(b.insert(1));
-        assert!(b.insert(5));
-        assert!(b.insert(9));
-        assert!(b.insert(13));
-        assert!(b.insert(19));
-
-        let mut i = 0;
-        let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24];
-        for x in a.union(&b) {
-            assert!(expected.contains(x));
-            i += 1
-        }
-        assert_eq!(i, expected.len());
-
-        assert!(a.insert(9)); // make a bigger than b
-        assert!(a.insert(5));
-
-        i = 0;
-        for x in a.union(&b) {
-            assert!(expected.contains(x));
-            i += 1
-        }
-        assert_eq!(i, expected.len());
-
-        i = 0;
-        for x in b.union(&a) {
-            assert!(expected.contains(x));
-            i += 1
-        }
-        assert_eq!(i, expected.len());
-    }
-
-    #[test]
-    fn test_from_iter() {
-        let xs = [1, 2, 2, 3, 4, 5, 6, 7, 8, 9];
-
-        let set: HashSet<_> = xs.iter().cloned().collect();
-
-        for x in &xs {
-            assert!(set.contains(x));
-        }
-
-        assert_eq!(set.iter().len(), xs.len() - 1);
-    }
-
-    #[test]
-    fn test_move_iter() {
-        let hs = {
-            let mut hs = HashSet::new();
-
-            hs.insert('a');
-            hs.insert('b');
-
-            hs
-        };
-
-        let v = hs.into_iter().collect::<Vec<char>>();
-        assert!(v == ['a', 'b'] || v == ['b', 'a']);
-    }
-
-    #[test]
-    fn test_eq() {
-        // These constants once happened to expose a bug in insert().
-        // I'm keeping them around to prevent a regression.
-        let mut s1 = HashSet::new();
-
-        s1.insert(1);
-        s1.insert(2);
-        s1.insert(3);
-
-        let mut s2 = HashSet::new();
-
-        s2.insert(1);
-        s2.insert(2);
-
-        assert!(s1 != s2);
-
-        s2.insert(3);
-
-        assert_eq!(s1, s2);
-    }
-
-    #[test]
-    fn test_show() {
-        let mut set = HashSet::new();
-        let empty = HashSet::<i32>::new();
-
-        set.insert(1);
-        set.insert(2);
-
-        let set_str = format!("{:?}", set);
-
-        assert!(set_str == "{1, 2}" || set_str == "{2, 1}");
-        assert_eq!(format!("{:?}", empty), "{}");
-    }
-
-    #[test]
-    fn test_trivial_drain() {
-        let mut s = HashSet::<i32>::new();
-        for _ in s.drain() {}
-        assert!(s.is_empty());
-        drop(s);
-
-        let mut s = HashSet::<i32>::new();
-        drop(s.drain());
-        assert!(s.is_empty());
-    }
-
-    #[test]
-    fn test_drain() {
-        let mut s: HashSet<_> = (1..100).collect();
-
-        // try this a bunch of times to make sure we don't screw up internal state.
-        for _ in 0..20 {
-            assert_eq!(s.len(), 99);
-
-            {
-                let mut last_i = 0;
-                let mut d = s.drain();
-                for (i, x) in d.by_ref().take(50).enumerate() {
-                    last_i = i;
-                    assert!(x != 0);
-                }
-                assert_eq!(last_i, 49);
-            }
-
-            for _ in &s {
-                panic!("s should be empty!");
-            }
-
-            // reset to try again.
-            s.extend(1..100);
-        }
-    }
-
-    #[test]
-    fn test_replace() {
-        use crate::hash;
-
-        #[derive(Debug)]
-        struct Foo(&'static str, i32);
-
-        impl PartialEq for Foo {
-            fn eq(&self, other: &Self) -> bool {
-                self.0 == other.0
-            }
-        }
-
-        impl Eq for Foo {}
-
-        impl hash::Hash for Foo {
-            fn hash<H: hash::Hasher>(&self, h: &mut H) {
-                self.0.hash(h);
-            }
-        }
-
-        let mut s = HashSet::new();
-        assert_eq!(s.replace(Foo("a", 1)), None);
-        assert_eq!(s.len(), 1);
-        assert_eq!(s.replace(Foo("a", 2)), Some(Foo("a", 1)));
-        assert_eq!(s.len(), 1);
-
-        let mut it = s.iter();
-        assert_eq!(it.next(), Some(&Foo("a", 2)));
-        assert_eq!(it.next(), None);
-    }
-
-    #[test]
-    fn test_extend_ref() {
-        let mut a = HashSet::new();
-        a.insert(1);
-
-        a.extend(&[2, 3, 4]);
-
-        assert_eq!(a.len(), 4);
-        assert!(a.contains(&1));
-        assert!(a.contains(&2));
-        assert!(a.contains(&3));
-        assert!(a.contains(&4));
-
-        let mut b = HashSet::new();
-        b.insert(5);
-        b.insert(6);
-
-        a.extend(&b);
-
-        assert_eq!(a.len(), 6);
-        assert!(a.contains(&1));
-        assert!(a.contains(&2));
-        assert!(a.contains(&3));
-        assert!(a.contains(&4));
-        assert!(a.contains(&5));
-        assert!(a.contains(&6));
-    }
-
-    #[test]
-    fn test_retain() {
-        let xs = [1, 2, 3, 4, 5, 6];
-        let mut set: HashSet<i32> = xs.iter().cloned().collect();
-        set.retain(|&k| k % 2 == 0);
-        assert_eq!(set.len(), 3);
-        assert!(set.contains(&2));
-        assert!(set.contains(&4));
-        assert!(set.contains(&6));
-    }
-}
diff --git a/library/std/src/collections/hash/set/tests.rs b/library/std/src/collections/hash/set/tests.rs
new file mode 100644
index 00000000000..3582390cee4
--- /dev/null
+++ b/library/std/src/collections/hash/set/tests.rs
@@ -0,0 +1,415 @@
+use super::super::map::RandomState;
+use super::HashSet;
+
+#[test]
+fn test_zero_capacities() {
+    type HS = HashSet<i32>;
+
+    let s = HS::new();
+    assert_eq!(s.capacity(), 0);
+
+    let s = HS::default();
+    assert_eq!(s.capacity(), 0);
+
+    let s = HS::with_hasher(RandomState::new());
+    assert_eq!(s.capacity(), 0);
+
+    let s = HS::with_capacity(0);
+    assert_eq!(s.capacity(), 0);
+
+    let s = HS::with_capacity_and_hasher(0, RandomState::new());
+    assert_eq!(s.capacity(), 0);
+
+    let mut s = HS::new();
+    s.insert(1);
+    s.insert(2);
+    s.remove(&1);
+    s.remove(&2);
+    s.shrink_to_fit();
+    assert_eq!(s.capacity(), 0);
+
+    let mut s = HS::new();
+    s.reserve(0);
+    assert_eq!(s.capacity(), 0);
+}
+
+#[test]
+fn test_disjoint() {
+    let mut xs = HashSet::new();
+    let mut ys = HashSet::new();
+    assert!(xs.is_disjoint(&ys));
+    assert!(ys.is_disjoint(&xs));
+    assert!(xs.insert(5));
+    assert!(ys.insert(11));
+    assert!(xs.is_disjoint(&ys));
+    assert!(ys.is_disjoint(&xs));
+    assert!(xs.insert(7));
+    assert!(xs.insert(19));
+    assert!(xs.insert(4));
+    assert!(ys.insert(2));
+    assert!(ys.insert(-11));
+    assert!(xs.is_disjoint(&ys));
+    assert!(ys.is_disjoint(&xs));
+    assert!(ys.insert(7));
+    assert!(!xs.is_disjoint(&ys));
+    assert!(!ys.is_disjoint(&xs));
+}
+
+#[test]
+fn test_subset_and_superset() {
+    let mut a = HashSet::new();
+    assert!(a.insert(0));
+    assert!(a.insert(5));
+    assert!(a.insert(11));
+    assert!(a.insert(7));
+
+    let mut b = HashSet::new();
+    assert!(b.insert(0));
+    assert!(b.insert(7));
+    assert!(b.insert(19));
+    assert!(b.insert(250));
+    assert!(b.insert(11));
+    assert!(b.insert(200));
+
+    assert!(!a.is_subset(&b));
+    assert!(!a.is_superset(&b));
+    assert!(!b.is_subset(&a));
+    assert!(!b.is_superset(&a));
+
+    assert!(b.insert(5));
+
+    assert!(a.is_subset(&b));
+    assert!(!a.is_superset(&b));
+    assert!(!b.is_subset(&a));
+    assert!(b.is_superset(&a));
+}
+
+#[test]
+fn test_iterate() {
+    let mut a = HashSet::new();
+    for i in 0..32 {
+        assert!(a.insert(i));
+    }
+    let mut observed: u32 = 0;
+    for k in &a {
+        observed |= 1 << *k;
+    }
+    assert_eq!(observed, 0xFFFF_FFFF);
+}
+
+#[test]
+fn test_intersection() {
+    let mut a = HashSet::new();
+    let mut b = HashSet::new();
+    assert!(a.intersection(&b).next().is_none());
+
+    assert!(a.insert(11));
+    assert!(a.insert(1));
+    assert!(a.insert(3));
+    assert!(a.insert(77));
+    assert!(a.insert(103));
+    assert!(a.insert(5));
+    assert!(a.insert(-5));
+
+    assert!(b.insert(2));
+    assert!(b.insert(11));
+    assert!(b.insert(77));
+    assert!(b.insert(-9));
+    assert!(b.insert(-42));
+    assert!(b.insert(5));
+    assert!(b.insert(3));
+
+    let mut i = 0;
+    let expected = [3, 5, 11, 77];
+    for x in a.intersection(&b) {
+        assert!(expected.contains(x));
+        i += 1
+    }
+    assert_eq!(i, expected.len());
+
+    assert!(a.insert(9)); // make a bigger than b
+
+    i = 0;
+    for x in a.intersection(&b) {
+        assert!(expected.contains(x));
+        i += 1
+    }
+    assert_eq!(i, expected.len());
+
+    i = 0;
+    for x in b.intersection(&a) {
+        assert!(expected.contains(x));
+        i += 1
+    }
+    assert_eq!(i, expected.len());
+}
+
+#[test]
+fn test_difference() {
+    let mut a = HashSet::new();
+    let mut b = HashSet::new();
+
+    assert!(a.insert(1));
+    assert!(a.insert(3));
+    assert!(a.insert(5));
+    assert!(a.insert(9));
+    assert!(a.insert(11));
+
+    assert!(b.insert(3));
+    assert!(b.insert(9));
+
+    let mut i = 0;
+    let expected = [1, 5, 11];
+    for x in a.difference(&b) {
+        assert!(expected.contains(x));
+        i += 1
+    }
+    assert_eq!(i, expected.len());
+}
+
+#[test]
+fn test_symmetric_difference() {
+    let mut a = HashSet::new();
+    let mut b = HashSet::new();
+
+    assert!(a.insert(1));
+    assert!(a.insert(3));
+    assert!(a.insert(5));
+    assert!(a.insert(9));
+    assert!(a.insert(11));
+
+    assert!(b.insert(-2));
+    assert!(b.insert(3));
+    assert!(b.insert(9));
+    assert!(b.insert(14));
+    assert!(b.insert(22));
+
+    let mut i = 0;
+    let expected = [-2, 1, 5, 11, 14, 22];
+    for x in a.symmetric_difference(&b) {
+        assert!(expected.contains(x));
+        i += 1
+    }
+    assert_eq!(i, expected.len());
+}
+
+#[test]
+fn test_union() {
+    let mut a = HashSet::new();
+    let mut b = HashSet::new();
+    assert!(a.union(&b).next().is_none());
+    assert!(b.union(&a).next().is_none());
+
+    assert!(a.insert(1));
+    assert!(a.insert(3));
+    assert!(a.insert(11));
+    assert!(a.insert(16));
+    assert!(a.insert(19));
+    assert!(a.insert(24));
+
+    assert!(b.insert(-2));
+    assert!(b.insert(1));
+    assert!(b.insert(5));
+    assert!(b.insert(9));
+    assert!(b.insert(13));
+    assert!(b.insert(19));
+
+    let mut i = 0;
+    let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24];
+    for x in a.union(&b) {
+        assert!(expected.contains(x));
+        i += 1
+    }
+    assert_eq!(i, expected.len());
+
+    assert!(a.insert(9)); // make a bigger than b
+    assert!(a.insert(5));
+
+    i = 0;
+    for x in a.union(&b) {
+        assert!(expected.contains(x));
+        i += 1
+    }
+    assert_eq!(i, expected.len());
+
+    i = 0;
+    for x in b.union(&a) {
+        assert!(expected.contains(x));
+        i += 1
+    }
+    assert_eq!(i, expected.len());
+}
+
+#[test]
+fn test_from_iter() {
+    let xs = [1, 2, 2, 3, 4, 5, 6, 7, 8, 9];
+
+    let set: HashSet<_> = xs.iter().cloned().collect();
+
+    for x in &xs {
+        assert!(set.contains(x));
+    }
+
+    assert_eq!(set.iter().len(), xs.len() - 1);
+}
+
+#[test]
+fn test_move_iter() {
+    let hs = {
+        let mut hs = HashSet::new();
+
+        hs.insert('a');
+        hs.insert('b');
+
+        hs
+    };
+
+    let v = hs.into_iter().collect::<Vec<char>>();
+    assert!(v == ['a', 'b'] || v == ['b', 'a']);
+}
+
+#[test]
+fn test_eq() {
+    // These constants once happened to expose a bug in insert().
+    // I'm keeping them around to prevent a regression.
+    let mut s1 = HashSet::new();
+
+    s1.insert(1);
+    s1.insert(2);
+    s1.insert(3);
+
+    let mut s2 = HashSet::new();
+
+    s2.insert(1);
+    s2.insert(2);
+
+    assert!(s1 != s2);
+
+    s2.insert(3);
+
+    assert_eq!(s1, s2);
+}
+
+#[test]
+fn test_show() {
+    let mut set = HashSet::new();
+    let empty = HashSet::<i32>::new();
+
+    set.insert(1);
+    set.insert(2);
+
+    let set_str = format!("{:?}", set);
+
+    assert!(set_str == "{1, 2}" || set_str == "{2, 1}");
+    assert_eq!(format!("{:?}", empty), "{}");
+}
+
+#[test]
+fn test_trivial_drain() {
+    let mut s = HashSet::<i32>::new();
+    for _ in s.drain() {}
+    assert!(s.is_empty());
+    drop(s);
+
+    let mut s = HashSet::<i32>::new();
+    drop(s.drain());
+    assert!(s.is_empty());
+}
+
+#[test]
+fn test_drain() {
+    let mut s: HashSet<_> = (1..100).collect();
+
+    // try this a bunch of times to make sure we don't screw up internal state.
+    for _ in 0..20 {
+        assert_eq!(s.len(), 99);
+
+        {
+            let mut last_i = 0;
+            let mut d = s.drain();
+            for (i, x) in d.by_ref().take(50).enumerate() {
+                last_i = i;
+                assert!(x != 0);
+            }
+            assert_eq!(last_i, 49);
+        }
+
+        for _ in &s {
+            panic!("s should be empty!");
+        }
+
+        // reset to try again.
+        s.extend(1..100);
+    }
+}
+
+#[test]
+fn test_replace() {
+    use crate::hash;
+
+    #[derive(Debug)]
+    struct Foo(&'static str, i32);
+
+    impl PartialEq for Foo {
+        fn eq(&self, other: &Self) -> bool {
+            self.0 == other.0
+        }
+    }
+
+    impl Eq for Foo {}
+
+    impl hash::Hash for Foo {
+        fn hash<H: hash::Hasher>(&self, h: &mut H) {
+            self.0.hash(h);
+        }
+    }
+
+    let mut s = HashSet::new();
+    assert_eq!(s.replace(Foo("a", 1)), None);
+    assert_eq!(s.len(), 1);
+    assert_eq!(s.replace(Foo("a", 2)), Some(Foo("a", 1)));
+    assert_eq!(s.len(), 1);
+
+    let mut it = s.iter();
+    assert_eq!(it.next(), Some(&Foo("a", 2)));
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_extend_ref() {
+    let mut a = HashSet::new();
+    a.insert(1);
+
+    a.extend(&[2, 3, 4]);
+
+    assert_eq!(a.len(), 4);
+    assert!(a.contains(&1));
+    assert!(a.contains(&2));
+    assert!(a.contains(&3));
+    assert!(a.contains(&4));
+
+    let mut b = HashSet::new();
+    b.insert(5);
+    b.insert(6);
+
+    a.extend(&b);
+
+    assert_eq!(a.len(), 6);
+    assert!(a.contains(&1));
+    assert!(a.contains(&2));
+    assert!(a.contains(&3));
+    assert!(a.contains(&4));
+    assert!(a.contains(&5));
+    assert!(a.contains(&6));
+}
+
+#[test]
+fn test_retain() {
+    let xs = [1, 2, 3, 4, 5, 6];
+    let mut set: HashSet<i32> = xs.iter().cloned().collect();
+    set.retain(|&k| k % 2 == 0);
+    assert_eq!(set.len(), 3);
+    assert!(set.contains(&2));
+    assert!(set.contains(&4));
+    assert!(set.contains(&6));
+}
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index 387c588f4a0..970dea6b299 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -10,6 +10,9 @@
 
 #![stable(feature = "env", since = "1.0.0")]
 
+#[cfg(test)]
+mod tests;
+
 use crate::error::Error;
 use crate::ffi::{OsStr, OsString};
 use crate::fmt;
@@ -65,10 +68,9 @@ pub fn set_current_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
 
 /// An iterator over a snapshot of the environment variables of this process.
 ///
-/// This structure is created by the [`std::env::vars`] function. See its
-/// documentation for more.
+/// This structure is created by [`env::vars()`]. See its documentation for more.
 ///
-/// [`std::env::vars`]: vars
+/// [`env::vars()`]: vars
 #[stable(feature = "env", since = "1.0.0")]
 pub struct Vars {
     inner: VarsOs,
@@ -76,10 +78,9 @@ pub struct Vars {
 
 /// An iterator over a snapshot of the environment variables of this process.
 ///
-/// This structure is created by the [`std::env::vars_os`] function. See
-/// its documentation for more.
+/// This structure is created by [`env::vars_os()`]. See its documentation for more.
 ///
-/// [`std::env::vars_os`]: vars_os
+/// [`env::vars_os()`]: vars_os
 #[stable(feature = "env", since = "1.0.0")]
 pub struct VarsOs {
     inner: os_imp::Env,
@@ -95,10 +96,8 @@ pub struct VarsOs {
 /// # Panics
 ///
 /// While iterating, the returned iterator will panic if any key or value in the
-/// environment is not valid unicode. If this is not desired, consider using the
-/// [`env::vars_os`] function.
-///
-/// [`env::vars_os`]: vars_os
+/// environment is not valid unicode. If this is not desired, consider using
+/// [`env::vars_os()`].
 ///
 /// # Examples
 ///
@@ -111,6 +110,8 @@ pub struct VarsOs {
 ///     println!("{}: {}", key, value);
 /// }
 /// ```
+///
+/// [`env::vars_os()`]: vars_os
 #[stable(feature = "env", since = "1.0.0")]
 pub fn vars() -> Vars {
     Vars { inner: vars_os() }
@@ -242,9 +243,9 @@ fn _var_os(key: &OsStr) -> Option<OsString> {
 }
 
 /// The error type for operations interacting with environment variables.
-/// Possibly returned from the [`env::var`] function.
+/// Possibly returned from [`env::var()`].
 ///
-/// [`env::var`]: var
+/// [`env::var()`]: var
 #[derive(Debug, PartialEq, Eq, Clone)]
 #[stable(feature = "env", since = "1.0.0")]
 pub enum VarError {
@@ -369,10 +370,10 @@ fn _remove_var(k: &OsStr) {
 ///
 /// The iterator element type is [`PathBuf`].
 ///
-/// This structure is created by the [`std::env::split_paths`] function. See its
+/// This structure is created by [`env::split_paths()`]. See its
 /// documentation for more.
 ///
-/// [`std::env::split_paths`]: split_paths
+/// [`env::split_paths()`]: split_paths
 #[stable(feature = "env", since = "1.0.0")]
 pub struct SplitPaths<'a> {
     inner: os_imp::SplitPaths<'a>,
@@ -423,9 +424,9 @@ impl fmt::Debug for SplitPaths<'_> {
 }
 
 /// The error type for operations on the `PATH` variable. Possibly returned from
-/// the [`env::join_paths`] function.
+/// [`env::join_paths()`].
 ///
-/// [`env::join_paths`]: join_paths
+/// [`env::join_paths()`]: join_paths
 #[derive(Debug)]
 #[stable(feature = "env", since = "1.0.0")]
 pub struct JoinPathsError {
@@ -460,7 +461,8 @@ pub struct JoinPathsError {
 /// }
 /// ```
 ///
-/// Joining a path containing a colon on a Unix-like platform results in an error:
+/// Joining a path containing a colon on a Unix-like platform results in an
+/// error:
 ///
 /// ```
 /// # if cfg!(unix) {
@@ -472,8 +474,8 @@ pub struct JoinPathsError {
 /// # }
 /// ```
 ///
-/// Using `env::join_paths` with [`env::split_paths`] to append an item to the `PATH` environment
-/// variable:
+/// Using `env::join_paths()` with [`env::split_paths()`] to append an item to
+/// the `PATH` environment variable:
 ///
 /// ```
 /// use std::env;
@@ -491,7 +493,7 @@ pub struct JoinPathsError {
 /// }
 /// ```
 ///
-/// [`env::split_paths`]: split_paths
+/// [`env::split_paths()`]: split_paths
 #[stable(feature = "env", since = "1.0.0")]
 pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
 where
@@ -664,14 +666,14 @@ pub fn current_exe() -> io::Result<PathBuf> {
 /// An iterator over the arguments of a process, yielding a [`String`] value for
 /// each argument.
 ///
-/// This struct is created by the [`std::env::args`] function. See its
-/// documentation for more.
+/// This struct is created by [`env::args()`]. See its documentation
+/// for more.
 ///
 /// The first element is traditionally the path of the executable, but it can be
 /// set to arbitrary text, and may not even exist. This means this property
 /// should not be relied upon for security purposes.
 ///
-/// [`std::env::args`]: args
+/// [`env::args()`]: args
 #[stable(feature = "env", since = "1.0.0")]
 pub struct Args {
     inner: ArgsOs,
@@ -680,14 +682,14 @@ pub struct Args {
 /// An iterator over the arguments of a process, yielding an [`OsString`] value
 /// for each argument.
 ///
-/// This struct is created by the [`std::env::args_os`] function. See its
-/// documentation for more.
+/// This struct is created by [`env::args_os()`]. See its documentation
+/// for more.
 ///
 /// The first element is traditionally the path of the executable, but it can be
 /// set to arbitrary text, and may not even exist. This means this property
 /// should not be relied upon for security purposes.
 ///
-/// [`std::env::args_os`]: args_os
+/// [`env::args_os()`]: args_os
 #[stable(feature = "env", since = "1.0.0")]
 pub struct ArgsOs {
     inner: sys::args::Args,
@@ -944,112 +946,3 @@ pub mod consts {
     #[stable(feature = "env", since = "1.0.0")]
     pub const EXE_EXTENSION: &str = os::EXE_EXTENSION;
 }
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    use crate::path::Path;
-
-    #[test]
-    #[cfg_attr(any(target_os = "emscripten", target_env = "sgx"), ignore)]
-    fn test_self_exe_path() {
-        let path = current_exe();
-        assert!(path.is_ok());
-        let path = path.unwrap();
-
-        // Hard to test this function
-        assert!(path.is_absolute());
-    }
-
-    #[test]
-    fn test() {
-        assert!((!Path::new("test-path").is_absolute()));
-
-        #[cfg(not(target_env = "sgx"))]
-        current_dir().unwrap();
-    }
-
-    #[test]
-    #[cfg(windows)]
-    fn split_paths_windows() {
-        use crate::path::PathBuf;
-
-        fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
-            split_paths(unparsed).collect::<Vec<_>>()
-                == parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
-        }
-
-        assert!(check_parse("", &mut [""]));
-        assert!(check_parse(r#""""#, &mut [""]));
-        assert!(check_parse(";;", &mut ["", "", ""]));
-        assert!(check_parse(r"c:\", &mut [r"c:\"]));
-        assert!(check_parse(r"c:\;", &mut [r"c:\", ""]));
-        assert!(check_parse(r"c:\;c:\Program Files\", &mut [r"c:\", r"c:\Program Files\"]));
-        assert!(check_parse(r#"c:\;c:\"foo"\"#, &mut [r"c:\", r"c:\foo\"]));
-        assert!(check_parse(
-            r#"c:\;c:\"foo;bar"\;c:\baz"#,
-            &mut [r"c:\", r"c:\foo;bar\", r"c:\baz"]
-        ));
-    }
-
-    #[test]
-    #[cfg(unix)]
-    fn split_paths_unix() {
-        use crate::path::PathBuf;
-
-        fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
-            split_paths(unparsed).collect::<Vec<_>>()
-                == parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
-        }
-
-        assert!(check_parse("", &mut [""]));
-        assert!(check_parse("::", &mut ["", "", ""]));
-        assert!(check_parse("/", &mut ["/"]));
-        assert!(check_parse("/:", &mut ["/", ""]));
-        assert!(check_parse("/:/usr/local", &mut ["/", "/usr/local"]));
-    }
-
-    #[test]
-    #[cfg(unix)]
-    fn join_paths_unix() {
-        use crate::ffi::OsStr;
-
-        fn test_eq(input: &[&str], output: &str) -> bool {
-            &*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
-        }
-
-        assert!(test_eq(&[], ""));
-        assert!(test_eq(&["/bin", "/usr/bin", "/usr/local/bin"], "/bin:/usr/bin:/usr/local/bin"));
-        assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""], ":/bin:::/usr/bin:"));
-        assert!(join_paths(["/te:st"].iter().cloned()).is_err());
-    }
-
-    #[test]
-    #[cfg(windows)]
-    fn join_paths_windows() {
-        use crate::ffi::OsStr;
-
-        fn test_eq(input: &[&str], output: &str) -> bool {
-            &*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
-        }
-
-        assert!(test_eq(&[], ""));
-        assert!(test_eq(&[r"c:\windows", r"c:\"], r"c:\windows;c:\"));
-        assert!(test_eq(&["", r"c:\windows", "", "", r"c:\", ""], r";c:\windows;;;c:\;"));
-        assert!(test_eq(&[r"c:\te;st", r"c:\"], r#""c:\te;st";c:\"#));
-        assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err());
-    }
-
-    #[test]
-    fn args_debug() {
-        assert_eq!(
-            format!("Args {{ inner: {:?} }}", args().collect::<Vec<_>>()),
-            format!("{:?}", args())
-        );
-        assert_eq!(
-            format!("ArgsOs {{ inner: {:?} }}", args_os().collect::<Vec<_>>()),
-            format!("{:?}", args_os())
-        );
-    }
-}
diff --git a/library/std/src/env/tests.rs b/library/std/src/env/tests.rs
new file mode 100644
index 00000000000..94cace03af6
--- /dev/null
+++ b/library/std/src/env/tests.rs
@@ -0,0 +1,102 @@
+use super::*;
+
+use crate::path::Path;
+
+#[test]
+#[cfg_attr(any(target_os = "emscripten", target_env = "sgx"), ignore)]
+fn test_self_exe_path() {
+    let path = current_exe();
+    assert!(path.is_ok());
+    let path = path.unwrap();
+
+    // Hard to test this function
+    assert!(path.is_absolute());
+}
+
+#[test]
+fn test() {
+    assert!((!Path::new("test-path").is_absolute()));
+
+    #[cfg(not(target_env = "sgx"))]
+    current_dir().unwrap();
+}
+
+#[test]
+#[cfg(windows)]
+fn split_paths_windows() {
+    use crate::path::PathBuf;
+
+    fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
+        split_paths(unparsed).collect::<Vec<_>>()
+            == parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
+    }
+
+    assert!(check_parse("", &mut [""]));
+    assert!(check_parse(r#""""#, &mut [""]));
+    assert!(check_parse(";;", &mut ["", "", ""]));
+    assert!(check_parse(r"c:\", &mut [r"c:\"]));
+    assert!(check_parse(r"c:\;", &mut [r"c:\", ""]));
+    assert!(check_parse(r"c:\;c:\Program Files\", &mut [r"c:\", r"c:\Program Files\"]));
+    assert!(check_parse(r#"c:\;c:\"foo"\"#, &mut [r"c:\", r"c:\foo\"]));
+    assert!(check_parse(r#"c:\;c:\"foo;bar"\;c:\baz"#, &mut [r"c:\", r"c:\foo;bar\", r"c:\baz"]));
+}
+
+#[test]
+#[cfg(unix)]
+fn split_paths_unix() {
+    use crate::path::PathBuf;
+
+    fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
+        split_paths(unparsed).collect::<Vec<_>>()
+            == parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
+    }
+
+    assert!(check_parse("", &mut [""]));
+    assert!(check_parse("::", &mut ["", "", ""]));
+    assert!(check_parse("/", &mut ["/"]));
+    assert!(check_parse("/:", &mut ["/", ""]));
+    assert!(check_parse("/:/usr/local", &mut ["/", "/usr/local"]));
+}
+
+#[test]
+#[cfg(unix)]
+fn join_paths_unix() {
+    use crate::ffi::OsStr;
+
+    fn test_eq(input: &[&str], output: &str) -> bool {
+        &*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
+    }
+
+    assert!(test_eq(&[], ""));
+    assert!(test_eq(&["/bin", "/usr/bin", "/usr/local/bin"], "/bin:/usr/bin:/usr/local/bin"));
+    assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""], ":/bin:::/usr/bin:"));
+    assert!(join_paths(["/te:st"].iter().cloned()).is_err());
+}
+
+#[test]
+#[cfg(windows)]
+fn join_paths_windows() {
+    use crate::ffi::OsStr;
+
+    fn test_eq(input: &[&str], output: &str) -> bool {
+        &*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
+    }
+
+    assert!(test_eq(&[], ""));
+    assert!(test_eq(&[r"c:\windows", r"c:\"], r"c:\windows;c:\"));
+    assert!(test_eq(&["", r"c:\windows", "", "", r"c:\", ""], r";c:\windows;;;c:\;"));
+    assert!(test_eq(&[r"c:\te;st", r"c:\"], r#""c:\te;st";c:\"#));
+    assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err());
+}
+
+#[test]
+fn args_debug() {
+    assert_eq!(
+        format!("Args {{ inner: {:?} }}", args().collect::<Vec<_>>()),
+        format!("{:?}", args())
+    );
+    assert_eq!(
+        format!("ArgsOs {{ inner: {:?} }}", args_os().collect::<Vec<_>>()),
+        format!("{:?}", args_os())
+    );
+}
diff --git a/library/std/src/error.rs b/library/std/src/error.rs
index d3b0f8ceb68..8da03343976 100644
--- a/library/std/src/error.rs
+++ b/library/std/src/error.rs
@@ -13,6 +13,9 @@
 // coherence challenge (e.g., specialization, neg impls, etc) we can
 // reconsider what crate these items belong in.
 
+#[cfg(test)]
+mod tests;
+
 use core::array;
 use core::convert::Infallible;
 
@@ -738,44 +741,3 @@ impl dyn Error + Send + Sync {
         })
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use super::Error;
-    use crate::fmt;
-
-    #[derive(Debug, PartialEq)]
-    struct A;
-    #[derive(Debug, PartialEq)]
-    struct B;
-
-    impl fmt::Display for A {
-        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-            write!(f, "A")
-        }
-    }
-    impl fmt::Display for B {
-        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-            write!(f, "B")
-        }
-    }
-
-    impl Error for A {}
-    impl Error for B {}
-
-    #[test]
-    fn downcasting() {
-        let mut a = A;
-        let a = &mut a as &mut (dyn Error + 'static);
-        assert_eq!(a.downcast_ref::<A>(), Some(&A));
-        assert_eq!(a.downcast_ref::<B>(), None);
-        assert_eq!(a.downcast_mut::<A>(), Some(&mut A));
-        assert_eq!(a.downcast_mut::<B>(), None);
-
-        let a: Box<dyn Error> = Box::new(A);
-        match a.downcast::<B>() {
-            Ok(..) => panic!("expected error"),
-            Err(e) => assert_eq!(*e.downcast::<A>().unwrap(), A),
-        }
-    }
-}
diff --git a/library/std/src/error/tests.rs b/library/std/src/error/tests.rs
new file mode 100644
index 00000000000..66d6924f34d
--- /dev/null
+++ b/library/std/src/error/tests.rs
@@ -0,0 +1,37 @@
+use super::Error;
+use crate::fmt;
+
+#[derive(Debug, PartialEq)]
+struct A;
+#[derive(Debug, PartialEq)]
+struct B;
+
+impl fmt::Display for A {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "A")
+    }
+}
+impl fmt::Display for B {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "B")
+    }
+}
+
+impl Error for A {}
+impl Error for B {}
+
+#[test]
+fn downcasting() {
+    let mut a = A;
+    let a = &mut a as &mut (dyn Error + 'static);
+    assert_eq!(a.downcast_ref::<A>(), Some(&A));
+    assert_eq!(a.downcast_ref::<B>(), None);
+    assert_eq!(a.downcast_mut::<A>(), Some(&mut A));
+    assert_eq!(a.downcast_mut::<B>(), None);
+
+    let a: Box<dyn Error> = Box::new(A);
+    match a.downcast::<B>() {
+        Ok(..) => panic!("expected error"),
+        Err(e) => assert_eq!(*e.downcast::<A>().unwrap(), A),
+    }
+}
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index c905bcf5e3d..59c2da5273b 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -11,6 +11,9 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 #![allow(missing_docs)]
 
+#[cfg(test)]
+mod tests;
+
 #[cfg(not(test))]
 use crate::intrinsics;
 #[cfg(not(test))]
@@ -909,766 +912,3 @@ impl f32 {
         x
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use crate::f32::consts;
-    use crate::num::FpCategory as Fp;
-    use crate::num::*;
-
-    #[test]
-    fn test_num_f32() {
-        test_num(10f32, 2f32);
-    }
-
-    #[test]
-    fn test_min_nan() {
-        assert_eq!(f32::NAN.min(2.0), 2.0);
-        assert_eq!(2.0f32.min(f32::NAN), 2.0);
-    }
-
-    #[test]
-    fn test_max_nan() {
-        assert_eq!(f32::NAN.max(2.0), 2.0);
-        assert_eq!(2.0f32.max(f32::NAN), 2.0);
-    }
-
-    #[test]
-    fn test_nan() {
-        let nan: f32 = f32::NAN;
-        assert!(nan.is_nan());
-        assert!(!nan.is_infinite());
-        assert!(!nan.is_finite());
-        assert!(!nan.is_normal());
-        assert!(nan.is_sign_positive());
-        assert!(!nan.is_sign_negative());
-        assert_eq!(Fp::Nan, nan.classify());
-    }
-
-    #[test]
-    fn test_infinity() {
-        let inf: f32 = f32::INFINITY;
-        assert!(inf.is_infinite());
-        assert!(!inf.is_finite());
-        assert!(inf.is_sign_positive());
-        assert!(!inf.is_sign_negative());
-        assert!(!inf.is_nan());
-        assert!(!inf.is_normal());
-        assert_eq!(Fp::Infinite, inf.classify());
-    }
-
-    #[test]
-    fn test_neg_infinity() {
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        assert!(neg_inf.is_infinite());
-        assert!(!neg_inf.is_finite());
-        assert!(!neg_inf.is_sign_positive());
-        assert!(neg_inf.is_sign_negative());
-        assert!(!neg_inf.is_nan());
-        assert!(!neg_inf.is_normal());
-        assert_eq!(Fp::Infinite, neg_inf.classify());
-    }
-
-    #[test]
-    fn test_zero() {
-        let zero: f32 = 0.0f32;
-        assert_eq!(0.0, zero);
-        assert!(!zero.is_infinite());
-        assert!(zero.is_finite());
-        assert!(zero.is_sign_positive());
-        assert!(!zero.is_sign_negative());
-        assert!(!zero.is_nan());
-        assert!(!zero.is_normal());
-        assert_eq!(Fp::Zero, zero.classify());
-    }
-
-    #[test]
-    fn test_neg_zero() {
-        let neg_zero: f32 = -0.0;
-        assert_eq!(0.0, neg_zero);
-        assert!(!neg_zero.is_infinite());
-        assert!(neg_zero.is_finite());
-        assert!(!neg_zero.is_sign_positive());
-        assert!(neg_zero.is_sign_negative());
-        assert!(!neg_zero.is_nan());
-        assert!(!neg_zero.is_normal());
-        assert_eq!(Fp::Zero, neg_zero.classify());
-    }
-
-    #[test]
-    fn test_one() {
-        let one: f32 = 1.0f32;
-        assert_eq!(1.0, one);
-        assert!(!one.is_infinite());
-        assert!(one.is_finite());
-        assert!(one.is_sign_positive());
-        assert!(!one.is_sign_negative());
-        assert!(!one.is_nan());
-        assert!(one.is_normal());
-        assert_eq!(Fp::Normal, one.classify());
-    }
-
-    #[test]
-    fn test_is_nan() {
-        let nan: f32 = f32::NAN;
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        assert!(nan.is_nan());
-        assert!(!0.0f32.is_nan());
-        assert!(!5.3f32.is_nan());
-        assert!(!(-10.732f32).is_nan());
-        assert!(!inf.is_nan());
-        assert!(!neg_inf.is_nan());
-    }
-
-    #[test]
-    fn test_is_infinite() {
-        let nan: f32 = f32::NAN;
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        assert!(!nan.is_infinite());
-        assert!(inf.is_infinite());
-        assert!(neg_inf.is_infinite());
-        assert!(!0.0f32.is_infinite());
-        assert!(!42.8f32.is_infinite());
-        assert!(!(-109.2f32).is_infinite());
-    }
-
-    #[test]
-    fn test_is_finite() {
-        let nan: f32 = f32::NAN;
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        assert!(!nan.is_finite());
-        assert!(!inf.is_finite());
-        assert!(!neg_inf.is_finite());
-        assert!(0.0f32.is_finite());
-        assert!(42.8f32.is_finite());
-        assert!((-109.2f32).is_finite());
-    }
-
-    #[test]
-    fn test_is_normal() {
-        let nan: f32 = f32::NAN;
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        let zero: f32 = 0.0f32;
-        let neg_zero: f32 = -0.0;
-        assert!(!nan.is_normal());
-        assert!(!inf.is_normal());
-        assert!(!neg_inf.is_normal());
-        assert!(!zero.is_normal());
-        assert!(!neg_zero.is_normal());
-        assert!(1f32.is_normal());
-        assert!(1e-37f32.is_normal());
-        assert!(!1e-38f32.is_normal());
-    }
-
-    #[test]
-    fn test_classify() {
-        let nan: f32 = f32::NAN;
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        let zero: f32 = 0.0f32;
-        let neg_zero: f32 = -0.0;
-        assert_eq!(nan.classify(), Fp::Nan);
-        assert_eq!(inf.classify(), Fp::Infinite);
-        assert_eq!(neg_inf.classify(), Fp::Infinite);
-        assert_eq!(zero.classify(), Fp::Zero);
-        assert_eq!(neg_zero.classify(), Fp::Zero);
-        assert_eq!(1f32.classify(), Fp::Normal);
-        assert_eq!(1e-37f32.classify(), Fp::Normal);
-        assert_eq!(1e-38f32.classify(), Fp::Subnormal);
-    }
-
-    #[test]
-    fn test_floor() {
-        assert_approx_eq!(1.0f32.floor(), 1.0f32);
-        assert_approx_eq!(1.3f32.floor(), 1.0f32);
-        assert_approx_eq!(1.5f32.floor(), 1.0f32);
-        assert_approx_eq!(1.7f32.floor(), 1.0f32);
-        assert_approx_eq!(0.0f32.floor(), 0.0f32);
-        assert_approx_eq!((-0.0f32).floor(), -0.0f32);
-        assert_approx_eq!((-1.0f32).floor(), -1.0f32);
-        assert_approx_eq!((-1.3f32).floor(), -2.0f32);
-        assert_approx_eq!((-1.5f32).floor(), -2.0f32);
-        assert_approx_eq!((-1.7f32).floor(), -2.0f32);
-    }
-
-    #[test]
-    fn test_ceil() {
-        assert_approx_eq!(1.0f32.ceil(), 1.0f32);
-        assert_approx_eq!(1.3f32.ceil(), 2.0f32);
-        assert_approx_eq!(1.5f32.ceil(), 2.0f32);
-        assert_approx_eq!(1.7f32.ceil(), 2.0f32);
-        assert_approx_eq!(0.0f32.ceil(), 0.0f32);
-        assert_approx_eq!((-0.0f32).ceil(), -0.0f32);
-        assert_approx_eq!((-1.0f32).ceil(), -1.0f32);
-        assert_approx_eq!((-1.3f32).ceil(), -1.0f32);
-        assert_approx_eq!((-1.5f32).ceil(), -1.0f32);
-        assert_approx_eq!((-1.7f32).ceil(), -1.0f32);
-    }
-
-    #[test]
-    fn test_round() {
-        assert_approx_eq!(1.0f32.round(), 1.0f32);
-        assert_approx_eq!(1.3f32.round(), 1.0f32);
-        assert_approx_eq!(1.5f32.round(), 2.0f32);
-        assert_approx_eq!(1.7f32.round(), 2.0f32);
-        assert_approx_eq!(0.0f32.round(), 0.0f32);
-        assert_approx_eq!((-0.0f32).round(), -0.0f32);
-        assert_approx_eq!((-1.0f32).round(), -1.0f32);
-        assert_approx_eq!((-1.3f32).round(), -1.0f32);
-        assert_approx_eq!((-1.5f32).round(), -2.0f32);
-        assert_approx_eq!((-1.7f32).round(), -2.0f32);
-    }
-
-    #[test]
-    fn test_trunc() {
-        assert_approx_eq!(1.0f32.trunc(), 1.0f32);
-        assert_approx_eq!(1.3f32.trunc(), 1.0f32);
-        assert_approx_eq!(1.5f32.trunc(), 1.0f32);
-        assert_approx_eq!(1.7f32.trunc(), 1.0f32);
-        assert_approx_eq!(0.0f32.trunc(), 0.0f32);
-        assert_approx_eq!((-0.0f32).trunc(), -0.0f32);
-        assert_approx_eq!((-1.0f32).trunc(), -1.0f32);
-        assert_approx_eq!((-1.3f32).trunc(), -1.0f32);
-        assert_approx_eq!((-1.5f32).trunc(), -1.0f32);
-        assert_approx_eq!((-1.7f32).trunc(), -1.0f32);
-    }
-
-    #[test]
-    fn test_fract() {
-        assert_approx_eq!(1.0f32.fract(), 0.0f32);
-        assert_approx_eq!(1.3f32.fract(), 0.3f32);
-        assert_approx_eq!(1.5f32.fract(), 0.5f32);
-        assert_approx_eq!(1.7f32.fract(), 0.7f32);
-        assert_approx_eq!(0.0f32.fract(), 0.0f32);
-        assert_approx_eq!((-0.0f32).fract(), -0.0f32);
-        assert_approx_eq!((-1.0f32).fract(), -0.0f32);
-        assert_approx_eq!((-1.3f32).fract(), -0.3f32);
-        assert_approx_eq!((-1.5f32).fract(), -0.5f32);
-        assert_approx_eq!((-1.7f32).fract(), -0.7f32);
-    }
-
-    #[test]
-    fn test_abs() {
-        assert_eq!(f32::INFINITY.abs(), f32::INFINITY);
-        assert_eq!(1f32.abs(), 1f32);
-        assert_eq!(0f32.abs(), 0f32);
-        assert_eq!((-0f32).abs(), 0f32);
-        assert_eq!((-1f32).abs(), 1f32);
-        assert_eq!(f32::NEG_INFINITY.abs(), f32::INFINITY);
-        assert_eq!((1f32 / f32::NEG_INFINITY).abs(), 0f32);
-        assert!(f32::NAN.abs().is_nan());
-    }
-
-    #[test]
-    fn test_signum() {
-        assert_eq!(f32::INFINITY.signum(), 1f32);
-        assert_eq!(1f32.signum(), 1f32);
-        assert_eq!(0f32.signum(), 1f32);
-        assert_eq!((-0f32).signum(), -1f32);
-        assert_eq!((-1f32).signum(), -1f32);
-        assert_eq!(f32::NEG_INFINITY.signum(), -1f32);
-        assert_eq!((1f32 / f32::NEG_INFINITY).signum(), -1f32);
-        assert!(f32::NAN.signum().is_nan());
-    }
-
-    #[test]
-    fn test_is_sign_positive() {
-        assert!(f32::INFINITY.is_sign_positive());
-        assert!(1f32.is_sign_positive());
-        assert!(0f32.is_sign_positive());
-        assert!(!(-0f32).is_sign_positive());
-        assert!(!(-1f32).is_sign_positive());
-        assert!(!f32::NEG_INFINITY.is_sign_positive());
-        assert!(!(1f32 / f32::NEG_INFINITY).is_sign_positive());
-        assert!(f32::NAN.is_sign_positive());
-        assert!(!(-f32::NAN).is_sign_positive());
-    }
-
-    #[test]
-    fn test_is_sign_negative() {
-        assert!(!f32::INFINITY.is_sign_negative());
-        assert!(!1f32.is_sign_negative());
-        assert!(!0f32.is_sign_negative());
-        assert!((-0f32).is_sign_negative());
-        assert!((-1f32).is_sign_negative());
-        assert!(f32::NEG_INFINITY.is_sign_negative());
-        assert!((1f32 / f32::NEG_INFINITY).is_sign_negative());
-        assert!(!f32::NAN.is_sign_negative());
-        assert!((-f32::NAN).is_sign_negative());
-    }
-
-    #[test]
-    fn test_mul_add() {
-        let nan: f32 = f32::NAN;
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        assert_approx_eq!(12.3f32.mul_add(4.5, 6.7), 62.05);
-        assert_approx_eq!((-12.3f32).mul_add(-4.5, -6.7), 48.65);
-        assert_approx_eq!(0.0f32.mul_add(8.9, 1.2), 1.2);
-        assert_approx_eq!(3.4f32.mul_add(-0.0, 5.6), 5.6);
-        assert!(nan.mul_add(7.8, 9.0).is_nan());
-        assert_eq!(inf.mul_add(7.8, 9.0), inf);
-        assert_eq!(neg_inf.mul_add(7.8, 9.0), neg_inf);
-        assert_eq!(8.9f32.mul_add(inf, 3.2), inf);
-        assert_eq!((-3.2f32).mul_add(2.4, neg_inf), neg_inf);
-    }
-
-    #[test]
-    fn test_recip() {
-        let nan: f32 = f32::NAN;
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        assert_eq!(1.0f32.recip(), 1.0);
-        assert_eq!(2.0f32.recip(), 0.5);
-        assert_eq!((-0.4f32).recip(), -2.5);
-        assert_eq!(0.0f32.recip(), inf);
-        assert!(nan.recip().is_nan());
-        assert_eq!(inf.recip(), 0.0);
-        assert_eq!(neg_inf.recip(), 0.0);
-    }
-
-    #[test]
-    fn test_powi() {
-        let nan: f32 = f32::NAN;
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        assert_eq!(1.0f32.powi(1), 1.0);
-        assert_approx_eq!((-3.1f32).powi(2), 9.61);
-        assert_approx_eq!(5.9f32.powi(-2), 0.028727);
-        assert_eq!(8.3f32.powi(0), 1.0);
-        assert!(nan.powi(2).is_nan());
-        assert_eq!(inf.powi(3), inf);
-        assert_eq!(neg_inf.powi(2), inf);
-    }
-
-    #[test]
-    fn test_powf() {
-        let nan: f32 = f32::NAN;
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        assert_eq!(1.0f32.powf(1.0), 1.0);
-        assert_approx_eq!(3.4f32.powf(4.5), 246.408218);
-        assert_approx_eq!(2.7f32.powf(-3.2), 0.041652);
-        assert_approx_eq!((-3.1f32).powf(2.0), 9.61);
-        assert_approx_eq!(5.9f32.powf(-2.0), 0.028727);
-        assert_eq!(8.3f32.powf(0.0), 1.0);
-        assert!(nan.powf(2.0).is_nan());
-        assert_eq!(inf.powf(2.0), inf);
-        assert_eq!(neg_inf.powf(3.0), neg_inf);
-    }
-
-    #[test]
-    fn test_sqrt_domain() {
-        assert!(f32::NAN.sqrt().is_nan());
-        assert!(f32::NEG_INFINITY.sqrt().is_nan());
-        assert!((-1.0f32).sqrt().is_nan());
-        assert_eq!((-0.0f32).sqrt(), -0.0);
-        assert_eq!(0.0f32.sqrt(), 0.0);
-        assert_eq!(1.0f32.sqrt(), 1.0);
-        assert_eq!(f32::INFINITY.sqrt(), f32::INFINITY);
-    }
-
-    #[test]
-    fn test_exp() {
-        assert_eq!(1.0, 0.0f32.exp());
-        assert_approx_eq!(2.718282, 1.0f32.exp());
-        assert_approx_eq!(148.413162, 5.0f32.exp());
-
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        let nan: f32 = f32::NAN;
-        assert_eq!(inf, inf.exp());
-        assert_eq!(0.0, neg_inf.exp());
-        assert!(nan.exp().is_nan());
-    }
-
-    #[test]
-    fn test_exp2() {
-        assert_eq!(32.0, 5.0f32.exp2());
-        assert_eq!(1.0, 0.0f32.exp2());
-
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        let nan: f32 = f32::NAN;
-        assert_eq!(inf, inf.exp2());
-        assert_eq!(0.0, neg_inf.exp2());
-        assert!(nan.exp2().is_nan());
-    }
-
-    #[test]
-    fn test_ln() {
-        let nan: f32 = f32::NAN;
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        assert_approx_eq!(1.0f32.exp().ln(), 1.0);
-        assert!(nan.ln().is_nan());
-        assert_eq!(inf.ln(), inf);
-        assert!(neg_inf.ln().is_nan());
-        assert!((-2.3f32).ln().is_nan());
-        assert_eq!((-0.0f32).ln(), neg_inf);
-        assert_eq!(0.0f32.ln(), neg_inf);
-        assert_approx_eq!(4.0f32.ln(), 1.386294);
-    }
-
-    #[test]
-    fn test_log() {
-        let nan: f32 = f32::NAN;
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        assert_eq!(10.0f32.log(10.0), 1.0);
-        assert_approx_eq!(2.3f32.log(3.5), 0.664858);
-        assert_eq!(1.0f32.exp().log(1.0f32.exp()), 1.0);
-        assert!(1.0f32.log(1.0).is_nan());
-        assert!(1.0f32.log(-13.9).is_nan());
-        assert!(nan.log(2.3).is_nan());
-        assert_eq!(inf.log(10.0), inf);
-        assert!(neg_inf.log(8.8).is_nan());
-        assert!((-2.3f32).log(0.1).is_nan());
-        assert_eq!((-0.0f32).log(2.0), neg_inf);
-        assert_eq!(0.0f32.log(7.0), neg_inf);
-    }
-
-    #[test]
-    fn test_log2() {
-        let nan: f32 = f32::NAN;
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        assert_approx_eq!(10.0f32.log2(), 3.321928);
-        assert_approx_eq!(2.3f32.log2(), 1.201634);
-        assert_approx_eq!(1.0f32.exp().log2(), 1.442695);
-        assert!(nan.log2().is_nan());
-        assert_eq!(inf.log2(), inf);
-        assert!(neg_inf.log2().is_nan());
-        assert!((-2.3f32).log2().is_nan());
-        assert_eq!((-0.0f32).log2(), neg_inf);
-        assert_eq!(0.0f32.log2(), neg_inf);
-    }
-
-    #[test]
-    fn test_log10() {
-        let nan: f32 = f32::NAN;
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        assert_eq!(10.0f32.log10(), 1.0);
-        assert_approx_eq!(2.3f32.log10(), 0.361728);
-        assert_approx_eq!(1.0f32.exp().log10(), 0.434294);
-        assert_eq!(1.0f32.log10(), 0.0);
-        assert!(nan.log10().is_nan());
-        assert_eq!(inf.log10(), inf);
-        assert!(neg_inf.log10().is_nan());
-        assert!((-2.3f32).log10().is_nan());
-        assert_eq!((-0.0f32).log10(), neg_inf);
-        assert_eq!(0.0f32.log10(), neg_inf);
-    }
-
-    #[test]
-    fn test_to_degrees() {
-        let pi: f32 = consts::PI;
-        let nan: f32 = f32::NAN;
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        assert_eq!(0.0f32.to_degrees(), 0.0);
-        assert_approx_eq!((-5.8f32).to_degrees(), -332.315521);
-        assert_eq!(pi.to_degrees(), 180.0);
-        assert!(nan.to_degrees().is_nan());
-        assert_eq!(inf.to_degrees(), inf);
-        assert_eq!(neg_inf.to_degrees(), neg_inf);
-        assert_eq!(1_f32.to_degrees(), 57.2957795130823208767981548141051703);
-    }
-
-    #[test]
-    fn test_to_radians() {
-        let pi: f32 = consts::PI;
-        let nan: f32 = f32::NAN;
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        assert_eq!(0.0f32.to_radians(), 0.0);
-        assert_approx_eq!(154.6f32.to_radians(), 2.698279);
-        assert_approx_eq!((-332.31f32).to_radians(), -5.799903);
-        assert_eq!(180.0f32.to_radians(), pi);
-        assert!(nan.to_radians().is_nan());
-        assert_eq!(inf.to_radians(), inf);
-        assert_eq!(neg_inf.to_radians(), neg_inf);
-    }
-
-    #[test]
-    fn test_asinh() {
-        assert_eq!(0.0f32.asinh(), 0.0f32);
-        assert_eq!((-0.0f32).asinh(), -0.0f32);
-
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        let nan: f32 = f32::NAN;
-        assert_eq!(inf.asinh(), inf);
-        assert_eq!(neg_inf.asinh(), neg_inf);
-        assert!(nan.asinh().is_nan());
-        assert!((-0.0f32).asinh().is_sign_negative()); // issue 63271
-        assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32);
-        assert_approx_eq!((-2.0f32).asinh(), -1.443635475178810342493276740273105f32);
-        // regression test for the catastrophic cancellation fixed in 72486
-        assert_approx_eq!((-3000.0f32).asinh(), -8.699514775987968673236893537700647f32);
-    }
-
-    #[test]
-    fn test_acosh() {
-        assert_eq!(1.0f32.acosh(), 0.0f32);
-        assert!(0.999f32.acosh().is_nan());
-
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        let nan: f32 = f32::NAN;
-        assert_eq!(inf.acosh(), inf);
-        assert!(neg_inf.acosh().is_nan());
-        assert!(nan.acosh().is_nan());
-        assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32);
-        assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32);
-    }
-
-    #[test]
-    fn test_atanh() {
-        assert_eq!(0.0f32.atanh(), 0.0f32);
-        assert_eq!((-0.0f32).atanh(), -0.0f32);
-
-        let inf32: f32 = f32::INFINITY;
-        let neg_inf32: f32 = f32::NEG_INFINITY;
-        assert_eq!(1.0f32.atanh(), inf32);
-        assert_eq!((-1.0f32).atanh(), neg_inf32);
-
-        assert!(2f64.atanh().atanh().is_nan());
-        assert!((-2f64).atanh().atanh().is_nan());
-
-        let inf64: f32 = f32::INFINITY;
-        let neg_inf64: f32 = f32::NEG_INFINITY;
-        let nan32: f32 = f32::NAN;
-        assert!(inf64.atanh().is_nan());
-        assert!(neg_inf64.atanh().is_nan());
-        assert!(nan32.atanh().is_nan());
-
-        assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32);
-        assert_approx_eq!((-0.5f32).atanh(), -0.54930614433405484569762261846126285f32);
-    }
-
-    #[test]
-    fn test_real_consts() {
-        use super::consts;
-
-        let pi: f32 = consts::PI;
-        let frac_pi_2: f32 = consts::FRAC_PI_2;
-        let frac_pi_3: f32 = consts::FRAC_PI_3;
-        let frac_pi_4: f32 = consts::FRAC_PI_4;
-        let frac_pi_6: f32 = consts::FRAC_PI_6;
-        let frac_pi_8: f32 = consts::FRAC_PI_8;
-        let frac_1_pi: f32 = consts::FRAC_1_PI;
-        let frac_2_pi: f32 = consts::FRAC_2_PI;
-        let frac_2_sqrtpi: f32 = consts::FRAC_2_SQRT_PI;
-        let sqrt2: f32 = consts::SQRT_2;
-        let frac_1_sqrt2: f32 = consts::FRAC_1_SQRT_2;
-        let e: f32 = consts::E;
-        let log2_e: f32 = consts::LOG2_E;
-        let log10_e: f32 = consts::LOG10_E;
-        let ln_2: f32 = consts::LN_2;
-        let ln_10: f32 = consts::LN_10;
-
-        assert_approx_eq!(frac_pi_2, pi / 2f32);
-        assert_approx_eq!(frac_pi_3, pi / 3f32);
-        assert_approx_eq!(frac_pi_4, pi / 4f32);
-        assert_approx_eq!(frac_pi_6, pi / 6f32);
-        assert_approx_eq!(frac_pi_8, pi / 8f32);
-        assert_approx_eq!(frac_1_pi, 1f32 / pi);
-        assert_approx_eq!(frac_2_pi, 2f32 / pi);
-        assert_approx_eq!(frac_2_sqrtpi, 2f32 / pi.sqrt());
-        assert_approx_eq!(sqrt2, 2f32.sqrt());
-        assert_approx_eq!(frac_1_sqrt2, 1f32 / 2f32.sqrt());
-        assert_approx_eq!(log2_e, e.log2());
-        assert_approx_eq!(log10_e, e.log10());
-        assert_approx_eq!(ln_2, 2f32.ln());
-        assert_approx_eq!(ln_10, 10f32.ln());
-    }
-
-    #[test]
-    fn test_float_bits_conv() {
-        assert_eq!((1f32).to_bits(), 0x3f800000);
-        assert_eq!((12.5f32).to_bits(), 0x41480000);
-        assert_eq!((1337f32).to_bits(), 0x44a72000);
-        assert_eq!((-14.25f32).to_bits(), 0xc1640000);
-        assert_approx_eq!(f32::from_bits(0x3f800000), 1.0);
-        assert_approx_eq!(f32::from_bits(0x41480000), 12.5);
-        assert_approx_eq!(f32::from_bits(0x44a72000), 1337.0);
-        assert_approx_eq!(f32::from_bits(0xc1640000), -14.25);
-
-        // Check that NaNs roundtrip their bits regardless of signaling-ness
-        // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
-        let masked_nan1 = f32::NAN.to_bits() ^ 0x002A_AAAA;
-        let masked_nan2 = f32::NAN.to_bits() ^ 0x0055_5555;
-        assert!(f32::from_bits(masked_nan1).is_nan());
-        assert!(f32::from_bits(masked_nan2).is_nan());
-
-        assert_eq!(f32::from_bits(masked_nan1).to_bits(), masked_nan1);
-        assert_eq!(f32::from_bits(masked_nan2).to_bits(), masked_nan2);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_clamp_min_greater_than_max() {
-        let _ = 1.0f32.clamp(3.0, 1.0);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_clamp_min_is_nan() {
-        let _ = 1.0f32.clamp(f32::NAN, 1.0);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_clamp_max_is_nan() {
-        let _ = 1.0f32.clamp(3.0, f32::NAN);
-    }
-
-    #[test]
-    fn test_total_cmp() {
-        use core::cmp::Ordering;
-
-        fn quiet_bit_mask() -> u32 {
-            1 << (f32::MANTISSA_DIGITS - 2)
-        }
-
-        fn min_subnorm() -> f32 {
-            f32::MIN_POSITIVE / f32::powf(2.0, f32::MANTISSA_DIGITS as f32 - 1.0)
-        }
-
-        fn max_subnorm() -> f32 {
-            f32::MIN_POSITIVE - min_subnorm()
-        }
-
-        fn q_nan() -> f32 {
-            f32::from_bits(f32::NAN.to_bits() | quiet_bit_mask())
-        }
-
-        fn s_nan() -> f32 {
-            f32::from_bits((f32::NAN.to_bits() & !quiet_bit_mask()) + 42)
-        }
-
-        assert_eq!(Ordering::Equal, (-q_nan()).total_cmp(&-q_nan()));
-        assert_eq!(Ordering::Equal, (-s_nan()).total_cmp(&-s_nan()));
-        assert_eq!(Ordering::Equal, (-f32::INFINITY).total_cmp(&-f32::INFINITY));
-        assert_eq!(Ordering::Equal, (-f32::MAX).total_cmp(&-f32::MAX));
-        assert_eq!(Ordering::Equal, (-2.5_f32).total_cmp(&-2.5));
-        assert_eq!(Ordering::Equal, (-1.0_f32).total_cmp(&-1.0));
-        assert_eq!(Ordering::Equal, (-1.5_f32).total_cmp(&-1.5));
-        assert_eq!(Ordering::Equal, (-0.5_f32).total_cmp(&-0.5));
-        assert_eq!(Ordering::Equal, (-f32::MIN_POSITIVE).total_cmp(&-f32::MIN_POSITIVE));
-        assert_eq!(Ordering::Equal, (-max_subnorm()).total_cmp(&-max_subnorm()));
-        assert_eq!(Ordering::Equal, (-min_subnorm()).total_cmp(&-min_subnorm()));
-        assert_eq!(Ordering::Equal, (-0.0_f32).total_cmp(&-0.0));
-        assert_eq!(Ordering::Equal, 0.0_f32.total_cmp(&0.0));
-        assert_eq!(Ordering::Equal, min_subnorm().total_cmp(&min_subnorm()));
-        assert_eq!(Ordering::Equal, max_subnorm().total_cmp(&max_subnorm()));
-        assert_eq!(Ordering::Equal, f32::MIN_POSITIVE.total_cmp(&f32::MIN_POSITIVE));
-        assert_eq!(Ordering::Equal, 0.5_f32.total_cmp(&0.5));
-        assert_eq!(Ordering::Equal, 1.0_f32.total_cmp(&1.0));
-        assert_eq!(Ordering::Equal, 1.5_f32.total_cmp(&1.5));
-        assert_eq!(Ordering::Equal, 2.5_f32.total_cmp(&2.5));
-        assert_eq!(Ordering::Equal, f32::MAX.total_cmp(&f32::MAX));
-        assert_eq!(Ordering::Equal, f32::INFINITY.total_cmp(&f32::INFINITY));
-        assert_eq!(Ordering::Equal, s_nan().total_cmp(&s_nan()));
-        assert_eq!(Ordering::Equal, q_nan().total_cmp(&q_nan()));
-
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-s_nan()));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f32::INFINITY));
-        assert_eq!(Ordering::Less, (-f32::INFINITY).total_cmp(&-f32::MAX));
-        assert_eq!(Ordering::Less, (-f32::MAX).total_cmp(&-2.5));
-        assert_eq!(Ordering::Less, (-2.5_f32).total_cmp(&-1.5));
-        assert_eq!(Ordering::Less, (-1.5_f32).total_cmp(&-1.0));
-        assert_eq!(Ordering::Less, (-1.0_f32).total_cmp(&-0.5));
-        assert_eq!(Ordering::Less, (-0.5_f32).total_cmp(&-f32::MIN_POSITIVE));
-        assert_eq!(Ordering::Less, (-f32::MIN_POSITIVE).total_cmp(&-max_subnorm()));
-        assert_eq!(Ordering::Less, (-max_subnorm()).total_cmp(&-min_subnorm()));
-        assert_eq!(Ordering::Less, (-min_subnorm()).total_cmp(&-0.0));
-        assert_eq!(Ordering::Less, (-0.0_f32).total_cmp(&0.0));
-        assert_eq!(Ordering::Less, 0.0_f32.total_cmp(&min_subnorm()));
-        assert_eq!(Ordering::Less, min_subnorm().total_cmp(&max_subnorm()));
-        assert_eq!(Ordering::Less, max_subnorm().total_cmp(&f32::MIN_POSITIVE));
-        assert_eq!(Ordering::Less, f32::MIN_POSITIVE.total_cmp(&0.5));
-        assert_eq!(Ordering::Less, 0.5_f32.total_cmp(&1.0));
-        assert_eq!(Ordering::Less, 1.0_f32.total_cmp(&1.5));
-        assert_eq!(Ordering::Less, 1.5_f32.total_cmp(&2.5));
-        assert_eq!(Ordering::Less, 2.5_f32.total_cmp(&f32::MAX));
-        assert_eq!(Ordering::Less, f32::MAX.total_cmp(&f32::INFINITY));
-        assert_eq!(Ordering::Less, f32::INFINITY.total_cmp(&s_nan()));
-        assert_eq!(Ordering::Less, s_nan().total_cmp(&q_nan()));
-
-        assert_eq!(Ordering::Greater, (-s_nan()).total_cmp(&-q_nan()));
-        assert_eq!(Ordering::Greater, (-f32::INFINITY).total_cmp(&-s_nan()));
-        assert_eq!(Ordering::Greater, (-f32::MAX).total_cmp(&-f32::INFINITY));
-        assert_eq!(Ordering::Greater, (-2.5_f32).total_cmp(&-f32::MAX));
-        assert_eq!(Ordering::Greater, (-1.5_f32).total_cmp(&-2.5));
-        assert_eq!(Ordering::Greater, (-1.0_f32).total_cmp(&-1.5));
-        assert_eq!(Ordering::Greater, (-0.5_f32).total_cmp(&-1.0));
-        assert_eq!(Ordering::Greater, (-f32::MIN_POSITIVE).total_cmp(&-0.5));
-        assert_eq!(Ordering::Greater, (-max_subnorm()).total_cmp(&-f32::MIN_POSITIVE));
-        assert_eq!(Ordering::Greater, (-min_subnorm()).total_cmp(&-max_subnorm()));
-        assert_eq!(Ordering::Greater, (-0.0_f32).total_cmp(&-min_subnorm()));
-        assert_eq!(Ordering::Greater, 0.0_f32.total_cmp(&-0.0));
-        assert_eq!(Ordering::Greater, min_subnorm().total_cmp(&0.0));
-        assert_eq!(Ordering::Greater, max_subnorm().total_cmp(&min_subnorm()));
-        assert_eq!(Ordering::Greater, f32::MIN_POSITIVE.total_cmp(&max_subnorm()));
-        assert_eq!(Ordering::Greater, 0.5_f32.total_cmp(&f32::MIN_POSITIVE));
-        assert_eq!(Ordering::Greater, 1.0_f32.total_cmp(&0.5));
-        assert_eq!(Ordering::Greater, 1.5_f32.total_cmp(&1.0));
-        assert_eq!(Ordering::Greater, 2.5_f32.total_cmp(&1.5));
-        assert_eq!(Ordering::Greater, f32::MAX.total_cmp(&2.5));
-        assert_eq!(Ordering::Greater, f32::INFINITY.total_cmp(&f32::MAX));
-        assert_eq!(Ordering::Greater, s_nan().total_cmp(&f32::INFINITY));
-        assert_eq!(Ordering::Greater, q_nan().total_cmp(&s_nan()));
-
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-s_nan()));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f32::INFINITY));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f32::MAX));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-2.5));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-1.5));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-1.0));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-0.5));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f32::MIN_POSITIVE));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-max_subnorm()));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-min_subnorm()));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-0.0));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&0.0));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&min_subnorm()));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&max_subnorm()));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f32::MIN_POSITIVE));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&0.5));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&1.0));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&1.5));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&2.5));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f32::MAX));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f32::INFINITY));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&s_nan()));
-
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f32::INFINITY));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f32::MAX));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-2.5));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-1.5));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-1.0));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-0.5));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f32::MIN_POSITIVE));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-max_subnorm()));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-min_subnorm()));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-0.0));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&0.0));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&min_subnorm()));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&max_subnorm()));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f32::MIN_POSITIVE));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&0.5));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&1.0));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&1.5));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&2.5));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f32::MAX));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f32::INFINITY));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&s_nan()));
-    }
-}
diff --git a/library/std/src/f32/tests.rs b/library/std/src/f32/tests.rs
new file mode 100644
index 00000000000..0d4b865f339
--- /dev/null
+++ b/library/std/src/f32/tests.rs
@@ -0,0 +1,759 @@
+use crate::f32::consts;
+use crate::num::FpCategory as Fp;
+use crate::num::*;
+
+#[test]
+fn test_num_f32() {
+    test_num(10f32, 2f32);
+}
+
+#[test]
+fn test_min_nan() {
+    assert_eq!(f32::NAN.min(2.0), 2.0);
+    assert_eq!(2.0f32.min(f32::NAN), 2.0);
+}
+
+#[test]
+fn test_max_nan() {
+    assert_eq!(f32::NAN.max(2.0), 2.0);
+    assert_eq!(2.0f32.max(f32::NAN), 2.0);
+}
+
+#[test]
+fn test_nan() {
+    let nan: f32 = f32::NAN;
+    assert!(nan.is_nan());
+    assert!(!nan.is_infinite());
+    assert!(!nan.is_finite());
+    assert!(!nan.is_normal());
+    assert!(nan.is_sign_positive());
+    assert!(!nan.is_sign_negative());
+    assert_eq!(Fp::Nan, nan.classify());
+}
+
+#[test]
+fn test_infinity() {
+    let inf: f32 = f32::INFINITY;
+    assert!(inf.is_infinite());
+    assert!(!inf.is_finite());
+    assert!(inf.is_sign_positive());
+    assert!(!inf.is_sign_negative());
+    assert!(!inf.is_nan());
+    assert!(!inf.is_normal());
+    assert_eq!(Fp::Infinite, inf.classify());
+}
+
+#[test]
+fn test_neg_infinity() {
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    assert!(neg_inf.is_infinite());
+    assert!(!neg_inf.is_finite());
+    assert!(!neg_inf.is_sign_positive());
+    assert!(neg_inf.is_sign_negative());
+    assert!(!neg_inf.is_nan());
+    assert!(!neg_inf.is_normal());
+    assert_eq!(Fp::Infinite, neg_inf.classify());
+}
+
+#[test]
+fn test_zero() {
+    let zero: f32 = 0.0f32;
+    assert_eq!(0.0, zero);
+    assert!(!zero.is_infinite());
+    assert!(zero.is_finite());
+    assert!(zero.is_sign_positive());
+    assert!(!zero.is_sign_negative());
+    assert!(!zero.is_nan());
+    assert!(!zero.is_normal());
+    assert_eq!(Fp::Zero, zero.classify());
+}
+
+#[test]
+fn test_neg_zero() {
+    let neg_zero: f32 = -0.0;
+    assert_eq!(0.0, neg_zero);
+    assert!(!neg_zero.is_infinite());
+    assert!(neg_zero.is_finite());
+    assert!(!neg_zero.is_sign_positive());
+    assert!(neg_zero.is_sign_negative());
+    assert!(!neg_zero.is_nan());
+    assert!(!neg_zero.is_normal());
+    assert_eq!(Fp::Zero, neg_zero.classify());
+}
+
+#[test]
+fn test_one() {
+    let one: f32 = 1.0f32;
+    assert_eq!(1.0, one);
+    assert!(!one.is_infinite());
+    assert!(one.is_finite());
+    assert!(one.is_sign_positive());
+    assert!(!one.is_sign_negative());
+    assert!(!one.is_nan());
+    assert!(one.is_normal());
+    assert_eq!(Fp::Normal, one.classify());
+}
+
+#[test]
+fn test_is_nan() {
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    assert!(nan.is_nan());
+    assert!(!0.0f32.is_nan());
+    assert!(!5.3f32.is_nan());
+    assert!(!(-10.732f32).is_nan());
+    assert!(!inf.is_nan());
+    assert!(!neg_inf.is_nan());
+}
+
+#[test]
+fn test_is_infinite() {
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    assert!(!nan.is_infinite());
+    assert!(inf.is_infinite());
+    assert!(neg_inf.is_infinite());
+    assert!(!0.0f32.is_infinite());
+    assert!(!42.8f32.is_infinite());
+    assert!(!(-109.2f32).is_infinite());
+}
+
+#[test]
+fn test_is_finite() {
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    assert!(!nan.is_finite());
+    assert!(!inf.is_finite());
+    assert!(!neg_inf.is_finite());
+    assert!(0.0f32.is_finite());
+    assert!(42.8f32.is_finite());
+    assert!((-109.2f32).is_finite());
+}
+
+#[test]
+fn test_is_normal() {
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    let zero: f32 = 0.0f32;
+    let neg_zero: f32 = -0.0;
+    assert!(!nan.is_normal());
+    assert!(!inf.is_normal());
+    assert!(!neg_inf.is_normal());
+    assert!(!zero.is_normal());
+    assert!(!neg_zero.is_normal());
+    assert!(1f32.is_normal());
+    assert!(1e-37f32.is_normal());
+    assert!(!1e-38f32.is_normal());
+}
+
+#[test]
+fn test_classify() {
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    let zero: f32 = 0.0f32;
+    let neg_zero: f32 = -0.0;
+    assert_eq!(nan.classify(), Fp::Nan);
+    assert_eq!(inf.classify(), Fp::Infinite);
+    assert_eq!(neg_inf.classify(), Fp::Infinite);
+    assert_eq!(zero.classify(), Fp::Zero);
+    assert_eq!(neg_zero.classify(), Fp::Zero);
+    assert_eq!(1f32.classify(), Fp::Normal);
+    assert_eq!(1e-37f32.classify(), Fp::Normal);
+    assert_eq!(1e-38f32.classify(), Fp::Subnormal);
+}
+
+#[test]
+fn test_floor() {
+    assert_approx_eq!(1.0f32.floor(), 1.0f32);
+    assert_approx_eq!(1.3f32.floor(), 1.0f32);
+    assert_approx_eq!(1.5f32.floor(), 1.0f32);
+    assert_approx_eq!(1.7f32.floor(), 1.0f32);
+    assert_approx_eq!(0.0f32.floor(), 0.0f32);
+    assert_approx_eq!((-0.0f32).floor(), -0.0f32);
+    assert_approx_eq!((-1.0f32).floor(), -1.0f32);
+    assert_approx_eq!((-1.3f32).floor(), -2.0f32);
+    assert_approx_eq!((-1.5f32).floor(), -2.0f32);
+    assert_approx_eq!((-1.7f32).floor(), -2.0f32);
+}
+
+#[test]
+fn test_ceil() {
+    assert_approx_eq!(1.0f32.ceil(), 1.0f32);
+    assert_approx_eq!(1.3f32.ceil(), 2.0f32);
+    assert_approx_eq!(1.5f32.ceil(), 2.0f32);
+    assert_approx_eq!(1.7f32.ceil(), 2.0f32);
+    assert_approx_eq!(0.0f32.ceil(), 0.0f32);
+    assert_approx_eq!((-0.0f32).ceil(), -0.0f32);
+    assert_approx_eq!((-1.0f32).ceil(), -1.0f32);
+    assert_approx_eq!((-1.3f32).ceil(), -1.0f32);
+    assert_approx_eq!((-1.5f32).ceil(), -1.0f32);
+    assert_approx_eq!((-1.7f32).ceil(), -1.0f32);
+}
+
+#[test]
+fn test_round() {
+    assert_approx_eq!(1.0f32.round(), 1.0f32);
+    assert_approx_eq!(1.3f32.round(), 1.0f32);
+    assert_approx_eq!(1.5f32.round(), 2.0f32);
+    assert_approx_eq!(1.7f32.round(), 2.0f32);
+    assert_approx_eq!(0.0f32.round(), 0.0f32);
+    assert_approx_eq!((-0.0f32).round(), -0.0f32);
+    assert_approx_eq!((-1.0f32).round(), -1.0f32);
+    assert_approx_eq!((-1.3f32).round(), -1.0f32);
+    assert_approx_eq!((-1.5f32).round(), -2.0f32);
+    assert_approx_eq!((-1.7f32).round(), -2.0f32);
+}
+
+#[test]
+fn test_trunc() {
+    assert_approx_eq!(1.0f32.trunc(), 1.0f32);
+    assert_approx_eq!(1.3f32.trunc(), 1.0f32);
+    assert_approx_eq!(1.5f32.trunc(), 1.0f32);
+    assert_approx_eq!(1.7f32.trunc(), 1.0f32);
+    assert_approx_eq!(0.0f32.trunc(), 0.0f32);
+    assert_approx_eq!((-0.0f32).trunc(), -0.0f32);
+    assert_approx_eq!((-1.0f32).trunc(), -1.0f32);
+    assert_approx_eq!((-1.3f32).trunc(), -1.0f32);
+    assert_approx_eq!((-1.5f32).trunc(), -1.0f32);
+    assert_approx_eq!((-1.7f32).trunc(), -1.0f32);
+}
+
+#[test]
+fn test_fract() {
+    assert_approx_eq!(1.0f32.fract(), 0.0f32);
+    assert_approx_eq!(1.3f32.fract(), 0.3f32);
+    assert_approx_eq!(1.5f32.fract(), 0.5f32);
+    assert_approx_eq!(1.7f32.fract(), 0.7f32);
+    assert_approx_eq!(0.0f32.fract(), 0.0f32);
+    assert_approx_eq!((-0.0f32).fract(), -0.0f32);
+    assert_approx_eq!((-1.0f32).fract(), -0.0f32);
+    assert_approx_eq!((-1.3f32).fract(), -0.3f32);
+    assert_approx_eq!((-1.5f32).fract(), -0.5f32);
+    assert_approx_eq!((-1.7f32).fract(), -0.7f32);
+}
+
+#[test]
+fn test_abs() {
+    assert_eq!(f32::INFINITY.abs(), f32::INFINITY);
+    assert_eq!(1f32.abs(), 1f32);
+    assert_eq!(0f32.abs(), 0f32);
+    assert_eq!((-0f32).abs(), 0f32);
+    assert_eq!((-1f32).abs(), 1f32);
+    assert_eq!(f32::NEG_INFINITY.abs(), f32::INFINITY);
+    assert_eq!((1f32 / f32::NEG_INFINITY).abs(), 0f32);
+    assert!(f32::NAN.abs().is_nan());
+}
+
+#[test]
+fn test_signum() {
+    assert_eq!(f32::INFINITY.signum(), 1f32);
+    assert_eq!(1f32.signum(), 1f32);
+    assert_eq!(0f32.signum(), 1f32);
+    assert_eq!((-0f32).signum(), -1f32);
+    assert_eq!((-1f32).signum(), -1f32);
+    assert_eq!(f32::NEG_INFINITY.signum(), -1f32);
+    assert_eq!((1f32 / f32::NEG_INFINITY).signum(), -1f32);
+    assert!(f32::NAN.signum().is_nan());
+}
+
+#[test]
+fn test_is_sign_positive() {
+    assert!(f32::INFINITY.is_sign_positive());
+    assert!(1f32.is_sign_positive());
+    assert!(0f32.is_sign_positive());
+    assert!(!(-0f32).is_sign_positive());
+    assert!(!(-1f32).is_sign_positive());
+    assert!(!f32::NEG_INFINITY.is_sign_positive());
+    assert!(!(1f32 / f32::NEG_INFINITY).is_sign_positive());
+    assert!(f32::NAN.is_sign_positive());
+    assert!(!(-f32::NAN).is_sign_positive());
+}
+
+#[test]
+fn test_is_sign_negative() {
+    assert!(!f32::INFINITY.is_sign_negative());
+    assert!(!1f32.is_sign_negative());
+    assert!(!0f32.is_sign_negative());
+    assert!((-0f32).is_sign_negative());
+    assert!((-1f32).is_sign_negative());
+    assert!(f32::NEG_INFINITY.is_sign_negative());
+    assert!((1f32 / f32::NEG_INFINITY).is_sign_negative());
+    assert!(!f32::NAN.is_sign_negative());
+    assert!((-f32::NAN).is_sign_negative());
+}
+
+#[test]
+fn test_mul_add() {
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    assert_approx_eq!(12.3f32.mul_add(4.5, 6.7), 62.05);
+    assert_approx_eq!((-12.3f32).mul_add(-4.5, -6.7), 48.65);
+    assert_approx_eq!(0.0f32.mul_add(8.9, 1.2), 1.2);
+    assert_approx_eq!(3.4f32.mul_add(-0.0, 5.6), 5.6);
+    assert!(nan.mul_add(7.8, 9.0).is_nan());
+    assert_eq!(inf.mul_add(7.8, 9.0), inf);
+    assert_eq!(neg_inf.mul_add(7.8, 9.0), neg_inf);
+    assert_eq!(8.9f32.mul_add(inf, 3.2), inf);
+    assert_eq!((-3.2f32).mul_add(2.4, neg_inf), neg_inf);
+}
+
+#[test]
+fn test_recip() {
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    assert_eq!(1.0f32.recip(), 1.0);
+    assert_eq!(2.0f32.recip(), 0.5);
+    assert_eq!((-0.4f32).recip(), -2.5);
+    assert_eq!(0.0f32.recip(), inf);
+    assert!(nan.recip().is_nan());
+    assert_eq!(inf.recip(), 0.0);
+    assert_eq!(neg_inf.recip(), 0.0);
+}
+
+#[test]
+fn test_powi() {
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    assert_eq!(1.0f32.powi(1), 1.0);
+    assert_approx_eq!((-3.1f32).powi(2), 9.61);
+    assert_approx_eq!(5.9f32.powi(-2), 0.028727);
+    assert_eq!(8.3f32.powi(0), 1.0);
+    assert!(nan.powi(2).is_nan());
+    assert_eq!(inf.powi(3), inf);
+    assert_eq!(neg_inf.powi(2), inf);
+}
+
+#[test]
+fn test_powf() {
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    assert_eq!(1.0f32.powf(1.0), 1.0);
+    assert_approx_eq!(3.4f32.powf(4.5), 246.408218);
+    assert_approx_eq!(2.7f32.powf(-3.2), 0.041652);
+    assert_approx_eq!((-3.1f32).powf(2.0), 9.61);
+    assert_approx_eq!(5.9f32.powf(-2.0), 0.028727);
+    assert_eq!(8.3f32.powf(0.0), 1.0);
+    assert!(nan.powf(2.0).is_nan());
+    assert_eq!(inf.powf(2.0), inf);
+    assert_eq!(neg_inf.powf(3.0), neg_inf);
+}
+
+#[test]
+fn test_sqrt_domain() {
+    assert!(f32::NAN.sqrt().is_nan());
+    assert!(f32::NEG_INFINITY.sqrt().is_nan());
+    assert!((-1.0f32).sqrt().is_nan());
+    assert_eq!((-0.0f32).sqrt(), -0.0);
+    assert_eq!(0.0f32.sqrt(), 0.0);
+    assert_eq!(1.0f32.sqrt(), 1.0);
+    assert_eq!(f32::INFINITY.sqrt(), f32::INFINITY);
+}
+
+#[test]
+fn test_exp() {
+    assert_eq!(1.0, 0.0f32.exp());
+    assert_approx_eq!(2.718282, 1.0f32.exp());
+    assert_approx_eq!(148.413162, 5.0f32.exp());
+
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    let nan: f32 = f32::NAN;
+    assert_eq!(inf, inf.exp());
+    assert_eq!(0.0, neg_inf.exp());
+    assert!(nan.exp().is_nan());
+}
+
+#[test]
+fn test_exp2() {
+    assert_eq!(32.0, 5.0f32.exp2());
+    assert_eq!(1.0, 0.0f32.exp2());
+
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    let nan: f32 = f32::NAN;
+    assert_eq!(inf, inf.exp2());
+    assert_eq!(0.0, neg_inf.exp2());
+    assert!(nan.exp2().is_nan());
+}
+
+#[test]
+fn test_ln() {
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    assert_approx_eq!(1.0f32.exp().ln(), 1.0);
+    assert!(nan.ln().is_nan());
+    assert_eq!(inf.ln(), inf);
+    assert!(neg_inf.ln().is_nan());
+    assert!((-2.3f32).ln().is_nan());
+    assert_eq!((-0.0f32).ln(), neg_inf);
+    assert_eq!(0.0f32.ln(), neg_inf);
+    assert_approx_eq!(4.0f32.ln(), 1.386294);
+}
+
+#[test]
+fn test_log() {
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    assert_eq!(10.0f32.log(10.0), 1.0);
+    assert_approx_eq!(2.3f32.log(3.5), 0.664858);
+    assert_eq!(1.0f32.exp().log(1.0f32.exp()), 1.0);
+    assert!(1.0f32.log(1.0).is_nan());
+    assert!(1.0f32.log(-13.9).is_nan());
+    assert!(nan.log(2.3).is_nan());
+    assert_eq!(inf.log(10.0), inf);
+    assert!(neg_inf.log(8.8).is_nan());
+    assert!((-2.3f32).log(0.1).is_nan());
+    assert_eq!((-0.0f32).log(2.0), neg_inf);
+    assert_eq!(0.0f32.log(7.0), neg_inf);
+}
+
+#[test]
+fn test_log2() {
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    assert_approx_eq!(10.0f32.log2(), 3.321928);
+    assert_approx_eq!(2.3f32.log2(), 1.201634);
+    assert_approx_eq!(1.0f32.exp().log2(), 1.442695);
+    assert!(nan.log2().is_nan());
+    assert_eq!(inf.log2(), inf);
+    assert!(neg_inf.log2().is_nan());
+    assert!((-2.3f32).log2().is_nan());
+    assert_eq!((-0.0f32).log2(), neg_inf);
+    assert_eq!(0.0f32.log2(), neg_inf);
+}
+
+#[test]
+fn test_log10() {
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    assert_eq!(10.0f32.log10(), 1.0);
+    assert_approx_eq!(2.3f32.log10(), 0.361728);
+    assert_approx_eq!(1.0f32.exp().log10(), 0.434294);
+    assert_eq!(1.0f32.log10(), 0.0);
+    assert!(nan.log10().is_nan());
+    assert_eq!(inf.log10(), inf);
+    assert!(neg_inf.log10().is_nan());
+    assert!((-2.3f32).log10().is_nan());
+    assert_eq!((-0.0f32).log10(), neg_inf);
+    assert_eq!(0.0f32.log10(), neg_inf);
+}
+
+#[test]
+fn test_to_degrees() {
+    let pi: f32 = consts::PI;
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    assert_eq!(0.0f32.to_degrees(), 0.0);
+    assert_approx_eq!((-5.8f32).to_degrees(), -332.315521);
+    assert_eq!(pi.to_degrees(), 180.0);
+    assert!(nan.to_degrees().is_nan());
+    assert_eq!(inf.to_degrees(), inf);
+    assert_eq!(neg_inf.to_degrees(), neg_inf);
+    assert_eq!(1_f32.to_degrees(), 57.2957795130823208767981548141051703);
+}
+
+#[test]
+fn test_to_radians() {
+    let pi: f32 = consts::PI;
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    assert_eq!(0.0f32.to_radians(), 0.0);
+    assert_approx_eq!(154.6f32.to_radians(), 2.698279);
+    assert_approx_eq!((-332.31f32).to_radians(), -5.799903);
+    assert_eq!(180.0f32.to_radians(), pi);
+    assert!(nan.to_radians().is_nan());
+    assert_eq!(inf.to_radians(), inf);
+    assert_eq!(neg_inf.to_radians(), neg_inf);
+}
+
+#[test]
+fn test_asinh() {
+    assert_eq!(0.0f32.asinh(), 0.0f32);
+    assert_eq!((-0.0f32).asinh(), -0.0f32);
+
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    let nan: f32 = f32::NAN;
+    assert_eq!(inf.asinh(), inf);
+    assert_eq!(neg_inf.asinh(), neg_inf);
+    assert!(nan.asinh().is_nan());
+    assert!((-0.0f32).asinh().is_sign_negative()); // issue 63271
+    assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32);
+    assert_approx_eq!((-2.0f32).asinh(), -1.443635475178810342493276740273105f32);
+    // regression test for the catastrophic cancellation fixed in 72486
+    assert_approx_eq!((-3000.0f32).asinh(), -8.699514775987968673236893537700647f32);
+}
+
+#[test]
+fn test_acosh() {
+    assert_eq!(1.0f32.acosh(), 0.0f32);
+    assert!(0.999f32.acosh().is_nan());
+
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    let nan: f32 = f32::NAN;
+    assert_eq!(inf.acosh(), inf);
+    assert!(neg_inf.acosh().is_nan());
+    assert!(nan.acosh().is_nan());
+    assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32);
+    assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32);
+}
+
+#[test]
+fn test_atanh() {
+    assert_eq!(0.0f32.atanh(), 0.0f32);
+    assert_eq!((-0.0f32).atanh(), -0.0f32);
+
+    let inf32: f32 = f32::INFINITY;
+    let neg_inf32: f32 = f32::NEG_INFINITY;
+    assert_eq!(1.0f32.atanh(), inf32);
+    assert_eq!((-1.0f32).atanh(), neg_inf32);
+
+    assert!(2f64.atanh().atanh().is_nan());
+    assert!((-2f64).atanh().atanh().is_nan());
+
+    let inf64: f32 = f32::INFINITY;
+    let neg_inf64: f32 = f32::NEG_INFINITY;
+    let nan32: f32 = f32::NAN;
+    assert!(inf64.atanh().is_nan());
+    assert!(neg_inf64.atanh().is_nan());
+    assert!(nan32.atanh().is_nan());
+
+    assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32);
+    assert_approx_eq!((-0.5f32).atanh(), -0.54930614433405484569762261846126285f32);
+}
+
+#[test]
+fn test_real_consts() {
+    use super::consts;
+
+    let pi: f32 = consts::PI;
+    let frac_pi_2: f32 = consts::FRAC_PI_2;
+    let frac_pi_3: f32 = consts::FRAC_PI_3;
+    let frac_pi_4: f32 = consts::FRAC_PI_4;
+    let frac_pi_6: f32 = consts::FRAC_PI_6;
+    let frac_pi_8: f32 = consts::FRAC_PI_8;
+    let frac_1_pi: f32 = consts::FRAC_1_PI;
+    let frac_2_pi: f32 = consts::FRAC_2_PI;
+    let frac_2_sqrtpi: f32 = consts::FRAC_2_SQRT_PI;
+    let sqrt2: f32 = consts::SQRT_2;
+    let frac_1_sqrt2: f32 = consts::FRAC_1_SQRT_2;
+    let e: f32 = consts::E;
+    let log2_e: f32 = consts::LOG2_E;
+    let log10_e: f32 = consts::LOG10_E;
+    let ln_2: f32 = consts::LN_2;
+    let ln_10: f32 = consts::LN_10;
+
+    assert_approx_eq!(frac_pi_2, pi / 2f32);
+    assert_approx_eq!(frac_pi_3, pi / 3f32);
+    assert_approx_eq!(frac_pi_4, pi / 4f32);
+    assert_approx_eq!(frac_pi_6, pi / 6f32);
+    assert_approx_eq!(frac_pi_8, pi / 8f32);
+    assert_approx_eq!(frac_1_pi, 1f32 / pi);
+    assert_approx_eq!(frac_2_pi, 2f32 / pi);
+    assert_approx_eq!(frac_2_sqrtpi, 2f32 / pi.sqrt());
+    assert_approx_eq!(sqrt2, 2f32.sqrt());
+    assert_approx_eq!(frac_1_sqrt2, 1f32 / 2f32.sqrt());
+    assert_approx_eq!(log2_e, e.log2());
+    assert_approx_eq!(log10_e, e.log10());
+    assert_approx_eq!(ln_2, 2f32.ln());
+    assert_approx_eq!(ln_10, 10f32.ln());
+}
+
+#[test]
+fn test_float_bits_conv() {
+    assert_eq!((1f32).to_bits(), 0x3f800000);
+    assert_eq!((12.5f32).to_bits(), 0x41480000);
+    assert_eq!((1337f32).to_bits(), 0x44a72000);
+    assert_eq!((-14.25f32).to_bits(), 0xc1640000);
+    assert_approx_eq!(f32::from_bits(0x3f800000), 1.0);
+    assert_approx_eq!(f32::from_bits(0x41480000), 12.5);
+    assert_approx_eq!(f32::from_bits(0x44a72000), 1337.0);
+    assert_approx_eq!(f32::from_bits(0xc1640000), -14.25);
+
+    // Check that NaNs roundtrip their bits regardless of signaling-ness
+    // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
+    let masked_nan1 = f32::NAN.to_bits() ^ 0x002A_AAAA;
+    let masked_nan2 = f32::NAN.to_bits() ^ 0x0055_5555;
+    assert!(f32::from_bits(masked_nan1).is_nan());
+    assert!(f32::from_bits(masked_nan2).is_nan());
+
+    assert_eq!(f32::from_bits(masked_nan1).to_bits(), masked_nan1);
+    assert_eq!(f32::from_bits(masked_nan2).to_bits(), masked_nan2);
+}
+
+#[test]
+#[should_panic]
+fn test_clamp_min_greater_than_max() {
+    let _ = 1.0f32.clamp(3.0, 1.0);
+}
+
+#[test]
+#[should_panic]
+fn test_clamp_min_is_nan() {
+    let _ = 1.0f32.clamp(f32::NAN, 1.0);
+}
+
+#[test]
+#[should_panic]
+fn test_clamp_max_is_nan() {
+    let _ = 1.0f32.clamp(3.0, f32::NAN);
+}
+
+#[test]
+fn test_total_cmp() {
+    use core::cmp::Ordering;
+
+    fn quiet_bit_mask() -> u32 {
+        1 << (f32::MANTISSA_DIGITS - 2)
+    }
+
+    fn min_subnorm() -> f32 {
+        f32::MIN_POSITIVE / f32::powf(2.0, f32::MANTISSA_DIGITS as f32 - 1.0)
+    }
+
+    fn max_subnorm() -> f32 {
+        f32::MIN_POSITIVE - min_subnorm()
+    }
+
+    fn q_nan() -> f32 {
+        f32::from_bits(f32::NAN.to_bits() | quiet_bit_mask())
+    }
+
+    fn s_nan() -> f32 {
+        f32::from_bits((f32::NAN.to_bits() & !quiet_bit_mask()) + 42)
+    }
+
+    assert_eq!(Ordering::Equal, (-q_nan()).total_cmp(&-q_nan()));
+    assert_eq!(Ordering::Equal, (-s_nan()).total_cmp(&-s_nan()));
+    assert_eq!(Ordering::Equal, (-f32::INFINITY).total_cmp(&-f32::INFINITY));
+    assert_eq!(Ordering::Equal, (-f32::MAX).total_cmp(&-f32::MAX));
+    assert_eq!(Ordering::Equal, (-2.5_f32).total_cmp(&-2.5));
+    assert_eq!(Ordering::Equal, (-1.0_f32).total_cmp(&-1.0));
+    assert_eq!(Ordering::Equal, (-1.5_f32).total_cmp(&-1.5));
+    assert_eq!(Ordering::Equal, (-0.5_f32).total_cmp(&-0.5));
+    assert_eq!(Ordering::Equal, (-f32::MIN_POSITIVE).total_cmp(&-f32::MIN_POSITIVE));
+    assert_eq!(Ordering::Equal, (-max_subnorm()).total_cmp(&-max_subnorm()));
+    assert_eq!(Ordering::Equal, (-min_subnorm()).total_cmp(&-min_subnorm()));
+    assert_eq!(Ordering::Equal, (-0.0_f32).total_cmp(&-0.0));
+    assert_eq!(Ordering::Equal, 0.0_f32.total_cmp(&0.0));
+    assert_eq!(Ordering::Equal, min_subnorm().total_cmp(&min_subnorm()));
+    assert_eq!(Ordering::Equal, max_subnorm().total_cmp(&max_subnorm()));
+    assert_eq!(Ordering::Equal, f32::MIN_POSITIVE.total_cmp(&f32::MIN_POSITIVE));
+    assert_eq!(Ordering::Equal, 0.5_f32.total_cmp(&0.5));
+    assert_eq!(Ordering::Equal, 1.0_f32.total_cmp(&1.0));
+    assert_eq!(Ordering::Equal, 1.5_f32.total_cmp(&1.5));
+    assert_eq!(Ordering::Equal, 2.5_f32.total_cmp(&2.5));
+    assert_eq!(Ordering::Equal, f32::MAX.total_cmp(&f32::MAX));
+    assert_eq!(Ordering::Equal, f32::INFINITY.total_cmp(&f32::INFINITY));
+    assert_eq!(Ordering::Equal, s_nan().total_cmp(&s_nan()));
+    assert_eq!(Ordering::Equal, q_nan().total_cmp(&q_nan()));
+
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-s_nan()));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f32::INFINITY));
+    assert_eq!(Ordering::Less, (-f32::INFINITY).total_cmp(&-f32::MAX));
+    assert_eq!(Ordering::Less, (-f32::MAX).total_cmp(&-2.5));
+    assert_eq!(Ordering::Less, (-2.5_f32).total_cmp(&-1.5));
+    assert_eq!(Ordering::Less, (-1.5_f32).total_cmp(&-1.0));
+    assert_eq!(Ordering::Less, (-1.0_f32).total_cmp(&-0.5));
+    assert_eq!(Ordering::Less, (-0.5_f32).total_cmp(&-f32::MIN_POSITIVE));
+    assert_eq!(Ordering::Less, (-f32::MIN_POSITIVE).total_cmp(&-max_subnorm()));
+    assert_eq!(Ordering::Less, (-max_subnorm()).total_cmp(&-min_subnorm()));
+    assert_eq!(Ordering::Less, (-min_subnorm()).total_cmp(&-0.0));
+    assert_eq!(Ordering::Less, (-0.0_f32).total_cmp(&0.0));
+    assert_eq!(Ordering::Less, 0.0_f32.total_cmp(&min_subnorm()));
+    assert_eq!(Ordering::Less, min_subnorm().total_cmp(&max_subnorm()));
+    assert_eq!(Ordering::Less, max_subnorm().total_cmp(&f32::MIN_POSITIVE));
+    assert_eq!(Ordering::Less, f32::MIN_POSITIVE.total_cmp(&0.5));
+    assert_eq!(Ordering::Less, 0.5_f32.total_cmp(&1.0));
+    assert_eq!(Ordering::Less, 1.0_f32.total_cmp(&1.5));
+    assert_eq!(Ordering::Less, 1.5_f32.total_cmp(&2.5));
+    assert_eq!(Ordering::Less, 2.5_f32.total_cmp(&f32::MAX));
+    assert_eq!(Ordering::Less, f32::MAX.total_cmp(&f32::INFINITY));
+    assert_eq!(Ordering::Less, f32::INFINITY.total_cmp(&s_nan()));
+    assert_eq!(Ordering::Less, s_nan().total_cmp(&q_nan()));
+
+    assert_eq!(Ordering::Greater, (-s_nan()).total_cmp(&-q_nan()));
+    assert_eq!(Ordering::Greater, (-f32::INFINITY).total_cmp(&-s_nan()));
+    assert_eq!(Ordering::Greater, (-f32::MAX).total_cmp(&-f32::INFINITY));
+    assert_eq!(Ordering::Greater, (-2.5_f32).total_cmp(&-f32::MAX));
+    assert_eq!(Ordering::Greater, (-1.5_f32).total_cmp(&-2.5));
+    assert_eq!(Ordering::Greater, (-1.0_f32).total_cmp(&-1.5));
+    assert_eq!(Ordering::Greater, (-0.5_f32).total_cmp(&-1.0));
+    assert_eq!(Ordering::Greater, (-f32::MIN_POSITIVE).total_cmp(&-0.5));
+    assert_eq!(Ordering::Greater, (-max_subnorm()).total_cmp(&-f32::MIN_POSITIVE));
+    assert_eq!(Ordering::Greater, (-min_subnorm()).total_cmp(&-max_subnorm()));
+    assert_eq!(Ordering::Greater, (-0.0_f32).total_cmp(&-min_subnorm()));
+    assert_eq!(Ordering::Greater, 0.0_f32.total_cmp(&-0.0));
+    assert_eq!(Ordering::Greater, min_subnorm().total_cmp(&0.0));
+    assert_eq!(Ordering::Greater, max_subnorm().total_cmp(&min_subnorm()));
+    assert_eq!(Ordering::Greater, f32::MIN_POSITIVE.total_cmp(&max_subnorm()));
+    assert_eq!(Ordering::Greater, 0.5_f32.total_cmp(&f32::MIN_POSITIVE));
+    assert_eq!(Ordering::Greater, 1.0_f32.total_cmp(&0.5));
+    assert_eq!(Ordering::Greater, 1.5_f32.total_cmp(&1.0));
+    assert_eq!(Ordering::Greater, 2.5_f32.total_cmp(&1.5));
+    assert_eq!(Ordering::Greater, f32::MAX.total_cmp(&2.5));
+    assert_eq!(Ordering::Greater, f32::INFINITY.total_cmp(&f32::MAX));
+    assert_eq!(Ordering::Greater, s_nan().total_cmp(&f32::INFINITY));
+    assert_eq!(Ordering::Greater, q_nan().total_cmp(&s_nan()));
+
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-s_nan()));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f32::INFINITY));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f32::MAX));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-2.5));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-1.5));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-1.0));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-0.5));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f32::MIN_POSITIVE));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-max_subnorm()));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-min_subnorm()));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-0.0));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&0.0));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&min_subnorm()));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&max_subnorm()));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f32::MIN_POSITIVE));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&0.5));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&1.0));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&1.5));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&2.5));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f32::MAX));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f32::INFINITY));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&s_nan()));
+
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f32::INFINITY));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f32::MAX));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-2.5));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-1.5));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-1.0));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-0.5));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f32::MIN_POSITIVE));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-max_subnorm()));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-min_subnorm()));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-0.0));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&0.0));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&min_subnorm()));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&max_subnorm()));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f32::MIN_POSITIVE));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&0.5));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&1.0));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&1.5));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&2.5));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f32::MAX));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f32::INFINITY));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&s_nan()));
+}
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index f09fc8d790b..bd094bdb55d 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -11,6 +11,9 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 #![allow(missing_docs)]
 
+#[cfg(test)]
+mod tests;
+
 #[cfg(not(test))]
 use crate::intrinsics;
 #[cfg(not(test))]
@@ -936,762 +939,3 @@ impl f64 {
         }
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use crate::f64::consts;
-    use crate::num::FpCategory as Fp;
-    use crate::num::*;
-
-    #[test]
-    fn test_num_f64() {
-        test_num(10f64, 2f64);
-    }
-
-    #[test]
-    fn test_min_nan() {
-        assert_eq!(f64::NAN.min(2.0), 2.0);
-        assert_eq!(2.0f64.min(f64::NAN), 2.0);
-    }
-
-    #[test]
-    fn test_max_nan() {
-        assert_eq!(f64::NAN.max(2.0), 2.0);
-        assert_eq!(2.0f64.max(f64::NAN), 2.0);
-    }
-
-    #[test]
-    fn test_nan() {
-        let nan: f64 = f64::NAN;
-        assert!(nan.is_nan());
-        assert!(!nan.is_infinite());
-        assert!(!nan.is_finite());
-        assert!(!nan.is_normal());
-        assert!(nan.is_sign_positive());
-        assert!(!nan.is_sign_negative());
-        assert_eq!(Fp::Nan, nan.classify());
-    }
-
-    #[test]
-    fn test_infinity() {
-        let inf: f64 = f64::INFINITY;
-        assert!(inf.is_infinite());
-        assert!(!inf.is_finite());
-        assert!(inf.is_sign_positive());
-        assert!(!inf.is_sign_negative());
-        assert!(!inf.is_nan());
-        assert!(!inf.is_normal());
-        assert_eq!(Fp::Infinite, inf.classify());
-    }
-
-    #[test]
-    fn test_neg_infinity() {
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        assert!(neg_inf.is_infinite());
-        assert!(!neg_inf.is_finite());
-        assert!(!neg_inf.is_sign_positive());
-        assert!(neg_inf.is_sign_negative());
-        assert!(!neg_inf.is_nan());
-        assert!(!neg_inf.is_normal());
-        assert_eq!(Fp::Infinite, neg_inf.classify());
-    }
-
-    #[test]
-    fn test_zero() {
-        let zero: f64 = 0.0f64;
-        assert_eq!(0.0, zero);
-        assert!(!zero.is_infinite());
-        assert!(zero.is_finite());
-        assert!(zero.is_sign_positive());
-        assert!(!zero.is_sign_negative());
-        assert!(!zero.is_nan());
-        assert!(!zero.is_normal());
-        assert_eq!(Fp::Zero, zero.classify());
-    }
-
-    #[test]
-    fn test_neg_zero() {
-        let neg_zero: f64 = -0.0;
-        assert_eq!(0.0, neg_zero);
-        assert!(!neg_zero.is_infinite());
-        assert!(neg_zero.is_finite());
-        assert!(!neg_zero.is_sign_positive());
-        assert!(neg_zero.is_sign_negative());
-        assert!(!neg_zero.is_nan());
-        assert!(!neg_zero.is_normal());
-        assert_eq!(Fp::Zero, neg_zero.classify());
-    }
-
-    #[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
-    #[test]
-    fn test_one() {
-        let one: f64 = 1.0f64;
-        assert_eq!(1.0, one);
-        assert!(!one.is_infinite());
-        assert!(one.is_finite());
-        assert!(one.is_sign_positive());
-        assert!(!one.is_sign_negative());
-        assert!(!one.is_nan());
-        assert!(one.is_normal());
-        assert_eq!(Fp::Normal, one.classify());
-    }
-
-    #[test]
-    fn test_is_nan() {
-        let nan: f64 = f64::NAN;
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        assert!(nan.is_nan());
-        assert!(!0.0f64.is_nan());
-        assert!(!5.3f64.is_nan());
-        assert!(!(-10.732f64).is_nan());
-        assert!(!inf.is_nan());
-        assert!(!neg_inf.is_nan());
-    }
-
-    #[test]
-    fn test_is_infinite() {
-        let nan: f64 = f64::NAN;
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        assert!(!nan.is_infinite());
-        assert!(inf.is_infinite());
-        assert!(neg_inf.is_infinite());
-        assert!(!0.0f64.is_infinite());
-        assert!(!42.8f64.is_infinite());
-        assert!(!(-109.2f64).is_infinite());
-    }
-
-    #[test]
-    fn test_is_finite() {
-        let nan: f64 = f64::NAN;
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        assert!(!nan.is_finite());
-        assert!(!inf.is_finite());
-        assert!(!neg_inf.is_finite());
-        assert!(0.0f64.is_finite());
-        assert!(42.8f64.is_finite());
-        assert!((-109.2f64).is_finite());
-    }
-
-    #[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
-    #[test]
-    fn test_is_normal() {
-        let nan: f64 = f64::NAN;
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        let zero: f64 = 0.0f64;
-        let neg_zero: f64 = -0.0;
-        assert!(!nan.is_normal());
-        assert!(!inf.is_normal());
-        assert!(!neg_inf.is_normal());
-        assert!(!zero.is_normal());
-        assert!(!neg_zero.is_normal());
-        assert!(1f64.is_normal());
-        assert!(1e-307f64.is_normal());
-        assert!(!1e-308f64.is_normal());
-    }
-
-    #[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
-    #[test]
-    fn test_classify() {
-        let nan: f64 = f64::NAN;
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        let zero: f64 = 0.0f64;
-        let neg_zero: f64 = -0.0;
-        assert_eq!(nan.classify(), Fp::Nan);
-        assert_eq!(inf.classify(), Fp::Infinite);
-        assert_eq!(neg_inf.classify(), Fp::Infinite);
-        assert_eq!(zero.classify(), Fp::Zero);
-        assert_eq!(neg_zero.classify(), Fp::Zero);
-        assert_eq!(1e-307f64.classify(), Fp::Normal);
-        assert_eq!(1e-308f64.classify(), Fp::Subnormal);
-    }
-
-    #[test]
-    fn test_floor() {
-        assert_approx_eq!(1.0f64.floor(), 1.0f64);
-        assert_approx_eq!(1.3f64.floor(), 1.0f64);
-        assert_approx_eq!(1.5f64.floor(), 1.0f64);
-        assert_approx_eq!(1.7f64.floor(), 1.0f64);
-        assert_approx_eq!(0.0f64.floor(), 0.0f64);
-        assert_approx_eq!((-0.0f64).floor(), -0.0f64);
-        assert_approx_eq!((-1.0f64).floor(), -1.0f64);
-        assert_approx_eq!((-1.3f64).floor(), -2.0f64);
-        assert_approx_eq!((-1.5f64).floor(), -2.0f64);
-        assert_approx_eq!((-1.7f64).floor(), -2.0f64);
-    }
-
-    #[test]
-    fn test_ceil() {
-        assert_approx_eq!(1.0f64.ceil(), 1.0f64);
-        assert_approx_eq!(1.3f64.ceil(), 2.0f64);
-        assert_approx_eq!(1.5f64.ceil(), 2.0f64);
-        assert_approx_eq!(1.7f64.ceil(), 2.0f64);
-        assert_approx_eq!(0.0f64.ceil(), 0.0f64);
-        assert_approx_eq!((-0.0f64).ceil(), -0.0f64);
-        assert_approx_eq!((-1.0f64).ceil(), -1.0f64);
-        assert_approx_eq!((-1.3f64).ceil(), -1.0f64);
-        assert_approx_eq!((-1.5f64).ceil(), -1.0f64);
-        assert_approx_eq!((-1.7f64).ceil(), -1.0f64);
-    }
-
-    #[test]
-    fn test_round() {
-        assert_approx_eq!(1.0f64.round(), 1.0f64);
-        assert_approx_eq!(1.3f64.round(), 1.0f64);
-        assert_approx_eq!(1.5f64.round(), 2.0f64);
-        assert_approx_eq!(1.7f64.round(), 2.0f64);
-        assert_approx_eq!(0.0f64.round(), 0.0f64);
-        assert_approx_eq!((-0.0f64).round(), -0.0f64);
-        assert_approx_eq!((-1.0f64).round(), -1.0f64);
-        assert_approx_eq!((-1.3f64).round(), -1.0f64);
-        assert_approx_eq!((-1.5f64).round(), -2.0f64);
-        assert_approx_eq!((-1.7f64).round(), -2.0f64);
-    }
-
-    #[test]
-    fn test_trunc() {
-        assert_approx_eq!(1.0f64.trunc(), 1.0f64);
-        assert_approx_eq!(1.3f64.trunc(), 1.0f64);
-        assert_approx_eq!(1.5f64.trunc(), 1.0f64);
-        assert_approx_eq!(1.7f64.trunc(), 1.0f64);
-        assert_approx_eq!(0.0f64.trunc(), 0.0f64);
-        assert_approx_eq!((-0.0f64).trunc(), -0.0f64);
-        assert_approx_eq!((-1.0f64).trunc(), -1.0f64);
-        assert_approx_eq!((-1.3f64).trunc(), -1.0f64);
-        assert_approx_eq!((-1.5f64).trunc(), -1.0f64);
-        assert_approx_eq!((-1.7f64).trunc(), -1.0f64);
-    }
-
-    #[test]
-    fn test_fract() {
-        assert_approx_eq!(1.0f64.fract(), 0.0f64);
-        assert_approx_eq!(1.3f64.fract(), 0.3f64);
-        assert_approx_eq!(1.5f64.fract(), 0.5f64);
-        assert_approx_eq!(1.7f64.fract(), 0.7f64);
-        assert_approx_eq!(0.0f64.fract(), 0.0f64);
-        assert_approx_eq!((-0.0f64).fract(), -0.0f64);
-        assert_approx_eq!((-1.0f64).fract(), -0.0f64);
-        assert_approx_eq!((-1.3f64).fract(), -0.3f64);
-        assert_approx_eq!((-1.5f64).fract(), -0.5f64);
-        assert_approx_eq!((-1.7f64).fract(), -0.7f64);
-    }
-
-    #[test]
-    fn test_abs() {
-        assert_eq!(f64::INFINITY.abs(), f64::INFINITY);
-        assert_eq!(1f64.abs(), 1f64);
-        assert_eq!(0f64.abs(), 0f64);
-        assert_eq!((-0f64).abs(), 0f64);
-        assert_eq!((-1f64).abs(), 1f64);
-        assert_eq!(f64::NEG_INFINITY.abs(), f64::INFINITY);
-        assert_eq!((1f64 / f64::NEG_INFINITY).abs(), 0f64);
-        assert!(f64::NAN.abs().is_nan());
-    }
-
-    #[test]
-    fn test_signum() {
-        assert_eq!(f64::INFINITY.signum(), 1f64);
-        assert_eq!(1f64.signum(), 1f64);
-        assert_eq!(0f64.signum(), 1f64);
-        assert_eq!((-0f64).signum(), -1f64);
-        assert_eq!((-1f64).signum(), -1f64);
-        assert_eq!(f64::NEG_INFINITY.signum(), -1f64);
-        assert_eq!((1f64 / f64::NEG_INFINITY).signum(), -1f64);
-        assert!(f64::NAN.signum().is_nan());
-    }
-
-    #[test]
-    fn test_is_sign_positive() {
-        assert!(f64::INFINITY.is_sign_positive());
-        assert!(1f64.is_sign_positive());
-        assert!(0f64.is_sign_positive());
-        assert!(!(-0f64).is_sign_positive());
-        assert!(!(-1f64).is_sign_positive());
-        assert!(!f64::NEG_INFINITY.is_sign_positive());
-        assert!(!(1f64 / f64::NEG_INFINITY).is_sign_positive());
-        assert!(f64::NAN.is_sign_positive());
-        assert!(!(-f64::NAN).is_sign_positive());
-    }
-
-    #[test]
-    fn test_is_sign_negative() {
-        assert!(!f64::INFINITY.is_sign_negative());
-        assert!(!1f64.is_sign_negative());
-        assert!(!0f64.is_sign_negative());
-        assert!((-0f64).is_sign_negative());
-        assert!((-1f64).is_sign_negative());
-        assert!(f64::NEG_INFINITY.is_sign_negative());
-        assert!((1f64 / f64::NEG_INFINITY).is_sign_negative());
-        assert!(!f64::NAN.is_sign_negative());
-        assert!((-f64::NAN).is_sign_negative());
-    }
-
-    #[test]
-    fn test_mul_add() {
-        let nan: f64 = f64::NAN;
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        assert_approx_eq!(12.3f64.mul_add(4.5, 6.7), 62.05);
-        assert_approx_eq!((-12.3f64).mul_add(-4.5, -6.7), 48.65);
-        assert_approx_eq!(0.0f64.mul_add(8.9, 1.2), 1.2);
-        assert_approx_eq!(3.4f64.mul_add(-0.0, 5.6), 5.6);
-        assert!(nan.mul_add(7.8, 9.0).is_nan());
-        assert_eq!(inf.mul_add(7.8, 9.0), inf);
-        assert_eq!(neg_inf.mul_add(7.8, 9.0), neg_inf);
-        assert_eq!(8.9f64.mul_add(inf, 3.2), inf);
-        assert_eq!((-3.2f64).mul_add(2.4, neg_inf), neg_inf);
-    }
-
-    #[test]
-    fn test_recip() {
-        let nan: f64 = f64::NAN;
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        assert_eq!(1.0f64.recip(), 1.0);
-        assert_eq!(2.0f64.recip(), 0.5);
-        assert_eq!((-0.4f64).recip(), -2.5);
-        assert_eq!(0.0f64.recip(), inf);
-        assert!(nan.recip().is_nan());
-        assert_eq!(inf.recip(), 0.0);
-        assert_eq!(neg_inf.recip(), 0.0);
-    }
-
-    #[test]
-    fn test_powi() {
-        let nan: f64 = f64::NAN;
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        assert_eq!(1.0f64.powi(1), 1.0);
-        assert_approx_eq!((-3.1f64).powi(2), 9.61);
-        assert_approx_eq!(5.9f64.powi(-2), 0.028727);
-        assert_eq!(8.3f64.powi(0), 1.0);
-        assert!(nan.powi(2).is_nan());
-        assert_eq!(inf.powi(3), inf);
-        assert_eq!(neg_inf.powi(2), inf);
-    }
-
-    #[test]
-    fn test_powf() {
-        let nan: f64 = f64::NAN;
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        assert_eq!(1.0f64.powf(1.0), 1.0);
-        assert_approx_eq!(3.4f64.powf(4.5), 246.408183);
-        assert_approx_eq!(2.7f64.powf(-3.2), 0.041652);
-        assert_approx_eq!((-3.1f64).powf(2.0), 9.61);
-        assert_approx_eq!(5.9f64.powf(-2.0), 0.028727);
-        assert_eq!(8.3f64.powf(0.0), 1.0);
-        assert!(nan.powf(2.0).is_nan());
-        assert_eq!(inf.powf(2.0), inf);
-        assert_eq!(neg_inf.powf(3.0), neg_inf);
-    }
-
-    #[test]
-    fn test_sqrt_domain() {
-        assert!(f64::NAN.sqrt().is_nan());
-        assert!(f64::NEG_INFINITY.sqrt().is_nan());
-        assert!((-1.0f64).sqrt().is_nan());
-        assert_eq!((-0.0f64).sqrt(), -0.0);
-        assert_eq!(0.0f64.sqrt(), 0.0);
-        assert_eq!(1.0f64.sqrt(), 1.0);
-        assert_eq!(f64::INFINITY.sqrt(), f64::INFINITY);
-    }
-
-    #[test]
-    fn test_exp() {
-        assert_eq!(1.0, 0.0f64.exp());
-        assert_approx_eq!(2.718282, 1.0f64.exp());
-        assert_approx_eq!(148.413159, 5.0f64.exp());
-
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        let nan: f64 = f64::NAN;
-        assert_eq!(inf, inf.exp());
-        assert_eq!(0.0, neg_inf.exp());
-        assert!(nan.exp().is_nan());
-    }
-
-    #[test]
-    fn test_exp2() {
-        assert_eq!(32.0, 5.0f64.exp2());
-        assert_eq!(1.0, 0.0f64.exp2());
-
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        let nan: f64 = f64::NAN;
-        assert_eq!(inf, inf.exp2());
-        assert_eq!(0.0, neg_inf.exp2());
-        assert!(nan.exp2().is_nan());
-    }
-
-    #[test]
-    fn test_ln() {
-        let nan: f64 = f64::NAN;
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        assert_approx_eq!(1.0f64.exp().ln(), 1.0);
-        assert!(nan.ln().is_nan());
-        assert_eq!(inf.ln(), inf);
-        assert!(neg_inf.ln().is_nan());
-        assert!((-2.3f64).ln().is_nan());
-        assert_eq!((-0.0f64).ln(), neg_inf);
-        assert_eq!(0.0f64.ln(), neg_inf);
-        assert_approx_eq!(4.0f64.ln(), 1.386294);
-    }
-
-    #[test]
-    fn test_log() {
-        let nan: f64 = f64::NAN;
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        assert_eq!(10.0f64.log(10.0), 1.0);
-        assert_approx_eq!(2.3f64.log(3.5), 0.664858);
-        assert_eq!(1.0f64.exp().log(1.0f64.exp()), 1.0);
-        assert!(1.0f64.log(1.0).is_nan());
-        assert!(1.0f64.log(-13.9).is_nan());
-        assert!(nan.log(2.3).is_nan());
-        assert_eq!(inf.log(10.0), inf);
-        assert!(neg_inf.log(8.8).is_nan());
-        assert!((-2.3f64).log(0.1).is_nan());
-        assert_eq!((-0.0f64).log(2.0), neg_inf);
-        assert_eq!(0.0f64.log(7.0), neg_inf);
-    }
-
-    #[test]
-    fn test_log2() {
-        let nan: f64 = f64::NAN;
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        assert_approx_eq!(10.0f64.log2(), 3.321928);
-        assert_approx_eq!(2.3f64.log2(), 1.201634);
-        assert_approx_eq!(1.0f64.exp().log2(), 1.442695);
-        assert!(nan.log2().is_nan());
-        assert_eq!(inf.log2(), inf);
-        assert!(neg_inf.log2().is_nan());
-        assert!((-2.3f64).log2().is_nan());
-        assert_eq!((-0.0f64).log2(), neg_inf);
-        assert_eq!(0.0f64.log2(), neg_inf);
-    }
-
-    #[test]
-    fn test_log10() {
-        let nan: f64 = f64::NAN;
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        assert_eq!(10.0f64.log10(), 1.0);
-        assert_approx_eq!(2.3f64.log10(), 0.361728);
-        assert_approx_eq!(1.0f64.exp().log10(), 0.434294);
-        assert_eq!(1.0f64.log10(), 0.0);
-        assert!(nan.log10().is_nan());
-        assert_eq!(inf.log10(), inf);
-        assert!(neg_inf.log10().is_nan());
-        assert!((-2.3f64).log10().is_nan());
-        assert_eq!((-0.0f64).log10(), neg_inf);
-        assert_eq!(0.0f64.log10(), neg_inf);
-    }
-
-    #[test]
-    fn test_to_degrees() {
-        let pi: f64 = consts::PI;
-        let nan: f64 = f64::NAN;
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        assert_eq!(0.0f64.to_degrees(), 0.0);
-        assert_approx_eq!((-5.8f64).to_degrees(), -332.315521);
-        assert_eq!(pi.to_degrees(), 180.0);
-        assert!(nan.to_degrees().is_nan());
-        assert_eq!(inf.to_degrees(), inf);
-        assert_eq!(neg_inf.to_degrees(), neg_inf);
-    }
-
-    #[test]
-    fn test_to_radians() {
-        let pi: f64 = consts::PI;
-        let nan: f64 = f64::NAN;
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        assert_eq!(0.0f64.to_radians(), 0.0);
-        assert_approx_eq!(154.6f64.to_radians(), 2.698279);
-        assert_approx_eq!((-332.31f64).to_radians(), -5.799903);
-        assert_eq!(180.0f64.to_radians(), pi);
-        assert!(nan.to_radians().is_nan());
-        assert_eq!(inf.to_radians(), inf);
-        assert_eq!(neg_inf.to_radians(), neg_inf);
-    }
-
-    #[test]
-    fn test_asinh() {
-        assert_eq!(0.0f64.asinh(), 0.0f64);
-        assert_eq!((-0.0f64).asinh(), -0.0f64);
-
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        let nan: f64 = f64::NAN;
-        assert_eq!(inf.asinh(), inf);
-        assert_eq!(neg_inf.asinh(), neg_inf);
-        assert!(nan.asinh().is_nan());
-        assert!((-0.0f64).asinh().is_sign_negative());
-        // issue 63271
-        assert_approx_eq!(2.0f64.asinh(), 1.443635475178810342493276740273105f64);
-        assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);
-        // regression test for the catastrophic cancellation fixed in 72486
-        assert_approx_eq!((-67452098.07139316f64).asinh(), -18.72007542627454439398548429400083);
-    }
-
-    #[test]
-    fn test_acosh() {
-        assert_eq!(1.0f64.acosh(), 0.0f64);
-        assert!(0.999f64.acosh().is_nan());
-
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        let nan: f64 = f64::NAN;
-        assert_eq!(inf.acosh(), inf);
-        assert!(neg_inf.acosh().is_nan());
-        assert!(nan.acosh().is_nan());
-        assert_approx_eq!(2.0f64.acosh(), 1.31695789692481670862504634730796844f64);
-        assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64);
-    }
-
-    #[test]
-    fn test_atanh() {
-        assert_eq!(0.0f64.atanh(), 0.0f64);
-        assert_eq!((-0.0f64).atanh(), -0.0f64);
-
-        let inf: f64 = f64::INFINITY;
-        let neg_inf: f64 = f64::NEG_INFINITY;
-        let nan: f64 = f64::NAN;
-        assert_eq!(1.0f64.atanh(), inf);
-        assert_eq!((-1.0f64).atanh(), neg_inf);
-        assert!(2f64.atanh().atanh().is_nan());
-        assert!((-2f64).atanh().atanh().is_nan());
-        assert!(inf.atanh().is_nan());
-        assert!(neg_inf.atanh().is_nan());
-        assert!(nan.atanh().is_nan());
-        assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64);
-        assert_approx_eq!((-0.5f64).atanh(), -0.54930614433405484569762261846126285f64);
-    }
-
-    #[test]
-    fn test_real_consts() {
-        use super::consts;
-        let pi: f64 = consts::PI;
-        let frac_pi_2: f64 = consts::FRAC_PI_2;
-        let frac_pi_3: f64 = consts::FRAC_PI_3;
-        let frac_pi_4: f64 = consts::FRAC_PI_4;
-        let frac_pi_6: f64 = consts::FRAC_PI_6;
-        let frac_pi_8: f64 = consts::FRAC_PI_8;
-        let frac_1_pi: f64 = consts::FRAC_1_PI;
-        let frac_2_pi: f64 = consts::FRAC_2_PI;
-        let frac_2_sqrtpi: f64 = consts::FRAC_2_SQRT_PI;
-        let sqrt2: f64 = consts::SQRT_2;
-        let frac_1_sqrt2: f64 = consts::FRAC_1_SQRT_2;
-        let e: f64 = consts::E;
-        let log2_e: f64 = consts::LOG2_E;
-        let log10_e: f64 = consts::LOG10_E;
-        let ln_2: f64 = consts::LN_2;
-        let ln_10: f64 = consts::LN_10;
-
-        assert_approx_eq!(frac_pi_2, pi / 2f64);
-        assert_approx_eq!(frac_pi_3, pi / 3f64);
-        assert_approx_eq!(frac_pi_4, pi / 4f64);
-        assert_approx_eq!(frac_pi_6, pi / 6f64);
-        assert_approx_eq!(frac_pi_8, pi / 8f64);
-        assert_approx_eq!(frac_1_pi, 1f64 / pi);
-        assert_approx_eq!(frac_2_pi, 2f64 / pi);
-        assert_approx_eq!(frac_2_sqrtpi, 2f64 / pi.sqrt());
-        assert_approx_eq!(sqrt2, 2f64.sqrt());
-        assert_approx_eq!(frac_1_sqrt2, 1f64 / 2f64.sqrt());
-        assert_approx_eq!(log2_e, e.log2());
-        assert_approx_eq!(log10_e, e.log10());
-        assert_approx_eq!(ln_2, 2f64.ln());
-        assert_approx_eq!(ln_10, 10f64.ln());
-    }
-
-    #[test]
-    fn test_float_bits_conv() {
-        assert_eq!((1f64).to_bits(), 0x3ff0000000000000);
-        assert_eq!((12.5f64).to_bits(), 0x4029000000000000);
-        assert_eq!((1337f64).to_bits(), 0x4094e40000000000);
-        assert_eq!((-14.25f64).to_bits(), 0xc02c800000000000);
-        assert_approx_eq!(f64::from_bits(0x3ff0000000000000), 1.0);
-        assert_approx_eq!(f64::from_bits(0x4029000000000000), 12.5);
-        assert_approx_eq!(f64::from_bits(0x4094e40000000000), 1337.0);
-        assert_approx_eq!(f64::from_bits(0xc02c800000000000), -14.25);
-
-        // Check that NaNs roundtrip their bits regardless of signaling-ness
-        // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
-        let masked_nan1 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA;
-        let masked_nan2 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555;
-        assert!(f64::from_bits(masked_nan1).is_nan());
-        assert!(f64::from_bits(masked_nan2).is_nan());
-
-        assert_eq!(f64::from_bits(masked_nan1).to_bits(), masked_nan1);
-        assert_eq!(f64::from_bits(masked_nan2).to_bits(), masked_nan2);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_clamp_min_greater_than_max() {
-        let _ = 1.0f64.clamp(3.0, 1.0);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_clamp_min_is_nan() {
-        let _ = 1.0f64.clamp(f64::NAN, 1.0);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_clamp_max_is_nan() {
-        let _ = 1.0f64.clamp(3.0, f64::NAN);
-    }
-
-    #[test]
-    fn test_total_cmp() {
-        use core::cmp::Ordering;
-
-        fn quiet_bit_mask() -> u64 {
-            1 << (f64::MANTISSA_DIGITS - 2)
-        }
-
-        fn min_subnorm() -> f64 {
-            f64::MIN_POSITIVE / f64::powf(2.0, f64::MANTISSA_DIGITS as f64 - 1.0)
-        }
-
-        fn max_subnorm() -> f64 {
-            f64::MIN_POSITIVE - min_subnorm()
-        }
-
-        fn q_nan() -> f64 {
-            f64::from_bits(f64::NAN.to_bits() | quiet_bit_mask())
-        }
-
-        fn s_nan() -> f64 {
-            f64::from_bits((f64::NAN.to_bits() & !quiet_bit_mask()) + 42)
-        }
-
-        assert_eq!(Ordering::Equal, (-q_nan()).total_cmp(&-q_nan()));
-        assert_eq!(Ordering::Equal, (-s_nan()).total_cmp(&-s_nan()));
-        assert_eq!(Ordering::Equal, (-f64::INFINITY).total_cmp(&-f64::INFINITY));
-        assert_eq!(Ordering::Equal, (-f64::MAX).total_cmp(&-f64::MAX));
-        assert_eq!(Ordering::Equal, (-2.5_f64).total_cmp(&-2.5));
-        assert_eq!(Ordering::Equal, (-1.0_f64).total_cmp(&-1.0));
-        assert_eq!(Ordering::Equal, (-1.5_f64).total_cmp(&-1.5));
-        assert_eq!(Ordering::Equal, (-0.5_f64).total_cmp(&-0.5));
-        assert_eq!(Ordering::Equal, (-f64::MIN_POSITIVE).total_cmp(&-f64::MIN_POSITIVE));
-        assert_eq!(Ordering::Equal, (-max_subnorm()).total_cmp(&-max_subnorm()));
-        assert_eq!(Ordering::Equal, (-min_subnorm()).total_cmp(&-min_subnorm()));
-        assert_eq!(Ordering::Equal, (-0.0_f64).total_cmp(&-0.0));
-        assert_eq!(Ordering::Equal, 0.0_f64.total_cmp(&0.0));
-        assert_eq!(Ordering::Equal, min_subnorm().total_cmp(&min_subnorm()));
-        assert_eq!(Ordering::Equal, max_subnorm().total_cmp(&max_subnorm()));
-        assert_eq!(Ordering::Equal, f64::MIN_POSITIVE.total_cmp(&f64::MIN_POSITIVE));
-        assert_eq!(Ordering::Equal, 0.5_f64.total_cmp(&0.5));
-        assert_eq!(Ordering::Equal, 1.0_f64.total_cmp(&1.0));
-        assert_eq!(Ordering::Equal, 1.5_f64.total_cmp(&1.5));
-        assert_eq!(Ordering::Equal, 2.5_f64.total_cmp(&2.5));
-        assert_eq!(Ordering::Equal, f64::MAX.total_cmp(&f64::MAX));
-        assert_eq!(Ordering::Equal, f64::INFINITY.total_cmp(&f64::INFINITY));
-        assert_eq!(Ordering::Equal, s_nan().total_cmp(&s_nan()));
-        assert_eq!(Ordering::Equal, q_nan().total_cmp(&q_nan()));
-
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-s_nan()));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f64::INFINITY));
-        assert_eq!(Ordering::Less, (-f64::INFINITY).total_cmp(&-f64::MAX));
-        assert_eq!(Ordering::Less, (-f64::MAX).total_cmp(&-2.5));
-        assert_eq!(Ordering::Less, (-2.5_f64).total_cmp(&-1.5));
-        assert_eq!(Ordering::Less, (-1.5_f64).total_cmp(&-1.0));
-        assert_eq!(Ordering::Less, (-1.0_f64).total_cmp(&-0.5));
-        assert_eq!(Ordering::Less, (-0.5_f64).total_cmp(&-f64::MIN_POSITIVE));
-        assert_eq!(Ordering::Less, (-f64::MIN_POSITIVE).total_cmp(&-max_subnorm()));
-        assert_eq!(Ordering::Less, (-max_subnorm()).total_cmp(&-min_subnorm()));
-        assert_eq!(Ordering::Less, (-min_subnorm()).total_cmp(&-0.0));
-        assert_eq!(Ordering::Less, (-0.0_f64).total_cmp(&0.0));
-        assert_eq!(Ordering::Less, 0.0_f64.total_cmp(&min_subnorm()));
-        assert_eq!(Ordering::Less, min_subnorm().total_cmp(&max_subnorm()));
-        assert_eq!(Ordering::Less, max_subnorm().total_cmp(&f64::MIN_POSITIVE));
-        assert_eq!(Ordering::Less, f64::MIN_POSITIVE.total_cmp(&0.5));
-        assert_eq!(Ordering::Less, 0.5_f64.total_cmp(&1.0));
-        assert_eq!(Ordering::Less, 1.0_f64.total_cmp(&1.5));
-        assert_eq!(Ordering::Less, 1.5_f64.total_cmp(&2.5));
-        assert_eq!(Ordering::Less, 2.5_f64.total_cmp(&f64::MAX));
-        assert_eq!(Ordering::Less, f64::MAX.total_cmp(&f64::INFINITY));
-        assert_eq!(Ordering::Less, f64::INFINITY.total_cmp(&s_nan()));
-        assert_eq!(Ordering::Less, s_nan().total_cmp(&q_nan()));
-
-        assert_eq!(Ordering::Greater, (-s_nan()).total_cmp(&-q_nan()));
-        assert_eq!(Ordering::Greater, (-f64::INFINITY).total_cmp(&-s_nan()));
-        assert_eq!(Ordering::Greater, (-f64::MAX).total_cmp(&-f64::INFINITY));
-        assert_eq!(Ordering::Greater, (-2.5_f64).total_cmp(&-f64::MAX));
-        assert_eq!(Ordering::Greater, (-1.5_f64).total_cmp(&-2.5));
-        assert_eq!(Ordering::Greater, (-1.0_f64).total_cmp(&-1.5));
-        assert_eq!(Ordering::Greater, (-0.5_f64).total_cmp(&-1.0));
-        assert_eq!(Ordering::Greater, (-f64::MIN_POSITIVE).total_cmp(&-0.5));
-        assert_eq!(Ordering::Greater, (-max_subnorm()).total_cmp(&-f64::MIN_POSITIVE));
-        assert_eq!(Ordering::Greater, (-min_subnorm()).total_cmp(&-max_subnorm()));
-        assert_eq!(Ordering::Greater, (-0.0_f64).total_cmp(&-min_subnorm()));
-        assert_eq!(Ordering::Greater, 0.0_f64.total_cmp(&-0.0));
-        assert_eq!(Ordering::Greater, min_subnorm().total_cmp(&0.0));
-        assert_eq!(Ordering::Greater, max_subnorm().total_cmp(&min_subnorm()));
-        assert_eq!(Ordering::Greater, f64::MIN_POSITIVE.total_cmp(&max_subnorm()));
-        assert_eq!(Ordering::Greater, 0.5_f64.total_cmp(&f64::MIN_POSITIVE));
-        assert_eq!(Ordering::Greater, 1.0_f64.total_cmp(&0.5));
-        assert_eq!(Ordering::Greater, 1.5_f64.total_cmp(&1.0));
-        assert_eq!(Ordering::Greater, 2.5_f64.total_cmp(&1.5));
-        assert_eq!(Ordering::Greater, f64::MAX.total_cmp(&2.5));
-        assert_eq!(Ordering::Greater, f64::INFINITY.total_cmp(&f64::MAX));
-        assert_eq!(Ordering::Greater, s_nan().total_cmp(&f64::INFINITY));
-        assert_eq!(Ordering::Greater, q_nan().total_cmp(&s_nan()));
-
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-s_nan()));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f64::INFINITY));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f64::MAX));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-2.5));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-1.5));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-1.0));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-0.5));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f64::MIN_POSITIVE));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-max_subnorm()));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-min_subnorm()));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-0.0));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&0.0));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&min_subnorm()));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&max_subnorm()));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f64::MIN_POSITIVE));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&0.5));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&1.0));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&1.5));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&2.5));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f64::MAX));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f64::INFINITY));
-        assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&s_nan()));
-
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f64::INFINITY));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f64::MAX));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-2.5));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-1.5));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-1.0));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-0.5));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f64::MIN_POSITIVE));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-max_subnorm()));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-min_subnorm()));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-0.0));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&0.0));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&min_subnorm()));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&max_subnorm()));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f64::MIN_POSITIVE));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&0.5));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&1.0));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&1.5));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&2.5));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f64::MAX));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f64::INFINITY));
-        assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&s_nan()));
-    }
-}
diff --git a/library/std/src/f64/tests.rs b/library/std/src/f64/tests.rs
new file mode 100644
index 00000000000..5c163cfe90e
--- /dev/null
+++ b/library/std/src/f64/tests.rs
@@ -0,0 +1,755 @@
+use crate::f64::consts;
+use crate::num::FpCategory as Fp;
+use crate::num::*;
+
+#[test]
+fn test_num_f64() {
+    test_num(10f64, 2f64);
+}
+
+#[test]
+fn test_min_nan() {
+    assert_eq!(f64::NAN.min(2.0), 2.0);
+    assert_eq!(2.0f64.min(f64::NAN), 2.0);
+}
+
+#[test]
+fn test_max_nan() {
+    assert_eq!(f64::NAN.max(2.0), 2.0);
+    assert_eq!(2.0f64.max(f64::NAN), 2.0);
+}
+
+#[test]
+fn test_nan() {
+    let nan: f64 = f64::NAN;
+    assert!(nan.is_nan());
+    assert!(!nan.is_infinite());
+    assert!(!nan.is_finite());
+    assert!(!nan.is_normal());
+    assert!(nan.is_sign_positive());
+    assert!(!nan.is_sign_negative());
+    assert_eq!(Fp::Nan, nan.classify());
+}
+
+#[test]
+fn test_infinity() {
+    let inf: f64 = f64::INFINITY;
+    assert!(inf.is_infinite());
+    assert!(!inf.is_finite());
+    assert!(inf.is_sign_positive());
+    assert!(!inf.is_sign_negative());
+    assert!(!inf.is_nan());
+    assert!(!inf.is_normal());
+    assert_eq!(Fp::Infinite, inf.classify());
+}
+
+#[test]
+fn test_neg_infinity() {
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    assert!(neg_inf.is_infinite());
+    assert!(!neg_inf.is_finite());
+    assert!(!neg_inf.is_sign_positive());
+    assert!(neg_inf.is_sign_negative());
+    assert!(!neg_inf.is_nan());
+    assert!(!neg_inf.is_normal());
+    assert_eq!(Fp::Infinite, neg_inf.classify());
+}
+
+#[test]
+fn test_zero() {
+    let zero: f64 = 0.0f64;
+    assert_eq!(0.0, zero);
+    assert!(!zero.is_infinite());
+    assert!(zero.is_finite());
+    assert!(zero.is_sign_positive());
+    assert!(!zero.is_sign_negative());
+    assert!(!zero.is_nan());
+    assert!(!zero.is_normal());
+    assert_eq!(Fp::Zero, zero.classify());
+}
+
+#[test]
+fn test_neg_zero() {
+    let neg_zero: f64 = -0.0;
+    assert_eq!(0.0, neg_zero);
+    assert!(!neg_zero.is_infinite());
+    assert!(neg_zero.is_finite());
+    assert!(!neg_zero.is_sign_positive());
+    assert!(neg_zero.is_sign_negative());
+    assert!(!neg_zero.is_nan());
+    assert!(!neg_zero.is_normal());
+    assert_eq!(Fp::Zero, neg_zero.classify());
+}
+
+#[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
+#[test]
+fn test_one() {
+    let one: f64 = 1.0f64;
+    assert_eq!(1.0, one);
+    assert!(!one.is_infinite());
+    assert!(one.is_finite());
+    assert!(one.is_sign_positive());
+    assert!(!one.is_sign_negative());
+    assert!(!one.is_nan());
+    assert!(one.is_normal());
+    assert_eq!(Fp::Normal, one.classify());
+}
+
+#[test]
+fn test_is_nan() {
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    assert!(nan.is_nan());
+    assert!(!0.0f64.is_nan());
+    assert!(!5.3f64.is_nan());
+    assert!(!(-10.732f64).is_nan());
+    assert!(!inf.is_nan());
+    assert!(!neg_inf.is_nan());
+}
+
+#[test]
+fn test_is_infinite() {
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    assert!(!nan.is_infinite());
+    assert!(inf.is_infinite());
+    assert!(neg_inf.is_infinite());
+    assert!(!0.0f64.is_infinite());
+    assert!(!42.8f64.is_infinite());
+    assert!(!(-109.2f64).is_infinite());
+}
+
+#[test]
+fn test_is_finite() {
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    assert!(!nan.is_finite());
+    assert!(!inf.is_finite());
+    assert!(!neg_inf.is_finite());
+    assert!(0.0f64.is_finite());
+    assert!(42.8f64.is_finite());
+    assert!((-109.2f64).is_finite());
+}
+
+#[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
+#[test]
+fn test_is_normal() {
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    let zero: f64 = 0.0f64;
+    let neg_zero: f64 = -0.0;
+    assert!(!nan.is_normal());
+    assert!(!inf.is_normal());
+    assert!(!neg_inf.is_normal());
+    assert!(!zero.is_normal());
+    assert!(!neg_zero.is_normal());
+    assert!(1f64.is_normal());
+    assert!(1e-307f64.is_normal());
+    assert!(!1e-308f64.is_normal());
+}
+
+#[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
+#[test]
+fn test_classify() {
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    let zero: f64 = 0.0f64;
+    let neg_zero: f64 = -0.0;
+    assert_eq!(nan.classify(), Fp::Nan);
+    assert_eq!(inf.classify(), Fp::Infinite);
+    assert_eq!(neg_inf.classify(), Fp::Infinite);
+    assert_eq!(zero.classify(), Fp::Zero);
+    assert_eq!(neg_zero.classify(), Fp::Zero);
+    assert_eq!(1e-307f64.classify(), Fp::Normal);
+    assert_eq!(1e-308f64.classify(), Fp::Subnormal);
+}
+
+#[test]
+fn test_floor() {
+    assert_approx_eq!(1.0f64.floor(), 1.0f64);
+    assert_approx_eq!(1.3f64.floor(), 1.0f64);
+    assert_approx_eq!(1.5f64.floor(), 1.0f64);
+    assert_approx_eq!(1.7f64.floor(), 1.0f64);
+    assert_approx_eq!(0.0f64.floor(), 0.0f64);
+    assert_approx_eq!((-0.0f64).floor(), -0.0f64);
+    assert_approx_eq!((-1.0f64).floor(), -1.0f64);
+    assert_approx_eq!((-1.3f64).floor(), -2.0f64);
+    assert_approx_eq!((-1.5f64).floor(), -2.0f64);
+    assert_approx_eq!((-1.7f64).floor(), -2.0f64);
+}
+
+#[test]
+fn test_ceil() {
+    assert_approx_eq!(1.0f64.ceil(), 1.0f64);
+    assert_approx_eq!(1.3f64.ceil(), 2.0f64);
+    assert_approx_eq!(1.5f64.ceil(), 2.0f64);
+    assert_approx_eq!(1.7f64.ceil(), 2.0f64);
+    assert_approx_eq!(0.0f64.ceil(), 0.0f64);
+    assert_approx_eq!((-0.0f64).ceil(), -0.0f64);
+    assert_approx_eq!((-1.0f64).ceil(), -1.0f64);
+    assert_approx_eq!((-1.3f64).ceil(), -1.0f64);
+    assert_approx_eq!((-1.5f64).ceil(), -1.0f64);
+    assert_approx_eq!((-1.7f64).ceil(), -1.0f64);
+}
+
+#[test]
+fn test_round() {
+    assert_approx_eq!(1.0f64.round(), 1.0f64);
+    assert_approx_eq!(1.3f64.round(), 1.0f64);
+    assert_approx_eq!(1.5f64.round(), 2.0f64);
+    assert_approx_eq!(1.7f64.round(), 2.0f64);
+    assert_approx_eq!(0.0f64.round(), 0.0f64);
+    assert_approx_eq!((-0.0f64).round(), -0.0f64);
+    assert_approx_eq!((-1.0f64).round(), -1.0f64);
+    assert_approx_eq!((-1.3f64).round(), -1.0f64);
+    assert_approx_eq!((-1.5f64).round(), -2.0f64);
+    assert_approx_eq!((-1.7f64).round(), -2.0f64);
+}
+
+#[test]
+fn test_trunc() {
+    assert_approx_eq!(1.0f64.trunc(), 1.0f64);
+    assert_approx_eq!(1.3f64.trunc(), 1.0f64);
+    assert_approx_eq!(1.5f64.trunc(), 1.0f64);
+    assert_approx_eq!(1.7f64.trunc(), 1.0f64);
+    assert_approx_eq!(0.0f64.trunc(), 0.0f64);
+    assert_approx_eq!((-0.0f64).trunc(), -0.0f64);
+    assert_approx_eq!((-1.0f64).trunc(), -1.0f64);
+    assert_approx_eq!((-1.3f64).trunc(), -1.0f64);
+    assert_approx_eq!((-1.5f64).trunc(), -1.0f64);
+    assert_approx_eq!((-1.7f64).trunc(), -1.0f64);
+}
+
+#[test]
+fn test_fract() {
+    assert_approx_eq!(1.0f64.fract(), 0.0f64);
+    assert_approx_eq!(1.3f64.fract(), 0.3f64);
+    assert_approx_eq!(1.5f64.fract(), 0.5f64);
+    assert_approx_eq!(1.7f64.fract(), 0.7f64);
+    assert_approx_eq!(0.0f64.fract(), 0.0f64);
+    assert_approx_eq!((-0.0f64).fract(), -0.0f64);
+    assert_approx_eq!((-1.0f64).fract(), -0.0f64);
+    assert_approx_eq!((-1.3f64).fract(), -0.3f64);
+    assert_approx_eq!((-1.5f64).fract(), -0.5f64);
+    assert_approx_eq!((-1.7f64).fract(), -0.7f64);
+}
+
+#[test]
+fn test_abs() {
+    assert_eq!(f64::INFINITY.abs(), f64::INFINITY);
+    assert_eq!(1f64.abs(), 1f64);
+    assert_eq!(0f64.abs(), 0f64);
+    assert_eq!((-0f64).abs(), 0f64);
+    assert_eq!((-1f64).abs(), 1f64);
+    assert_eq!(f64::NEG_INFINITY.abs(), f64::INFINITY);
+    assert_eq!((1f64 / f64::NEG_INFINITY).abs(), 0f64);
+    assert!(f64::NAN.abs().is_nan());
+}
+
+#[test]
+fn test_signum() {
+    assert_eq!(f64::INFINITY.signum(), 1f64);
+    assert_eq!(1f64.signum(), 1f64);
+    assert_eq!(0f64.signum(), 1f64);
+    assert_eq!((-0f64).signum(), -1f64);
+    assert_eq!((-1f64).signum(), -1f64);
+    assert_eq!(f64::NEG_INFINITY.signum(), -1f64);
+    assert_eq!((1f64 / f64::NEG_INFINITY).signum(), -1f64);
+    assert!(f64::NAN.signum().is_nan());
+}
+
+#[test]
+fn test_is_sign_positive() {
+    assert!(f64::INFINITY.is_sign_positive());
+    assert!(1f64.is_sign_positive());
+    assert!(0f64.is_sign_positive());
+    assert!(!(-0f64).is_sign_positive());
+    assert!(!(-1f64).is_sign_positive());
+    assert!(!f64::NEG_INFINITY.is_sign_positive());
+    assert!(!(1f64 / f64::NEG_INFINITY).is_sign_positive());
+    assert!(f64::NAN.is_sign_positive());
+    assert!(!(-f64::NAN).is_sign_positive());
+}
+
+#[test]
+fn test_is_sign_negative() {
+    assert!(!f64::INFINITY.is_sign_negative());
+    assert!(!1f64.is_sign_negative());
+    assert!(!0f64.is_sign_negative());
+    assert!((-0f64).is_sign_negative());
+    assert!((-1f64).is_sign_negative());
+    assert!(f64::NEG_INFINITY.is_sign_negative());
+    assert!((1f64 / f64::NEG_INFINITY).is_sign_negative());
+    assert!(!f64::NAN.is_sign_negative());
+    assert!((-f64::NAN).is_sign_negative());
+}
+
+#[test]
+fn test_mul_add() {
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    assert_approx_eq!(12.3f64.mul_add(4.5, 6.7), 62.05);
+    assert_approx_eq!((-12.3f64).mul_add(-4.5, -6.7), 48.65);
+    assert_approx_eq!(0.0f64.mul_add(8.9, 1.2), 1.2);
+    assert_approx_eq!(3.4f64.mul_add(-0.0, 5.6), 5.6);
+    assert!(nan.mul_add(7.8, 9.0).is_nan());
+    assert_eq!(inf.mul_add(7.8, 9.0), inf);
+    assert_eq!(neg_inf.mul_add(7.8, 9.0), neg_inf);
+    assert_eq!(8.9f64.mul_add(inf, 3.2), inf);
+    assert_eq!((-3.2f64).mul_add(2.4, neg_inf), neg_inf);
+}
+
+#[test]
+fn test_recip() {
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    assert_eq!(1.0f64.recip(), 1.0);
+    assert_eq!(2.0f64.recip(), 0.5);
+    assert_eq!((-0.4f64).recip(), -2.5);
+    assert_eq!(0.0f64.recip(), inf);
+    assert!(nan.recip().is_nan());
+    assert_eq!(inf.recip(), 0.0);
+    assert_eq!(neg_inf.recip(), 0.0);
+}
+
+#[test]
+fn test_powi() {
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    assert_eq!(1.0f64.powi(1), 1.0);
+    assert_approx_eq!((-3.1f64).powi(2), 9.61);
+    assert_approx_eq!(5.9f64.powi(-2), 0.028727);
+    assert_eq!(8.3f64.powi(0), 1.0);
+    assert!(nan.powi(2).is_nan());
+    assert_eq!(inf.powi(3), inf);
+    assert_eq!(neg_inf.powi(2), inf);
+}
+
+#[test]
+fn test_powf() {
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    assert_eq!(1.0f64.powf(1.0), 1.0);
+    assert_approx_eq!(3.4f64.powf(4.5), 246.408183);
+    assert_approx_eq!(2.7f64.powf(-3.2), 0.041652);
+    assert_approx_eq!((-3.1f64).powf(2.0), 9.61);
+    assert_approx_eq!(5.9f64.powf(-2.0), 0.028727);
+    assert_eq!(8.3f64.powf(0.0), 1.0);
+    assert!(nan.powf(2.0).is_nan());
+    assert_eq!(inf.powf(2.0), inf);
+    assert_eq!(neg_inf.powf(3.0), neg_inf);
+}
+
+#[test]
+fn test_sqrt_domain() {
+    assert!(f64::NAN.sqrt().is_nan());
+    assert!(f64::NEG_INFINITY.sqrt().is_nan());
+    assert!((-1.0f64).sqrt().is_nan());
+    assert_eq!((-0.0f64).sqrt(), -0.0);
+    assert_eq!(0.0f64.sqrt(), 0.0);
+    assert_eq!(1.0f64.sqrt(), 1.0);
+    assert_eq!(f64::INFINITY.sqrt(), f64::INFINITY);
+}
+
+#[test]
+fn test_exp() {
+    assert_eq!(1.0, 0.0f64.exp());
+    assert_approx_eq!(2.718282, 1.0f64.exp());
+    assert_approx_eq!(148.413159, 5.0f64.exp());
+
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    let nan: f64 = f64::NAN;
+    assert_eq!(inf, inf.exp());
+    assert_eq!(0.0, neg_inf.exp());
+    assert!(nan.exp().is_nan());
+}
+
+#[test]
+fn test_exp2() {
+    assert_eq!(32.0, 5.0f64.exp2());
+    assert_eq!(1.0, 0.0f64.exp2());
+
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    let nan: f64 = f64::NAN;
+    assert_eq!(inf, inf.exp2());
+    assert_eq!(0.0, neg_inf.exp2());
+    assert!(nan.exp2().is_nan());
+}
+
+#[test]
+fn test_ln() {
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    assert_approx_eq!(1.0f64.exp().ln(), 1.0);
+    assert!(nan.ln().is_nan());
+    assert_eq!(inf.ln(), inf);
+    assert!(neg_inf.ln().is_nan());
+    assert!((-2.3f64).ln().is_nan());
+    assert_eq!((-0.0f64).ln(), neg_inf);
+    assert_eq!(0.0f64.ln(), neg_inf);
+    assert_approx_eq!(4.0f64.ln(), 1.386294);
+}
+
+#[test]
+fn test_log() {
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    assert_eq!(10.0f64.log(10.0), 1.0);
+    assert_approx_eq!(2.3f64.log(3.5), 0.664858);
+    assert_eq!(1.0f64.exp().log(1.0f64.exp()), 1.0);
+    assert!(1.0f64.log(1.0).is_nan());
+    assert!(1.0f64.log(-13.9).is_nan());
+    assert!(nan.log(2.3).is_nan());
+    assert_eq!(inf.log(10.0), inf);
+    assert!(neg_inf.log(8.8).is_nan());
+    assert!((-2.3f64).log(0.1).is_nan());
+    assert_eq!((-0.0f64).log(2.0), neg_inf);
+    assert_eq!(0.0f64.log(7.0), neg_inf);
+}
+
+#[test]
+fn test_log2() {
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    assert_approx_eq!(10.0f64.log2(), 3.321928);
+    assert_approx_eq!(2.3f64.log2(), 1.201634);
+    assert_approx_eq!(1.0f64.exp().log2(), 1.442695);
+    assert!(nan.log2().is_nan());
+    assert_eq!(inf.log2(), inf);
+    assert!(neg_inf.log2().is_nan());
+    assert!((-2.3f64).log2().is_nan());
+    assert_eq!((-0.0f64).log2(), neg_inf);
+    assert_eq!(0.0f64.log2(), neg_inf);
+}
+
+#[test]
+fn test_log10() {
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    assert_eq!(10.0f64.log10(), 1.0);
+    assert_approx_eq!(2.3f64.log10(), 0.361728);
+    assert_approx_eq!(1.0f64.exp().log10(), 0.434294);
+    assert_eq!(1.0f64.log10(), 0.0);
+    assert!(nan.log10().is_nan());
+    assert_eq!(inf.log10(), inf);
+    assert!(neg_inf.log10().is_nan());
+    assert!((-2.3f64).log10().is_nan());
+    assert_eq!((-0.0f64).log10(), neg_inf);
+    assert_eq!(0.0f64.log10(), neg_inf);
+}
+
+#[test]
+fn test_to_degrees() {
+    let pi: f64 = consts::PI;
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    assert_eq!(0.0f64.to_degrees(), 0.0);
+    assert_approx_eq!((-5.8f64).to_degrees(), -332.315521);
+    assert_eq!(pi.to_degrees(), 180.0);
+    assert!(nan.to_degrees().is_nan());
+    assert_eq!(inf.to_degrees(), inf);
+    assert_eq!(neg_inf.to_degrees(), neg_inf);
+}
+
+#[test]
+fn test_to_radians() {
+    let pi: f64 = consts::PI;
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    assert_eq!(0.0f64.to_radians(), 0.0);
+    assert_approx_eq!(154.6f64.to_radians(), 2.698279);
+    assert_approx_eq!((-332.31f64).to_radians(), -5.799903);
+    assert_eq!(180.0f64.to_radians(), pi);
+    assert!(nan.to_radians().is_nan());
+    assert_eq!(inf.to_radians(), inf);
+    assert_eq!(neg_inf.to_radians(), neg_inf);
+}
+
+#[test]
+fn test_asinh() {
+    assert_eq!(0.0f64.asinh(), 0.0f64);
+    assert_eq!((-0.0f64).asinh(), -0.0f64);
+
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    let nan: f64 = f64::NAN;
+    assert_eq!(inf.asinh(), inf);
+    assert_eq!(neg_inf.asinh(), neg_inf);
+    assert!(nan.asinh().is_nan());
+    assert!((-0.0f64).asinh().is_sign_negative());
+    // issue 63271
+    assert_approx_eq!(2.0f64.asinh(), 1.443635475178810342493276740273105f64);
+    assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);
+    // regression test for the catastrophic cancellation fixed in 72486
+    assert_approx_eq!((-67452098.07139316f64).asinh(), -18.72007542627454439398548429400083);
+}
+
+#[test]
+fn test_acosh() {
+    assert_eq!(1.0f64.acosh(), 0.0f64);
+    assert!(0.999f64.acosh().is_nan());
+
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    let nan: f64 = f64::NAN;
+    assert_eq!(inf.acosh(), inf);
+    assert!(neg_inf.acosh().is_nan());
+    assert!(nan.acosh().is_nan());
+    assert_approx_eq!(2.0f64.acosh(), 1.31695789692481670862504634730796844f64);
+    assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64);
+}
+
+#[test]
+fn test_atanh() {
+    assert_eq!(0.0f64.atanh(), 0.0f64);
+    assert_eq!((-0.0f64).atanh(), -0.0f64);
+
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    let nan: f64 = f64::NAN;
+    assert_eq!(1.0f64.atanh(), inf);
+    assert_eq!((-1.0f64).atanh(), neg_inf);
+    assert!(2f64.atanh().atanh().is_nan());
+    assert!((-2f64).atanh().atanh().is_nan());
+    assert!(inf.atanh().is_nan());
+    assert!(neg_inf.atanh().is_nan());
+    assert!(nan.atanh().is_nan());
+    assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64);
+    assert_approx_eq!((-0.5f64).atanh(), -0.54930614433405484569762261846126285f64);
+}
+
+#[test]
+fn test_real_consts() {
+    use super::consts;
+    let pi: f64 = consts::PI;
+    let frac_pi_2: f64 = consts::FRAC_PI_2;
+    let frac_pi_3: f64 = consts::FRAC_PI_3;
+    let frac_pi_4: f64 = consts::FRAC_PI_4;
+    let frac_pi_6: f64 = consts::FRAC_PI_6;
+    let frac_pi_8: f64 = consts::FRAC_PI_8;
+    let frac_1_pi: f64 = consts::FRAC_1_PI;
+    let frac_2_pi: f64 = consts::FRAC_2_PI;
+    let frac_2_sqrtpi: f64 = consts::FRAC_2_SQRT_PI;
+    let sqrt2: f64 = consts::SQRT_2;
+    let frac_1_sqrt2: f64 = consts::FRAC_1_SQRT_2;
+    let e: f64 = consts::E;
+    let log2_e: f64 = consts::LOG2_E;
+    let log10_e: f64 = consts::LOG10_E;
+    let ln_2: f64 = consts::LN_2;
+    let ln_10: f64 = consts::LN_10;
+
+    assert_approx_eq!(frac_pi_2, pi / 2f64);
+    assert_approx_eq!(frac_pi_3, pi / 3f64);
+    assert_approx_eq!(frac_pi_4, pi / 4f64);
+    assert_approx_eq!(frac_pi_6, pi / 6f64);
+    assert_approx_eq!(frac_pi_8, pi / 8f64);
+    assert_approx_eq!(frac_1_pi, 1f64 / pi);
+    assert_approx_eq!(frac_2_pi, 2f64 / pi);
+    assert_approx_eq!(frac_2_sqrtpi, 2f64 / pi.sqrt());
+    assert_approx_eq!(sqrt2, 2f64.sqrt());
+    assert_approx_eq!(frac_1_sqrt2, 1f64 / 2f64.sqrt());
+    assert_approx_eq!(log2_e, e.log2());
+    assert_approx_eq!(log10_e, e.log10());
+    assert_approx_eq!(ln_2, 2f64.ln());
+    assert_approx_eq!(ln_10, 10f64.ln());
+}
+
+#[test]
+fn test_float_bits_conv() {
+    assert_eq!((1f64).to_bits(), 0x3ff0000000000000);
+    assert_eq!((12.5f64).to_bits(), 0x4029000000000000);
+    assert_eq!((1337f64).to_bits(), 0x4094e40000000000);
+    assert_eq!((-14.25f64).to_bits(), 0xc02c800000000000);
+    assert_approx_eq!(f64::from_bits(0x3ff0000000000000), 1.0);
+    assert_approx_eq!(f64::from_bits(0x4029000000000000), 12.5);
+    assert_approx_eq!(f64::from_bits(0x4094e40000000000), 1337.0);
+    assert_approx_eq!(f64::from_bits(0xc02c800000000000), -14.25);
+
+    // Check that NaNs roundtrip their bits regardless of signaling-ness
+    // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
+    let masked_nan1 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA;
+    let masked_nan2 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555;
+    assert!(f64::from_bits(masked_nan1).is_nan());
+    assert!(f64::from_bits(masked_nan2).is_nan());
+
+    assert_eq!(f64::from_bits(masked_nan1).to_bits(), masked_nan1);
+    assert_eq!(f64::from_bits(masked_nan2).to_bits(), masked_nan2);
+}
+
+#[test]
+#[should_panic]
+fn test_clamp_min_greater_than_max() {
+    let _ = 1.0f64.clamp(3.0, 1.0);
+}
+
+#[test]
+#[should_panic]
+fn test_clamp_min_is_nan() {
+    let _ = 1.0f64.clamp(f64::NAN, 1.0);
+}
+
+#[test]
+#[should_panic]
+fn test_clamp_max_is_nan() {
+    let _ = 1.0f64.clamp(3.0, f64::NAN);
+}
+
+#[test]
+fn test_total_cmp() {
+    use core::cmp::Ordering;
+
+    fn quiet_bit_mask() -> u64 {
+        1 << (f64::MANTISSA_DIGITS - 2)
+    }
+
+    fn min_subnorm() -> f64 {
+        f64::MIN_POSITIVE / f64::powf(2.0, f64::MANTISSA_DIGITS as f64 - 1.0)
+    }
+
+    fn max_subnorm() -> f64 {
+        f64::MIN_POSITIVE - min_subnorm()
+    }
+
+    fn q_nan() -> f64 {
+        f64::from_bits(f64::NAN.to_bits() | quiet_bit_mask())
+    }
+
+    fn s_nan() -> f64 {
+        f64::from_bits((f64::NAN.to_bits() & !quiet_bit_mask()) + 42)
+    }
+
+    assert_eq!(Ordering::Equal, (-q_nan()).total_cmp(&-q_nan()));
+    assert_eq!(Ordering::Equal, (-s_nan()).total_cmp(&-s_nan()));
+    assert_eq!(Ordering::Equal, (-f64::INFINITY).total_cmp(&-f64::INFINITY));
+    assert_eq!(Ordering::Equal, (-f64::MAX).total_cmp(&-f64::MAX));
+    assert_eq!(Ordering::Equal, (-2.5_f64).total_cmp(&-2.5));
+    assert_eq!(Ordering::Equal, (-1.0_f64).total_cmp(&-1.0));
+    assert_eq!(Ordering::Equal, (-1.5_f64).total_cmp(&-1.5));
+    assert_eq!(Ordering::Equal, (-0.5_f64).total_cmp(&-0.5));
+    assert_eq!(Ordering::Equal, (-f64::MIN_POSITIVE).total_cmp(&-f64::MIN_POSITIVE));
+    assert_eq!(Ordering::Equal, (-max_subnorm()).total_cmp(&-max_subnorm()));
+    assert_eq!(Ordering::Equal, (-min_subnorm()).total_cmp(&-min_subnorm()));
+    assert_eq!(Ordering::Equal, (-0.0_f64).total_cmp(&-0.0));
+    assert_eq!(Ordering::Equal, 0.0_f64.total_cmp(&0.0));
+    assert_eq!(Ordering::Equal, min_subnorm().total_cmp(&min_subnorm()));
+    assert_eq!(Ordering::Equal, max_subnorm().total_cmp(&max_subnorm()));
+    assert_eq!(Ordering::Equal, f64::MIN_POSITIVE.total_cmp(&f64::MIN_POSITIVE));
+    assert_eq!(Ordering::Equal, 0.5_f64.total_cmp(&0.5));
+    assert_eq!(Ordering::Equal, 1.0_f64.total_cmp(&1.0));
+    assert_eq!(Ordering::Equal, 1.5_f64.total_cmp(&1.5));
+    assert_eq!(Ordering::Equal, 2.5_f64.total_cmp(&2.5));
+    assert_eq!(Ordering::Equal, f64::MAX.total_cmp(&f64::MAX));
+    assert_eq!(Ordering::Equal, f64::INFINITY.total_cmp(&f64::INFINITY));
+    assert_eq!(Ordering::Equal, s_nan().total_cmp(&s_nan()));
+    assert_eq!(Ordering::Equal, q_nan().total_cmp(&q_nan()));
+
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-s_nan()));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f64::INFINITY));
+    assert_eq!(Ordering::Less, (-f64::INFINITY).total_cmp(&-f64::MAX));
+    assert_eq!(Ordering::Less, (-f64::MAX).total_cmp(&-2.5));
+    assert_eq!(Ordering::Less, (-2.5_f64).total_cmp(&-1.5));
+    assert_eq!(Ordering::Less, (-1.5_f64).total_cmp(&-1.0));
+    assert_eq!(Ordering::Less, (-1.0_f64).total_cmp(&-0.5));
+    assert_eq!(Ordering::Less, (-0.5_f64).total_cmp(&-f64::MIN_POSITIVE));
+    assert_eq!(Ordering::Less, (-f64::MIN_POSITIVE).total_cmp(&-max_subnorm()));
+    assert_eq!(Ordering::Less, (-max_subnorm()).total_cmp(&-min_subnorm()));
+    assert_eq!(Ordering::Less, (-min_subnorm()).total_cmp(&-0.0));
+    assert_eq!(Ordering::Less, (-0.0_f64).total_cmp(&0.0));
+    assert_eq!(Ordering::Less, 0.0_f64.total_cmp(&min_subnorm()));
+    assert_eq!(Ordering::Less, min_subnorm().total_cmp(&max_subnorm()));
+    assert_eq!(Ordering::Less, max_subnorm().total_cmp(&f64::MIN_POSITIVE));
+    assert_eq!(Ordering::Less, f64::MIN_POSITIVE.total_cmp(&0.5));
+    assert_eq!(Ordering::Less, 0.5_f64.total_cmp(&1.0));
+    assert_eq!(Ordering::Less, 1.0_f64.total_cmp(&1.5));
+    assert_eq!(Ordering::Less, 1.5_f64.total_cmp(&2.5));
+    assert_eq!(Ordering::Less, 2.5_f64.total_cmp(&f64::MAX));
+    assert_eq!(Ordering::Less, f64::MAX.total_cmp(&f64::INFINITY));
+    assert_eq!(Ordering::Less, f64::INFINITY.total_cmp(&s_nan()));
+    assert_eq!(Ordering::Less, s_nan().total_cmp(&q_nan()));
+
+    assert_eq!(Ordering::Greater, (-s_nan()).total_cmp(&-q_nan()));
+    assert_eq!(Ordering::Greater, (-f64::INFINITY).total_cmp(&-s_nan()));
+    assert_eq!(Ordering::Greater, (-f64::MAX).total_cmp(&-f64::INFINITY));
+    assert_eq!(Ordering::Greater, (-2.5_f64).total_cmp(&-f64::MAX));
+    assert_eq!(Ordering::Greater, (-1.5_f64).total_cmp(&-2.5));
+    assert_eq!(Ordering::Greater, (-1.0_f64).total_cmp(&-1.5));
+    assert_eq!(Ordering::Greater, (-0.5_f64).total_cmp(&-1.0));
+    assert_eq!(Ordering::Greater, (-f64::MIN_POSITIVE).total_cmp(&-0.5));
+    assert_eq!(Ordering::Greater, (-max_subnorm()).total_cmp(&-f64::MIN_POSITIVE));
+    assert_eq!(Ordering::Greater, (-min_subnorm()).total_cmp(&-max_subnorm()));
+    assert_eq!(Ordering::Greater, (-0.0_f64).total_cmp(&-min_subnorm()));
+    assert_eq!(Ordering::Greater, 0.0_f64.total_cmp(&-0.0));
+    assert_eq!(Ordering::Greater, min_subnorm().total_cmp(&0.0));
+    assert_eq!(Ordering::Greater, max_subnorm().total_cmp(&min_subnorm()));
+    assert_eq!(Ordering::Greater, f64::MIN_POSITIVE.total_cmp(&max_subnorm()));
+    assert_eq!(Ordering::Greater, 0.5_f64.total_cmp(&f64::MIN_POSITIVE));
+    assert_eq!(Ordering::Greater, 1.0_f64.total_cmp(&0.5));
+    assert_eq!(Ordering::Greater, 1.5_f64.total_cmp(&1.0));
+    assert_eq!(Ordering::Greater, 2.5_f64.total_cmp(&1.5));
+    assert_eq!(Ordering::Greater, f64::MAX.total_cmp(&2.5));
+    assert_eq!(Ordering::Greater, f64::INFINITY.total_cmp(&f64::MAX));
+    assert_eq!(Ordering::Greater, s_nan().total_cmp(&f64::INFINITY));
+    assert_eq!(Ordering::Greater, q_nan().total_cmp(&s_nan()));
+
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-s_nan()));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f64::INFINITY));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f64::MAX));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-2.5));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-1.5));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-1.0));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-0.5));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f64::MIN_POSITIVE));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-max_subnorm()));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-min_subnorm()));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-0.0));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&0.0));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&min_subnorm()));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&max_subnorm()));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f64::MIN_POSITIVE));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&0.5));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&1.0));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&1.5));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&2.5));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f64::MAX));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f64::INFINITY));
+    assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&s_nan()));
+
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f64::INFINITY));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f64::MAX));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-2.5));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-1.5));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-1.0));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-0.5));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f64::MIN_POSITIVE));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-max_subnorm()));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-min_subnorm()));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-0.0));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&0.0));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&min_subnorm()));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&max_subnorm()));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f64::MIN_POSITIVE));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&0.5));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&1.0));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&1.5));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&2.5));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f64::MAX));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f64::INFINITY));
+    assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&s_nan()));
+}
diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs
index 717967fb768..51deb217c7c 100644
--- a/library/std/src/ffi/c_str.rs
+++ b/library/std/src/ffi/c_str.rs
@@ -1,4 +1,8 @@
 #![deny(unsafe_op_in_unsafe_fn)]
+
+#[cfg(test)]
+mod tests;
+
 use crate::ascii;
 use crate::borrow::{Borrow, Cow};
 use crate::cmp::Ordering;
@@ -1522,202 +1526,3 @@ impl AsRef<CStr> for CString {
         self
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::borrow::Cow::{Borrowed, Owned};
-    use crate::collections::hash_map::DefaultHasher;
-    use crate::hash::{Hash, Hasher};
-    use crate::os::raw::c_char;
-    use crate::rc::Rc;
-    use crate::sync::Arc;
-
-    #[test]
-    fn c_to_rust() {
-        let data = b"123\0";
-        let ptr = data.as_ptr() as *const c_char;
-        unsafe {
-            assert_eq!(CStr::from_ptr(ptr).to_bytes(), b"123");
-            assert_eq!(CStr::from_ptr(ptr).to_bytes_with_nul(), b"123\0");
-        }
-    }
-
-    #[test]
-    fn simple() {
-        let s = CString::new("1234").unwrap();
-        assert_eq!(s.as_bytes(), b"1234");
-        assert_eq!(s.as_bytes_with_nul(), b"1234\0");
-    }
-
-    #[test]
-    fn build_with_zero1() {
-        assert!(CString::new(&b"\0"[..]).is_err());
-    }
-    #[test]
-    fn build_with_zero2() {
-        assert!(CString::new(vec![0]).is_err());
-    }
-
-    #[test]
-    fn build_with_zero3() {
-        unsafe {
-            let s = CString::from_vec_unchecked(vec![0]);
-            assert_eq!(s.as_bytes(), b"\0");
-        }
-    }
-
-    #[test]
-    fn formatted() {
-        let s = CString::new(&b"abc\x01\x02\n\xE2\x80\xA6\xFF"[..]).unwrap();
-        assert_eq!(format!("{:?}", s), r#""abc\x01\x02\n\xe2\x80\xa6\xff""#);
-    }
-
-    #[test]
-    fn borrowed() {
-        unsafe {
-            let s = CStr::from_ptr(b"12\0".as_ptr() as *const _);
-            assert_eq!(s.to_bytes(), b"12");
-            assert_eq!(s.to_bytes_with_nul(), b"12\0");
-        }
-    }
-
-    #[test]
-    fn to_str() {
-        let data = b"123\xE2\x80\xA6\0";
-        let ptr = data.as_ptr() as *const c_char;
-        unsafe {
-            assert_eq!(CStr::from_ptr(ptr).to_str(), Ok("123…"));
-            assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Borrowed("123…"));
-        }
-        let data = b"123\xE2\0";
-        let ptr = data.as_ptr() as *const c_char;
-        unsafe {
-            assert!(CStr::from_ptr(ptr).to_str().is_err());
-            assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Owned::<str>(format!("123\u{FFFD}")));
-        }
-    }
-
-    #[test]
-    fn to_owned() {
-        let data = b"123\0";
-        let ptr = data.as_ptr() as *const c_char;
-
-        let owned = unsafe { CStr::from_ptr(ptr).to_owned() };
-        assert_eq!(owned.as_bytes_with_nul(), data);
-    }
-
-    #[test]
-    fn equal_hash() {
-        let data = b"123\xE2\xFA\xA6\0";
-        let ptr = data.as_ptr() as *const c_char;
-        let cstr: &'static CStr = unsafe { CStr::from_ptr(ptr) };
-
-        let mut s = DefaultHasher::new();
-        cstr.hash(&mut s);
-        let cstr_hash = s.finish();
-        let mut s = DefaultHasher::new();
-        CString::new(&data[..data.len() - 1]).unwrap().hash(&mut s);
-        let cstring_hash = s.finish();
-
-        assert_eq!(cstr_hash, cstring_hash);
-    }
-
-    #[test]
-    fn from_bytes_with_nul() {
-        let data = b"123\0";
-        let cstr = CStr::from_bytes_with_nul(data);
-        assert_eq!(cstr.map(CStr::to_bytes), Ok(&b"123"[..]));
-        let cstr = CStr::from_bytes_with_nul(data);
-        assert_eq!(cstr.map(CStr::to_bytes_with_nul), Ok(&b"123\0"[..]));
-
-        unsafe {
-            let cstr = CStr::from_bytes_with_nul(data);
-            let cstr_unchecked = CStr::from_bytes_with_nul_unchecked(data);
-            assert_eq!(cstr, Ok(cstr_unchecked));
-        }
-    }
-
-    #[test]
-    fn from_bytes_with_nul_unterminated() {
-        let data = b"123";
-        let cstr = CStr::from_bytes_with_nul(data);
-        assert!(cstr.is_err());
-    }
-
-    #[test]
-    fn from_bytes_with_nul_interior() {
-        let data = b"1\023\0";
-        let cstr = CStr::from_bytes_with_nul(data);
-        assert!(cstr.is_err());
-    }
-
-    #[test]
-    fn into_boxed() {
-        let orig: &[u8] = b"Hello, world!\0";
-        let cstr = CStr::from_bytes_with_nul(orig).unwrap();
-        let boxed: Box<CStr> = Box::from(cstr);
-        let cstring = cstr.to_owned().into_boxed_c_str().into_c_string();
-        assert_eq!(cstr, &*boxed);
-        assert_eq!(&*boxed, &*cstring);
-        assert_eq!(&*cstring, cstr);
-    }
-
-    #[test]
-    fn boxed_default() {
-        let boxed = <Box<CStr>>::default();
-        assert_eq!(boxed.to_bytes_with_nul(), &[0]);
-    }
-
-    #[test]
-    fn test_c_str_clone_into() {
-        let mut c_string = CString::new("lorem").unwrap();
-        let c_ptr = c_string.as_ptr();
-        let c_str = CStr::from_bytes_with_nul(b"ipsum\0").unwrap();
-        c_str.clone_into(&mut c_string);
-        assert_eq!(c_str, c_string.as_c_str());
-        // The exact same size shouldn't have needed to move its allocation
-        assert_eq!(c_ptr, c_string.as_ptr());
-    }
-
-    #[test]
-    fn into_rc() {
-        let orig: &[u8] = b"Hello, world!\0";
-        let cstr = CStr::from_bytes_with_nul(orig).unwrap();
-        let rc: Rc<CStr> = Rc::from(cstr);
-        let arc: Arc<CStr> = Arc::from(cstr);
-
-        assert_eq!(&*rc, cstr);
-        assert_eq!(&*arc, cstr);
-
-        let rc2: Rc<CStr> = Rc::from(cstr.to_owned());
-        let arc2: Arc<CStr> = Arc::from(cstr.to_owned());
-
-        assert_eq!(&*rc2, cstr);
-        assert_eq!(&*arc2, cstr);
-    }
-
-    #[test]
-    fn cstr_const_constructor() {
-        const CSTR: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"Hello, world!\0") };
-
-        assert_eq!(CSTR.to_str().unwrap(), "Hello, world!");
-    }
-
-    #[test]
-    fn cstr_index_from() {
-        let original = b"Hello, world!\0";
-        let cstr = CStr::from_bytes_with_nul(original).unwrap();
-        let result = CStr::from_bytes_with_nul(&original[7..]).unwrap();
-
-        assert_eq!(&cstr[7..], result);
-    }
-
-    #[test]
-    #[should_panic]
-    fn cstr_index_from_empty() {
-        let original = b"Hello, world!\0";
-        let cstr = CStr::from_bytes_with_nul(original).unwrap();
-        let _ = &cstr[original.len()..];
-    }
-}
diff --git a/library/std/src/ffi/c_str/tests.rs b/library/std/src/ffi/c_str/tests.rs
new file mode 100644
index 00000000000..4dff3df63a8
--- /dev/null
+++ b/library/std/src/ffi/c_str/tests.rs
@@ -0,0 +1,195 @@
+use super::*;
+use crate::borrow::Cow::{Borrowed, Owned};
+use crate::collections::hash_map::DefaultHasher;
+use crate::hash::{Hash, Hasher};
+use crate::os::raw::c_char;
+use crate::rc::Rc;
+use crate::sync::Arc;
+
+#[test]
+fn c_to_rust() {
+    let data = b"123\0";
+    let ptr = data.as_ptr() as *const c_char;
+    unsafe {
+        assert_eq!(CStr::from_ptr(ptr).to_bytes(), b"123");
+        assert_eq!(CStr::from_ptr(ptr).to_bytes_with_nul(), b"123\0");
+    }
+}
+
+#[test]
+fn simple() {
+    let s = CString::new("1234").unwrap();
+    assert_eq!(s.as_bytes(), b"1234");
+    assert_eq!(s.as_bytes_with_nul(), b"1234\0");
+}
+
+#[test]
+fn build_with_zero1() {
+    assert!(CString::new(&b"\0"[..]).is_err());
+}
+#[test]
+fn build_with_zero2() {
+    assert!(CString::new(vec![0]).is_err());
+}
+
+#[test]
+fn build_with_zero3() {
+    unsafe {
+        let s = CString::from_vec_unchecked(vec![0]);
+        assert_eq!(s.as_bytes(), b"\0");
+    }
+}
+
+#[test]
+fn formatted() {
+    let s = CString::new(&b"abc\x01\x02\n\xE2\x80\xA6\xFF"[..]).unwrap();
+    assert_eq!(format!("{:?}", s), r#""abc\x01\x02\n\xe2\x80\xa6\xff""#);
+}
+
+#[test]
+fn borrowed() {
+    unsafe {
+        let s = CStr::from_ptr(b"12\0".as_ptr() as *const _);
+        assert_eq!(s.to_bytes(), b"12");
+        assert_eq!(s.to_bytes_with_nul(), b"12\0");
+    }
+}
+
+#[test]
+fn to_str() {
+    let data = b"123\xE2\x80\xA6\0";
+    let ptr = data.as_ptr() as *const c_char;
+    unsafe {
+        assert_eq!(CStr::from_ptr(ptr).to_str(), Ok("123…"));
+        assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Borrowed("123…"));
+    }
+    let data = b"123\xE2\0";
+    let ptr = data.as_ptr() as *const c_char;
+    unsafe {
+        assert!(CStr::from_ptr(ptr).to_str().is_err());
+        assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Owned::<str>(format!("123\u{FFFD}")));
+    }
+}
+
+#[test]
+fn to_owned() {
+    let data = b"123\0";
+    let ptr = data.as_ptr() as *const c_char;
+
+    let owned = unsafe { CStr::from_ptr(ptr).to_owned() };
+    assert_eq!(owned.as_bytes_with_nul(), data);
+}
+
+#[test]
+fn equal_hash() {
+    let data = b"123\xE2\xFA\xA6\0";
+    let ptr = data.as_ptr() as *const c_char;
+    let cstr: &'static CStr = unsafe { CStr::from_ptr(ptr) };
+
+    let mut s = DefaultHasher::new();
+    cstr.hash(&mut s);
+    let cstr_hash = s.finish();
+    let mut s = DefaultHasher::new();
+    CString::new(&data[..data.len() - 1]).unwrap().hash(&mut s);
+    let cstring_hash = s.finish();
+
+    assert_eq!(cstr_hash, cstring_hash);
+}
+
+#[test]
+fn from_bytes_with_nul() {
+    let data = b"123\0";
+    let cstr = CStr::from_bytes_with_nul(data);
+    assert_eq!(cstr.map(CStr::to_bytes), Ok(&b"123"[..]));
+    let cstr = CStr::from_bytes_with_nul(data);
+    assert_eq!(cstr.map(CStr::to_bytes_with_nul), Ok(&b"123\0"[..]));
+
+    unsafe {
+        let cstr = CStr::from_bytes_with_nul(data);
+        let cstr_unchecked = CStr::from_bytes_with_nul_unchecked(data);
+        assert_eq!(cstr, Ok(cstr_unchecked));
+    }
+}
+
+#[test]
+fn from_bytes_with_nul_unterminated() {
+    let data = b"123";
+    let cstr = CStr::from_bytes_with_nul(data);
+    assert!(cstr.is_err());
+}
+
+#[test]
+fn from_bytes_with_nul_interior() {
+    let data = b"1\023\0";
+    let cstr = CStr::from_bytes_with_nul(data);
+    assert!(cstr.is_err());
+}
+
+#[test]
+fn into_boxed() {
+    let orig: &[u8] = b"Hello, world!\0";
+    let cstr = CStr::from_bytes_with_nul(orig).unwrap();
+    let boxed: Box<CStr> = Box::from(cstr);
+    let cstring = cstr.to_owned().into_boxed_c_str().into_c_string();
+    assert_eq!(cstr, &*boxed);
+    assert_eq!(&*boxed, &*cstring);
+    assert_eq!(&*cstring, cstr);
+}
+
+#[test]
+fn boxed_default() {
+    let boxed = <Box<CStr>>::default();
+    assert_eq!(boxed.to_bytes_with_nul(), &[0]);
+}
+
+#[test]
+fn test_c_str_clone_into() {
+    let mut c_string = CString::new("lorem").unwrap();
+    let c_ptr = c_string.as_ptr();
+    let c_str = CStr::from_bytes_with_nul(b"ipsum\0").unwrap();
+    c_str.clone_into(&mut c_string);
+    assert_eq!(c_str, c_string.as_c_str());
+    // The exact same size shouldn't have needed to move its allocation
+    assert_eq!(c_ptr, c_string.as_ptr());
+}
+
+#[test]
+fn into_rc() {
+    let orig: &[u8] = b"Hello, world!\0";
+    let cstr = CStr::from_bytes_with_nul(orig).unwrap();
+    let rc: Rc<CStr> = Rc::from(cstr);
+    let arc: Arc<CStr> = Arc::from(cstr);
+
+    assert_eq!(&*rc, cstr);
+    assert_eq!(&*arc, cstr);
+
+    let rc2: Rc<CStr> = Rc::from(cstr.to_owned());
+    let arc2: Arc<CStr> = Arc::from(cstr.to_owned());
+
+    assert_eq!(&*rc2, cstr);
+    assert_eq!(&*arc2, cstr);
+}
+
+#[test]
+fn cstr_const_constructor() {
+    const CSTR: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"Hello, world!\0") };
+
+    assert_eq!(CSTR.to_str().unwrap(), "Hello, world!");
+}
+
+#[test]
+fn cstr_index_from() {
+    let original = b"Hello, world!\0";
+    let cstr = CStr::from_bytes_with_nul(original).unwrap();
+    let result = CStr::from_bytes_with_nul(&original[7..]).unwrap();
+
+    assert_eq!(&cstr[7..], result);
+}
+
+#[test]
+#[should_panic]
+fn cstr_index_from_empty() {
+    let original = b"Hello, world!\0";
+    let cstr = CStr::from_bytes_with_nul(original).unwrap();
+    let _ = &cstr[original.len()..];
+}
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index 262d39d98ee..e0be6d1c836 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -1,3 +1,6 @@
+#[cfg(test)]
+mod tests;
+
 use crate::borrow::{Borrow, Cow};
 use crate::cmp;
 use crate::fmt;
@@ -1145,172 +1148,3 @@ impl FromStr for OsString {
         Ok(OsString::from(s))
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::sys_common::{AsInner, IntoInner};
-
-    use crate::rc::Rc;
-    use crate::sync::Arc;
-
-    #[test]
-    fn test_os_string_with_capacity() {
-        let os_string = OsString::with_capacity(0);
-        assert_eq!(0, os_string.inner.into_inner().capacity());
-
-        let os_string = OsString::with_capacity(10);
-        assert_eq!(10, os_string.inner.into_inner().capacity());
-
-        let mut os_string = OsString::with_capacity(0);
-        os_string.push("abc");
-        assert!(os_string.inner.into_inner().capacity() >= 3);
-    }
-
-    #[test]
-    fn test_os_string_clear() {
-        let mut os_string = OsString::from("abc");
-        assert_eq!(3, os_string.inner.as_inner().len());
-
-        os_string.clear();
-        assert_eq!(&os_string, "");
-        assert_eq!(0, os_string.inner.as_inner().len());
-    }
-
-    #[test]
-    fn test_os_string_capacity() {
-        let os_string = OsString::with_capacity(0);
-        assert_eq!(0, os_string.capacity());
-
-        let os_string = OsString::with_capacity(10);
-        assert_eq!(10, os_string.capacity());
-
-        let mut os_string = OsString::with_capacity(0);
-        os_string.push("abc");
-        assert!(os_string.capacity() >= 3);
-    }
-
-    #[test]
-    fn test_os_string_reserve() {
-        let mut os_string = OsString::new();
-        assert_eq!(os_string.capacity(), 0);
-
-        os_string.reserve(2);
-        assert!(os_string.capacity() >= 2);
-
-        for _ in 0..16 {
-            os_string.push("a");
-        }
-
-        assert!(os_string.capacity() >= 16);
-        os_string.reserve(16);
-        assert!(os_string.capacity() >= 32);
-
-        os_string.push("a");
-
-        os_string.reserve(16);
-        assert!(os_string.capacity() >= 33)
-    }
-
-    #[test]
-    fn test_os_string_reserve_exact() {
-        let mut os_string = OsString::new();
-        assert_eq!(os_string.capacity(), 0);
-
-        os_string.reserve_exact(2);
-        assert!(os_string.capacity() >= 2);
-
-        for _ in 0..16 {
-            os_string.push("a");
-        }
-
-        assert!(os_string.capacity() >= 16);
-        os_string.reserve_exact(16);
-        assert!(os_string.capacity() >= 32);
-
-        os_string.push("a");
-
-        os_string.reserve_exact(16);
-        assert!(os_string.capacity() >= 33)
-    }
-
-    #[test]
-    fn test_os_string_default() {
-        let os_string: OsString = Default::default();
-        assert_eq!("", &os_string);
-    }
-
-    #[test]
-    fn test_os_str_is_empty() {
-        let mut os_string = OsString::new();
-        assert!(os_string.is_empty());
-
-        os_string.push("abc");
-        assert!(!os_string.is_empty());
-
-        os_string.clear();
-        assert!(os_string.is_empty());
-    }
-
-    #[test]
-    fn test_os_str_len() {
-        let mut os_string = OsString::new();
-        assert_eq!(0, os_string.len());
-
-        os_string.push("abc");
-        assert_eq!(3, os_string.len());
-
-        os_string.clear();
-        assert_eq!(0, os_string.len());
-    }
-
-    #[test]
-    fn test_os_str_default() {
-        let os_str: &OsStr = Default::default();
-        assert_eq!("", os_str);
-    }
-
-    #[test]
-    fn into_boxed() {
-        let orig = "Hello, world!";
-        let os_str = OsStr::new(orig);
-        let boxed: Box<OsStr> = Box::from(os_str);
-        let os_string = os_str.to_owned().into_boxed_os_str().into_os_string();
-        assert_eq!(os_str, &*boxed);
-        assert_eq!(&*boxed, &*os_string);
-        assert_eq!(&*os_string, os_str);
-    }
-
-    #[test]
-    fn boxed_default() {
-        let boxed = <Box<OsStr>>::default();
-        assert!(boxed.is_empty());
-    }
-
-    #[test]
-    fn test_os_str_clone_into() {
-        let mut os_string = OsString::with_capacity(123);
-        os_string.push("hello");
-        let os_str = OsStr::new("bonjour");
-        os_str.clone_into(&mut os_string);
-        assert_eq!(os_str, os_string);
-        assert!(os_string.capacity() >= 123);
-    }
-
-    #[test]
-    fn into_rc() {
-        let orig = "Hello, world!";
-        let os_str = OsStr::new(orig);
-        let rc: Rc<OsStr> = Rc::from(os_str);
-        let arc: Arc<OsStr> = Arc::from(os_str);
-
-        assert_eq!(&*rc, os_str);
-        assert_eq!(&*arc, os_str);
-
-        let rc2: Rc<OsStr> = Rc::from(os_str.to_owned());
-        let arc2: Arc<OsStr> = Arc::from(os_str.to_owned());
-
-        assert_eq!(&*rc2, os_str);
-        assert_eq!(&*arc2, os_str);
-    }
-}
diff --git a/library/std/src/ffi/os_str/tests.rs b/library/std/src/ffi/os_str/tests.rs
new file mode 100644
index 00000000000..283f2b577e8
--- /dev/null
+++ b/library/std/src/ffi/os_str/tests.rs
@@ -0,0 +1,165 @@
+use super::*;
+use crate::sys_common::{AsInner, IntoInner};
+
+use crate::rc::Rc;
+use crate::sync::Arc;
+
+#[test]
+fn test_os_string_with_capacity() {
+    let os_string = OsString::with_capacity(0);
+    assert_eq!(0, os_string.inner.into_inner().capacity());
+
+    let os_string = OsString::with_capacity(10);
+    assert_eq!(10, os_string.inner.into_inner().capacity());
+
+    let mut os_string = OsString::with_capacity(0);
+    os_string.push("abc");
+    assert!(os_string.inner.into_inner().capacity() >= 3);
+}
+
+#[test]
+fn test_os_string_clear() {
+    let mut os_string = OsString::from("abc");
+    assert_eq!(3, os_string.inner.as_inner().len());
+
+    os_string.clear();
+    assert_eq!(&os_string, "");
+    assert_eq!(0, os_string.inner.as_inner().len());
+}
+
+#[test]
+fn test_os_string_capacity() {
+    let os_string = OsString::with_capacity(0);
+    assert_eq!(0, os_string.capacity());
+
+    let os_string = OsString::with_capacity(10);
+    assert_eq!(10, os_string.capacity());
+
+    let mut os_string = OsString::with_capacity(0);
+    os_string.push("abc");
+    assert!(os_string.capacity() >= 3);
+}
+
+#[test]
+fn test_os_string_reserve() {
+    let mut os_string = OsString::new();
+    assert_eq!(os_string.capacity(), 0);
+
+    os_string.reserve(2);
+    assert!(os_string.capacity() >= 2);
+
+    for _ in 0..16 {
+        os_string.push("a");
+    }
+
+    assert!(os_string.capacity() >= 16);
+    os_string.reserve(16);
+    assert!(os_string.capacity() >= 32);
+
+    os_string.push("a");
+
+    os_string.reserve(16);
+    assert!(os_string.capacity() >= 33)
+}
+
+#[test]
+fn test_os_string_reserve_exact() {
+    let mut os_string = OsString::new();
+    assert_eq!(os_string.capacity(), 0);
+
+    os_string.reserve_exact(2);
+    assert!(os_string.capacity() >= 2);
+
+    for _ in 0..16 {
+        os_string.push("a");
+    }
+
+    assert!(os_string.capacity() >= 16);
+    os_string.reserve_exact(16);
+    assert!(os_string.capacity() >= 32);
+
+    os_string.push("a");
+
+    os_string.reserve_exact(16);
+    assert!(os_string.capacity() >= 33)
+}
+
+#[test]
+fn test_os_string_default() {
+    let os_string: OsString = Default::default();
+    assert_eq!("", &os_string);
+}
+
+#[test]
+fn test_os_str_is_empty() {
+    let mut os_string = OsString::new();
+    assert!(os_string.is_empty());
+
+    os_string.push("abc");
+    assert!(!os_string.is_empty());
+
+    os_string.clear();
+    assert!(os_string.is_empty());
+}
+
+#[test]
+fn test_os_str_len() {
+    let mut os_string = OsString::new();
+    assert_eq!(0, os_string.len());
+
+    os_string.push("abc");
+    assert_eq!(3, os_string.len());
+
+    os_string.clear();
+    assert_eq!(0, os_string.len());
+}
+
+#[test]
+fn test_os_str_default() {
+    let os_str: &OsStr = Default::default();
+    assert_eq!("", os_str);
+}
+
+#[test]
+fn into_boxed() {
+    let orig = "Hello, world!";
+    let os_str = OsStr::new(orig);
+    let boxed: Box<OsStr> = Box::from(os_str);
+    let os_string = os_str.to_owned().into_boxed_os_str().into_os_string();
+    assert_eq!(os_str, &*boxed);
+    assert_eq!(&*boxed, &*os_string);
+    assert_eq!(&*os_string, os_str);
+}
+
+#[test]
+fn boxed_default() {
+    let boxed = <Box<OsStr>>::default();
+    assert!(boxed.is_empty());
+}
+
+#[test]
+fn test_os_str_clone_into() {
+    let mut os_string = OsString::with_capacity(123);
+    os_string.push("hello");
+    let os_str = OsStr::new("bonjour");
+    os_str.clone_into(&mut os_string);
+    assert_eq!(os_str, os_string);
+    assert!(os_string.capacity() >= 123);
+}
+
+#[test]
+fn into_rc() {
+    let orig = "Hello, world!";
+    let os_str = OsStr::new(orig);
+    let rc: Rc<OsStr> = Rc::from(os_str);
+    let arc: Arc<OsStr> = Arc::from(os_str);
+
+    assert_eq!(&*rc, os_str);
+    assert_eq!(&*arc, os_str);
+
+    let rc2: Rc<OsStr> = Rc::from(os_str.to_owned());
+    let arc2: Arc<OsStr> = Arc::from(os_str.to_owned());
+
+    assert_eq!(&*rc2, os_str);
+    assert_eq!(&*arc2, os_str);
+}
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index b1630f8f549..161bfe3795c 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-filelength
-
 //! Filesystem manipulation operations.
 //!
 //! This module contains basic methods to manipulate the contents of the local
@@ -10,6 +8,9 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 #![deny(unsafe_op_in_unsafe_fn)]
 
+#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))]
+mod tests;
+
 use crate::ffi::OsString;
 use crate::fmt;
 use crate::io::{self, Initializer, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};
@@ -552,7 +553,7 @@ impl File {
     /// the `SetFileInformationByHandle` function on Windows. Note that, this
     /// [may change in the future][changes].
     ///
-    /// [changes]: ../io/index.html#platform-specific-behavior
+    /// [changes]: io#platform-specific-behavior
     ///
     /// # Errors
     ///
@@ -1502,7 +1503,7 @@ impl AsInner<fs_imp::DirEntry> for DirEntry {
 /// and the `DeleteFile` function on Windows.
 /// Note that, this [may change in the future][changes].
 ///
-/// [changes]: ../io/index.html#platform-specific-behavior
+/// [changes]: io#platform-specific-behavior
 ///
 /// # Errors
 ///
@@ -1540,7 +1541,7 @@ pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// and the `GetFileAttributesEx` function on Windows.
 /// Note that, this [may change in the future][changes].
 ///
-/// [changes]: ../io/index.html#platform-specific-behavior
+/// [changes]: io#platform-specific-behavior
 ///
 /// # Errors
 ///
@@ -1574,7 +1575,7 @@ pub fn metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
 /// and the `GetFileAttributesEx` function on Windows.
 /// Note that, this [may change in the future][changes].
 ///
-/// [changes]: ../io/index.html#platform-specific-behavior
+/// [changes]: io#platform-specific-behavior
 ///
 /// # Errors
 ///
@@ -1617,7 +1618,7 @@ pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
 ///
 /// Note that, this [may change in the future][changes].
 ///
-/// [changes]: ../io/index.html#platform-specific-behavior
+/// [changes]: io#platform-specific-behavior
 ///
 /// # Errors
 ///
@@ -1668,7 +1669,7 @@ pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()>
 /// `fcopyfile`.
 /// Note that, this [may change in the future][changes].
 ///
-/// [changes]: ../io/index.html#platform-specific-behavior
+/// [changes]: io#platform-specific-behavior
 ///
 /// # Errors
 ///
@@ -1706,7 +1707,7 @@ pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64> {
 /// and the `CreateHardLink` function on Windows.
 /// Note that, this [may change in the future][changes].
 ///
-/// [changes]: ../io/index.html#platform-specific-behavior
+/// [changes]: io#platform-specific-behavior
 ///
 /// # Errors
 ///
@@ -1771,7 +1772,7 @@ pub fn soft_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<(
 /// `FILE_FLAG_BACKUP_SEMANTICS` flags on Windows.
 /// Note that, this [may change in the future][changes].
 ///
-/// [changes]: ../io/index.html#platform-specific-behavior
+/// [changes]: io#platform-specific-behavior
 ///
 /// # Errors
 ///
@@ -1811,7 +1812,7 @@ pub fn read_link<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
 /// with other applications (if passed to the application on the command-line,
 /// or written to a file another application may read).
 ///
-/// [changes]: ../io/index.html#platform-specific-behavior
+/// [changes]: io#platform-specific-behavior
 /// [path]: https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
 ///
 /// # Errors
@@ -1845,7 +1846,7 @@ pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
 /// and the `CreateDirectory` function on Windows.
 /// Note that, this [may change in the future][changes].
 ///
-/// [changes]: ../io/index.html#platform-specific-behavior
+/// [changes]: io#platform-specific-behavior
 ///
 /// **NOTE**: If a parent of the given path doesn't exist, this function will
 /// return an error. To create a directory and all its missing parents at the
@@ -1886,7 +1887,7 @@ pub fn create_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// and the `CreateDirectory` function on Windows.
 /// Note that, this [may change in the future][changes].
 ///
-/// [changes]: ../io/index.html#platform-specific-behavior
+/// [changes]: io#platform-specific-behavior
 ///
 /// # Errors
 ///
@@ -1929,7 +1930,7 @@ pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// and the `RemoveDirectory` function on Windows.
 /// Note that, this [may change in the future][changes].
 ///
-/// [changes]: ../io/index.html#platform-specific-behavior
+/// [changes]: io#platform-specific-behavior
 ///
 /// # Errors
 ///
@@ -1969,7 +1970,7 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// on Windows.
 /// Note that, this [may change in the future][changes].
 ///
-/// [changes]: ../io/index.html#platform-specific-behavior
+/// [changes]: io#platform-specific-behavior
 ///
 /// # Errors
 ///
@@ -2005,7 +2006,7 @@ pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// currently corresponds to `readdir` on Unix and `FindNextFile` on Windows.
 /// Note that, this [may change in the future][changes].
 ///
-/// [changes]: ../io/index.html#platform-specific-behavior
+/// [changes]: io#platform-specific-behavior
 ///
 /// The order in which this iterator returns entries is platform and filesystem
 /// dependent.
@@ -2074,7 +2075,7 @@ pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir> {
 /// and the `SetFileAttributes` function on Windows.
 /// Note that, this [may change in the future][changes].
 ///
-/// [changes]: ../io/index.html#platform-specific-behavior
+/// [changes]: io#platform-specific-behavior
 ///
 /// # Errors
 ///
@@ -2194,1349 +2195,3 @@ impl AsInnerMut<fs_imp::DirBuilder> for DirBuilder {
         &mut self.inner
     }
 }
-
-#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))]
-mod tests {
-    use crate::io::prelude::*;
-
-    use crate::fs::{self, File, OpenOptions};
-    use crate::io::{ErrorKind, SeekFrom};
-    use crate::path::Path;
-    use crate::str;
-    use crate::sys_common::io::test::{tmpdir, TempDir};
-    use crate::thread;
-
-    use rand::{rngs::StdRng, RngCore, SeedableRng};
-
-    #[cfg(unix)]
-    use crate::os::unix::fs::symlink as symlink_dir;
-    #[cfg(unix)]
-    use crate::os::unix::fs::symlink as symlink_file;
-    #[cfg(unix)]
-    use crate::os::unix::fs::symlink as symlink_junction;
-    #[cfg(windows)]
-    use crate::os::windows::fs::{symlink_dir, symlink_file};
-    #[cfg(windows)]
-    use crate::sys::fs::symlink_junction;
-
-    macro_rules! check {
-        ($e:expr) => {
-            match $e {
-                Ok(t) => t,
-                Err(e) => panic!("{} failed with: {}", stringify!($e), e),
-            }
-        };
-    }
-
-    #[cfg(windows)]
-    macro_rules! error {
-        ($e:expr, $s:expr) => {
-            match $e {
-                Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
-                Err(ref err) => assert!(
-                    err.raw_os_error() == Some($s),
-                    format!("`{}` did not have a code of `{}`", err, $s)
-                ),
-            }
-        };
-    }
-
-    #[cfg(unix)]
-    macro_rules! error {
-        ($e:expr, $s:expr) => {
-            error_contains!($e, $s)
-        };
-    }
-
-    macro_rules! error_contains {
-        ($e:expr, $s:expr) => {
-            match $e {
-                Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
-                Err(ref err) => assert!(
-                    err.to_string().contains($s),
-                    format!("`{}` did not contain `{}`", err, $s)
-                ),
-            }
-        };
-    }
-
-    // Several test fail on windows if the user does not have permission to
-    // create symlinks (the `SeCreateSymbolicLinkPrivilege`). Instead of
-    // disabling these test on Windows, use this function to test whether we
-    // have permission, and return otherwise. This way, we still don't run these
-    // tests most of the time, but at least we do if the user has the right
-    // permissions.
-    pub fn got_symlink_permission(tmpdir: &TempDir) -> bool {
-        if cfg!(unix) {
-            return true;
-        }
-        let link = tmpdir.join("some_hopefully_unique_link_name");
-
-        match symlink_file(r"nonexisting_target", link) {
-            Ok(_) => true,
-            // ERROR_PRIVILEGE_NOT_HELD = 1314
-            Err(ref err) if err.raw_os_error() == Some(1314) => false,
-            Err(_) => true,
-        }
-    }
-
-    #[test]
-    fn file_test_io_smoke_test() {
-        let message = "it's alright. have a good time";
-        let tmpdir = tmpdir();
-        let filename = &tmpdir.join("file_rt_io_file_test.txt");
-        {
-            let mut write_stream = check!(File::create(filename));
-            check!(write_stream.write(message.as_bytes()));
-        }
-        {
-            let mut read_stream = check!(File::open(filename));
-            let mut read_buf = [0; 1028];
-            let read_str = match check!(read_stream.read(&mut read_buf)) {
-                0 => panic!("shouldn't happen"),
-                n => str::from_utf8(&read_buf[..n]).unwrap().to_string(),
-            };
-            assert_eq!(read_str, message);
-        }
-        check!(fs::remove_file(filename));
-    }
-
-    #[test]
-    fn invalid_path_raises() {
-        let tmpdir = tmpdir();
-        let filename = &tmpdir.join("file_that_does_not_exist.txt");
-        let result = File::open(filename);
-
-        #[cfg(all(unix, not(target_os = "vxworks")))]
-        error!(result, "No such file or directory");
-        #[cfg(target_os = "vxworks")]
-        error!(result, "no such file or directory");
-        #[cfg(windows)]
-        error!(result, 2); // ERROR_FILE_NOT_FOUND
-    }
-
-    #[test]
-    fn file_test_iounlinking_invalid_path_should_raise_condition() {
-        let tmpdir = tmpdir();
-        let filename = &tmpdir.join("file_another_file_that_does_not_exist.txt");
-
-        let result = fs::remove_file(filename);
-
-        #[cfg(all(unix, not(target_os = "vxworks")))]
-        error!(result, "No such file or directory");
-        #[cfg(target_os = "vxworks")]
-        error!(result, "no such file or directory");
-        #[cfg(windows)]
-        error!(result, 2); // ERROR_FILE_NOT_FOUND
-    }
-
-    #[test]
-    fn file_test_io_non_positional_read() {
-        let message: &str = "ten-four";
-        let mut read_mem = [0; 8];
-        let tmpdir = tmpdir();
-        let filename = &tmpdir.join("file_rt_io_file_test_positional.txt");
-        {
-            let mut rw_stream = check!(File::create(filename));
-            check!(rw_stream.write(message.as_bytes()));
-        }
-        {
-            let mut read_stream = check!(File::open(filename));
-            {
-                let read_buf = &mut read_mem[0..4];
-                check!(read_stream.read(read_buf));
-            }
-            {
-                let read_buf = &mut read_mem[4..8];
-                check!(read_stream.read(read_buf));
-            }
-        }
-        check!(fs::remove_file(filename));
-        let read_str = str::from_utf8(&read_mem).unwrap();
-        assert_eq!(read_str, message);
-    }
-
-    #[test]
-    fn file_test_io_seek_and_tell_smoke_test() {
-        let message = "ten-four";
-        let mut read_mem = [0; 4];
-        let set_cursor = 4 as u64;
-        let tell_pos_pre_read;
-        let tell_pos_post_read;
-        let tmpdir = tmpdir();
-        let filename = &tmpdir.join("file_rt_io_file_test_seeking.txt");
-        {
-            let mut rw_stream = check!(File::create(filename));
-            check!(rw_stream.write(message.as_bytes()));
-        }
-        {
-            let mut read_stream = check!(File::open(filename));
-            check!(read_stream.seek(SeekFrom::Start(set_cursor)));
-            tell_pos_pre_read = check!(read_stream.seek(SeekFrom::Current(0)));
-            check!(read_stream.read(&mut read_mem));
-            tell_pos_post_read = check!(read_stream.seek(SeekFrom::Current(0)));
-        }
-        check!(fs::remove_file(filename));
-        let read_str = str::from_utf8(&read_mem).unwrap();
-        assert_eq!(read_str, &message[4..8]);
-        assert_eq!(tell_pos_pre_read, set_cursor);
-        assert_eq!(tell_pos_post_read, message.len() as u64);
-    }
-
-    #[test]
-    fn file_test_io_seek_and_write() {
-        let initial_msg = "food-is-yummy";
-        let overwrite_msg = "-the-bar!!";
-        let final_msg = "foo-the-bar!!";
-        let seek_idx = 3;
-        let mut read_mem = [0; 13];
-        let tmpdir = tmpdir();
-        let filename = &tmpdir.join("file_rt_io_file_test_seek_and_write.txt");
-        {
-            let mut rw_stream = check!(File::create(filename));
-            check!(rw_stream.write(initial_msg.as_bytes()));
-            check!(rw_stream.seek(SeekFrom::Start(seek_idx)));
-            check!(rw_stream.write(overwrite_msg.as_bytes()));
-        }
-        {
-            let mut read_stream = check!(File::open(filename));
-            check!(read_stream.read(&mut read_mem));
-        }
-        check!(fs::remove_file(filename));
-        let read_str = str::from_utf8(&read_mem).unwrap();
-        assert!(read_str == final_msg);
-    }
-
-    #[test]
-    fn file_test_io_seek_shakedown() {
-        //                   01234567890123
-        let initial_msg = "qwer-asdf-zxcv";
-        let chunk_one: &str = "qwer";
-        let chunk_two: &str = "asdf";
-        let chunk_three: &str = "zxcv";
-        let mut read_mem = [0; 4];
-        let tmpdir = tmpdir();
-        let filename = &tmpdir.join("file_rt_io_file_test_seek_shakedown.txt");
-        {
-            let mut rw_stream = check!(File::create(filename));
-            check!(rw_stream.write(initial_msg.as_bytes()));
-        }
-        {
-            let mut read_stream = check!(File::open(filename));
-
-            check!(read_stream.seek(SeekFrom::End(-4)));
-            check!(read_stream.read(&mut read_mem));
-            assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_three);
-
-            check!(read_stream.seek(SeekFrom::Current(-9)));
-            check!(read_stream.read(&mut read_mem));
-            assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_two);
-
-            check!(read_stream.seek(SeekFrom::Start(0)));
-            check!(read_stream.read(&mut read_mem));
-            assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_one);
-        }
-        check!(fs::remove_file(filename));
-    }
-
-    #[test]
-    fn file_test_io_eof() {
-        let tmpdir = tmpdir();
-        let filename = tmpdir.join("file_rt_io_file_test_eof.txt");
-        let mut buf = [0; 256];
-        {
-            let oo = OpenOptions::new().create_new(true).write(true).read(true).clone();
-            let mut rw = check!(oo.open(&filename));
-            assert_eq!(check!(rw.read(&mut buf)), 0);
-            assert_eq!(check!(rw.read(&mut buf)), 0);
-        }
-        check!(fs::remove_file(&filename));
-    }
-
-    #[test]
-    #[cfg(unix)]
-    fn file_test_io_read_write_at() {
-        use crate::os::unix::fs::FileExt;
-
-        let tmpdir = tmpdir();
-        let filename = tmpdir.join("file_rt_io_file_test_read_write_at.txt");
-        let mut buf = [0; 256];
-        let write1 = "asdf";
-        let write2 = "qwer-";
-        let write3 = "-zxcv";
-        let content = "qwer-asdf-zxcv";
-        {
-            let oo = OpenOptions::new().create_new(true).write(true).read(true).clone();
-            let mut rw = check!(oo.open(&filename));
-            assert_eq!(check!(rw.write_at(write1.as_bytes(), 5)), write1.len());
-            assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 0);
-            assert_eq!(check!(rw.read_at(&mut buf, 5)), write1.len());
-            assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1));
-            assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 0);
-            assert_eq!(check!(rw.read_at(&mut buf[..write2.len()], 0)), write2.len());
-            assert_eq!(str::from_utf8(&buf[..write2.len()]), Ok("\0\0\0\0\0"));
-            assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 0);
-            assert_eq!(check!(rw.write(write2.as_bytes())), write2.len());
-            assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 5);
-            assert_eq!(check!(rw.read(&mut buf)), write1.len());
-            assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1));
-            assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9);
-            assert_eq!(check!(rw.read_at(&mut buf[..write2.len()], 0)), write2.len());
-            assert_eq!(str::from_utf8(&buf[..write2.len()]), Ok(write2));
-            assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9);
-            assert_eq!(check!(rw.write_at(write3.as_bytes(), 9)), write3.len());
-            assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9);
-        }
-        {
-            let mut read = check!(File::open(&filename));
-            assert_eq!(check!(read.read_at(&mut buf, 0)), content.len());
-            assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content));
-            assert_eq!(check!(read.seek(SeekFrom::Current(0))), 0);
-            assert_eq!(check!(read.seek(SeekFrom::End(-5))), 9);
-            assert_eq!(check!(read.read_at(&mut buf, 0)), content.len());
-            assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content));
-            assert_eq!(check!(read.seek(SeekFrom::Current(0))), 9);
-            assert_eq!(check!(read.read(&mut buf)), write3.len());
-            assert_eq!(str::from_utf8(&buf[..write3.len()]), Ok(write3));
-            assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
-            assert_eq!(check!(read.read_at(&mut buf, 0)), content.len());
-            assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content));
-            assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
-            assert_eq!(check!(read.read_at(&mut buf, 14)), 0);
-            assert_eq!(check!(read.read_at(&mut buf, 15)), 0);
-            assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
-        }
-        check!(fs::remove_file(&filename));
-    }
-
-    #[test]
-    #[cfg(unix)]
-    fn set_get_unix_permissions() {
-        use crate::os::unix::fs::PermissionsExt;
-
-        let tmpdir = tmpdir();
-        let filename = &tmpdir.join("set_get_unix_permissions");
-        check!(fs::create_dir(filename));
-        let mask = 0o7777;
-
-        check!(fs::set_permissions(filename, fs::Permissions::from_mode(0)));
-        let metadata0 = check!(fs::metadata(filename));
-        assert_eq!(mask & metadata0.permissions().mode(), 0);
-
-        check!(fs::set_permissions(filename, fs::Permissions::from_mode(0o1777)));
-        let metadata1 = check!(fs::metadata(filename));
-        #[cfg(all(unix, not(target_os = "vxworks")))]
-        assert_eq!(mask & metadata1.permissions().mode(), 0o1777);
-        #[cfg(target_os = "vxworks")]
-        assert_eq!(mask & metadata1.permissions().mode(), 0o0777);
-    }
-
-    #[test]
-    #[cfg(windows)]
-    fn file_test_io_seek_read_write() {
-        use crate::os::windows::fs::FileExt;
-
-        let tmpdir = tmpdir();
-        let filename = tmpdir.join("file_rt_io_file_test_seek_read_write.txt");
-        let mut buf = [0; 256];
-        let write1 = "asdf";
-        let write2 = "qwer-";
-        let write3 = "-zxcv";
-        let content = "qwer-asdf-zxcv";
-        {
-            let oo = OpenOptions::new().create_new(true).write(true).read(true).clone();
-            let mut rw = check!(oo.open(&filename));
-            assert_eq!(check!(rw.seek_write(write1.as_bytes(), 5)), write1.len());
-            assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9);
-            assert_eq!(check!(rw.seek_read(&mut buf, 5)), write1.len());
-            assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1));
-            assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9);
-            assert_eq!(check!(rw.seek(SeekFrom::Start(0))), 0);
-            assert_eq!(check!(rw.write(write2.as_bytes())), write2.len());
-            assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 5);
-            assert_eq!(check!(rw.read(&mut buf)), write1.len());
-            assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1));
-            assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9);
-            assert_eq!(check!(rw.seek_read(&mut buf[..write2.len()], 0)), write2.len());
-            assert_eq!(str::from_utf8(&buf[..write2.len()]), Ok(write2));
-            assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 5);
-            assert_eq!(check!(rw.seek_write(write3.as_bytes(), 9)), write3.len());
-            assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 14);
-        }
-        {
-            let mut read = check!(File::open(&filename));
-            assert_eq!(check!(read.seek_read(&mut buf, 0)), content.len());
-            assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content));
-            assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
-            assert_eq!(check!(read.seek(SeekFrom::End(-5))), 9);
-            assert_eq!(check!(read.seek_read(&mut buf, 0)), content.len());
-            assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content));
-            assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
-            assert_eq!(check!(read.seek(SeekFrom::End(-5))), 9);
-            assert_eq!(check!(read.read(&mut buf)), write3.len());
-            assert_eq!(str::from_utf8(&buf[..write3.len()]), Ok(write3));
-            assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
-            assert_eq!(check!(read.seek_read(&mut buf, 0)), content.len());
-            assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content));
-            assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
-            assert_eq!(check!(read.seek_read(&mut buf, 14)), 0);
-            assert_eq!(check!(read.seek_read(&mut buf, 15)), 0);
-        }
-        check!(fs::remove_file(&filename));
-    }
-
-    #[test]
-    fn file_test_stat_is_correct_on_is_file() {
-        let tmpdir = tmpdir();
-        let filename = &tmpdir.join("file_stat_correct_on_is_file.txt");
-        {
-            let mut opts = OpenOptions::new();
-            let mut fs = check!(opts.read(true).write(true).create(true).open(filename));
-            let msg = "hw";
-            fs.write(msg.as_bytes()).unwrap();
-
-            let fstat_res = check!(fs.metadata());
-            assert!(fstat_res.is_file());
-        }
-        let stat_res_fn = check!(fs::metadata(filename));
-        assert!(stat_res_fn.is_file());
-        let stat_res_meth = check!(filename.metadata());
-        assert!(stat_res_meth.is_file());
-        check!(fs::remove_file(filename));
-    }
-
-    #[test]
-    fn file_test_stat_is_correct_on_is_dir() {
-        let tmpdir = tmpdir();
-        let filename = &tmpdir.join("file_stat_correct_on_is_dir");
-        check!(fs::create_dir(filename));
-        let stat_res_fn = check!(fs::metadata(filename));
-        assert!(stat_res_fn.is_dir());
-        let stat_res_meth = check!(filename.metadata());
-        assert!(stat_res_meth.is_dir());
-        check!(fs::remove_dir(filename));
-    }
-
-    #[test]
-    fn file_test_fileinfo_false_when_checking_is_file_on_a_directory() {
-        let tmpdir = tmpdir();
-        let dir = &tmpdir.join("fileinfo_false_on_dir");
-        check!(fs::create_dir(dir));
-        assert!(!dir.is_file());
-        check!(fs::remove_dir(dir));
-    }
-
-    #[test]
-    fn file_test_fileinfo_check_exists_before_and_after_file_creation() {
-        let tmpdir = tmpdir();
-        let file = &tmpdir.join("fileinfo_check_exists_b_and_a.txt");
-        check!(check!(File::create(file)).write(b"foo"));
-        assert!(file.exists());
-        check!(fs::remove_file(file));
-        assert!(!file.exists());
-    }
-
-    #[test]
-    fn file_test_directoryinfo_check_exists_before_and_after_mkdir() {
-        let tmpdir = tmpdir();
-        let dir = &tmpdir.join("before_and_after_dir");
-        assert!(!dir.exists());
-        check!(fs::create_dir(dir));
-        assert!(dir.exists());
-        assert!(dir.is_dir());
-        check!(fs::remove_dir(dir));
-        assert!(!dir.exists());
-    }
-
-    #[test]
-    fn file_test_directoryinfo_readdir() {
-        let tmpdir = tmpdir();
-        let dir = &tmpdir.join("di_readdir");
-        check!(fs::create_dir(dir));
-        let prefix = "foo";
-        for n in 0..3 {
-            let f = dir.join(&format!("{}.txt", n));
-            let mut w = check!(File::create(&f));
-            let msg_str = format!("{}{}", prefix, n.to_string());
-            let msg = msg_str.as_bytes();
-            check!(w.write(msg));
-        }
-        let files = check!(fs::read_dir(dir));
-        let mut mem = [0; 4];
-        for f in files {
-            let f = f.unwrap().path();
-            {
-                let n = f.file_stem().unwrap();
-                check!(check!(File::open(&f)).read(&mut mem));
-                let read_str = str::from_utf8(&mem).unwrap();
-                let expected = format!("{}{}", prefix, n.to_str().unwrap());
-                assert_eq!(expected, read_str);
-            }
-            check!(fs::remove_file(&f));
-        }
-        check!(fs::remove_dir(dir));
-    }
-
-    #[test]
-    fn file_create_new_already_exists_error() {
-        let tmpdir = tmpdir();
-        let file = &tmpdir.join("file_create_new_error_exists");
-        check!(fs::File::create(file));
-        let e = fs::OpenOptions::new().write(true).create_new(true).open(file).unwrap_err();
-        assert_eq!(e.kind(), ErrorKind::AlreadyExists);
-    }
-
-    #[test]
-    fn mkdir_path_already_exists_error() {
-        let tmpdir = tmpdir();
-        let dir = &tmpdir.join("mkdir_error_twice");
-        check!(fs::create_dir(dir));
-        let e = fs::create_dir(dir).unwrap_err();
-        assert_eq!(e.kind(), ErrorKind::AlreadyExists);
-    }
-
-    #[test]
-    fn recursive_mkdir() {
-        let tmpdir = tmpdir();
-        let dir = tmpdir.join("d1/d2");
-        check!(fs::create_dir_all(&dir));
-        assert!(dir.is_dir())
-    }
-
-    #[test]
-    fn recursive_mkdir_failure() {
-        let tmpdir = tmpdir();
-        let dir = tmpdir.join("d1");
-        let file = dir.join("f1");
-
-        check!(fs::create_dir_all(&dir));
-        check!(File::create(&file));
-
-        let result = fs::create_dir_all(&file);
-
-        assert!(result.is_err());
-    }
-
-    #[test]
-    fn concurrent_recursive_mkdir() {
-        for _ in 0..100 {
-            let dir = tmpdir();
-            let mut dir = dir.join("a");
-            for _ in 0..40 {
-                dir = dir.join("a");
-            }
-            let mut join = vec![];
-            for _ in 0..8 {
-                let dir = dir.clone();
-                join.push(thread::spawn(move || {
-                    check!(fs::create_dir_all(&dir));
-                }))
-            }
-
-            // No `Display` on result of `join()`
-            join.drain(..).map(|join| join.join().unwrap()).count();
-        }
-    }
-
-    #[test]
-    fn recursive_mkdir_slash() {
-        check!(fs::create_dir_all(Path::new("/")));
-    }
-
-    #[test]
-    fn recursive_mkdir_dot() {
-        check!(fs::create_dir_all(Path::new(".")));
-    }
-
-    #[test]
-    fn recursive_mkdir_empty() {
-        check!(fs::create_dir_all(Path::new("")));
-    }
-
-    #[test]
-    fn recursive_rmdir() {
-        let tmpdir = tmpdir();
-        let d1 = tmpdir.join("d1");
-        let dt = d1.join("t");
-        let dtt = dt.join("t");
-        let d2 = tmpdir.join("d2");
-        let canary = d2.join("do_not_delete");
-        check!(fs::create_dir_all(&dtt));
-        check!(fs::create_dir_all(&d2));
-        check!(check!(File::create(&canary)).write(b"foo"));
-        check!(symlink_junction(&d2, &dt.join("d2")));
-        let _ = symlink_file(&canary, &d1.join("canary"));
-        check!(fs::remove_dir_all(&d1));
-
-        assert!(!d1.is_dir());
-        assert!(canary.exists());
-    }
-
-    #[test]
-    fn recursive_rmdir_of_symlink() {
-        // test we do not recursively delete a symlink but only dirs.
-        let tmpdir = tmpdir();
-        let link = tmpdir.join("d1");
-        let dir = tmpdir.join("d2");
-        let canary = dir.join("do_not_delete");
-        check!(fs::create_dir_all(&dir));
-        check!(check!(File::create(&canary)).write(b"foo"));
-        check!(symlink_junction(&dir, &link));
-        check!(fs::remove_dir_all(&link));
-
-        assert!(!link.is_dir());
-        assert!(canary.exists());
-    }
-
-    #[test]
-    // only Windows makes a distinction between file and directory symlinks.
-    #[cfg(windows)]
-    fn recursive_rmdir_of_file_symlink() {
-        let tmpdir = tmpdir();
-        if !got_symlink_permission(&tmpdir) {
-            return;
-        };
-
-        let f1 = tmpdir.join("f1");
-        let f2 = tmpdir.join("f2");
-        check!(check!(File::create(&f1)).write(b"foo"));
-        check!(symlink_file(&f1, &f2));
-        match fs::remove_dir_all(&f2) {
-            Ok(..) => panic!("wanted a failure"),
-            Err(..) => {}
-        }
-    }
-
-    #[test]
-    fn unicode_path_is_dir() {
-        assert!(Path::new(".").is_dir());
-        assert!(!Path::new("test/stdtest/fs.rs").is_dir());
-
-        let tmpdir = tmpdir();
-
-        let mut dirpath = tmpdir.path().to_path_buf();
-        dirpath.push("test-가一ー你好");
-        check!(fs::create_dir(&dirpath));
-        assert!(dirpath.is_dir());
-
-        let mut filepath = dirpath;
-        filepath.push("unicode-file-\u{ac00}\u{4e00}\u{30fc}\u{4f60}\u{597d}.rs");
-        check!(File::create(&filepath)); // ignore return; touch only
-        assert!(!filepath.is_dir());
-        assert!(filepath.exists());
-    }
-
-    #[test]
-    fn unicode_path_exists() {
-        assert!(Path::new(".").exists());
-        assert!(!Path::new("test/nonexistent-bogus-path").exists());
-
-        let tmpdir = tmpdir();
-        let unicode = tmpdir.path();
-        let unicode = unicode.join("test-각丁ー再见");
-        check!(fs::create_dir(&unicode));
-        assert!(unicode.exists());
-        assert!(!Path::new("test/unicode-bogus-path-각丁ー再见").exists());
-    }
-
-    #[test]
-    fn copy_file_does_not_exist() {
-        let from = Path::new("test/nonexistent-bogus-path");
-        let to = Path::new("test/other-bogus-path");
-
-        match fs::copy(&from, &to) {
-            Ok(..) => panic!(),
-            Err(..) => {
-                assert!(!from.exists());
-                assert!(!to.exists());
-            }
-        }
-    }
-
-    #[test]
-    fn copy_src_does_not_exist() {
-        let tmpdir = tmpdir();
-        let from = Path::new("test/nonexistent-bogus-path");
-        let to = tmpdir.join("out.txt");
-        check!(check!(File::create(&to)).write(b"hello"));
-        assert!(fs::copy(&from, &to).is_err());
-        assert!(!from.exists());
-        let mut v = Vec::new();
-        check!(check!(File::open(&to)).read_to_end(&mut v));
-        assert_eq!(v, b"hello");
-    }
-
-    #[test]
-    fn copy_file_ok() {
-        let tmpdir = tmpdir();
-        let input = tmpdir.join("in.txt");
-        let out = tmpdir.join("out.txt");
-
-        check!(check!(File::create(&input)).write(b"hello"));
-        check!(fs::copy(&input, &out));
-        let mut v = Vec::new();
-        check!(check!(File::open(&out)).read_to_end(&mut v));
-        assert_eq!(v, b"hello");
-
-        assert_eq!(check!(input.metadata()).permissions(), check!(out.metadata()).permissions());
-    }
-
-    #[test]
-    fn copy_file_dst_dir() {
-        let tmpdir = tmpdir();
-        let out = tmpdir.join("out");
-
-        check!(File::create(&out));
-        match fs::copy(&*out, tmpdir.path()) {
-            Ok(..) => panic!(),
-            Err(..) => {}
-        }
-    }
-
-    #[test]
-    fn copy_file_dst_exists() {
-        let tmpdir = tmpdir();
-        let input = tmpdir.join("in");
-        let output = tmpdir.join("out");
-
-        check!(check!(File::create(&input)).write("foo".as_bytes()));
-        check!(check!(File::create(&output)).write("bar".as_bytes()));
-        check!(fs::copy(&input, &output));
-
-        let mut v = Vec::new();
-        check!(check!(File::open(&output)).read_to_end(&mut v));
-        assert_eq!(v, b"foo".to_vec());
-    }
-
-    #[test]
-    fn copy_file_src_dir() {
-        let tmpdir = tmpdir();
-        let out = tmpdir.join("out");
-
-        match fs::copy(tmpdir.path(), &out) {
-            Ok(..) => panic!(),
-            Err(..) => {}
-        }
-        assert!(!out.exists());
-    }
-
-    #[test]
-    fn copy_file_preserves_perm_bits() {
-        let tmpdir = tmpdir();
-        let input = tmpdir.join("in.txt");
-        let out = tmpdir.join("out.txt");
-
-        let attr = check!(check!(File::create(&input)).metadata());
-        let mut p = attr.permissions();
-        p.set_readonly(true);
-        check!(fs::set_permissions(&input, p));
-        check!(fs::copy(&input, &out));
-        assert!(check!(out.metadata()).permissions().readonly());
-        check!(fs::set_permissions(&input, attr.permissions()));
-        check!(fs::set_permissions(&out, attr.permissions()));
-    }
-
-    #[test]
-    #[cfg(windows)]
-    fn copy_file_preserves_streams() {
-        let tmp = tmpdir();
-        check!(check!(File::create(tmp.join("in.txt:bunny"))).write("carrot".as_bytes()));
-        assert_eq!(check!(fs::copy(tmp.join("in.txt"), tmp.join("out.txt"))), 0);
-        assert_eq!(check!(tmp.join("out.txt").metadata()).len(), 0);
-        let mut v = Vec::new();
-        check!(check!(File::open(tmp.join("out.txt:bunny"))).read_to_end(&mut v));
-        assert_eq!(v, b"carrot".to_vec());
-    }
-
-    #[test]
-    fn copy_file_returns_metadata_len() {
-        let tmp = tmpdir();
-        let in_path = tmp.join("in.txt");
-        let out_path = tmp.join("out.txt");
-        check!(check!(File::create(&in_path)).write(b"lettuce"));
-        #[cfg(windows)]
-        check!(check!(File::create(tmp.join("in.txt:bunny"))).write(b"carrot"));
-        let copied_len = check!(fs::copy(&in_path, &out_path));
-        assert_eq!(check!(out_path.metadata()).len(), copied_len);
-    }
-
-    #[test]
-    fn copy_file_follows_dst_symlink() {
-        let tmp = tmpdir();
-        if !got_symlink_permission(&tmp) {
-            return;
-        };
-
-        let in_path = tmp.join("in.txt");
-        let out_path = tmp.join("out.txt");
-        let out_path_symlink = tmp.join("out_symlink.txt");
-
-        check!(fs::write(&in_path, "foo"));
-        check!(fs::write(&out_path, "bar"));
-        check!(symlink_file(&out_path, &out_path_symlink));
-
-        check!(fs::copy(&in_path, &out_path_symlink));
-
-        assert!(check!(out_path_symlink.symlink_metadata()).file_type().is_symlink());
-        assert_eq!(check!(fs::read(&out_path_symlink)), b"foo".to_vec());
-        assert_eq!(check!(fs::read(&out_path)), b"foo".to_vec());
-    }
-
-    #[test]
-    fn symlinks_work() {
-        let tmpdir = tmpdir();
-        if !got_symlink_permission(&tmpdir) {
-            return;
-        };
-
-        let input = tmpdir.join("in.txt");
-        let out = tmpdir.join("out.txt");
-
-        check!(check!(File::create(&input)).write("foobar".as_bytes()));
-        check!(symlink_file(&input, &out));
-        assert!(check!(out.symlink_metadata()).file_type().is_symlink());
-        assert_eq!(check!(fs::metadata(&out)).len(), check!(fs::metadata(&input)).len());
-        let mut v = Vec::new();
-        check!(check!(File::open(&out)).read_to_end(&mut v));
-        assert_eq!(v, b"foobar".to_vec());
-    }
-
-    #[test]
-    fn symlink_noexist() {
-        // Symlinks can point to things that don't exist
-        let tmpdir = tmpdir();
-        if !got_symlink_permission(&tmpdir) {
-            return;
-        };
-
-        // Use a relative path for testing. Symlinks get normalized by Windows,
-        // so we may not get the same path back for absolute paths
-        check!(symlink_file(&"foo", &tmpdir.join("bar")));
-        assert_eq!(check!(fs::read_link(&tmpdir.join("bar"))).to_str().unwrap(), "foo");
-    }
-
-    #[test]
-    fn read_link() {
-        if cfg!(windows) {
-            // directory symlink
-            assert_eq!(
-                check!(fs::read_link(r"C:\Users\All Users")).to_str().unwrap(),
-                r"C:\ProgramData"
-            );
-            // junction
-            assert_eq!(
-                check!(fs::read_link(r"C:\Users\Default User")).to_str().unwrap(),
-                r"C:\Users\Default"
-            );
-            // junction with special permissions
-            assert_eq!(
-                check!(fs::read_link(r"C:\Documents and Settings\")).to_str().unwrap(),
-                r"C:\Users"
-            );
-        }
-        let tmpdir = tmpdir();
-        let link = tmpdir.join("link");
-        if !got_symlink_permission(&tmpdir) {
-            return;
-        };
-        check!(symlink_file(&"foo", &link));
-        assert_eq!(check!(fs::read_link(&link)).to_str().unwrap(), "foo");
-    }
-
-    #[test]
-    fn readlink_not_symlink() {
-        let tmpdir = tmpdir();
-        match fs::read_link(tmpdir.path()) {
-            Ok(..) => panic!("wanted a failure"),
-            Err(..) => {}
-        }
-    }
-
-    #[test]
-    fn links_work() {
-        let tmpdir = tmpdir();
-        let input = tmpdir.join("in.txt");
-        let out = tmpdir.join("out.txt");
-
-        check!(check!(File::create(&input)).write("foobar".as_bytes()));
-        check!(fs::hard_link(&input, &out));
-        assert_eq!(check!(fs::metadata(&out)).len(), check!(fs::metadata(&input)).len());
-        assert_eq!(check!(fs::metadata(&out)).len(), check!(input.metadata()).len());
-        let mut v = Vec::new();
-        check!(check!(File::open(&out)).read_to_end(&mut v));
-        assert_eq!(v, b"foobar".to_vec());
-
-        // can't link to yourself
-        match fs::hard_link(&input, &input) {
-            Ok(..) => panic!("wanted a failure"),
-            Err(..) => {}
-        }
-        // can't link to something that doesn't exist
-        match fs::hard_link(&tmpdir.join("foo"), &tmpdir.join("bar")) {
-            Ok(..) => panic!("wanted a failure"),
-            Err(..) => {}
-        }
-    }
-
-    #[test]
-    fn chmod_works() {
-        let tmpdir = tmpdir();
-        let file = tmpdir.join("in.txt");
-
-        check!(File::create(&file));
-        let attr = check!(fs::metadata(&file));
-        assert!(!attr.permissions().readonly());
-        let mut p = attr.permissions();
-        p.set_readonly(true);
-        check!(fs::set_permissions(&file, p.clone()));
-        let attr = check!(fs::metadata(&file));
-        assert!(attr.permissions().readonly());
-
-        match fs::set_permissions(&tmpdir.join("foo"), p.clone()) {
-            Ok(..) => panic!("wanted an error"),
-            Err(..) => {}
-        }
-
-        p.set_readonly(false);
-        check!(fs::set_permissions(&file, p));
-    }
-
-    #[test]
-    fn fchmod_works() {
-        let tmpdir = tmpdir();
-        let path = tmpdir.join("in.txt");
-
-        let file = check!(File::create(&path));
-        let attr = check!(fs::metadata(&path));
-        assert!(!attr.permissions().readonly());
-        let mut p = attr.permissions();
-        p.set_readonly(true);
-        check!(file.set_permissions(p.clone()));
-        let attr = check!(fs::metadata(&path));
-        assert!(attr.permissions().readonly());
-
-        p.set_readonly(false);
-        check!(file.set_permissions(p));
-    }
-
-    #[test]
-    fn sync_doesnt_kill_anything() {
-        let tmpdir = tmpdir();
-        let path = tmpdir.join("in.txt");
-
-        let mut file = check!(File::create(&path));
-        check!(file.sync_all());
-        check!(file.sync_data());
-        check!(file.write(b"foo"));
-        check!(file.sync_all());
-        check!(file.sync_data());
-    }
-
-    #[test]
-    fn truncate_works() {
-        let tmpdir = tmpdir();
-        let path = tmpdir.join("in.txt");
-
-        let mut file = check!(File::create(&path));
-        check!(file.write(b"foo"));
-        check!(file.sync_all());
-
-        // Do some simple things with truncation
-        assert_eq!(check!(file.metadata()).len(), 3);
-        check!(file.set_len(10));
-        assert_eq!(check!(file.metadata()).len(), 10);
-        check!(file.write(b"bar"));
-        check!(file.sync_all());
-        assert_eq!(check!(file.metadata()).len(), 10);
-
-        let mut v = Vec::new();
-        check!(check!(File::open(&path)).read_to_end(&mut v));
-        assert_eq!(v, b"foobar\0\0\0\0".to_vec());
-
-        // Truncate to a smaller length, don't seek, and then write something.
-        // Ensure that the intermediate zeroes are all filled in (we have `seek`ed
-        // past the end of the file).
-        check!(file.set_len(2));
-        assert_eq!(check!(file.metadata()).len(), 2);
-        check!(file.write(b"wut"));
-        check!(file.sync_all());
-        assert_eq!(check!(file.metadata()).len(), 9);
-        let mut v = Vec::new();
-        check!(check!(File::open(&path)).read_to_end(&mut v));
-        assert_eq!(v, b"fo\0\0\0\0wut".to_vec());
-    }
-
-    #[test]
-    fn open_flavors() {
-        use crate::fs::OpenOptions as OO;
-        fn c<T: Clone>(t: &T) -> T {
-            t.clone()
-        }
-
-        let tmpdir = tmpdir();
-
-        let mut r = OO::new();
-        r.read(true);
-        let mut w = OO::new();
-        w.write(true);
-        let mut rw = OO::new();
-        rw.read(true).write(true);
-        let mut a = OO::new();
-        a.append(true);
-        let mut ra = OO::new();
-        ra.read(true).append(true);
-
-        #[cfg(windows)]
-        let invalid_options = 87; // ERROR_INVALID_PARAMETER
-        #[cfg(all(unix, not(target_os = "vxworks")))]
-        let invalid_options = "Invalid argument";
-        #[cfg(target_os = "vxworks")]
-        let invalid_options = "invalid argument";
-
-        // Test various combinations of creation modes and access modes.
-        //
-        // Allowed:
-        // creation mode           | read  | write | read-write | append | read-append |
-        // :-----------------------|:-----:|:-----:|:----------:|:------:|:-----------:|
-        // not set (open existing) |   X   |   X   |     X      |   X    |      X      |
-        // create                  |       |   X   |     X      |   X    |      X      |
-        // truncate                |       |   X   |     X      |        |             |
-        // create and truncate     |       |   X   |     X      |        |             |
-        // create_new              |       |   X   |     X      |   X    |      X      |
-        //
-        // tested in reverse order, so 'create_new' creates the file, and 'open existing' opens it.
-
-        // write-only
-        check!(c(&w).create_new(true).open(&tmpdir.join("a")));
-        check!(c(&w).create(true).truncate(true).open(&tmpdir.join("a")));
-        check!(c(&w).truncate(true).open(&tmpdir.join("a")));
-        check!(c(&w).create(true).open(&tmpdir.join("a")));
-        check!(c(&w).open(&tmpdir.join("a")));
-
-        // read-only
-        error!(c(&r).create_new(true).open(&tmpdir.join("b")), invalid_options);
-        error!(c(&r).create(true).truncate(true).open(&tmpdir.join("b")), invalid_options);
-        error!(c(&r).truncate(true).open(&tmpdir.join("b")), invalid_options);
-        error!(c(&r).create(true).open(&tmpdir.join("b")), invalid_options);
-        check!(c(&r).open(&tmpdir.join("a"))); // try opening the file created with write_only
-
-        // read-write
-        check!(c(&rw).create_new(true).open(&tmpdir.join("c")));
-        check!(c(&rw).create(true).truncate(true).open(&tmpdir.join("c")));
-        check!(c(&rw).truncate(true).open(&tmpdir.join("c")));
-        check!(c(&rw).create(true).open(&tmpdir.join("c")));
-        check!(c(&rw).open(&tmpdir.join("c")));
-
-        // append
-        check!(c(&a).create_new(true).open(&tmpdir.join("d")));
-        error!(c(&a).create(true).truncate(true).open(&tmpdir.join("d")), invalid_options);
-        error!(c(&a).truncate(true).open(&tmpdir.join("d")), invalid_options);
-        check!(c(&a).create(true).open(&tmpdir.join("d")));
-        check!(c(&a).open(&tmpdir.join("d")));
-
-        // read-append
-        check!(c(&ra).create_new(true).open(&tmpdir.join("e")));
-        error!(c(&ra).create(true).truncate(true).open(&tmpdir.join("e")), invalid_options);
-        error!(c(&ra).truncate(true).open(&tmpdir.join("e")), invalid_options);
-        check!(c(&ra).create(true).open(&tmpdir.join("e")));
-        check!(c(&ra).open(&tmpdir.join("e")));
-
-        // Test opening a file without setting an access mode
-        let mut blank = OO::new();
-        error!(blank.create(true).open(&tmpdir.join("f")), invalid_options);
-
-        // Test write works
-        check!(check!(File::create(&tmpdir.join("h"))).write("foobar".as_bytes()));
-
-        // Test write fails for read-only
-        check!(r.open(&tmpdir.join("h")));
-        {
-            let mut f = check!(r.open(&tmpdir.join("h")));
-            assert!(f.write("wut".as_bytes()).is_err());
-        }
-
-        // Test write overwrites
-        {
-            let mut f = check!(c(&w).open(&tmpdir.join("h")));
-            check!(f.write("baz".as_bytes()));
-        }
-        {
-            let mut f = check!(c(&r).open(&tmpdir.join("h")));
-            let mut b = vec![0; 6];
-            check!(f.read(&mut b));
-            assert_eq!(b, "bazbar".as_bytes());
-        }
-
-        // Test truncate works
-        {
-            let mut f = check!(c(&w).truncate(true).open(&tmpdir.join("h")));
-            check!(f.write("foo".as_bytes()));
-        }
-        assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 3);
-
-        // Test append works
-        assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 3);
-        {
-            let mut f = check!(c(&a).open(&tmpdir.join("h")));
-            check!(f.write("bar".as_bytes()));
-        }
-        assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 6);
-
-        // Test .append(true) equals .write(true).append(true)
-        {
-            let mut f = check!(c(&w).append(true).open(&tmpdir.join("h")));
-            check!(f.write("baz".as_bytes()));
-        }
-        assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 9);
-    }
-
-    #[test]
-    fn _assert_send_sync() {
-        fn _assert_send_sync<T: Send + Sync>() {}
-        _assert_send_sync::<OpenOptions>();
-    }
-
-    #[test]
-    fn binary_file() {
-        let mut bytes = [0; 1024];
-        StdRng::from_entropy().fill_bytes(&mut bytes);
-
-        let tmpdir = tmpdir();
-
-        check!(check!(File::create(&tmpdir.join("test"))).write(&bytes));
-        let mut v = Vec::new();
-        check!(check!(File::open(&tmpdir.join("test"))).read_to_end(&mut v));
-        assert!(v == &bytes[..]);
-    }
-
-    #[test]
-    fn write_then_read() {
-        let mut bytes = [0; 1024];
-        StdRng::from_entropy().fill_bytes(&mut bytes);
-
-        let tmpdir = tmpdir();
-
-        check!(fs::write(&tmpdir.join("test"), &bytes[..]));
-        let v = check!(fs::read(&tmpdir.join("test")));
-        assert!(v == &bytes[..]);
-
-        check!(fs::write(&tmpdir.join("not-utf8"), &[0xFF]));
-        error_contains!(
-            fs::read_to_string(&tmpdir.join("not-utf8")),
-            "stream did not contain valid UTF-8"
-        );
-
-        let s = "𐁁𐀓𐀠𐀴𐀍";
-        check!(fs::write(&tmpdir.join("utf8"), s.as_bytes()));
-        let string = check!(fs::read_to_string(&tmpdir.join("utf8")));
-        assert_eq!(string, s);
-    }
-
-    #[test]
-    fn file_try_clone() {
-        let tmpdir = tmpdir();
-
-        let mut f1 = check!(
-            OpenOptions::new().read(true).write(true).create(true).open(&tmpdir.join("test"))
-        );
-        let mut f2 = check!(f1.try_clone());
-
-        check!(f1.write_all(b"hello world"));
-        check!(f1.seek(SeekFrom::Start(2)));
-
-        let mut buf = vec![];
-        check!(f2.read_to_end(&mut buf));
-        assert_eq!(buf, b"llo world");
-        drop(f2);
-
-        check!(f1.write_all(b"!"));
-    }
-
-    #[test]
-    #[cfg(not(windows))]
-    fn unlink_readonly() {
-        let tmpdir = tmpdir();
-        let path = tmpdir.join("file");
-        check!(File::create(&path));
-        let mut perm = check!(fs::metadata(&path)).permissions();
-        perm.set_readonly(true);
-        check!(fs::set_permissions(&path, perm));
-        check!(fs::remove_file(&path));
-    }
-
-    #[test]
-    fn mkdir_trailing_slash() {
-        let tmpdir = tmpdir();
-        let path = tmpdir.join("file");
-        check!(fs::create_dir_all(&path.join("a/")));
-    }
-
-    #[test]
-    fn canonicalize_works_simple() {
-        let tmpdir = tmpdir();
-        let tmpdir = fs::canonicalize(tmpdir.path()).unwrap();
-        let file = tmpdir.join("test");
-        File::create(&file).unwrap();
-        assert_eq!(fs::canonicalize(&file).unwrap(), file);
-    }
-
-    #[test]
-    fn realpath_works() {
-        let tmpdir = tmpdir();
-        if !got_symlink_permission(&tmpdir) {
-            return;
-        };
-
-        let tmpdir = fs::canonicalize(tmpdir.path()).unwrap();
-        let file = tmpdir.join("test");
-        let dir = tmpdir.join("test2");
-        let link = dir.join("link");
-        let linkdir = tmpdir.join("test3");
-
-        File::create(&file).unwrap();
-        fs::create_dir(&dir).unwrap();
-        symlink_file(&file, &link).unwrap();
-        symlink_dir(&dir, &linkdir).unwrap();
-
-        assert!(link.symlink_metadata().unwrap().file_type().is_symlink());
-
-        assert_eq!(fs::canonicalize(&tmpdir).unwrap(), tmpdir);
-        assert_eq!(fs::canonicalize(&file).unwrap(), file);
-        assert_eq!(fs::canonicalize(&link).unwrap(), file);
-        assert_eq!(fs::canonicalize(&linkdir).unwrap(), dir);
-        assert_eq!(fs::canonicalize(&linkdir.join("link")).unwrap(), file);
-    }
-
-    #[test]
-    fn realpath_works_tricky() {
-        let tmpdir = tmpdir();
-        if !got_symlink_permission(&tmpdir) {
-            return;
-        };
-
-        let tmpdir = fs::canonicalize(tmpdir.path()).unwrap();
-        let a = tmpdir.join("a");
-        let b = a.join("b");
-        let c = b.join("c");
-        let d = a.join("d");
-        let e = d.join("e");
-        let f = a.join("f");
-
-        fs::create_dir_all(&b).unwrap();
-        fs::create_dir_all(&d).unwrap();
-        File::create(&f).unwrap();
-        if cfg!(not(windows)) {
-            symlink_file("../d/e", &c).unwrap();
-            symlink_file("../f", &e).unwrap();
-        }
-        if cfg!(windows) {
-            symlink_file(r"..\d\e", &c).unwrap();
-            symlink_file(r"..\f", &e).unwrap();
-        }
-
-        assert_eq!(fs::canonicalize(&c).unwrap(), f);
-        assert_eq!(fs::canonicalize(&e).unwrap(), f);
-    }
-
-    #[test]
-    fn dir_entry_methods() {
-        let tmpdir = tmpdir();
-
-        fs::create_dir_all(&tmpdir.join("a")).unwrap();
-        File::create(&tmpdir.join("b")).unwrap();
-
-        for file in tmpdir.path().read_dir().unwrap().map(|f| f.unwrap()) {
-            let fname = file.file_name();
-            match fname.to_str() {
-                Some("a") => {
-                    assert!(file.file_type().unwrap().is_dir());
-                    assert!(file.metadata().unwrap().is_dir());
-                }
-                Some("b") => {
-                    assert!(file.file_type().unwrap().is_file());
-                    assert!(file.metadata().unwrap().is_file());
-                }
-                f => panic!("unknown file name: {:?}", f),
-            }
-        }
-    }
-
-    #[test]
-    fn dir_entry_debug() {
-        let tmpdir = tmpdir();
-        File::create(&tmpdir.join("b")).unwrap();
-        let mut read_dir = tmpdir.path().read_dir().unwrap();
-        let dir_entry = read_dir.next().unwrap().unwrap();
-        let actual = format!("{:?}", dir_entry);
-        let expected = format!("DirEntry({:?})", dir_entry.0.path());
-        assert_eq!(actual, expected);
-    }
-
-    #[test]
-    fn read_dir_not_found() {
-        let res = fs::read_dir("/path/that/does/not/exist");
-        assert_eq!(res.err().unwrap().kind(), ErrorKind::NotFound);
-    }
-
-    #[test]
-    fn create_dir_all_with_junctions() {
-        let tmpdir = tmpdir();
-        let target = tmpdir.join("target");
-
-        let junction = tmpdir.join("junction");
-        let b = junction.join("a/b");
-
-        let link = tmpdir.join("link");
-        let d = link.join("c/d");
-
-        fs::create_dir(&target).unwrap();
-
-        check!(symlink_junction(&target, &junction));
-        check!(fs::create_dir_all(&b));
-        // the junction itself is not a directory, but `is_dir()` on a Path
-        // follows links
-        assert!(junction.is_dir());
-        assert!(b.exists());
-
-        if !got_symlink_permission(&tmpdir) {
-            return;
-        };
-        check!(symlink_dir(&target, &link));
-        check!(fs::create_dir_all(&d));
-        assert!(link.is_dir());
-        assert!(d.exists());
-    }
-
-    #[test]
-    fn metadata_access_times() {
-        let tmpdir = tmpdir();
-
-        let b = tmpdir.join("b");
-        File::create(&b).unwrap();
-
-        let a = check!(fs::metadata(&tmpdir.path()));
-        let b = check!(fs::metadata(&b));
-
-        assert_eq!(check!(a.accessed()), check!(a.accessed()));
-        assert_eq!(check!(a.modified()), check!(a.modified()));
-        assert_eq!(check!(b.accessed()), check!(b.modified()));
-
-        if cfg!(target_os = "macos") || cfg!(target_os = "windows") {
-            check!(a.created());
-            check!(b.created());
-        }
-
-        if cfg!(target_os = "linux") {
-            // Not always available
-            match (a.created(), b.created()) {
-                (Ok(t1), Ok(t2)) => assert!(t1 <= t2),
-                (Err(e1), Err(e2))
-                    if e1.kind() == ErrorKind::Other && e2.kind() == ErrorKind::Other => {}
-                (a, b) => panic!(
-                    "creation time must be always supported or not supported: {:?} {:?}",
-                    a, b,
-                ),
-            }
-        }
-    }
-}
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
new file mode 100644
index 00000000000..65a29076fef
--- /dev/null
+++ b/library/std/src/fs/tests.rs
@@ -0,0 +1,1339 @@
+use crate::io::prelude::*;
+
+use crate::fs::{self, File, OpenOptions};
+use crate::io::{ErrorKind, SeekFrom};
+use crate::path::Path;
+use crate::str;
+use crate::sys_common::io::test::{tmpdir, TempDir};
+use crate::thread;
+
+use rand::{rngs::StdRng, RngCore, SeedableRng};
+
+#[cfg(unix)]
+use crate::os::unix::fs::symlink as symlink_dir;
+#[cfg(unix)]
+use crate::os::unix::fs::symlink as symlink_file;
+#[cfg(unix)]
+use crate::os::unix::fs::symlink as symlink_junction;
+#[cfg(windows)]
+use crate::os::windows::fs::{symlink_dir, symlink_file};
+#[cfg(windows)]
+use crate::sys::fs::symlink_junction;
+
+macro_rules! check {
+    ($e:expr) => {
+        match $e {
+            Ok(t) => t,
+            Err(e) => panic!("{} failed with: {}", stringify!($e), e),
+        }
+    };
+}
+
+#[cfg(windows)]
+macro_rules! error {
+    ($e:expr, $s:expr) => {
+        match $e {
+            Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
+            Err(ref err) => assert!(
+                err.raw_os_error() == Some($s),
+                format!("`{}` did not have a code of `{}`", err, $s)
+            ),
+        }
+    };
+}
+
+#[cfg(unix)]
+macro_rules! error {
+    ($e:expr, $s:expr) => {
+        error_contains!($e, $s)
+    };
+}
+
+macro_rules! error_contains {
+    ($e:expr, $s:expr) => {
+        match $e {
+            Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
+            Err(ref err) => {
+                assert!(err.to_string().contains($s), format!("`{}` did not contain `{}`", err, $s))
+            }
+        }
+    };
+}
+
+// Several test fail on windows if the user does not have permission to
+// create symlinks (the `SeCreateSymbolicLinkPrivilege`). Instead of
+// disabling these test on Windows, use this function to test whether we
+// have permission, and return otherwise. This way, we still don't run these
+// tests most of the time, but at least we do if the user has the right
+// permissions.
+pub fn got_symlink_permission(tmpdir: &TempDir) -> bool {
+    if cfg!(unix) {
+        return true;
+    }
+    let link = tmpdir.join("some_hopefully_unique_link_name");
+
+    match symlink_file(r"nonexisting_target", link) {
+        Ok(_) => true,
+        // ERROR_PRIVILEGE_NOT_HELD = 1314
+        Err(ref err) if err.raw_os_error() == Some(1314) => false,
+        Err(_) => true,
+    }
+}
+
+#[test]
+fn file_test_io_smoke_test() {
+    let message = "it's alright. have a good time";
+    let tmpdir = tmpdir();
+    let filename = &tmpdir.join("file_rt_io_file_test.txt");
+    {
+        let mut write_stream = check!(File::create(filename));
+        check!(write_stream.write(message.as_bytes()));
+    }
+    {
+        let mut read_stream = check!(File::open(filename));
+        let mut read_buf = [0; 1028];
+        let read_str = match check!(read_stream.read(&mut read_buf)) {
+            0 => panic!("shouldn't happen"),
+            n => str::from_utf8(&read_buf[..n]).unwrap().to_string(),
+        };
+        assert_eq!(read_str, message);
+    }
+    check!(fs::remove_file(filename));
+}
+
+#[test]
+fn invalid_path_raises() {
+    let tmpdir = tmpdir();
+    let filename = &tmpdir.join("file_that_does_not_exist.txt");
+    let result = File::open(filename);
+
+    #[cfg(all(unix, not(target_os = "vxworks")))]
+    error!(result, "No such file or directory");
+    #[cfg(target_os = "vxworks")]
+    error!(result, "no such file or directory");
+    #[cfg(windows)]
+    error!(result, 2); // ERROR_FILE_NOT_FOUND
+}
+
+#[test]
+fn file_test_iounlinking_invalid_path_should_raise_condition() {
+    let tmpdir = tmpdir();
+    let filename = &tmpdir.join("file_another_file_that_does_not_exist.txt");
+
+    let result = fs::remove_file(filename);
+
+    #[cfg(all(unix, not(target_os = "vxworks")))]
+    error!(result, "No such file or directory");
+    #[cfg(target_os = "vxworks")]
+    error!(result, "no such file or directory");
+    #[cfg(windows)]
+    error!(result, 2); // ERROR_FILE_NOT_FOUND
+}
+
+#[test]
+fn file_test_io_non_positional_read() {
+    let message: &str = "ten-four";
+    let mut read_mem = [0; 8];
+    let tmpdir = tmpdir();
+    let filename = &tmpdir.join("file_rt_io_file_test_positional.txt");
+    {
+        let mut rw_stream = check!(File::create(filename));
+        check!(rw_stream.write(message.as_bytes()));
+    }
+    {
+        let mut read_stream = check!(File::open(filename));
+        {
+            let read_buf = &mut read_mem[0..4];
+            check!(read_stream.read(read_buf));
+        }
+        {
+            let read_buf = &mut read_mem[4..8];
+            check!(read_stream.read(read_buf));
+        }
+    }
+    check!(fs::remove_file(filename));
+    let read_str = str::from_utf8(&read_mem).unwrap();
+    assert_eq!(read_str, message);
+}
+
+#[test]
+fn file_test_io_seek_and_tell_smoke_test() {
+    let message = "ten-four";
+    let mut read_mem = [0; 4];
+    let set_cursor = 4 as u64;
+    let tell_pos_pre_read;
+    let tell_pos_post_read;
+    let tmpdir = tmpdir();
+    let filename = &tmpdir.join("file_rt_io_file_test_seeking.txt");
+    {
+        let mut rw_stream = check!(File::create(filename));
+        check!(rw_stream.write(message.as_bytes()));
+    }
+    {
+        let mut read_stream = check!(File::open(filename));
+        check!(read_stream.seek(SeekFrom::Start(set_cursor)));
+        tell_pos_pre_read = check!(read_stream.seek(SeekFrom::Current(0)));
+        check!(read_stream.read(&mut read_mem));
+        tell_pos_post_read = check!(read_stream.seek(SeekFrom::Current(0)));
+    }
+    check!(fs::remove_file(filename));
+    let read_str = str::from_utf8(&read_mem).unwrap();
+    assert_eq!(read_str, &message[4..8]);
+    assert_eq!(tell_pos_pre_read, set_cursor);
+    assert_eq!(tell_pos_post_read, message.len() as u64);
+}
+
+#[test]
+fn file_test_io_seek_and_write() {
+    let initial_msg = "food-is-yummy";
+    let overwrite_msg = "-the-bar!!";
+    let final_msg = "foo-the-bar!!";
+    let seek_idx = 3;
+    let mut read_mem = [0; 13];
+    let tmpdir = tmpdir();
+    let filename = &tmpdir.join("file_rt_io_file_test_seek_and_write.txt");
+    {
+        let mut rw_stream = check!(File::create(filename));
+        check!(rw_stream.write(initial_msg.as_bytes()));
+        check!(rw_stream.seek(SeekFrom::Start(seek_idx)));
+        check!(rw_stream.write(overwrite_msg.as_bytes()));
+    }
+    {
+        let mut read_stream = check!(File::open(filename));
+        check!(read_stream.read(&mut read_mem));
+    }
+    check!(fs::remove_file(filename));
+    let read_str = str::from_utf8(&read_mem).unwrap();
+    assert!(read_str == final_msg);
+}
+
+#[test]
+fn file_test_io_seek_shakedown() {
+    //                   01234567890123
+    let initial_msg = "qwer-asdf-zxcv";
+    let chunk_one: &str = "qwer";
+    let chunk_two: &str = "asdf";
+    let chunk_three: &str = "zxcv";
+    let mut read_mem = [0; 4];
+    let tmpdir = tmpdir();
+    let filename = &tmpdir.join("file_rt_io_file_test_seek_shakedown.txt");
+    {
+        let mut rw_stream = check!(File::create(filename));
+        check!(rw_stream.write(initial_msg.as_bytes()));
+    }
+    {
+        let mut read_stream = check!(File::open(filename));
+
+        check!(read_stream.seek(SeekFrom::End(-4)));
+        check!(read_stream.read(&mut read_mem));
+        assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_three);
+
+        check!(read_stream.seek(SeekFrom::Current(-9)));
+        check!(read_stream.read(&mut read_mem));
+        assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_two);
+
+        check!(read_stream.seek(SeekFrom::Start(0)));
+        check!(read_stream.read(&mut read_mem));
+        assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_one);
+    }
+    check!(fs::remove_file(filename));
+}
+
+#[test]
+fn file_test_io_eof() {
+    let tmpdir = tmpdir();
+    let filename = tmpdir.join("file_rt_io_file_test_eof.txt");
+    let mut buf = [0; 256];
+    {
+        let oo = OpenOptions::new().create_new(true).write(true).read(true).clone();
+        let mut rw = check!(oo.open(&filename));
+        assert_eq!(check!(rw.read(&mut buf)), 0);
+        assert_eq!(check!(rw.read(&mut buf)), 0);
+    }
+    check!(fs::remove_file(&filename));
+}
+
+#[test]
+#[cfg(unix)]
+fn file_test_io_read_write_at() {
+    use crate::os::unix::fs::FileExt;
+
+    let tmpdir = tmpdir();
+    let filename = tmpdir.join("file_rt_io_file_test_read_write_at.txt");
+    let mut buf = [0; 256];
+    let write1 = "asdf";
+    let write2 = "qwer-";
+    let write3 = "-zxcv";
+    let content = "qwer-asdf-zxcv";
+    {
+        let oo = OpenOptions::new().create_new(true).write(true).read(true).clone();
+        let mut rw = check!(oo.open(&filename));
+        assert_eq!(check!(rw.write_at(write1.as_bytes(), 5)), write1.len());
+        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 0);
+        assert_eq!(check!(rw.read_at(&mut buf, 5)), write1.len());
+        assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1));
+        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 0);
+        assert_eq!(check!(rw.read_at(&mut buf[..write2.len()], 0)), write2.len());
+        assert_eq!(str::from_utf8(&buf[..write2.len()]), Ok("\0\0\0\0\0"));
+        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 0);
+        assert_eq!(check!(rw.write(write2.as_bytes())), write2.len());
+        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 5);
+        assert_eq!(check!(rw.read(&mut buf)), write1.len());
+        assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1));
+        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9);
+        assert_eq!(check!(rw.read_at(&mut buf[..write2.len()], 0)), write2.len());
+        assert_eq!(str::from_utf8(&buf[..write2.len()]), Ok(write2));
+        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9);
+        assert_eq!(check!(rw.write_at(write3.as_bytes(), 9)), write3.len());
+        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9);
+    }
+    {
+        let mut read = check!(File::open(&filename));
+        assert_eq!(check!(read.read_at(&mut buf, 0)), content.len());
+        assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content));
+        assert_eq!(check!(read.seek(SeekFrom::Current(0))), 0);
+        assert_eq!(check!(read.seek(SeekFrom::End(-5))), 9);
+        assert_eq!(check!(read.read_at(&mut buf, 0)), content.len());
+        assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content));
+        assert_eq!(check!(read.seek(SeekFrom::Current(0))), 9);
+        assert_eq!(check!(read.read(&mut buf)), write3.len());
+        assert_eq!(str::from_utf8(&buf[..write3.len()]), Ok(write3));
+        assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
+        assert_eq!(check!(read.read_at(&mut buf, 0)), content.len());
+        assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content));
+        assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
+        assert_eq!(check!(read.read_at(&mut buf, 14)), 0);
+        assert_eq!(check!(read.read_at(&mut buf, 15)), 0);
+        assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
+    }
+    check!(fs::remove_file(&filename));
+}
+
+#[test]
+#[cfg(unix)]
+fn set_get_unix_permissions() {
+    use crate::os::unix::fs::PermissionsExt;
+
+    let tmpdir = tmpdir();
+    let filename = &tmpdir.join("set_get_unix_permissions");
+    check!(fs::create_dir(filename));
+    let mask = 0o7777;
+
+    check!(fs::set_permissions(filename, fs::Permissions::from_mode(0)));
+    let metadata0 = check!(fs::metadata(filename));
+    assert_eq!(mask & metadata0.permissions().mode(), 0);
+
+    check!(fs::set_permissions(filename, fs::Permissions::from_mode(0o1777)));
+    let metadata1 = check!(fs::metadata(filename));
+    #[cfg(all(unix, not(target_os = "vxworks")))]
+    assert_eq!(mask & metadata1.permissions().mode(), 0o1777);
+    #[cfg(target_os = "vxworks")]
+    assert_eq!(mask & metadata1.permissions().mode(), 0o0777);
+}
+
+#[test]
+#[cfg(windows)]
+fn file_test_io_seek_read_write() {
+    use crate::os::windows::fs::FileExt;
+
+    let tmpdir = tmpdir();
+    let filename = tmpdir.join("file_rt_io_file_test_seek_read_write.txt");
+    let mut buf = [0; 256];
+    let write1 = "asdf";
+    let write2 = "qwer-";
+    let write3 = "-zxcv";
+    let content = "qwer-asdf-zxcv";
+    {
+        let oo = OpenOptions::new().create_new(true).write(true).read(true).clone();
+        let mut rw = check!(oo.open(&filename));
+        assert_eq!(check!(rw.seek_write(write1.as_bytes(), 5)), write1.len());
+        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9);
+        assert_eq!(check!(rw.seek_read(&mut buf, 5)), write1.len());
+        assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1));
+        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9);
+        assert_eq!(check!(rw.seek(SeekFrom::Start(0))), 0);
+        assert_eq!(check!(rw.write(write2.as_bytes())), write2.len());
+        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 5);
+        assert_eq!(check!(rw.read(&mut buf)), write1.len());
+        assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1));
+        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9);
+        assert_eq!(check!(rw.seek_read(&mut buf[..write2.len()], 0)), write2.len());
+        assert_eq!(str::from_utf8(&buf[..write2.len()]), Ok(write2));
+        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 5);
+        assert_eq!(check!(rw.seek_write(write3.as_bytes(), 9)), write3.len());
+        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 14);
+    }
+    {
+        let mut read = check!(File::open(&filename));
+        assert_eq!(check!(read.seek_read(&mut buf, 0)), content.len());
+        assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content));
+        assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
+        assert_eq!(check!(read.seek(SeekFrom::End(-5))), 9);
+        assert_eq!(check!(read.seek_read(&mut buf, 0)), content.len());
+        assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content));
+        assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
+        assert_eq!(check!(read.seek(SeekFrom::End(-5))), 9);
+        assert_eq!(check!(read.read(&mut buf)), write3.len());
+        assert_eq!(str::from_utf8(&buf[..write3.len()]), Ok(write3));
+        assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
+        assert_eq!(check!(read.seek_read(&mut buf, 0)), content.len());
+        assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content));
+        assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
+        assert_eq!(check!(read.seek_read(&mut buf, 14)), 0);
+        assert_eq!(check!(read.seek_read(&mut buf, 15)), 0);
+    }
+    check!(fs::remove_file(&filename));
+}
+
+#[test]
+fn file_test_stat_is_correct_on_is_file() {
+    let tmpdir = tmpdir();
+    let filename = &tmpdir.join("file_stat_correct_on_is_file.txt");
+    {
+        let mut opts = OpenOptions::new();
+        let mut fs = check!(opts.read(true).write(true).create(true).open(filename));
+        let msg = "hw";
+        fs.write(msg.as_bytes()).unwrap();
+
+        let fstat_res = check!(fs.metadata());
+        assert!(fstat_res.is_file());
+    }
+    let stat_res_fn = check!(fs::metadata(filename));
+    assert!(stat_res_fn.is_file());
+    let stat_res_meth = check!(filename.metadata());
+    assert!(stat_res_meth.is_file());
+    check!(fs::remove_file(filename));
+}
+
+#[test]
+fn file_test_stat_is_correct_on_is_dir() {
+    let tmpdir = tmpdir();
+    let filename = &tmpdir.join("file_stat_correct_on_is_dir");
+    check!(fs::create_dir(filename));
+    let stat_res_fn = check!(fs::metadata(filename));
+    assert!(stat_res_fn.is_dir());
+    let stat_res_meth = check!(filename.metadata());
+    assert!(stat_res_meth.is_dir());
+    check!(fs::remove_dir(filename));
+}
+
+#[test]
+fn file_test_fileinfo_false_when_checking_is_file_on_a_directory() {
+    let tmpdir = tmpdir();
+    let dir = &tmpdir.join("fileinfo_false_on_dir");
+    check!(fs::create_dir(dir));
+    assert!(!dir.is_file());
+    check!(fs::remove_dir(dir));
+}
+
+#[test]
+fn file_test_fileinfo_check_exists_before_and_after_file_creation() {
+    let tmpdir = tmpdir();
+    let file = &tmpdir.join("fileinfo_check_exists_b_and_a.txt");
+    check!(check!(File::create(file)).write(b"foo"));
+    assert!(file.exists());
+    check!(fs::remove_file(file));
+    assert!(!file.exists());
+}
+
+#[test]
+fn file_test_directoryinfo_check_exists_before_and_after_mkdir() {
+    let tmpdir = tmpdir();
+    let dir = &tmpdir.join("before_and_after_dir");
+    assert!(!dir.exists());
+    check!(fs::create_dir(dir));
+    assert!(dir.exists());
+    assert!(dir.is_dir());
+    check!(fs::remove_dir(dir));
+    assert!(!dir.exists());
+}
+
+#[test]
+fn file_test_directoryinfo_readdir() {
+    let tmpdir = tmpdir();
+    let dir = &tmpdir.join("di_readdir");
+    check!(fs::create_dir(dir));
+    let prefix = "foo";
+    for n in 0..3 {
+        let f = dir.join(&format!("{}.txt", n));
+        let mut w = check!(File::create(&f));
+        let msg_str = format!("{}{}", prefix, n.to_string());
+        let msg = msg_str.as_bytes();
+        check!(w.write(msg));
+    }
+    let files = check!(fs::read_dir(dir));
+    let mut mem = [0; 4];
+    for f in files {
+        let f = f.unwrap().path();
+        {
+            let n = f.file_stem().unwrap();
+            check!(check!(File::open(&f)).read(&mut mem));
+            let read_str = str::from_utf8(&mem).unwrap();
+            let expected = format!("{}{}", prefix, n.to_str().unwrap());
+            assert_eq!(expected, read_str);
+        }
+        check!(fs::remove_file(&f));
+    }
+    check!(fs::remove_dir(dir));
+}
+
+#[test]
+fn file_create_new_already_exists_error() {
+    let tmpdir = tmpdir();
+    let file = &tmpdir.join("file_create_new_error_exists");
+    check!(fs::File::create(file));
+    let e = fs::OpenOptions::new().write(true).create_new(true).open(file).unwrap_err();
+    assert_eq!(e.kind(), ErrorKind::AlreadyExists);
+}
+
+#[test]
+fn mkdir_path_already_exists_error() {
+    let tmpdir = tmpdir();
+    let dir = &tmpdir.join("mkdir_error_twice");
+    check!(fs::create_dir(dir));
+    let e = fs::create_dir(dir).unwrap_err();
+    assert_eq!(e.kind(), ErrorKind::AlreadyExists);
+}
+
+#[test]
+fn recursive_mkdir() {
+    let tmpdir = tmpdir();
+    let dir = tmpdir.join("d1/d2");
+    check!(fs::create_dir_all(&dir));
+    assert!(dir.is_dir())
+}
+
+#[test]
+fn recursive_mkdir_failure() {
+    let tmpdir = tmpdir();
+    let dir = tmpdir.join("d1");
+    let file = dir.join("f1");
+
+    check!(fs::create_dir_all(&dir));
+    check!(File::create(&file));
+
+    let result = fs::create_dir_all(&file);
+
+    assert!(result.is_err());
+}
+
+#[test]
+fn concurrent_recursive_mkdir() {
+    for _ in 0..100 {
+        let dir = tmpdir();
+        let mut dir = dir.join("a");
+        for _ in 0..40 {
+            dir = dir.join("a");
+        }
+        let mut join = vec![];
+        for _ in 0..8 {
+            let dir = dir.clone();
+            join.push(thread::spawn(move || {
+                check!(fs::create_dir_all(&dir));
+            }))
+        }
+
+        // No `Display` on result of `join()`
+        join.drain(..).map(|join| join.join().unwrap()).count();
+    }
+}
+
+#[test]
+fn recursive_mkdir_slash() {
+    check!(fs::create_dir_all(Path::new("/")));
+}
+
+#[test]
+fn recursive_mkdir_dot() {
+    check!(fs::create_dir_all(Path::new(".")));
+}
+
+#[test]
+fn recursive_mkdir_empty() {
+    check!(fs::create_dir_all(Path::new("")));
+}
+
+#[test]
+fn recursive_rmdir() {
+    let tmpdir = tmpdir();
+    let d1 = tmpdir.join("d1");
+    let dt = d1.join("t");
+    let dtt = dt.join("t");
+    let d2 = tmpdir.join("d2");
+    let canary = d2.join("do_not_delete");
+    check!(fs::create_dir_all(&dtt));
+    check!(fs::create_dir_all(&d2));
+    check!(check!(File::create(&canary)).write(b"foo"));
+    check!(symlink_junction(&d2, &dt.join("d2")));
+    let _ = symlink_file(&canary, &d1.join("canary"));
+    check!(fs::remove_dir_all(&d1));
+
+    assert!(!d1.is_dir());
+    assert!(canary.exists());
+}
+
+#[test]
+fn recursive_rmdir_of_symlink() {
+    // test we do not recursively delete a symlink but only dirs.
+    let tmpdir = tmpdir();
+    let link = tmpdir.join("d1");
+    let dir = tmpdir.join("d2");
+    let canary = dir.join("do_not_delete");
+    check!(fs::create_dir_all(&dir));
+    check!(check!(File::create(&canary)).write(b"foo"));
+    check!(symlink_junction(&dir, &link));
+    check!(fs::remove_dir_all(&link));
+
+    assert!(!link.is_dir());
+    assert!(canary.exists());
+}
+
+#[test]
+// only Windows makes a distinction between file and directory symlinks.
+#[cfg(windows)]
+fn recursive_rmdir_of_file_symlink() {
+    let tmpdir = tmpdir();
+    if !got_symlink_permission(&tmpdir) {
+        return;
+    };
+
+    let f1 = tmpdir.join("f1");
+    let f2 = tmpdir.join("f2");
+    check!(check!(File::create(&f1)).write(b"foo"));
+    check!(symlink_file(&f1, &f2));
+    match fs::remove_dir_all(&f2) {
+        Ok(..) => panic!("wanted a failure"),
+        Err(..) => {}
+    }
+}
+
+#[test]
+fn unicode_path_is_dir() {
+    assert!(Path::new(".").is_dir());
+    assert!(!Path::new("test/stdtest/fs.rs").is_dir());
+
+    let tmpdir = tmpdir();
+
+    let mut dirpath = tmpdir.path().to_path_buf();
+    dirpath.push("test-가一ー你好");
+    check!(fs::create_dir(&dirpath));
+    assert!(dirpath.is_dir());
+
+    let mut filepath = dirpath;
+    filepath.push("unicode-file-\u{ac00}\u{4e00}\u{30fc}\u{4f60}\u{597d}.rs");
+    check!(File::create(&filepath)); // ignore return; touch only
+    assert!(!filepath.is_dir());
+    assert!(filepath.exists());
+}
+
+#[test]
+fn unicode_path_exists() {
+    assert!(Path::new(".").exists());
+    assert!(!Path::new("test/nonexistent-bogus-path").exists());
+
+    let tmpdir = tmpdir();
+    let unicode = tmpdir.path();
+    let unicode = unicode.join("test-각丁ー再见");
+    check!(fs::create_dir(&unicode));
+    assert!(unicode.exists());
+    assert!(!Path::new("test/unicode-bogus-path-각丁ー再见").exists());
+}
+
+#[test]
+fn copy_file_does_not_exist() {
+    let from = Path::new("test/nonexistent-bogus-path");
+    let to = Path::new("test/other-bogus-path");
+
+    match fs::copy(&from, &to) {
+        Ok(..) => panic!(),
+        Err(..) => {
+            assert!(!from.exists());
+            assert!(!to.exists());
+        }
+    }
+}
+
+#[test]
+fn copy_src_does_not_exist() {
+    let tmpdir = tmpdir();
+    let from = Path::new("test/nonexistent-bogus-path");
+    let to = tmpdir.join("out.txt");
+    check!(check!(File::create(&to)).write(b"hello"));
+    assert!(fs::copy(&from, &to).is_err());
+    assert!(!from.exists());
+    let mut v = Vec::new();
+    check!(check!(File::open(&to)).read_to_end(&mut v));
+    assert_eq!(v, b"hello");
+}
+
+#[test]
+fn copy_file_ok() {
+    let tmpdir = tmpdir();
+    let input = tmpdir.join("in.txt");
+    let out = tmpdir.join("out.txt");
+
+    check!(check!(File::create(&input)).write(b"hello"));
+    check!(fs::copy(&input, &out));
+    let mut v = Vec::new();
+    check!(check!(File::open(&out)).read_to_end(&mut v));
+    assert_eq!(v, b"hello");
+
+    assert_eq!(check!(input.metadata()).permissions(), check!(out.metadata()).permissions());
+}
+
+#[test]
+fn copy_file_dst_dir() {
+    let tmpdir = tmpdir();
+    let out = tmpdir.join("out");
+
+    check!(File::create(&out));
+    match fs::copy(&*out, tmpdir.path()) {
+        Ok(..) => panic!(),
+        Err(..) => {}
+    }
+}
+
+#[test]
+fn copy_file_dst_exists() {
+    let tmpdir = tmpdir();
+    let input = tmpdir.join("in");
+    let output = tmpdir.join("out");
+
+    check!(check!(File::create(&input)).write("foo".as_bytes()));
+    check!(check!(File::create(&output)).write("bar".as_bytes()));
+    check!(fs::copy(&input, &output));
+
+    let mut v = Vec::new();
+    check!(check!(File::open(&output)).read_to_end(&mut v));
+    assert_eq!(v, b"foo".to_vec());
+}
+
+#[test]
+fn copy_file_src_dir() {
+    let tmpdir = tmpdir();
+    let out = tmpdir.join("out");
+
+    match fs::copy(tmpdir.path(), &out) {
+        Ok(..) => panic!(),
+        Err(..) => {}
+    }
+    assert!(!out.exists());
+}
+
+#[test]
+fn copy_file_preserves_perm_bits() {
+    let tmpdir = tmpdir();
+    let input = tmpdir.join("in.txt");
+    let out = tmpdir.join("out.txt");
+
+    let attr = check!(check!(File::create(&input)).metadata());
+    let mut p = attr.permissions();
+    p.set_readonly(true);
+    check!(fs::set_permissions(&input, p));
+    check!(fs::copy(&input, &out));
+    assert!(check!(out.metadata()).permissions().readonly());
+    check!(fs::set_permissions(&input, attr.permissions()));
+    check!(fs::set_permissions(&out, attr.permissions()));
+}
+
+#[test]
+#[cfg(windows)]
+fn copy_file_preserves_streams() {
+    let tmp = tmpdir();
+    check!(check!(File::create(tmp.join("in.txt:bunny"))).write("carrot".as_bytes()));
+    assert_eq!(check!(fs::copy(tmp.join("in.txt"), tmp.join("out.txt"))), 0);
+    assert_eq!(check!(tmp.join("out.txt").metadata()).len(), 0);
+    let mut v = Vec::new();
+    check!(check!(File::open(tmp.join("out.txt:bunny"))).read_to_end(&mut v));
+    assert_eq!(v, b"carrot".to_vec());
+}
+
+#[test]
+fn copy_file_returns_metadata_len() {
+    let tmp = tmpdir();
+    let in_path = tmp.join("in.txt");
+    let out_path = tmp.join("out.txt");
+    check!(check!(File::create(&in_path)).write(b"lettuce"));
+    #[cfg(windows)]
+    check!(check!(File::create(tmp.join("in.txt:bunny"))).write(b"carrot"));
+    let copied_len = check!(fs::copy(&in_path, &out_path));
+    assert_eq!(check!(out_path.metadata()).len(), copied_len);
+}
+
+#[test]
+fn copy_file_follows_dst_symlink() {
+    let tmp = tmpdir();
+    if !got_symlink_permission(&tmp) {
+        return;
+    };
+
+    let in_path = tmp.join("in.txt");
+    let out_path = tmp.join("out.txt");
+    let out_path_symlink = tmp.join("out_symlink.txt");
+
+    check!(fs::write(&in_path, "foo"));
+    check!(fs::write(&out_path, "bar"));
+    check!(symlink_file(&out_path, &out_path_symlink));
+
+    check!(fs::copy(&in_path, &out_path_symlink));
+
+    assert!(check!(out_path_symlink.symlink_metadata()).file_type().is_symlink());
+    assert_eq!(check!(fs::read(&out_path_symlink)), b"foo".to_vec());
+    assert_eq!(check!(fs::read(&out_path)), b"foo".to_vec());
+}
+
+#[test]
+fn symlinks_work() {
+    let tmpdir = tmpdir();
+    if !got_symlink_permission(&tmpdir) {
+        return;
+    };
+
+    let input = tmpdir.join("in.txt");
+    let out = tmpdir.join("out.txt");
+
+    check!(check!(File::create(&input)).write("foobar".as_bytes()));
+    check!(symlink_file(&input, &out));
+    assert!(check!(out.symlink_metadata()).file_type().is_symlink());
+    assert_eq!(check!(fs::metadata(&out)).len(), check!(fs::metadata(&input)).len());
+    let mut v = Vec::new();
+    check!(check!(File::open(&out)).read_to_end(&mut v));
+    assert_eq!(v, b"foobar".to_vec());
+}
+
+#[test]
+fn symlink_noexist() {
+    // Symlinks can point to things that don't exist
+    let tmpdir = tmpdir();
+    if !got_symlink_permission(&tmpdir) {
+        return;
+    };
+
+    // Use a relative path for testing. Symlinks get normalized by Windows,
+    // so we may not get the same path back for absolute paths
+    check!(symlink_file(&"foo", &tmpdir.join("bar")));
+    assert_eq!(check!(fs::read_link(&tmpdir.join("bar"))).to_str().unwrap(), "foo");
+}
+
+#[test]
+fn read_link() {
+    if cfg!(windows) {
+        // directory symlink
+        assert_eq!(
+            check!(fs::read_link(r"C:\Users\All Users")).to_str().unwrap(),
+            r"C:\ProgramData"
+        );
+        // junction
+        assert_eq!(
+            check!(fs::read_link(r"C:\Users\Default User")).to_str().unwrap(),
+            r"C:\Users\Default"
+        );
+        // junction with special permissions
+        assert_eq!(
+            check!(fs::read_link(r"C:\Documents and Settings\")).to_str().unwrap(),
+            r"C:\Users"
+        );
+    }
+    let tmpdir = tmpdir();
+    let link = tmpdir.join("link");
+    if !got_symlink_permission(&tmpdir) {
+        return;
+    };
+    check!(symlink_file(&"foo", &link));
+    assert_eq!(check!(fs::read_link(&link)).to_str().unwrap(), "foo");
+}
+
+#[test]
+fn readlink_not_symlink() {
+    let tmpdir = tmpdir();
+    match fs::read_link(tmpdir.path()) {
+        Ok(..) => panic!("wanted a failure"),
+        Err(..) => {}
+    }
+}
+
+#[test]
+fn links_work() {
+    let tmpdir = tmpdir();
+    let input = tmpdir.join("in.txt");
+    let out = tmpdir.join("out.txt");
+
+    check!(check!(File::create(&input)).write("foobar".as_bytes()));
+    check!(fs::hard_link(&input, &out));
+    assert_eq!(check!(fs::metadata(&out)).len(), check!(fs::metadata(&input)).len());
+    assert_eq!(check!(fs::metadata(&out)).len(), check!(input.metadata()).len());
+    let mut v = Vec::new();
+    check!(check!(File::open(&out)).read_to_end(&mut v));
+    assert_eq!(v, b"foobar".to_vec());
+
+    // can't link to yourself
+    match fs::hard_link(&input, &input) {
+        Ok(..) => panic!("wanted a failure"),
+        Err(..) => {}
+    }
+    // can't link to something that doesn't exist
+    match fs::hard_link(&tmpdir.join("foo"), &tmpdir.join("bar")) {
+        Ok(..) => panic!("wanted a failure"),
+        Err(..) => {}
+    }
+}
+
+#[test]
+fn chmod_works() {
+    let tmpdir = tmpdir();
+    let file = tmpdir.join("in.txt");
+
+    check!(File::create(&file));
+    let attr = check!(fs::metadata(&file));
+    assert!(!attr.permissions().readonly());
+    let mut p = attr.permissions();
+    p.set_readonly(true);
+    check!(fs::set_permissions(&file, p.clone()));
+    let attr = check!(fs::metadata(&file));
+    assert!(attr.permissions().readonly());
+
+    match fs::set_permissions(&tmpdir.join("foo"), p.clone()) {
+        Ok(..) => panic!("wanted an error"),
+        Err(..) => {}
+    }
+
+    p.set_readonly(false);
+    check!(fs::set_permissions(&file, p));
+}
+
+#[test]
+fn fchmod_works() {
+    let tmpdir = tmpdir();
+    let path = tmpdir.join("in.txt");
+
+    let file = check!(File::create(&path));
+    let attr = check!(fs::metadata(&path));
+    assert!(!attr.permissions().readonly());
+    let mut p = attr.permissions();
+    p.set_readonly(true);
+    check!(file.set_permissions(p.clone()));
+    let attr = check!(fs::metadata(&path));
+    assert!(attr.permissions().readonly());
+
+    p.set_readonly(false);
+    check!(file.set_permissions(p));
+}
+
+#[test]
+fn sync_doesnt_kill_anything() {
+    let tmpdir = tmpdir();
+    let path = tmpdir.join("in.txt");
+
+    let mut file = check!(File::create(&path));
+    check!(file.sync_all());
+    check!(file.sync_data());
+    check!(file.write(b"foo"));
+    check!(file.sync_all());
+    check!(file.sync_data());
+}
+
+#[test]
+fn truncate_works() {
+    let tmpdir = tmpdir();
+    let path = tmpdir.join("in.txt");
+
+    let mut file = check!(File::create(&path));
+    check!(file.write(b"foo"));
+    check!(file.sync_all());
+
+    // Do some simple things with truncation
+    assert_eq!(check!(file.metadata()).len(), 3);
+    check!(file.set_len(10));
+    assert_eq!(check!(file.metadata()).len(), 10);
+    check!(file.write(b"bar"));
+    check!(file.sync_all());
+    assert_eq!(check!(file.metadata()).len(), 10);
+
+    let mut v = Vec::new();
+    check!(check!(File::open(&path)).read_to_end(&mut v));
+    assert_eq!(v, b"foobar\0\0\0\0".to_vec());
+
+    // Truncate to a smaller length, don't seek, and then write something.
+    // Ensure that the intermediate zeroes are all filled in (we have `seek`ed
+    // past the end of the file).
+    check!(file.set_len(2));
+    assert_eq!(check!(file.metadata()).len(), 2);
+    check!(file.write(b"wut"));
+    check!(file.sync_all());
+    assert_eq!(check!(file.metadata()).len(), 9);
+    let mut v = Vec::new();
+    check!(check!(File::open(&path)).read_to_end(&mut v));
+    assert_eq!(v, b"fo\0\0\0\0wut".to_vec());
+}
+
+#[test]
+fn open_flavors() {
+    use crate::fs::OpenOptions as OO;
+    fn c<T: Clone>(t: &T) -> T {
+        t.clone()
+    }
+
+    let tmpdir = tmpdir();
+
+    let mut r = OO::new();
+    r.read(true);
+    let mut w = OO::new();
+    w.write(true);
+    let mut rw = OO::new();
+    rw.read(true).write(true);
+    let mut a = OO::new();
+    a.append(true);
+    let mut ra = OO::new();
+    ra.read(true).append(true);
+
+    #[cfg(windows)]
+    let invalid_options = 87; // ERROR_INVALID_PARAMETER
+    #[cfg(all(unix, not(target_os = "vxworks")))]
+    let invalid_options = "Invalid argument";
+    #[cfg(target_os = "vxworks")]
+    let invalid_options = "invalid argument";
+
+    // Test various combinations of creation modes and access modes.
+    //
+    // Allowed:
+    // creation mode           | read  | write | read-write | append | read-append |
+    // :-----------------------|:-----:|:-----:|:----------:|:------:|:-----------:|
+    // not set (open existing) |   X   |   X   |     X      |   X    |      X      |
+    // create                  |       |   X   |     X      |   X    |      X      |
+    // truncate                |       |   X   |     X      |        |             |
+    // create and truncate     |       |   X   |     X      |        |             |
+    // create_new              |       |   X   |     X      |   X    |      X      |
+    //
+    // tested in reverse order, so 'create_new' creates the file, and 'open existing' opens it.
+
+    // write-only
+    check!(c(&w).create_new(true).open(&tmpdir.join("a")));
+    check!(c(&w).create(true).truncate(true).open(&tmpdir.join("a")));
+    check!(c(&w).truncate(true).open(&tmpdir.join("a")));
+    check!(c(&w).create(true).open(&tmpdir.join("a")));
+    check!(c(&w).open(&tmpdir.join("a")));
+
+    // read-only
+    error!(c(&r).create_new(true).open(&tmpdir.join("b")), invalid_options);
+    error!(c(&r).create(true).truncate(true).open(&tmpdir.join("b")), invalid_options);
+    error!(c(&r).truncate(true).open(&tmpdir.join("b")), invalid_options);
+    error!(c(&r).create(true).open(&tmpdir.join("b")), invalid_options);
+    check!(c(&r).open(&tmpdir.join("a"))); // try opening the file created with write_only
+
+    // read-write
+    check!(c(&rw).create_new(true).open(&tmpdir.join("c")));
+    check!(c(&rw).create(true).truncate(true).open(&tmpdir.join("c")));
+    check!(c(&rw).truncate(true).open(&tmpdir.join("c")));
+    check!(c(&rw).create(true).open(&tmpdir.join("c")));
+    check!(c(&rw).open(&tmpdir.join("c")));
+
+    // append
+    check!(c(&a).create_new(true).open(&tmpdir.join("d")));
+    error!(c(&a).create(true).truncate(true).open(&tmpdir.join("d")), invalid_options);
+    error!(c(&a).truncate(true).open(&tmpdir.join("d")), invalid_options);
+    check!(c(&a).create(true).open(&tmpdir.join("d")));
+    check!(c(&a).open(&tmpdir.join("d")));
+
+    // read-append
+    check!(c(&ra).create_new(true).open(&tmpdir.join("e")));
+    error!(c(&ra).create(true).truncate(true).open(&tmpdir.join("e")), invalid_options);
+    error!(c(&ra).truncate(true).open(&tmpdir.join("e")), invalid_options);
+    check!(c(&ra).create(true).open(&tmpdir.join("e")));
+    check!(c(&ra).open(&tmpdir.join("e")));
+
+    // Test opening a file without setting an access mode
+    let mut blank = OO::new();
+    error!(blank.create(true).open(&tmpdir.join("f")), invalid_options);
+
+    // Test write works
+    check!(check!(File::create(&tmpdir.join("h"))).write("foobar".as_bytes()));
+
+    // Test write fails for read-only
+    check!(r.open(&tmpdir.join("h")));
+    {
+        let mut f = check!(r.open(&tmpdir.join("h")));
+        assert!(f.write("wut".as_bytes()).is_err());
+    }
+
+    // Test write overwrites
+    {
+        let mut f = check!(c(&w).open(&tmpdir.join("h")));
+        check!(f.write("baz".as_bytes()));
+    }
+    {
+        let mut f = check!(c(&r).open(&tmpdir.join("h")));
+        let mut b = vec![0; 6];
+        check!(f.read(&mut b));
+        assert_eq!(b, "bazbar".as_bytes());
+    }
+
+    // Test truncate works
+    {
+        let mut f = check!(c(&w).truncate(true).open(&tmpdir.join("h")));
+        check!(f.write("foo".as_bytes()));
+    }
+    assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 3);
+
+    // Test append works
+    assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 3);
+    {
+        let mut f = check!(c(&a).open(&tmpdir.join("h")));
+        check!(f.write("bar".as_bytes()));
+    }
+    assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 6);
+
+    // Test .append(true) equals .write(true).append(true)
+    {
+        let mut f = check!(c(&w).append(true).open(&tmpdir.join("h")));
+        check!(f.write("baz".as_bytes()));
+    }
+    assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 9);
+}
+
+#[test]
+fn _assert_send_sync() {
+    fn _assert_send_sync<T: Send + Sync>() {}
+    _assert_send_sync::<OpenOptions>();
+}
+
+#[test]
+fn binary_file() {
+    let mut bytes = [0; 1024];
+    StdRng::from_entropy().fill_bytes(&mut bytes);
+
+    let tmpdir = tmpdir();
+
+    check!(check!(File::create(&tmpdir.join("test"))).write(&bytes));
+    let mut v = Vec::new();
+    check!(check!(File::open(&tmpdir.join("test"))).read_to_end(&mut v));
+    assert!(v == &bytes[..]);
+}
+
+#[test]
+fn write_then_read() {
+    let mut bytes = [0; 1024];
+    StdRng::from_entropy().fill_bytes(&mut bytes);
+
+    let tmpdir = tmpdir();
+
+    check!(fs::write(&tmpdir.join("test"), &bytes[..]));
+    let v = check!(fs::read(&tmpdir.join("test")));
+    assert!(v == &bytes[..]);
+
+    check!(fs::write(&tmpdir.join("not-utf8"), &[0xFF]));
+    error_contains!(
+        fs::read_to_string(&tmpdir.join("not-utf8")),
+        "stream did not contain valid UTF-8"
+    );
+
+    let s = "𐁁𐀓𐀠𐀴𐀍";
+    check!(fs::write(&tmpdir.join("utf8"), s.as_bytes()));
+    let string = check!(fs::read_to_string(&tmpdir.join("utf8")));
+    assert_eq!(string, s);
+}
+
+#[test]
+fn file_try_clone() {
+    let tmpdir = tmpdir();
+
+    let mut f1 =
+        check!(OpenOptions::new().read(true).write(true).create(true).open(&tmpdir.join("test")));
+    let mut f2 = check!(f1.try_clone());
+
+    check!(f1.write_all(b"hello world"));
+    check!(f1.seek(SeekFrom::Start(2)));
+
+    let mut buf = vec![];
+    check!(f2.read_to_end(&mut buf));
+    assert_eq!(buf, b"llo world");
+    drop(f2);
+
+    check!(f1.write_all(b"!"));
+}
+
+#[test]
+#[cfg(not(windows))]
+fn unlink_readonly() {
+    let tmpdir = tmpdir();
+    let path = tmpdir.join("file");
+    check!(File::create(&path));
+    let mut perm = check!(fs::metadata(&path)).permissions();
+    perm.set_readonly(true);
+    check!(fs::set_permissions(&path, perm));
+    check!(fs::remove_file(&path));
+}
+
+#[test]
+fn mkdir_trailing_slash() {
+    let tmpdir = tmpdir();
+    let path = tmpdir.join("file");
+    check!(fs::create_dir_all(&path.join("a/")));
+}
+
+#[test]
+fn canonicalize_works_simple() {
+    let tmpdir = tmpdir();
+    let tmpdir = fs::canonicalize(tmpdir.path()).unwrap();
+    let file = tmpdir.join("test");
+    File::create(&file).unwrap();
+    assert_eq!(fs::canonicalize(&file).unwrap(), file);
+}
+
+#[test]
+fn realpath_works() {
+    let tmpdir = tmpdir();
+    if !got_symlink_permission(&tmpdir) {
+        return;
+    };
+
+    let tmpdir = fs::canonicalize(tmpdir.path()).unwrap();
+    let file = tmpdir.join("test");
+    let dir = tmpdir.join("test2");
+    let link = dir.join("link");
+    let linkdir = tmpdir.join("test3");
+
+    File::create(&file).unwrap();
+    fs::create_dir(&dir).unwrap();
+    symlink_file(&file, &link).unwrap();
+    symlink_dir(&dir, &linkdir).unwrap();
+
+    assert!(link.symlink_metadata().unwrap().file_type().is_symlink());
+
+    assert_eq!(fs::canonicalize(&tmpdir).unwrap(), tmpdir);
+    assert_eq!(fs::canonicalize(&file).unwrap(), file);
+    assert_eq!(fs::canonicalize(&link).unwrap(), file);
+    assert_eq!(fs::canonicalize(&linkdir).unwrap(), dir);
+    assert_eq!(fs::canonicalize(&linkdir.join("link")).unwrap(), file);
+}
+
+#[test]
+fn realpath_works_tricky() {
+    let tmpdir = tmpdir();
+    if !got_symlink_permission(&tmpdir) {
+        return;
+    };
+
+    let tmpdir = fs::canonicalize(tmpdir.path()).unwrap();
+    let a = tmpdir.join("a");
+    let b = a.join("b");
+    let c = b.join("c");
+    let d = a.join("d");
+    let e = d.join("e");
+    let f = a.join("f");
+
+    fs::create_dir_all(&b).unwrap();
+    fs::create_dir_all(&d).unwrap();
+    File::create(&f).unwrap();
+    if cfg!(not(windows)) {
+        symlink_file("../d/e", &c).unwrap();
+        symlink_file("../f", &e).unwrap();
+    }
+    if cfg!(windows) {
+        symlink_file(r"..\d\e", &c).unwrap();
+        symlink_file(r"..\f", &e).unwrap();
+    }
+
+    assert_eq!(fs::canonicalize(&c).unwrap(), f);
+    assert_eq!(fs::canonicalize(&e).unwrap(), f);
+}
+
+#[test]
+fn dir_entry_methods() {
+    let tmpdir = tmpdir();
+
+    fs::create_dir_all(&tmpdir.join("a")).unwrap();
+    File::create(&tmpdir.join("b")).unwrap();
+
+    for file in tmpdir.path().read_dir().unwrap().map(|f| f.unwrap()) {
+        let fname = file.file_name();
+        match fname.to_str() {
+            Some("a") => {
+                assert!(file.file_type().unwrap().is_dir());
+                assert!(file.metadata().unwrap().is_dir());
+            }
+            Some("b") => {
+                assert!(file.file_type().unwrap().is_file());
+                assert!(file.metadata().unwrap().is_file());
+            }
+            f => panic!("unknown file name: {:?}", f),
+        }
+    }
+}
+
+#[test]
+fn dir_entry_debug() {
+    let tmpdir = tmpdir();
+    File::create(&tmpdir.join("b")).unwrap();
+    let mut read_dir = tmpdir.path().read_dir().unwrap();
+    let dir_entry = read_dir.next().unwrap().unwrap();
+    let actual = format!("{:?}", dir_entry);
+    let expected = format!("DirEntry({:?})", dir_entry.0.path());
+    assert_eq!(actual, expected);
+}
+
+#[test]
+fn read_dir_not_found() {
+    let res = fs::read_dir("/path/that/does/not/exist");
+    assert_eq!(res.err().unwrap().kind(), ErrorKind::NotFound);
+}
+
+#[test]
+fn create_dir_all_with_junctions() {
+    let tmpdir = tmpdir();
+    let target = tmpdir.join("target");
+
+    let junction = tmpdir.join("junction");
+    let b = junction.join("a/b");
+
+    let link = tmpdir.join("link");
+    let d = link.join("c/d");
+
+    fs::create_dir(&target).unwrap();
+
+    check!(symlink_junction(&target, &junction));
+    check!(fs::create_dir_all(&b));
+    // the junction itself is not a directory, but `is_dir()` on a Path
+    // follows links
+    assert!(junction.is_dir());
+    assert!(b.exists());
+
+    if !got_symlink_permission(&tmpdir) {
+        return;
+    };
+    check!(symlink_dir(&target, &link));
+    check!(fs::create_dir_all(&d));
+    assert!(link.is_dir());
+    assert!(d.exists());
+}
+
+#[test]
+fn metadata_access_times() {
+    let tmpdir = tmpdir();
+
+    let b = tmpdir.join("b");
+    File::create(&b).unwrap();
+
+    let a = check!(fs::metadata(&tmpdir.path()));
+    let b = check!(fs::metadata(&b));
+
+    assert_eq!(check!(a.accessed()), check!(a.accessed()));
+    assert_eq!(check!(a.modified()), check!(a.modified()));
+    assert_eq!(check!(b.accessed()), check!(b.modified()));
+
+    if cfg!(target_os = "macos") || cfg!(target_os = "windows") {
+        check!(a.created());
+        check!(b.created());
+    }
+
+    if cfg!(target_os = "linux") {
+        // Not always available
+        match (a.created(), b.created()) {
+            (Ok(t1), Ok(t2)) => assert!(t1 <= t2),
+            (Err(e1), Err(e2))
+                if e1.kind() == ErrorKind::Other && e2.kind() == ErrorKind::Other => {}
+            (a, b) => {
+                panic!("creation time must be always supported or not supported: {:?} {:?}", a, b,)
+            }
+        }
+    }
+}
diff --git a/library/std/src/io/buffered.rs b/library/std/src/io/buffered.rs
index ec3c69dd616..5ad8f8132e4 100644
--- a/library/std/src/io/buffered.rs
+++ b/library/std/src/io/buffered.rs
@@ -1,5 +1,8 @@
 //! Buffering wrappers for I/O traits
 
+#[cfg(test)]
+mod tests;
+
 use crate::io::prelude::*;
 
 use crate::cmp;
@@ -1388,923 +1391,3 @@ where
             .finish()
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use crate::io::prelude::*;
-    use crate::io::{self, BufReader, BufWriter, ErrorKind, IoSlice, LineWriter, SeekFrom};
-    use crate::sync::atomic::{AtomicUsize, Ordering};
-    use crate::thread;
-
-    /// A dummy reader intended at testing short-reads propagation.
-    pub struct ShortReader {
-        lengths: Vec<usize>,
-    }
-
-    // FIXME: rustfmt and tidy disagree about the correct formatting of this
-    // function. This leads to issues for users with editors configured to
-    // rustfmt-on-save.
-    impl Read for ShortReader {
-        fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
-            if self.lengths.is_empty() { Ok(0) } else { Ok(self.lengths.remove(0)) }
-        }
-    }
-
-    #[test]
-    fn test_buffered_reader() {
-        let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
-        let mut reader = BufReader::with_capacity(2, inner);
-
-        let mut buf = [0, 0, 0];
-        let nread = reader.read(&mut buf);
-        assert_eq!(nread.unwrap(), 3);
-        assert_eq!(buf, [5, 6, 7]);
-        assert_eq!(reader.buffer(), []);
-
-        let mut buf = [0, 0];
-        let nread = reader.read(&mut buf);
-        assert_eq!(nread.unwrap(), 2);
-        assert_eq!(buf, [0, 1]);
-        assert_eq!(reader.buffer(), []);
-
-        let mut buf = [0];
-        let nread = reader.read(&mut buf);
-        assert_eq!(nread.unwrap(), 1);
-        assert_eq!(buf, [2]);
-        assert_eq!(reader.buffer(), [3]);
-
-        let mut buf = [0, 0, 0];
-        let nread = reader.read(&mut buf);
-        assert_eq!(nread.unwrap(), 1);
-        assert_eq!(buf, [3, 0, 0]);
-        assert_eq!(reader.buffer(), []);
-
-        let nread = reader.read(&mut buf);
-        assert_eq!(nread.unwrap(), 1);
-        assert_eq!(buf, [4, 0, 0]);
-        assert_eq!(reader.buffer(), []);
-
-        assert_eq!(reader.read(&mut buf).unwrap(), 0);
-    }
-
-    #[test]
-    fn test_buffered_reader_seek() {
-        let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
-        let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner));
-
-        assert_eq!(reader.seek(SeekFrom::Start(3)).ok(), Some(3));
-        assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
-        assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(3));
-        assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
-        assert_eq!(reader.seek(SeekFrom::Current(1)).ok(), Some(4));
-        assert_eq!(reader.fill_buf().ok(), Some(&[1, 2][..]));
-        reader.consume(1);
-        assert_eq!(reader.seek(SeekFrom::Current(-2)).ok(), Some(3));
-    }
-
-    #[test]
-    fn test_buffered_reader_seek_relative() {
-        let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
-        let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner));
-
-        assert!(reader.seek_relative(3).is_ok());
-        assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
-        assert!(reader.seek_relative(0).is_ok());
-        assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
-        assert!(reader.seek_relative(1).is_ok());
-        assert_eq!(reader.fill_buf().ok(), Some(&[1][..]));
-        assert!(reader.seek_relative(-1).is_ok());
-        assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
-        assert!(reader.seek_relative(2).is_ok());
-        assert_eq!(reader.fill_buf().ok(), Some(&[2, 3][..]));
-    }
-
-    #[test]
-    fn test_buffered_reader_invalidated_after_read() {
-        let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
-        let mut reader = BufReader::with_capacity(3, io::Cursor::new(inner));
-
-        assert_eq!(reader.fill_buf().ok(), Some(&[5, 6, 7][..]));
-        reader.consume(3);
-
-        let mut buffer = [0, 0, 0, 0, 0];
-        assert_eq!(reader.read(&mut buffer).ok(), Some(5));
-        assert_eq!(buffer, [0, 1, 2, 3, 4]);
-
-        assert!(reader.seek_relative(-2).is_ok());
-        let mut buffer = [0, 0];
-        assert_eq!(reader.read(&mut buffer).ok(), Some(2));
-        assert_eq!(buffer, [3, 4]);
-    }
-
-    #[test]
-    fn test_buffered_reader_invalidated_after_seek() {
-        let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
-        let mut reader = BufReader::with_capacity(3, io::Cursor::new(inner));
-
-        assert_eq!(reader.fill_buf().ok(), Some(&[5, 6, 7][..]));
-        reader.consume(3);
-
-        assert!(reader.seek(SeekFrom::Current(5)).is_ok());
-
-        assert!(reader.seek_relative(-2).is_ok());
-        let mut buffer = [0, 0];
-        assert_eq!(reader.read(&mut buffer).ok(), Some(2));
-        assert_eq!(buffer, [3, 4]);
-    }
-
-    #[test]
-    fn test_buffered_reader_seek_underflow() {
-        // gimmick reader that yields its position modulo 256 for each byte
-        struct PositionReader {
-            pos: u64,
-        }
-        impl Read for PositionReader {
-            fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-                let len = buf.len();
-                for x in buf {
-                    *x = self.pos as u8;
-                    self.pos = self.pos.wrapping_add(1);
-                }
-                Ok(len)
-            }
-        }
-        impl Seek for PositionReader {
-            fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
-                match pos {
-                    SeekFrom::Start(n) => {
-                        self.pos = n;
-                    }
-                    SeekFrom::Current(n) => {
-                        self.pos = self.pos.wrapping_add(n as u64);
-                    }
-                    SeekFrom::End(n) => {
-                        self.pos = u64::MAX.wrapping_add(n as u64);
-                    }
-                }
-                Ok(self.pos)
-            }
-        }
-
-        let mut reader = BufReader::with_capacity(5, PositionReader { pos: 0 });
-        assert_eq!(reader.fill_buf().ok(), Some(&[0, 1, 2, 3, 4][..]));
-        assert_eq!(reader.seek(SeekFrom::End(-5)).ok(), Some(u64::MAX - 5));
-        assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5));
-        // the following seek will require two underlying seeks
-        let expected = 9223372036854775802;
-        assert_eq!(reader.seek(SeekFrom::Current(i64::MIN)).ok(), Some(expected));
-        assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5));
-        // seeking to 0 should empty the buffer.
-        assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(expected));
-        assert_eq!(reader.get_ref().pos, expected);
-    }
-
-    #[test]
-    fn test_buffered_reader_seek_underflow_discard_buffer_between_seeks() {
-        // gimmick reader that returns Err after first seek
-        struct ErrAfterFirstSeekReader {
-            first_seek: bool,
-        }
-        impl Read for ErrAfterFirstSeekReader {
-            fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-                for x in &mut *buf {
-                    *x = 0;
-                }
-                Ok(buf.len())
-            }
-        }
-        impl Seek for ErrAfterFirstSeekReader {
-            fn seek(&mut self, _: SeekFrom) -> io::Result<u64> {
-                if self.first_seek {
-                    self.first_seek = false;
-                    Ok(0)
-                } else {
-                    Err(io::Error::new(io::ErrorKind::Other, "oh no!"))
-                }
-            }
-        }
-
-        let mut reader = BufReader::with_capacity(5, ErrAfterFirstSeekReader { first_seek: true });
-        assert_eq!(reader.fill_buf().ok(), Some(&[0, 0, 0, 0, 0][..]));
-
-        // The following seek will require two underlying seeks.  The first will
-        // succeed but the second will fail.  This should still invalidate the
-        // buffer.
-        assert!(reader.seek(SeekFrom::Current(i64::MIN)).is_err());
-        assert_eq!(reader.buffer().len(), 0);
-    }
-
-    #[test]
-    fn test_buffered_writer() {
-        let inner = Vec::new();
-        let mut writer = BufWriter::with_capacity(2, inner);
-
-        writer.write(&[0, 1]).unwrap();
-        assert_eq!(writer.buffer(), []);
-        assert_eq!(*writer.get_ref(), [0, 1]);
-
-        writer.write(&[2]).unwrap();
-        assert_eq!(writer.buffer(), [2]);
-        assert_eq!(*writer.get_ref(), [0, 1]);
-
-        writer.write(&[3]).unwrap();
-        assert_eq!(writer.buffer(), [2, 3]);
-        assert_eq!(*writer.get_ref(), [0, 1]);
-
-        writer.flush().unwrap();
-        assert_eq!(writer.buffer(), []);
-        assert_eq!(*writer.get_ref(), [0, 1, 2, 3]);
-
-        writer.write(&[4]).unwrap();
-        writer.write(&[5]).unwrap();
-        assert_eq!(writer.buffer(), [4, 5]);
-        assert_eq!(*writer.get_ref(), [0, 1, 2, 3]);
-
-        writer.write(&[6]).unwrap();
-        assert_eq!(writer.buffer(), [6]);
-        assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5]);
-
-        writer.write(&[7, 8]).unwrap();
-        assert_eq!(writer.buffer(), []);
-        assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8]);
-
-        writer.write(&[9, 10, 11]).unwrap();
-        assert_eq!(writer.buffer(), []);
-        assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
-
-        writer.flush().unwrap();
-        assert_eq!(writer.buffer(), []);
-        assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
-    }
-
-    #[test]
-    fn test_buffered_writer_inner_flushes() {
-        let mut w = BufWriter::with_capacity(3, Vec::new());
-        w.write(&[0, 1]).unwrap();
-        assert_eq!(*w.get_ref(), []);
-        let w = w.into_inner().unwrap();
-        assert_eq!(w, [0, 1]);
-    }
-
-    #[test]
-    fn test_buffered_writer_seek() {
-        let mut w = BufWriter::with_capacity(3, io::Cursor::new(Vec::new()));
-        w.write_all(&[0, 1, 2, 3, 4, 5]).unwrap();
-        w.write_all(&[6, 7]).unwrap();
-        assert_eq!(w.seek(SeekFrom::Current(0)).ok(), Some(8));
-        assert_eq!(&w.get_ref().get_ref()[..], &[0, 1, 2, 3, 4, 5, 6, 7][..]);
-        assert_eq!(w.seek(SeekFrom::Start(2)).ok(), Some(2));
-        w.write_all(&[8, 9]).unwrap();
-        assert_eq!(&w.into_inner().unwrap().into_inner()[..], &[0, 1, 8, 9, 4, 5, 6, 7]);
-    }
-
-    #[test]
-    fn test_read_until() {
-        let inner: &[u8] = &[0, 1, 2, 1, 0];
-        let mut reader = BufReader::with_capacity(2, inner);
-        let mut v = Vec::new();
-        reader.read_until(0, &mut v).unwrap();
-        assert_eq!(v, [0]);
-        v.truncate(0);
-        reader.read_until(2, &mut v).unwrap();
-        assert_eq!(v, [1, 2]);
-        v.truncate(0);
-        reader.read_until(1, &mut v).unwrap();
-        assert_eq!(v, [1]);
-        v.truncate(0);
-        reader.read_until(8, &mut v).unwrap();
-        assert_eq!(v, [0]);
-        v.truncate(0);
-        reader.read_until(9, &mut v).unwrap();
-        assert_eq!(v, []);
-    }
-
-    #[test]
-    fn test_line_buffer() {
-        let mut writer = LineWriter::new(Vec::new());
-        writer.write(&[0]).unwrap();
-        assert_eq!(*writer.get_ref(), []);
-        writer.write(&[1]).unwrap();
-        assert_eq!(*writer.get_ref(), []);
-        writer.flush().unwrap();
-        assert_eq!(*writer.get_ref(), [0, 1]);
-        writer.write(&[0, b'\n', 1, b'\n', 2]).unwrap();
-        assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n']);
-        writer.flush().unwrap();
-        assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2]);
-        writer.write(&[3, b'\n']).unwrap();
-        assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2, 3, b'\n']);
-    }
-
-    #[test]
-    fn test_read_line() {
-        let in_buf: &[u8] = b"a\nb\nc";
-        let mut reader = BufReader::with_capacity(2, in_buf);
-        let mut s = String::new();
-        reader.read_line(&mut s).unwrap();
-        assert_eq!(s, "a\n");
-        s.truncate(0);
-        reader.read_line(&mut s).unwrap();
-        assert_eq!(s, "b\n");
-        s.truncate(0);
-        reader.read_line(&mut s).unwrap();
-        assert_eq!(s, "c");
-        s.truncate(0);
-        reader.read_line(&mut s).unwrap();
-        assert_eq!(s, "");
-    }
-
-    #[test]
-    fn test_lines() {
-        let in_buf: &[u8] = b"a\nb\nc";
-        let reader = BufReader::with_capacity(2, in_buf);
-        let mut it = reader.lines();
-        assert_eq!(it.next().unwrap().unwrap(), "a".to_string());
-        assert_eq!(it.next().unwrap().unwrap(), "b".to_string());
-        assert_eq!(it.next().unwrap().unwrap(), "c".to_string());
-        assert!(it.next().is_none());
-    }
-
-    #[test]
-    fn test_short_reads() {
-        let inner = ShortReader { lengths: vec![0, 1, 2, 0, 1, 0] };
-        let mut reader = BufReader::new(inner);
-        let mut buf = [0, 0];
-        assert_eq!(reader.read(&mut buf).unwrap(), 0);
-        assert_eq!(reader.read(&mut buf).unwrap(), 1);
-        assert_eq!(reader.read(&mut buf).unwrap(), 2);
-        assert_eq!(reader.read(&mut buf).unwrap(), 0);
-        assert_eq!(reader.read(&mut buf).unwrap(), 1);
-        assert_eq!(reader.read(&mut buf).unwrap(), 0);
-        assert_eq!(reader.read(&mut buf).unwrap(), 0);
-    }
-
-    #[test]
-    #[should_panic]
-    fn dont_panic_in_drop_on_panicked_flush() {
-        struct FailFlushWriter;
-
-        impl Write for FailFlushWriter {
-            fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-                Ok(buf.len())
-            }
-            fn flush(&mut self) -> io::Result<()> {
-                Err(io::Error::last_os_error())
-            }
-        }
-
-        let writer = FailFlushWriter;
-        let _writer = BufWriter::new(writer);
-
-        // If writer panics *again* due to the flush error then the process will
-        // abort.
-        panic!();
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    fn panic_in_write_doesnt_flush_in_drop() {
-        static WRITES: AtomicUsize = AtomicUsize::new(0);
-
-        struct PanicWriter;
-
-        impl Write for PanicWriter {
-            fn write(&mut self, _: &[u8]) -> io::Result<usize> {
-                WRITES.fetch_add(1, Ordering::SeqCst);
-                panic!();
-            }
-            fn flush(&mut self) -> io::Result<()> {
-                Ok(())
-            }
-        }
-
-        thread::spawn(|| {
-            let mut writer = BufWriter::new(PanicWriter);
-            let _ = writer.write(b"hello world");
-            let _ = writer.flush();
-        })
-        .join()
-        .unwrap_err();
-
-        assert_eq!(WRITES.load(Ordering::SeqCst), 1);
-    }
-
-    #[bench]
-    fn bench_buffered_reader(b: &mut test::Bencher) {
-        b.iter(|| BufReader::new(io::empty()));
-    }
-
-    #[bench]
-    fn bench_buffered_writer(b: &mut test::Bencher) {
-        b.iter(|| BufWriter::new(io::sink()));
-    }
-
-    /// A simple `Write` target, designed to be wrapped by `LineWriter` /
-    /// `BufWriter` / etc, that can have its `write` & `flush` behavior
-    /// configured
-    #[derive(Default, Clone)]
-    struct ProgrammableSink {
-        // Writes append to this slice
-        pub buffer: Vec<u8>,
-
-        // Flush sets this flag
-        pub flushed: bool,
-
-        // If true, writes will always be an error
-        pub always_write_error: bool,
-
-        // If true, flushes will always be an error
-        pub always_flush_error: bool,
-
-        // If set, only up to this number of bytes will be written in a single
-        // call to `write`
-        pub accept_prefix: Option<usize>,
-
-        // If set, counts down with each write, and writes return an error
-        // when it hits 0
-        pub max_writes: Option<usize>,
-
-        // If set, attempting to write when max_writes == Some(0) will be an
-        // error; otherwise, it will return Ok(0).
-        pub error_after_max_writes: bool,
-    }
-
-    impl Write for ProgrammableSink {
-        fn write(&mut self, data: &[u8]) -> io::Result<usize> {
-            if self.always_write_error {
-                return Err(io::Error::new(io::ErrorKind::Other, "test - always_write_error"));
-            }
-
-            match self.max_writes {
-                Some(0) if self.error_after_max_writes => {
-                    return Err(io::Error::new(io::ErrorKind::Other, "test - max_writes"));
-                }
-                Some(0) => return Ok(0),
-                Some(ref mut count) => *count -= 1,
-                None => {}
-            }
-
-            let len = match self.accept_prefix {
-                None => data.len(),
-                Some(prefix) => data.len().min(prefix),
-            };
-
-            let data = &data[..len];
-            self.buffer.extend_from_slice(data);
-
-            Ok(len)
-        }
-
-        fn flush(&mut self) -> io::Result<()> {
-            if self.always_flush_error {
-                Err(io::Error::new(io::ErrorKind::Other, "test - always_flush_error"))
-            } else {
-                self.flushed = true;
-                Ok(())
-            }
-        }
-    }
-
-    /// Previously the `LineWriter` could successfully write some bytes but
-    /// then fail to report that it has done so. Additionally, an erroneous
-    /// flush after a successful write was permanently ignored.
-    ///
-    /// Test that a line writer correctly reports the number of written bytes,
-    /// and that it attempts to flush buffered lines from previous writes
-    /// before processing new data
-    ///
-    /// Regression test for #37807
-    #[test]
-    fn erroneous_flush_retried() {
-        let writer = ProgrammableSink {
-            // Only write up to 4 bytes at a time
-            accept_prefix: Some(4),
-
-            // Accept the first two writes, then error the others
-            max_writes: Some(2),
-            error_after_max_writes: true,
-
-            ..Default::default()
-        };
-
-        // This should write the first 4 bytes. The rest will be buffered, out
-        // to the last newline.
-        let mut writer = LineWriter::new(writer);
-        assert_eq!(writer.write(b"a\nb\nc\nd\ne").unwrap(), 8);
-
-        // This write should attempt to flush "c\nd\n", then buffer "e". No
-        // errors should happen here because no further writes should be
-        // attempted against `writer`.
-        assert_eq!(writer.write(b"e").unwrap(), 1);
-        assert_eq!(&writer.get_ref().buffer, b"a\nb\nc\nd\n");
-    }
-
-    #[test]
-    fn line_vectored() {
-        let mut a = LineWriter::new(Vec::new());
-        assert_eq!(
-            a.write_vectored(&[
-                IoSlice::new(&[]),
-                IoSlice::new(b"\n"),
-                IoSlice::new(&[]),
-                IoSlice::new(b"a"),
-            ])
-            .unwrap(),
-            2,
-        );
-        assert_eq!(a.get_ref(), b"\n");
-
-        assert_eq!(
-            a.write_vectored(&[
-                IoSlice::new(&[]),
-                IoSlice::new(b"b"),
-                IoSlice::new(&[]),
-                IoSlice::new(b"a"),
-                IoSlice::new(&[]),
-                IoSlice::new(b"c"),
-            ])
-            .unwrap(),
-            3,
-        );
-        assert_eq!(a.get_ref(), b"\n");
-        a.flush().unwrap();
-        assert_eq!(a.get_ref(), b"\nabac");
-        assert_eq!(a.write_vectored(&[]).unwrap(), 0);
-        assert_eq!(
-            a.write_vectored(&[
-                IoSlice::new(&[]),
-                IoSlice::new(&[]),
-                IoSlice::new(&[]),
-                IoSlice::new(&[]),
-            ])
-            .unwrap(),
-            0,
-        );
-        assert_eq!(a.write_vectored(&[IoSlice::new(b"a\nb"),]).unwrap(), 3);
-        assert_eq!(a.get_ref(), b"\nabaca\nb");
-    }
-
-    #[test]
-    fn line_vectored_partial_and_errors() {
-        use crate::collections::VecDeque;
-
-        enum Call {
-            Write { inputs: Vec<&'static [u8]>, output: io::Result<usize> },
-            Flush { output: io::Result<()> },
-        }
-
-        #[derive(Default)]
-        struct Writer {
-            calls: VecDeque<Call>,
-        }
-
-        impl Write for Writer {
-            fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-                self.write_vectored(&[IoSlice::new(buf)])
-            }
-
-            fn write_vectored(&mut self, buf: &[IoSlice<'_>]) -> io::Result<usize> {
-                match self.calls.pop_front().expect("unexpected call to write") {
-                    Call::Write { inputs, output } => {
-                        assert_eq!(inputs, buf.iter().map(|b| &**b).collect::<Vec<_>>());
-                        output
-                    }
-                    Call::Flush { .. } => panic!("unexpected call to write; expected a flush"),
-                }
-            }
-
-            fn is_write_vectored(&self) -> bool {
-                true
-            }
-
-            fn flush(&mut self) -> io::Result<()> {
-                match self.calls.pop_front().expect("Unexpected call to flush") {
-                    Call::Flush { output } => output,
-                    Call::Write { .. } => panic!("unexpected call to flush; expected a write"),
-                }
-            }
-        }
-
-        impl Drop for Writer {
-            fn drop(&mut self) {
-                if !thread::panicking() {
-                    assert_eq!(self.calls.len(), 0);
-                }
-            }
-        }
-
-        // partial writes keep going
-        let mut a = LineWriter::new(Writer::default());
-        a.write_vectored(&[IoSlice::new(&[]), IoSlice::new(b"abc")]).unwrap();
-
-        a.get_mut().calls.push_back(Call::Write { inputs: vec![b"abc"], output: Ok(1) });
-        a.get_mut().calls.push_back(Call::Write { inputs: vec![b"bc"], output: Ok(2) });
-        a.get_mut().calls.push_back(Call::Write { inputs: vec![b"x", b"\n"], output: Ok(2) });
-
-        a.write_vectored(&[IoSlice::new(b"x"), IoSlice::new(b"\n")]).unwrap();
-
-        a.get_mut().calls.push_back(Call::Flush { output: Ok(()) });
-        a.flush().unwrap();
-
-        // erroneous writes stop and don't write more
-        a.get_mut().calls.push_back(Call::Write { inputs: vec![b"x", b"\na"], output: Err(err()) });
-        a.get_mut().calls.push_back(Call::Flush { output: Ok(()) });
-        assert!(a.write_vectored(&[IoSlice::new(b"x"), IoSlice::new(b"\na")]).is_err());
-        a.flush().unwrap();
-
-        fn err() -> io::Error {
-            io::Error::new(io::ErrorKind::Other, "x")
-        }
-    }
-
-    /// Test that, in cases where vectored writing is not enabled, the
-    /// LineWriter uses the normal `write` call, which more-correctly handles
-    /// partial lines
-    #[test]
-    fn line_vectored_ignored() {
-        let writer = ProgrammableSink::default();
-        let mut writer = LineWriter::new(writer);
-
-        let content = [
-            IoSlice::new(&[]),
-            IoSlice::new(b"Line 1\nLine"),
-            IoSlice::new(b" 2\nLine 3\nL"),
-            IoSlice::new(&[]),
-            IoSlice::new(&[]),
-            IoSlice::new(b"ine 4"),
-            IoSlice::new(b"\nLine 5\n"),
-        ];
-
-        let count = writer.write_vectored(&content).unwrap();
-        assert_eq!(count, 11);
-        assert_eq!(&writer.get_ref().buffer, b"Line 1\n");
-
-        let count = writer.write_vectored(&content[2..]).unwrap();
-        assert_eq!(count, 11);
-        assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\n");
-
-        let count = writer.write_vectored(&content[5..]).unwrap();
-        assert_eq!(count, 5);
-        assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\n");
-
-        let count = writer.write_vectored(&content[6..]).unwrap();
-        assert_eq!(count, 8);
-        assert_eq!(
-            writer.get_ref().buffer.as_slice(),
-            b"Line 1\nLine 2\nLine 3\nLine 4\nLine 5\n".as_ref()
-        );
-    }
-
-    /// Test that, given this input:
-    ///
-    /// Line 1\n
-    /// Line 2\n
-    /// Line 3\n
-    /// Line 4
-    ///
-    /// And given a result that only writes to midway through Line 2
-    ///
-    /// That only up to the end of Line 3 is buffered
-    ///
-    /// This behavior is desirable because it prevents flushing partial lines
-    #[test]
-    fn partial_write_buffers_line() {
-        let writer = ProgrammableSink { accept_prefix: Some(13), ..Default::default() };
-        let mut writer = LineWriter::new(writer);
-
-        assert_eq!(writer.write(b"Line 1\nLine 2\nLine 3\nLine4").unwrap(), 21);
-        assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2");
-
-        assert_eq!(writer.write(b"Line 4").unwrap(), 6);
-        assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\n");
-    }
-
-    /// Test that, given this input:
-    ///
-    /// Line 1\n
-    /// Line 2\n
-    /// Line 3
-    ///
-    /// And given that the full write of lines 1 and 2 was successful
-    /// That data up to Line 3 is buffered
-    #[test]
-    fn partial_line_buffered_after_line_write() {
-        let writer = ProgrammableSink::default();
-        let mut writer = LineWriter::new(writer);
-
-        assert_eq!(writer.write(b"Line 1\nLine 2\nLine 3").unwrap(), 20);
-        assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\n");
-
-        assert!(writer.flush().is_ok());
-        assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3");
-    }
-
-    /// Test that, given a partial line that exceeds the length of
-    /// LineBuffer's buffer (that is, without a trailing newline), that that
-    /// line is written to the inner writer
-    #[test]
-    fn long_line_flushed() {
-        let writer = ProgrammableSink::default();
-        let mut writer = LineWriter::with_capacity(5, writer);
-
-        assert_eq!(writer.write(b"0123456789").unwrap(), 10);
-        assert_eq!(&writer.get_ref().buffer, b"0123456789");
-    }
-
-    /// Test that, given a very long partial line *after* successfully
-    /// flushing a complete line, that that line is buffered unconditionally,
-    /// and no additional writes take place. This assures the property that
-    /// `write` should make at-most-one attempt to write new data.
-    #[test]
-    fn line_long_tail_not_flushed() {
-        let writer = ProgrammableSink::default();
-        let mut writer = LineWriter::with_capacity(5, writer);
-
-        // Assert that Line 1\n is flushed, and 01234 is buffered
-        assert_eq!(writer.write(b"Line 1\n0123456789").unwrap(), 12);
-        assert_eq!(&writer.get_ref().buffer, b"Line 1\n");
-
-        // Because the buffer is full, this subsequent write will flush it
-        assert_eq!(writer.write(b"5").unwrap(), 1);
-        assert_eq!(&writer.get_ref().buffer, b"Line 1\n01234");
-    }
-
-    /// Test that, if an attempt to pre-flush buffered data returns Ok(0),
-    /// this is propagated as an error.
-    #[test]
-    fn line_buffer_write0_error() {
-        let writer = ProgrammableSink {
-            // Accept one write, then return Ok(0) on subsequent ones
-            max_writes: Some(1),
-
-            ..Default::default()
-        };
-        let mut writer = LineWriter::new(writer);
-
-        // This should write "Line 1\n" and buffer "Partial"
-        assert_eq!(writer.write(b"Line 1\nPartial").unwrap(), 14);
-        assert_eq!(&writer.get_ref().buffer, b"Line 1\n");
-
-        // This will attempt to flush "partial", which will return Ok(0), which
-        // needs to be an error, because we've already informed the client
-        // that we accepted the write.
-        let err = writer.write(b" Line End\n").unwrap_err();
-        assert_eq!(err.kind(), ErrorKind::WriteZero);
-        assert_eq!(&writer.get_ref().buffer, b"Line 1\n");
-    }
-
-    /// Test that, if a write returns Ok(0) after a successful pre-flush, this
-    /// is propagated as Ok(0)
-    #[test]
-    fn line_buffer_write0_normal() {
-        let writer = ProgrammableSink {
-            // Accept two writes, then return Ok(0) on subsequent ones
-            max_writes: Some(2),
-
-            ..Default::default()
-        };
-        let mut writer = LineWriter::new(writer);
-
-        // This should write "Line 1\n" and buffer "Partial"
-        assert_eq!(writer.write(b"Line 1\nPartial").unwrap(), 14);
-        assert_eq!(&writer.get_ref().buffer, b"Line 1\n");
-
-        // This will flush partial, which will succeed, but then return Ok(0)
-        // when flushing " Line End\n"
-        assert_eq!(writer.write(b" Line End\n").unwrap(), 0);
-        assert_eq!(&writer.get_ref().buffer, b"Line 1\nPartial");
-    }
-
-    /// LineWriter has a custom `write_all`; make sure it works correctly
-    #[test]
-    fn line_write_all() {
-        let writer = ProgrammableSink {
-            // Only write 5 bytes at a time
-            accept_prefix: Some(5),
-            ..Default::default()
-        };
-        let mut writer = LineWriter::new(writer);
-
-        writer.write_all(b"Line 1\nLine 2\nLine 3\nLine 4\nPartial").unwrap();
-        assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\nLine 4\n");
-        writer.write_all(b" Line 5\n").unwrap();
-        assert_eq!(
-            writer.get_ref().buffer.as_slice(),
-            b"Line 1\nLine 2\nLine 3\nLine 4\nPartial Line 5\n".as_ref(),
-        );
-    }
-
-    #[test]
-    fn line_write_all_error() {
-        let writer = ProgrammableSink {
-            // Only accept up to 3 writes of up to 5 bytes each
-            accept_prefix: Some(5),
-            max_writes: Some(3),
-            ..Default::default()
-        };
-
-        let mut writer = LineWriter::new(writer);
-        let res = writer.write_all(b"Line 1\nLine 2\nLine 3\nLine 4\nPartial");
-        assert!(res.is_err());
-        // An error from write_all leaves everything in an indeterminate state,
-        // so there's nothing else to test here
-    }
-
-    /// Under certain circumstances, the old implementation of LineWriter
-    /// would try to buffer "to the last newline" but be forced to buffer
-    /// less than that, leading to inappropriate partial line writes.
-    /// Regression test for that issue.
-    #[test]
-    fn partial_multiline_buffering() {
-        let writer = ProgrammableSink {
-            // Write only up to 5 bytes at a time
-            accept_prefix: Some(5),
-            ..Default::default()
-        };
-
-        let mut writer = LineWriter::with_capacity(10, writer);
-
-        let content = b"AAAAABBBBB\nCCCCDDDDDD\nEEE";
-
-        // When content is written, LineWriter will try to write blocks A, B,
-        // C, and D. Only block A will succeed. Under the old behavior, LineWriter
-        // would then try to buffer B, C and D, but because its capacity is 10,
-        // it will only be able to buffer B and C. We don't want to buffer
-        // partial lines concurrent with whole lines, so the correct behavior
-        // is to buffer only block B (out to the newline)
-        assert_eq!(writer.write(content).unwrap(), 11);
-        assert_eq!(writer.get_ref().buffer, *b"AAAAA");
-
-        writer.flush().unwrap();
-        assert_eq!(writer.get_ref().buffer, *b"AAAAABBBBB\n");
-    }
-
-    /// Same as test_partial_multiline_buffering, but in the event NO full lines
-    /// fit in the buffer, just buffer as much as possible
-    #[test]
-    fn partial_multiline_buffering_without_full_line() {
-        let writer = ProgrammableSink {
-            // Write only up to 5 bytes at a time
-            accept_prefix: Some(5),
-            ..Default::default()
-        };
-
-        let mut writer = LineWriter::with_capacity(5, writer);
-
-        let content = b"AAAAABBBBBBBBBB\nCCCCC\nDDDDD";
-
-        // When content is written, LineWriter will try to write blocks A, B,
-        // and C. Only block A will succeed. Under the old behavior, LineWriter
-        // would then try to buffer B and C, but because its capacity is 5,
-        // it will only be able to buffer part of B. Because it's not possible
-        // for it to buffer any complete lines, it should buffer as much of B as
-        // possible
-        assert_eq!(writer.write(content).unwrap(), 10);
-        assert_eq!(writer.get_ref().buffer, *b"AAAAA");
-
-        writer.flush().unwrap();
-        assert_eq!(writer.get_ref().buffer, *b"AAAAABBBBB");
-    }
-
-    #[derive(Debug, Clone, PartialEq, Eq)]
-    enum RecordedEvent {
-        Write(String),
-        Flush,
-    }
-
-    #[derive(Debug, Clone, Default)]
-    struct WriteRecorder {
-        pub events: Vec<RecordedEvent>,
-    }
-
-    impl Write for WriteRecorder {
-        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-            use crate::str::from_utf8;
-
-            self.events.push(RecordedEvent::Write(from_utf8(buf).unwrap().to_string()));
-            Ok(buf.len())
-        }
-
-        fn flush(&mut self) -> io::Result<()> {
-            self.events.push(RecordedEvent::Flush);
-            Ok(())
-        }
-    }
-
-    /// Test that a normal, formatted writeln only results in a single write
-    /// call to the underlying writer. A naive implementation of
-    /// LineWriter::write_all results in two writes: one of the buffered data,
-    /// and another of the final substring in the formatted set
-    #[test]
-    fn single_formatted_write() {
-        let writer = WriteRecorder::default();
-        let mut writer = LineWriter::new(writer);
-
-        // Under a naive implementation of LineWriter, this will result in two
-        // writes: "hello, world" and "!\n", because write() has to flush the
-        // buffer before attempting to write the last "!\n". write_all shouldn't
-        // have this limitation.
-        writeln!(&mut writer, "{}, {}!", "hello", "world").unwrap();
-        assert_eq!(writer.get_ref().events, [RecordedEvent::Write("hello, world!\n".to_string())]);
-    }
-}
diff --git a/library/std/src/io/buffered/tests.rs b/library/std/src/io/buffered/tests.rs
new file mode 100644
index 00000000000..1cd02ee299a
--- /dev/null
+++ b/library/std/src/io/buffered/tests.rs
@@ -0,0 +1,916 @@
+use crate::io::prelude::*;
+use crate::io::{self, BufReader, BufWriter, ErrorKind, IoSlice, LineWriter, SeekFrom};
+use crate::sync::atomic::{AtomicUsize, Ordering};
+use crate::thread;
+
+/// A dummy reader intended at testing short-reads propagation.
+pub struct ShortReader {
+    lengths: Vec<usize>,
+}
+
+// FIXME: rustfmt and tidy disagree about the correct formatting of this
+// function. This leads to issues for users with editors configured to
+// rustfmt-on-save.
+impl Read for ShortReader {
+    fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
+        if self.lengths.is_empty() { Ok(0) } else { Ok(self.lengths.remove(0)) }
+    }
+}
+
+#[test]
+fn test_buffered_reader() {
+    let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
+    let mut reader = BufReader::with_capacity(2, inner);
+
+    let mut buf = [0, 0, 0];
+    let nread = reader.read(&mut buf);
+    assert_eq!(nread.unwrap(), 3);
+    assert_eq!(buf, [5, 6, 7]);
+    assert_eq!(reader.buffer(), []);
+
+    let mut buf = [0, 0];
+    let nread = reader.read(&mut buf);
+    assert_eq!(nread.unwrap(), 2);
+    assert_eq!(buf, [0, 1]);
+    assert_eq!(reader.buffer(), []);
+
+    let mut buf = [0];
+    let nread = reader.read(&mut buf);
+    assert_eq!(nread.unwrap(), 1);
+    assert_eq!(buf, [2]);
+    assert_eq!(reader.buffer(), [3]);
+
+    let mut buf = [0, 0, 0];
+    let nread = reader.read(&mut buf);
+    assert_eq!(nread.unwrap(), 1);
+    assert_eq!(buf, [3, 0, 0]);
+    assert_eq!(reader.buffer(), []);
+
+    let nread = reader.read(&mut buf);
+    assert_eq!(nread.unwrap(), 1);
+    assert_eq!(buf, [4, 0, 0]);
+    assert_eq!(reader.buffer(), []);
+
+    assert_eq!(reader.read(&mut buf).unwrap(), 0);
+}
+
+#[test]
+fn test_buffered_reader_seek() {
+    let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
+    let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner));
+
+    assert_eq!(reader.seek(SeekFrom::Start(3)).ok(), Some(3));
+    assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
+    assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(3));
+    assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
+    assert_eq!(reader.seek(SeekFrom::Current(1)).ok(), Some(4));
+    assert_eq!(reader.fill_buf().ok(), Some(&[1, 2][..]));
+    reader.consume(1);
+    assert_eq!(reader.seek(SeekFrom::Current(-2)).ok(), Some(3));
+}
+
+#[test]
+fn test_buffered_reader_seek_relative() {
+    let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
+    let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner));
+
+    assert!(reader.seek_relative(3).is_ok());
+    assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
+    assert!(reader.seek_relative(0).is_ok());
+    assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
+    assert!(reader.seek_relative(1).is_ok());
+    assert_eq!(reader.fill_buf().ok(), Some(&[1][..]));
+    assert!(reader.seek_relative(-1).is_ok());
+    assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
+    assert!(reader.seek_relative(2).is_ok());
+    assert_eq!(reader.fill_buf().ok(), Some(&[2, 3][..]));
+}
+
+#[test]
+fn test_buffered_reader_invalidated_after_read() {
+    let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
+    let mut reader = BufReader::with_capacity(3, io::Cursor::new(inner));
+
+    assert_eq!(reader.fill_buf().ok(), Some(&[5, 6, 7][..]));
+    reader.consume(3);
+
+    let mut buffer = [0, 0, 0, 0, 0];
+    assert_eq!(reader.read(&mut buffer).ok(), Some(5));
+    assert_eq!(buffer, [0, 1, 2, 3, 4]);
+
+    assert!(reader.seek_relative(-2).is_ok());
+    let mut buffer = [0, 0];
+    assert_eq!(reader.read(&mut buffer).ok(), Some(2));
+    assert_eq!(buffer, [3, 4]);
+}
+
+#[test]
+fn test_buffered_reader_invalidated_after_seek() {
+    let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
+    let mut reader = BufReader::with_capacity(3, io::Cursor::new(inner));
+
+    assert_eq!(reader.fill_buf().ok(), Some(&[5, 6, 7][..]));
+    reader.consume(3);
+
+    assert!(reader.seek(SeekFrom::Current(5)).is_ok());
+
+    assert!(reader.seek_relative(-2).is_ok());
+    let mut buffer = [0, 0];
+    assert_eq!(reader.read(&mut buffer).ok(), Some(2));
+    assert_eq!(buffer, [3, 4]);
+}
+
+#[test]
+fn test_buffered_reader_seek_underflow() {
+    // gimmick reader that yields its position modulo 256 for each byte
+    struct PositionReader {
+        pos: u64,
+    }
+    impl Read for PositionReader {
+        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+            let len = buf.len();
+            for x in buf {
+                *x = self.pos as u8;
+                self.pos = self.pos.wrapping_add(1);
+            }
+            Ok(len)
+        }
+    }
+    impl Seek for PositionReader {
+        fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
+            match pos {
+                SeekFrom::Start(n) => {
+                    self.pos = n;
+                }
+                SeekFrom::Current(n) => {
+                    self.pos = self.pos.wrapping_add(n as u64);
+                }
+                SeekFrom::End(n) => {
+                    self.pos = u64::MAX.wrapping_add(n as u64);
+                }
+            }
+            Ok(self.pos)
+        }
+    }
+
+    let mut reader = BufReader::with_capacity(5, PositionReader { pos: 0 });
+    assert_eq!(reader.fill_buf().ok(), Some(&[0, 1, 2, 3, 4][..]));
+    assert_eq!(reader.seek(SeekFrom::End(-5)).ok(), Some(u64::MAX - 5));
+    assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5));
+    // the following seek will require two underlying seeks
+    let expected = 9223372036854775802;
+    assert_eq!(reader.seek(SeekFrom::Current(i64::MIN)).ok(), Some(expected));
+    assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5));
+    // seeking to 0 should empty the buffer.
+    assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(expected));
+    assert_eq!(reader.get_ref().pos, expected);
+}
+
+#[test]
+fn test_buffered_reader_seek_underflow_discard_buffer_between_seeks() {
+    // gimmick reader that returns Err after first seek
+    struct ErrAfterFirstSeekReader {
+        first_seek: bool,
+    }
+    impl Read for ErrAfterFirstSeekReader {
+        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+            for x in &mut *buf {
+                *x = 0;
+            }
+            Ok(buf.len())
+        }
+    }
+    impl Seek for ErrAfterFirstSeekReader {
+        fn seek(&mut self, _: SeekFrom) -> io::Result<u64> {
+            if self.first_seek {
+                self.first_seek = false;
+                Ok(0)
+            } else {
+                Err(io::Error::new(io::ErrorKind::Other, "oh no!"))
+            }
+        }
+    }
+
+    let mut reader = BufReader::with_capacity(5, ErrAfterFirstSeekReader { first_seek: true });
+    assert_eq!(reader.fill_buf().ok(), Some(&[0, 0, 0, 0, 0][..]));
+
+    // The following seek will require two underlying seeks.  The first will
+    // succeed but the second will fail.  This should still invalidate the
+    // buffer.
+    assert!(reader.seek(SeekFrom::Current(i64::MIN)).is_err());
+    assert_eq!(reader.buffer().len(), 0);
+}
+
+#[test]
+fn test_buffered_writer() {
+    let inner = Vec::new();
+    let mut writer = BufWriter::with_capacity(2, inner);
+
+    writer.write(&[0, 1]).unwrap();
+    assert_eq!(writer.buffer(), []);
+    assert_eq!(*writer.get_ref(), [0, 1]);
+
+    writer.write(&[2]).unwrap();
+    assert_eq!(writer.buffer(), [2]);
+    assert_eq!(*writer.get_ref(), [0, 1]);
+
+    writer.write(&[3]).unwrap();
+    assert_eq!(writer.buffer(), [2, 3]);
+    assert_eq!(*writer.get_ref(), [0, 1]);
+
+    writer.flush().unwrap();
+    assert_eq!(writer.buffer(), []);
+    assert_eq!(*writer.get_ref(), [0, 1, 2, 3]);
+
+    writer.write(&[4]).unwrap();
+    writer.write(&[5]).unwrap();
+    assert_eq!(writer.buffer(), [4, 5]);
+    assert_eq!(*writer.get_ref(), [0, 1, 2, 3]);
+
+    writer.write(&[6]).unwrap();
+    assert_eq!(writer.buffer(), [6]);
+    assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5]);
+
+    writer.write(&[7, 8]).unwrap();
+    assert_eq!(writer.buffer(), []);
+    assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8]);
+
+    writer.write(&[9, 10, 11]).unwrap();
+    assert_eq!(writer.buffer(), []);
+    assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
+
+    writer.flush().unwrap();
+    assert_eq!(writer.buffer(), []);
+    assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
+}
+
+#[test]
+fn test_buffered_writer_inner_flushes() {
+    let mut w = BufWriter::with_capacity(3, Vec::new());
+    w.write(&[0, 1]).unwrap();
+    assert_eq!(*w.get_ref(), []);
+    let w = w.into_inner().unwrap();
+    assert_eq!(w, [0, 1]);
+}
+
+#[test]
+fn test_buffered_writer_seek() {
+    let mut w = BufWriter::with_capacity(3, io::Cursor::new(Vec::new()));
+    w.write_all(&[0, 1, 2, 3, 4, 5]).unwrap();
+    w.write_all(&[6, 7]).unwrap();
+    assert_eq!(w.seek(SeekFrom::Current(0)).ok(), Some(8));
+    assert_eq!(&w.get_ref().get_ref()[..], &[0, 1, 2, 3, 4, 5, 6, 7][..]);
+    assert_eq!(w.seek(SeekFrom::Start(2)).ok(), Some(2));
+    w.write_all(&[8, 9]).unwrap();
+    assert_eq!(&w.into_inner().unwrap().into_inner()[..], &[0, 1, 8, 9, 4, 5, 6, 7]);
+}
+
+#[test]
+fn test_read_until() {
+    let inner: &[u8] = &[0, 1, 2, 1, 0];
+    let mut reader = BufReader::with_capacity(2, inner);
+    let mut v = Vec::new();
+    reader.read_until(0, &mut v).unwrap();
+    assert_eq!(v, [0]);
+    v.truncate(0);
+    reader.read_until(2, &mut v).unwrap();
+    assert_eq!(v, [1, 2]);
+    v.truncate(0);
+    reader.read_until(1, &mut v).unwrap();
+    assert_eq!(v, [1]);
+    v.truncate(0);
+    reader.read_until(8, &mut v).unwrap();
+    assert_eq!(v, [0]);
+    v.truncate(0);
+    reader.read_until(9, &mut v).unwrap();
+    assert_eq!(v, []);
+}
+
+#[test]
+fn test_line_buffer() {
+    let mut writer = LineWriter::new(Vec::new());
+    writer.write(&[0]).unwrap();
+    assert_eq!(*writer.get_ref(), []);
+    writer.write(&[1]).unwrap();
+    assert_eq!(*writer.get_ref(), []);
+    writer.flush().unwrap();
+    assert_eq!(*writer.get_ref(), [0, 1]);
+    writer.write(&[0, b'\n', 1, b'\n', 2]).unwrap();
+    assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n']);
+    writer.flush().unwrap();
+    assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2]);
+    writer.write(&[3, b'\n']).unwrap();
+    assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2, 3, b'\n']);
+}
+
+#[test]
+fn test_read_line() {
+    let in_buf: &[u8] = b"a\nb\nc";
+    let mut reader = BufReader::with_capacity(2, in_buf);
+    let mut s = String::new();
+    reader.read_line(&mut s).unwrap();
+    assert_eq!(s, "a\n");
+    s.truncate(0);
+    reader.read_line(&mut s).unwrap();
+    assert_eq!(s, "b\n");
+    s.truncate(0);
+    reader.read_line(&mut s).unwrap();
+    assert_eq!(s, "c");
+    s.truncate(0);
+    reader.read_line(&mut s).unwrap();
+    assert_eq!(s, "");
+}
+
+#[test]
+fn test_lines() {
+    let in_buf: &[u8] = b"a\nb\nc";
+    let reader = BufReader::with_capacity(2, in_buf);
+    let mut it = reader.lines();
+    assert_eq!(it.next().unwrap().unwrap(), "a".to_string());
+    assert_eq!(it.next().unwrap().unwrap(), "b".to_string());
+    assert_eq!(it.next().unwrap().unwrap(), "c".to_string());
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn test_short_reads() {
+    let inner = ShortReader { lengths: vec![0, 1, 2, 0, 1, 0] };
+    let mut reader = BufReader::new(inner);
+    let mut buf = [0, 0];
+    assert_eq!(reader.read(&mut buf).unwrap(), 0);
+    assert_eq!(reader.read(&mut buf).unwrap(), 1);
+    assert_eq!(reader.read(&mut buf).unwrap(), 2);
+    assert_eq!(reader.read(&mut buf).unwrap(), 0);
+    assert_eq!(reader.read(&mut buf).unwrap(), 1);
+    assert_eq!(reader.read(&mut buf).unwrap(), 0);
+    assert_eq!(reader.read(&mut buf).unwrap(), 0);
+}
+
+#[test]
+#[should_panic]
+fn dont_panic_in_drop_on_panicked_flush() {
+    struct FailFlushWriter;
+
+    impl Write for FailFlushWriter {
+        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+            Ok(buf.len())
+        }
+        fn flush(&mut self) -> io::Result<()> {
+            Err(io::Error::last_os_error())
+        }
+    }
+
+    let writer = FailFlushWriter;
+    let _writer = BufWriter::new(writer);
+
+    // If writer panics *again* due to the flush error then the process will
+    // abort.
+    panic!();
+}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn panic_in_write_doesnt_flush_in_drop() {
+    static WRITES: AtomicUsize = AtomicUsize::new(0);
+
+    struct PanicWriter;
+
+    impl Write for PanicWriter {
+        fn write(&mut self, _: &[u8]) -> io::Result<usize> {
+            WRITES.fetch_add(1, Ordering::SeqCst);
+            panic!();
+        }
+        fn flush(&mut self) -> io::Result<()> {
+            Ok(())
+        }
+    }
+
+    thread::spawn(|| {
+        let mut writer = BufWriter::new(PanicWriter);
+        let _ = writer.write(b"hello world");
+        let _ = writer.flush();
+    })
+    .join()
+    .unwrap_err();
+
+    assert_eq!(WRITES.load(Ordering::SeqCst), 1);
+}
+
+#[bench]
+fn bench_buffered_reader(b: &mut test::Bencher) {
+    b.iter(|| BufReader::new(io::empty()));
+}
+
+#[bench]
+fn bench_buffered_writer(b: &mut test::Bencher) {
+    b.iter(|| BufWriter::new(io::sink()));
+}
+
+/// A simple `Write` target, designed to be wrapped by `LineWriter` /
+/// `BufWriter` / etc, that can have its `write` & `flush` behavior
+/// configured
+#[derive(Default, Clone)]
+struct ProgrammableSink {
+    // Writes append to this slice
+    pub buffer: Vec<u8>,
+
+    // Flush sets this flag
+    pub flushed: bool,
+
+    // If true, writes will always be an error
+    pub always_write_error: bool,
+
+    // If true, flushes will always be an error
+    pub always_flush_error: bool,
+
+    // If set, only up to this number of bytes will be written in a single
+    // call to `write`
+    pub accept_prefix: Option<usize>,
+
+    // If set, counts down with each write, and writes return an error
+    // when it hits 0
+    pub max_writes: Option<usize>,
+
+    // If set, attempting to write when max_writes == Some(0) will be an
+    // error; otherwise, it will return Ok(0).
+    pub error_after_max_writes: bool,
+}
+
+impl Write for ProgrammableSink {
+    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
+        if self.always_write_error {
+            return Err(io::Error::new(io::ErrorKind::Other, "test - always_write_error"));
+        }
+
+        match self.max_writes {
+            Some(0) if self.error_after_max_writes => {
+                return Err(io::Error::new(io::ErrorKind::Other, "test - max_writes"));
+            }
+            Some(0) => return Ok(0),
+            Some(ref mut count) => *count -= 1,
+            None => {}
+        }
+
+        let len = match self.accept_prefix {
+            None => data.len(),
+            Some(prefix) => data.len().min(prefix),
+        };
+
+        let data = &data[..len];
+        self.buffer.extend_from_slice(data);
+
+        Ok(len)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        if self.always_flush_error {
+            Err(io::Error::new(io::ErrorKind::Other, "test - always_flush_error"))
+        } else {
+            self.flushed = true;
+            Ok(())
+        }
+    }
+}
+
+/// Previously the `LineWriter` could successfully write some bytes but
+/// then fail to report that it has done so. Additionally, an erroneous
+/// flush after a successful write was permanently ignored.
+///
+/// Test that a line writer correctly reports the number of written bytes,
+/// and that it attempts to flush buffered lines from previous writes
+/// before processing new data
+///
+/// Regression test for #37807
+#[test]
+fn erroneous_flush_retried() {
+    let writer = ProgrammableSink {
+        // Only write up to 4 bytes at a time
+        accept_prefix: Some(4),
+
+        // Accept the first two writes, then error the others
+        max_writes: Some(2),
+        error_after_max_writes: true,
+
+        ..Default::default()
+    };
+
+    // This should write the first 4 bytes. The rest will be buffered, out
+    // to the last newline.
+    let mut writer = LineWriter::new(writer);
+    assert_eq!(writer.write(b"a\nb\nc\nd\ne").unwrap(), 8);
+
+    // This write should attempt to flush "c\nd\n", then buffer "e". No
+    // errors should happen here because no further writes should be
+    // attempted against `writer`.
+    assert_eq!(writer.write(b"e").unwrap(), 1);
+    assert_eq!(&writer.get_ref().buffer, b"a\nb\nc\nd\n");
+}
+
+#[test]
+fn line_vectored() {
+    let mut a = LineWriter::new(Vec::new());
+    assert_eq!(
+        a.write_vectored(&[
+            IoSlice::new(&[]),
+            IoSlice::new(b"\n"),
+            IoSlice::new(&[]),
+            IoSlice::new(b"a"),
+        ])
+        .unwrap(),
+        2,
+    );
+    assert_eq!(a.get_ref(), b"\n");
+
+    assert_eq!(
+        a.write_vectored(&[
+            IoSlice::new(&[]),
+            IoSlice::new(b"b"),
+            IoSlice::new(&[]),
+            IoSlice::new(b"a"),
+            IoSlice::new(&[]),
+            IoSlice::new(b"c"),
+        ])
+        .unwrap(),
+        3,
+    );
+    assert_eq!(a.get_ref(), b"\n");
+    a.flush().unwrap();
+    assert_eq!(a.get_ref(), b"\nabac");
+    assert_eq!(a.write_vectored(&[]).unwrap(), 0);
+    assert_eq!(
+        a.write_vectored(&[
+            IoSlice::new(&[]),
+            IoSlice::new(&[]),
+            IoSlice::new(&[]),
+            IoSlice::new(&[]),
+        ])
+        .unwrap(),
+        0,
+    );
+    assert_eq!(a.write_vectored(&[IoSlice::new(b"a\nb"),]).unwrap(), 3);
+    assert_eq!(a.get_ref(), b"\nabaca\nb");
+}
+
+#[test]
+fn line_vectored_partial_and_errors() {
+    use crate::collections::VecDeque;
+
+    enum Call {
+        Write { inputs: Vec<&'static [u8]>, output: io::Result<usize> },
+        Flush { output: io::Result<()> },
+    }
+
+    #[derive(Default)]
+    struct Writer {
+        calls: VecDeque<Call>,
+    }
+
+    impl Write for Writer {
+        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+            self.write_vectored(&[IoSlice::new(buf)])
+        }
+
+        fn write_vectored(&mut self, buf: &[IoSlice<'_>]) -> io::Result<usize> {
+            match self.calls.pop_front().expect("unexpected call to write") {
+                Call::Write { inputs, output } => {
+                    assert_eq!(inputs, buf.iter().map(|b| &**b).collect::<Vec<_>>());
+                    output
+                }
+                Call::Flush { .. } => panic!("unexpected call to write; expected a flush"),
+            }
+        }
+
+        fn is_write_vectored(&self) -> bool {
+            true
+        }
+
+        fn flush(&mut self) -> io::Result<()> {
+            match self.calls.pop_front().expect("Unexpected call to flush") {
+                Call::Flush { output } => output,
+                Call::Write { .. } => panic!("unexpected call to flush; expected a write"),
+            }
+        }
+    }
+
+    impl Drop for Writer {
+        fn drop(&mut self) {
+            if !thread::panicking() {
+                assert_eq!(self.calls.len(), 0);
+            }
+        }
+    }
+
+    // partial writes keep going
+    let mut a = LineWriter::new(Writer::default());
+    a.write_vectored(&[IoSlice::new(&[]), IoSlice::new(b"abc")]).unwrap();
+
+    a.get_mut().calls.push_back(Call::Write { inputs: vec![b"abc"], output: Ok(1) });
+    a.get_mut().calls.push_back(Call::Write { inputs: vec![b"bc"], output: Ok(2) });
+    a.get_mut().calls.push_back(Call::Write { inputs: vec![b"x", b"\n"], output: Ok(2) });
+
+    a.write_vectored(&[IoSlice::new(b"x"), IoSlice::new(b"\n")]).unwrap();
+
+    a.get_mut().calls.push_back(Call::Flush { output: Ok(()) });
+    a.flush().unwrap();
+
+    // erroneous writes stop and don't write more
+    a.get_mut().calls.push_back(Call::Write { inputs: vec![b"x", b"\na"], output: Err(err()) });
+    a.get_mut().calls.push_back(Call::Flush { output: Ok(()) });
+    assert!(a.write_vectored(&[IoSlice::new(b"x"), IoSlice::new(b"\na")]).is_err());
+    a.flush().unwrap();
+
+    fn err() -> io::Error {
+        io::Error::new(io::ErrorKind::Other, "x")
+    }
+}
+
+/// Test that, in cases where vectored writing is not enabled, the
+/// LineWriter uses the normal `write` call, which more-correctly handles
+/// partial lines
+#[test]
+fn line_vectored_ignored() {
+    let writer = ProgrammableSink::default();
+    let mut writer = LineWriter::new(writer);
+
+    let content = [
+        IoSlice::new(&[]),
+        IoSlice::new(b"Line 1\nLine"),
+        IoSlice::new(b" 2\nLine 3\nL"),
+        IoSlice::new(&[]),
+        IoSlice::new(&[]),
+        IoSlice::new(b"ine 4"),
+        IoSlice::new(b"\nLine 5\n"),
+    ];
+
+    let count = writer.write_vectored(&content).unwrap();
+    assert_eq!(count, 11);
+    assert_eq!(&writer.get_ref().buffer, b"Line 1\n");
+
+    let count = writer.write_vectored(&content[2..]).unwrap();
+    assert_eq!(count, 11);
+    assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\n");
+
+    let count = writer.write_vectored(&content[5..]).unwrap();
+    assert_eq!(count, 5);
+    assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\n");
+
+    let count = writer.write_vectored(&content[6..]).unwrap();
+    assert_eq!(count, 8);
+    assert_eq!(
+        writer.get_ref().buffer.as_slice(),
+        b"Line 1\nLine 2\nLine 3\nLine 4\nLine 5\n".as_ref()
+    );
+}
+
+/// Test that, given this input:
+///
+/// Line 1\n
+/// Line 2\n
+/// Line 3\n
+/// Line 4
+///
+/// And given a result that only writes to midway through Line 2
+///
+/// That only up to the end of Line 3 is buffered
+///
+/// This behavior is desirable because it prevents flushing partial lines
+#[test]
+fn partial_write_buffers_line() {
+    let writer = ProgrammableSink { accept_prefix: Some(13), ..Default::default() };
+    let mut writer = LineWriter::new(writer);
+
+    assert_eq!(writer.write(b"Line 1\nLine 2\nLine 3\nLine4").unwrap(), 21);
+    assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2");
+
+    assert_eq!(writer.write(b"Line 4").unwrap(), 6);
+    assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\n");
+}
+
+/// Test that, given this input:
+///
+/// Line 1\n
+/// Line 2\n
+/// Line 3
+///
+/// And given that the full write of lines 1 and 2 was successful
+/// That data up to Line 3 is buffered
+#[test]
+fn partial_line_buffered_after_line_write() {
+    let writer = ProgrammableSink::default();
+    let mut writer = LineWriter::new(writer);
+
+    assert_eq!(writer.write(b"Line 1\nLine 2\nLine 3").unwrap(), 20);
+    assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\n");
+
+    assert!(writer.flush().is_ok());
+    assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3");
+}
+
+/// Test that, given a partial line that exceeds the length of
+/// LineBuffer's buffer (that is, without a trailing newline), that that
+/// line is written to the inner writer
+#[test]
+fn long_line_flushed() {
+    let writer = ProgrammableSink::default();
+    let mut writer = LineWriter::with_capacity(5, writer);
+
+    assert_eq!(writer.write(b"0123456789").unwrap(), 10);
+    assert_eq!(&writer.get_ref().buffer, b"0123456789");
+}
+
+/// Test that, given a very long partial line *after* successfully
+/// flushing a complete line, that that line is buffered unconditionally,
+/// and no additional writes take place. This assures the property that
+/// `write` should make at-most-one attempt to write new data.
+#[test]
+fn line_long_tail_not_flushed() {
+    let writer = ProgrammableSink::default();
+    let mut writer = LineWriter::with_capacity(5, writer);
+
+    // Assert that Line 1\n is flushed, and 01234 is buffered
+    assert_eq!(writer.write(b"Line 1\n0123456789").unwrap(), 12);
+    assert_eq!(&writer.get_ref().buffer, b"Line 1\n");
+
+    // Because the buffer is full, this subsequent write will flush it
+    assert_eq!(writer.write(b"5").unwrap(), 1);
+    assert_eq!(&writer.get_ref().buffer, b"Line 1\n01234");
+}
+
+/// Test that, if an attempt to pre-flush buffered data returns Ok(0),
+/// this is propagated as an error.
+#[test]
+fn line_buffer_write0_error() {
+    let writer = ProgrammableSink {
+        // Accept one write, then return Ok(0) on subsequent ones
+        max_writes: Some(1),
+
+        ..Default::default()
+    };
+    let mut writer = LineWriter::new(writer);
+
+    // This should write "Line 1\n" and buffer "Partial"
+    assert_eq!(writer.write(b"Line 1\nPartial").unwrap(), 14);
+    assert_eq!(&writer.get_ref().buffer, b"Line 1\n");
+
+    // This will attempt to flush "partial", which will return Ok(0), which
+    // needs to be an error, because we've already informed the client
+    // that we accepted the write.
+    let err = writer.write(b" Line End\n").unwrap_err();
+    assert_eq!(err.kind(), ErrorKind::WriteZero);
+    assert_eq!(&writer.get_ref().buffer, b"Line 1\n");
+}
+
+/// Test that, if a write returns Ok(0) after a successful pre-flush, this
+/// is propagated as Ok(0)
+#[test]
+fn line_buffer_write0_normal() {
+    let writer = ProgrammableSink {
+        // Accept two writes, then return Ok(0) on subsequent ones
+        max_writes: Some(2),
+
+        ..Default::default()
+    };
+    let mut writer = LineWriter::new(writer);
+
+    // This should write "Line 1\n" and buffer "Partial"
+    assert_eq!(writer.write(b"Line 1\nPartial").unwrap(), 14);
+    assert_eq!(&writer.get_ref().buffer, b"Line 1\n");
+
+    // This will flush partial, which will succeed, but then return Ok(0)
+    // when flushing " Line End\n"
+    assert_eq!(writer.write(b" Line End\n").unwrap(), 0);
+    assert_eq!(&writer.get_ref().buffer, b"Line 1\nPartial");
+}
+
+/// LineWriter has a custom `write_all`; make sure it works correctly
+#[test]
+fn line_write_all() {
+    let writer = ProgrammableSink {
+        // Only write 5 bytes at a time
+        accept_prefix: Some(5),
+        ..Default::default()
+    };
+    let mut writer = LineWriter::new(writer);
+
+    writer.write_all(b"Line 1\nLine 2\nLine 3\nLine 4\nPartial").unwrap();
+    assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\nLine 4\n");
+    writer.write_all(b" Line 5\n").unwrap();
+    assert_eq!(
+        writer.get_ref().buffer.as_slice(),
+        b"Line 1\nLine 2\nLine 3\nLine 4\nPartial Line 5\n".as_ref(),
+    );
+}
+
+#[test]
+fn line_write_all_error() {
+    let writer = ProgrammableSink {
+        // Only accept up to 3 writes of up to 5 bytes each
+        accept_prefix: Some(5),
+        max_writes: Some(3),
+        ..Default::default()
+    };
+
+    let mut writer = LineWriter::new(writer);
+    let res = writer.write_all(b"Line 1\nLine 2\nLine 3\nLine 4\nPartial");
+    assert!(res.is_err());
+    // An error from write_all leaves everything in an indeterminate state,
+    // so there's nothing else to test here
+}
+
+/// Under certain circumstances, the old implementation of LineWriter
+/// would try to buffer "to the last newline" but be forced to buffer
+/// less than that, leading to inappropriate partial line writes.
+/// Regression test for that issue.
+#[test]
+fn partial_multiline_buffering() {
+    let writer = ProgrammableSink {
+        // Write only up to 5 bytes at a time
+        accept_prefix: Some(5),
+        ..Default::default()
+    };
+
+    let mut writer = LineWriter::with_capacity(10, writer);
+
+    let content = b"AAAAABBBBB\nCCCCDDDDDD\nEEE";
+
+    // When content is written, LineWriter will try to write blocks A, B,
+    // C, and D. Only block A will succeed. Under the old behavior, LineWriter
+    // would then try to buffer B, C and D, but because its capacity is 10,
+    // it will only be able to buffer B and C. We don't want to buffer
+    // partial lines concurrent with whole lines, so the correct behavior
+    // is to buffer only block B (out to the newline)
+    assert_eq!(writer.write(content).unwrap(), 11);
+    assert_eq!(writer.get_ref().buffer, *b"AAAAA");
+
+    writer.flush().unwrap();
+    assert_eq!(writer.get_ref().buffer, *b"AAAAABBBBB\n");
+}
+
+/// Same as test_partial_multiline_buffering, but in the event NO full lines
+/// fit in the buffer, just buffer as much as possible
+#[test]
+fn partial_multiline_buffering_without_full_line() {
+    let writer = ProgrammableSink {
+        // Write only up to 5 bytes at a time
+        accept_prefix: Some(5),
+        ..Default::default()
+    };
+
+    let mut writer = LineWriter::with_capacity(5, writer);
+
+    let content = b"AAAAABBBBBBBBBB\nCCCCC\nDDDDD";
+
+    // When content is written, LineWriter will try to write blocks A, B,
+    // and C. Only block A will succeed. Under the old behavior, LineWriter
+    // would then try to buffer B and C, but because its capacity is 5,
+    // it will only be able to buffer part of B. Because it's not possible
+    // for it to buffer any complete lines, it should buffer as much of B as
+    // possible
+    assert_eq!(writer.write(content).unwrap(), 10);
+    assert_eq!(writer.get_ref().buffer, *b"AAAAA");
+
+    writer.flush().unwrap();
+    assert_eq!(writer.get_ref().buffer, *b"AAAAABBBBB");
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+enum RecordedEvent {
+    Write(String),
+    Flush,
+}
+
+#[derive(Debug, Clone, Default)]
+struct WriteRecorder {
+    pub events: Vec<RecordedEvent>,
+}
+
+impl Write for WriteRecorder {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        use crate::str::from_utf8;
+
+        self.events.push(RecordedEvent::Write(from_utf8(buf).unwrap().to_string()));
+        Ok(buf.len())
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        self.events.push(RecordedEvent::Flush);
+        Ok(())
+    }
+}
+
+/// Test that a normal, formatted writeln only results in a single write
+/// call to the underlying writer. A naive implementation of
+/// LineWriter::write_all results in two writes: one of the buffered data,
+/// and another of the final substring in the formatted set
+#[test]
+fn single_formatted_write() {
+    let writer = WriteRecorder::default();
+    let mut writer = LineWriter::new(writer);
+
+    // Under a naive implementation of LineWriter, this will result in two
+    // writes: "hello, world" and "!\n", because write() has to flush the
+    // buffer before attempting to write the last "!\n". write_all shouldn't
+    // have this limitation.
+    writeln!(&mut writer, "{}, {}!", "hello", "world").unwrap();
+    assert_eq!(writer.get_ref().events, [RecordedEvent::Write("hello, world!\n".to_string())]);
+}
diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs
index 58343f66f3f..5733735dc4a 100644
--- a/library/std/src/io/cursor.rs
+++ b/library/std/src/io/cursor.rs
@@ -1,3 +1,6 @@
+#[cfg(test)]
+mod tests;
+
 use crate::io::prelude::*;
 
 use crate::cmp;
@@ -447,531 +450,3 @@ impl Write for Cursor<Box<[u8]>> {
         Ok(())
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use crate::io::prelude::*;
-    use crate::io::{Cursor, IoSlice, IoSliceMut, SeekFrom};
-
-    #[test]
-    fn test_vec_writer() {
-        let mut writer = Vec::new();
-        assert_eq!(writer.write(&[0]).unwrap(), 1);
-        assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
-        assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
-        assert_eq!(
-            writer
-                .write_vectored(&[IoSlice::new(&[]), IoSlice::new(&[8, 9]), IoSlice::new(&[10])],)
-                .unwrap(),
-            3
-        );
-        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-        assert_eq!(writer, b);
-    }
-
-    #[test]
-    fn test_mem_writer() {
-        let mut writer = Cursor::new(Vec::new());
-        assert_eq!(writer.write(&[0]).unwrap(), 1);
-        assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
-        assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
-        assert_eq!(
-            writer
-                .write_vectored(&[IoSlice::new(&[]), IoSlice::new(&[8, 9]), IoSlice::new(&[10])],)
-                .unwrap(),
-            3
-        );
-        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-        assert_eq!(&writer.get_ref()[..], b);
-    }
-
-    #[test]
-    fn test_mem_mut_writer() {
-        let mut vec = Vec::new();
-        let mut writer = Cursor::new(&mut vec);
-        assert_eq!(writer.write(&[0]).unwrap(), 1);
-        assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
-        assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
-        assert_eq!(
-            writer
-                .write_vectored(&[IoSlice::new(&[]), IoSlice::new(&[8, 9]), IoSlice::new(&[10])],)
-                .unwrap(),
-            3
-        );
-        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-        assert_eq!(&writer.get_ref()[..], b);
-    }
-
-    #[test]
-    fn test_box_slice_writer() {
-        let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice());
-        assert_eq!(writer.position(), 0);
-        assert_eq!(writer.write(&[0]).unwrap(), 1);
-        assert_eq!(writer.position(), 1);
-        assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
-        assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
-        assert_eq!(writer.position(), 8);
-        assert_eq!(writer.write(&[]).unwrap(), 0);
-        assert_eq!(writer.position(), 8);
-
-        assert_eq!(writer.write(&[8, 9]).unwrap(), 1);
-        assert_eq!(writer.write(&[10]).unwrap(), 0);
-        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
-        assert_eq!(&**writer.get_ref(), b);
-    }
-
-    #[test]
-    fn test_box_slice_writer_vectored() {
-        let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice());
-        assert_eq!(writer.position(), 0);
-        assert_eq!(writer.write_vectored(&[IoSlice::new(&[0])]).unwrap(), 1);
-        assert_eq!(writer.position(), 1);
-        assert_eq!(
-            writer
-                .write_vectored(&[IoSlice::new(&[1, 2, 3]), IoSlice::new(&[4, 5, 6, 7]),])
-                .unwrap(),
-            7,
-        );
-        assert_eq!(writer.position(), 8);
-        assert_eq!(writer.write_vectored(&[]).unwrap(), 0);
-        assert_eq!(writer.position(), 8);
-
-        assert_eq!(writer.write_vectored(&[IoSlice::new(&[8, 9])]).unwrap(), 1);
-        assert_eq!(writer.write_vectored(&[IoSlice::new(&[10])]).unwrap(), 0);
-        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
-        assert_eq!(&**writer.get_ref(), b);
-    }
-
-    #[test]
-    fn test_buf_writer() {
-        let mut buf = [0 as u8; 9];
-        {
-            let mut writer = Cursor::new(&mut buf[..]);
-            assert_eq!(writer.position(), 0);
-            assert_eq!(writer.write(&[0]).unwrap(), 1);
-            assert_eq!(writer.position(), 1);
-            assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
-            assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
-            assert_eq!(writer.position(), 8);
-            assert_eq!(writer.write(&[]).unwrap(), 0);
-            assert_eq!(writer.position(), 8);
-
-            assert_eq!(writer.write(&[8, 9]).unwrap(), 1);
-            assert_eq!(writer.write(&[10]).unwrap(), 0);
-        }
-        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
-        assert_eq!(buf, b);
-    }
-
-    #[test]
-    fn test_buf_writer_vectored() {
-        let mut buf = [0 as u8; 9];
-        {
-            let mut writer = Cursor::new(&mut buf[..]);
-            assert_eq!(writer.position(), 0);
-            assert_eq!(writer.write_vectored(&[IoSlice::new(&[0])]).unwrap(), 1);
-            assert_eq!(writer.position(), 1);
-            assert_eq!(
-                writer
-                    .write_vectored(&[IoSlice::new(&[1, 2, 3]), IoSlice::new(&[4, 5, 6, 7])],)
-                    .unwrap(),
-                7,
-            );
-            assert_eq!(writer.position(), 8);
-            assert_eq!(writer.write_vectored(&[]).unwrap(), 0);
-            assert_eq!(writer.position(), 8);
-
-            assert_eq!(writer.write_vectored(&[IoSlice::new(&[8, 9])]).unwrap(), 1);
-            assert_eq!(writer.write_vectored(&[IoSlice::new(&[10])]).unwrap(), 0);
-        }
-        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
-        assert_eq!(buf, b);
-    }
-
-    #[test]
-    fn test_buf_writer_seek() {
-        let mut buf = [0 as u8; 8];
-        {
-            let mut writer = Cursor::new(&mut buf[..]);
-            assert_eq!(writer.position(), 0);
-            assert_eq!(writer.write(&[1]).unwrap(), 1);
-            assert_eq!(writer.position(), 1);
-
-            assert_eq!(writer.seek(SeekFrom::Start(2)).unwrap(), 2);
-            assert_eq!(writer.position(), 2);
-            assert_eq!(writer.write(&[2]).unwrap(), 1);
-            assert_eq!(writer.position(), 3);
-
-            assert_eq!(writer.seek(SeekFrom::Current(-2)).unwrap(), 1);
-            assert_eq!(writer.position(), 1);
-            assert_eq!(writer.write(&[3]).unwrap(), 1);
-            assert_eq!(writer.position(), 2);
-
-            assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7);
-            assert_eq!(writer.position(), 7);
-            assert_eq!(writer.write(&[4]).unwrap(), 1);
-            assert_eq!(writer.position(), 8);
-        }
-        let b: &[_] = &[1, 3, 2, 0, 0, 0, 0, 4];
-        assert_eq!(buf, b);
-    }
-
-    #[test]
-    fn test_buf_writer_error() {
-        let mut buf = [0 as u8; 2];
-        let mut writer = Cursor::new(&mut buf[..]);
-        assert_eq!(writer.write(&[0]).unwrap(), 1);
-        assert_eq!(writer.write(&[0, 0]).unwrap(), 1);
-        assert_eq!(writer.write(&[0, 0]).unwrap(), 0);
-    }
-
-    #[test]
-    fn test_mem_reader() {
-        let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]);
-        let mut buf = [];
-        assert_eq!(reader.read(&mut buf).unwrap(), 0);
-        assert_eq!(reader.position(), 0);
-        let mut buf = [0];
-        assert_eq!(reader.read(&mut buf).unwrap(), 1);
-        assert_eq!(reader.position(), 1);
-        let b: &[_] = &[0];
-        assert_eq!(buf, b);
-        let mut buf = [0; 4];
-        assert_eq!(reader.read(&mut buf).unwrap(), 4);
-        assert_eq!(reader.position(), 5);
-        let b: &[_] = &[1, 2, 3, 4];
-        assert_eq!(buf, b);
-        assert_eq!(reader.read(&mut buf).unwrap(), 3);
-        let b: &[_] = &[5, 6, 7];
-        assert_eq!(&buf[..3], b);
-        assert_eq!(reader.read(&mut buf).unwrap(), 0);
-    }
-
-    #[test]
-    fn test_mem_reader_vectored() {
-        let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]);
-        let mut buf = [];
-        assert_eq!(reader.read_vectored(&mut [IoSliceMut::new(&mut buf)]).unwrap(), 0);
-        assert_eq!(reader.position(), 0);
-        let mut buf = [0];
-        assert_eq!(
-            reader
-                .read_vectored(&mut [IoSliceMut::new(&mut []), IoSliceMut::new(&mut buf),])
-                .unwrap(),
-            1,
-        );
-        assert_eq!(reader.position(), 1);
-        let b: &[_] = &[0];
-        assert_eq!(buf, b);
-        let mut buf1 = [0; 4];
-        let mut buf2 = [0; 4];
-        assert_eq!(
-            reader
-                .read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2),])
-                .unwrap(),
-            7,
-        );
-        let b1: &[_] = &[1, 2, 3, 4];
-        let b2: &[_] = &[5, 6, 7];
-        assert_eq!(buf1, b1);
-        assert_eq!(&buf2[..3], b2);
-        assert_eq!(reader.read(&mut buf).unwrap(), 0);
-    }
-
-    #[test]
-    fn test_boxed_slice_reader() {
-        let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice());
-        let mut buf = [];
-        assert_eq!(reader.read(&mut buf).unwrap(), 0);
-        assert_eq!(reader.position(), 0);
-        let mut buf = [0];
-        assert_eq!(reader.read(&mut buf).unwrap(), 1);
-        assert_eq!(reader.position(), 1);
-        let b: &[_] = &[0];
-        assert_eq!(buf, b);
-        let mut buf = [0; 4];
-        assert_eq!(reader.read(&mut buf).unwrap(), 4);
-        assert_eq!(reader.position(), 5);
-        let b: &[_] = &[1, 2, 3, 4];
-        assert_eq!(buf, b);
-        assert_eq!(reader.read(&mut buf).unwrap(), 3);
-        let b: &[_] = &[5, 6, 7];
-        assert_eq!(&buf[..3], b);
-        assert_eq!(reader.read(&mut buf).unwrap(), 0);
-    }
-
-    #[test]
-    fn test_boxed_slice_reader_vectored() {
-        let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice());
-        let mut buf = [];
-        assert_eq!(reader.read_vectored(&mut [IoSliceMut::new(&mut buf)]).unwrap(), 0);
-        assert_eq!(reader.position(), 0);
-        let mut buf = [0];
-        assert_eq!(
-            reader
-                .read_vectored(&mut [IoSliceMut::new(&mut []), IoSliceMut::new(&mut buf),])
-                .unwrap(),
-            1,
-        );
-        assert_eq!(reader.position(), 1);
-        let b: &[_] = &[0];
-        assert_eq!(buf, b);
-        let mut buf1 = [0; 4];
-        let mut buf2 = [0; 4];
-        assert_eq!(
-            reader
-                .read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2)],)
-                .unwrap(),
-            7,
-        );
-        let b1: &[_] = &[1, 2, 3, 4];
-        let b2: &[_] = &[5, 6, 7];
-        assert_eq!(buf1, b1);
-        assert_eq!(&buf2[..3], b2);
-        assert_eq!(reader.read(&mut buf).unwrap(), 0);
-    }
-
-    #[test]
-    fn read_to_end() {
-        let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]);
-        let mut v = Vec::new();
-        reader.read_to_end(&mut v).unwrap();
-        assert_eq!(v, [0, 1, 2, 3, 4, 5, 6, 7]);
-    }
-
-    #[test]
-    fn test_slice_reader() {
-        let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
-        let reader = &mut &in_buf[..];
-        let mut buf = [];
-        assert_eq!(reader.read(&mut buf).unwrap(), 0);
-        let mut buf = [0];
-        assert_eq!(reader.read(&mut buf).unwrap(), 1);
-        assert_eq!(reader.len(), 7);
-        let b: &[_] = &[0];
-        assert_eq!(&buf[..], b);
-        let mut buf = [0; 4];
-        assert_eq!(reader.read(&mut buf).unwrap(), 4);
-        assert_eq!(reader.len(), 3);
-        let b: &[_] = &[1, 2, 3, 4];
-        assert_eq!(&buf[..], b);
-        assert_eq!(reader.read(&mut buf).unwrap(), 3);
-        let b: &[_] = &[5, 6, 7];
-        assert_eq!(&buf[..3], b);
-        assert_eq!(reader.read(&mut buf).unwrap(), 0);
-    }
-
-    #[test]
-    fn test_slice_reader_vectored() {
-        let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
-        let reader = &mut &in_buf[..];
-        let mut buf = [];
-        assert_eq!(reader.read_vectored(&mut [IoSliceMut::new(&mut buf)]).unwrap(), 0);
-        let mut buf = [0];
-        assert_eq!(
-            reader
-                .read_vectored(&mut [IoSliceMut::new(&mut []), IoSliceMut::new(&mut buf),])
-                .unwrap(),
-            1,
-        );
-        assert_eq!(reader.len(), 7);
-        let b: &[_] = &[0];
-        assert_eq!(buf, b);
-        let mut buf1 = [0; 4];
-        let mut buf2 = [0; 4];
-        assert_eq!(
-            reader
-                .read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2)],)
-                .unwrap(),
-            7,
-        );
-        let b1: &[_] = &[1, 2, 3, 4];
-        let b2: &[_] = &[5, 6, 7];
-        assert_eq!(buf1, b1);
-        assert_eq!(&buf2[..3], b2);
-        assert_eq!(reader.read(&mut buf).unwrap(), 0);
-    }
-
-    #[test]
-    fn test_read_exact() {
-        let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
-        let reader = &mut &in_buf[..];
-        let mut buf = [];
-        assert!(reader.read_exact(&mut buf).is_ok());
-        let mut buf = [8];
-        assert!(reader.read_exact(&mut buf).is_ok());
-        assert_eq!(buf[0], 0);
-        assert_eq!(reader.len(), 7);
-        let mut buf = [0, 0, 0, 0, 0, 0, 0];
-        assert!(reader.read_exact(&mut buf).is_ok());
-        assert_eq!(buf, [1, 2, 3, 4, 5, 6, 7]);
-        assert_eq!(reader.len(), 0);
-        let mut buf = [0];
-        assert!(reader.read_exact(&mut buf).is_err());
-    }
-
-    #[test]
-    fn test_buf_reader() {
-        let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
-        let mut reader = Cursor::new(&in_buf[..]);
-        let mut buf = [];
-        assert_eq!(reader.read(&mut buf).unwrap(), 0);
-        assert_eq!(reader.position(), 0);
-        let mut buf = [0];
-        assert_eq!(reader.read(&mut buf).unwrap(), 1);
-        assert_eq!(reader.position(), 1);
-        let b: &[_] = &[0];
-        assert_eq!(buf, b);
-        let mut buf = [0; 4];
-        assert_eq!(reader.read(&mut buf).unwrap(), 4);
-        assert_eq!(reader.position(), 5);
-        let b: &[_] = &[1, 2, 3, 4];
-        assert_eq!(buf, b);
-        assert_eq!(reader.read(&mut buf).unwrap(), 3);
-        let b: &[_] = &[5, 6, 7];
-        assert_eq!(&buf[..3], b);
-        assert_eq!(reader.read(&mut buf).unwrap(), 0);
-    }
-
-    #[test]
-    fn seek_past_end() {
-        let buf = [0xff];
-        let mut r = Cursor::new(&buf[..]);
-        assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
-        assert_eq!(r.read(&mut [0]).unwrap(), 0);
-
-        let mut r = Cursor::new(vec![10]);
-        assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
-        assert_eq!(r.read(&mut [0]).unwrap(), 0);
-
-        let mut buf = [0];
-        let mut r = Cursor::new(&mut buf[..]);
-        assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
-        assert_eq!(r.write(&[3]).unwrap(), 0);
-
-        let mut r = Cursor::new(vec![10].into_boxed_slice());
-        assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
-        assert_eq!(r.write(&[3]).unwrap(), 0);
-    }
-
-    #[test]
-    fn seek_past_i64() {
-        let buf = [0xff];
-        let mut r = Cursor::new(&buf[..]);
-        assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6);
-        assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6);
-        assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006);
-        assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006);
-        assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err());
-        assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6);
-
-        let mut r = Cursor::new(vec![10]);
-        assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6);
-        assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6);
-        assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006);
-        assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006);
-        assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err());
-        assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6);
-
-        let mut buf = [0];
-        let mut r = Cursor::new(&mut buf[..]);
-        assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6);
-        assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6);
-        assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006);
-        assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006);
-        assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err());
-        assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6);
-
-        let mut r = Cursor::new(vec![10].into_boxed_slice());
-        assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6);
-        assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6);
-        assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006);
-        assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006);
-        assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err());
-        assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6);
-    }
-
-    #[test]
-    fn seek_before_0() {
-        let buf = [0xff];
-        let mut r = Cursor::new(&buf[..]);
-        assert!(r.seek(SeekFrom::End(-2)).is_err());
-
-        let mut r = Cursor::new(vec![10]);
-        assert!(r.seek(SeekFrom::End(-2)).is_err());
-
-        let mut buf = [0];
-        let mut r = Cursor::new(&mut buf[..]);
-        assert!(r.seek(SeekFrom::End(-2)).is_err());
-
-        let mut r = Cursor::new(vec![10].into_boxed_slice());
-        assert!(r.seek(SeekFrom::End(-2)).is_err());
-    }
-
-    #[test]
-    fn test_seekable_mem_writer() {
-        let mut writer = Cursor::new(Vec::<u8>::new());
-        assert_eq!(writer.position(), 0);
-        assert_eq!(writer.write(&[0]).unwrap(), 1);
-        assert_eq!(writer.position(), 1);
-        assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
-        assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
-        assert_eq!(writer.position(), 8);
-        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
-        assert_eq!(&writer.get_ref()[..], b);
-
-        assert_eq!(writer.seek(SeekFrom::Start(0)).unwrap(), 0);
-        assert_eq!(writer.position(), 0);
-        assert_eq!(writer.write(&[3, 4]).unwrap(), 2);
-        let b: &[_] = &[3, 4, 2, 3, 4, 5, 6, 7];
-        assert_eq!(&writer.get_ref()[..], b);
-
-        assert_eq!(writer.seek(SeekFrom::Current(1)).unwrap(), 3);
-        assert_eq!(writer.write(&[0, 1]).unwrap(), 2);
-        let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 7];
-        assert_eq!(&writer.get_ref()[..], b);
-
-        assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7);
-        assert_eq!(writer.write(&[1, 2]).unwrap(), 2);
-        let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2];
-        assert_eq!(&writer.get_ref()[..], b);
-
-        assert_eq!(writer.seek(SeekFrom::End(1)).unwrap(), 10);
-        assert_eq!(writer.write(&[1]).unwrap(), 1);
-        let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1];
-        assert_eq!(&writer.get_ref()[..], b);
-    }
-
-    #[test]
-    fn vec_seek_past_end() {
-        let mut r = Cursor::new(Vec::new());
-        assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
-        assert_eq!(r.write(&[3]).unwrap(), 1);
-    }
-
-    #[test]
-    fn vec_seek_before_0() {
-        let mut r = Cursor::new(Vec::new());
-        assert!(r.seek(SeekFrom::End(-2)).is_err());
-    }
-
-    #[test]
-    #[cfg(target_pointer_width = "32")]
-    fn vec_seek_and_write_past_usize_max() {
-        let mut c = Cursor::new(Vec::new());
-        c.set_position(usize::MAX as u64 + 1);
-        assert!(c.write_all(&[1, 2, 3]).is_err());
-    }
-
-    #[test]
-    fn test_partial_eq() {
-        assert_eq!(Cursor::new(Vec::<u8>::new()), Cursor::new(Vec::<u8>::new()));
-    }
-
-    #[test]
-    fn test_eq() {
-        struct AssertEq<T: Eq>(pub T);
-
-        let _: AssertEq<Cursor<Vec<u8>>> = AssertEq(Cursor::new(Vec::new()));
-    }
-}
diff --git a/library/std/src/io/cursor/tests.rs b/library/std/src/io/cursor/tests.rs
new file mode 100644
index 00000000000..80d88ca66f6
--- /dev/null
+++ b/library/std/src/io/cursor/tests.rs
@@ -0,0 +1,516 @@
+use crate::io::prelude::*;
+use crate::io::{Cursor, IoSlice, IoSliceMut, SeekFrom};
+
+#[test]
+fn test_vec_writer() {
+    let mut writer = Vec::new();
+    assert_eq!(writer.write(&[0]).unwrap(), 1);
+    assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
+    assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
+    assert_eq!(
+        writer
+            .write_vectored(&[IoSlice::new(&[]), IoSlice::new(&[8, 9]), IoSlice::new(&[10])],)
+            .unwrap(),
+        3
+    );
+    let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+    assert_eq!(writer, b);
+}
+
+#[test]
+fn test_mem_writer() {
+    let mut writer = Cursor::new(Vec::new());
+    assert_eq!(writer.write(&[0]).unwrap(), 1);
+    assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
+    assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
+    assert_eq!(
+        writer
+            .write_vectored(&[IoSlice::new(&[]), IoSlice::new(&[8, 9]), IoSlice::new(&[10])],)
+            .unwrap(),
+        3
+    );
+    let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+    assert_eq!(&writer.get_ref()[..], b);
+}
+
+#[test]
+fn test_mem_mut_writer() {
+    let mut vec = Vec::new();
+    let mut writer = Cursor::new(&mut vec);
+    assert_eq!(writer.write(&[0]).unwrap(), 1);
+    assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
+    assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
+    assert_eq!(
+        writer
+            .write_vectored(&[IoSlice::new(&[]), IoSlice::new(&[8, 9]), IoSlice::new(&[10])],)
+            .unwrap(),
+        3
+    );
+    let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+    assert_eq!(&writer.get_ref()[..], b);
+}
+
+#[test]
+fn test_box_slice_writer() {
+    let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice());
+    assert_eq!(writer.position(), 0);
+    assert_eq!(writer.write(&[0]).unwrap(), 1);
+    assert_eq!(writer.position(), 1);
+    assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
+    assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
+    assert_eq!(writer.position(), 8);
+    assert_eq!(writer.write(&[]).unwrap(), 0);
+    assert_eq!(writer.position(), 8);
+
+    assert_eq!(writer.write(&[8, 9]).unwrap(), 1);
+    assert_eq!(writer.write(&[10]).unwrap(), 0);
+    let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
+    assert_eq!(&**writer.get_ref(), b);
+}
+
+#[test]
+fn test_box_slice_writer_vectored() {
+    let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice());
+    assert_eq!(writer.position(), 0);
+    assert_eq!(writer.write_vectored(&[IoSlice::new(&[0])]).unwrap(), 1);
+    assert_eq!(writer.position(), 1);
+    assert_eq!(
+        writer.write_vectored(&[IoSlice::new(&[1, 2, 3]), IoSlice::new(&[4, 5, 6, 7]),]).unwrap(),
+        7,
+    );
+    assert_eq!(writer.position(), 8);
+    assert_eq!(writer.write_vectored(&[]).unwrap(), 0);
+    assert_eq!(writer.position(), 8);
+
+    assert_eq!(writer.write_vectored(&[IoSlice::new(&[8, 9])]).unwrap(), 1);
+    assert_eq!(writer.write_vectored(&[IoSlice::new(&[10])]).unwrap(), 0);
+    let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
+    assert_eq!(&**writer.get_ref(), b);
+}
+
+#[test]
+fn test_buf_writer() {
+    let mut buf = [0 as u8; 9];
+    {
+        let mut writer = Cursor::new(&mut buf[..]);
+        assert_eq!(writer.position(), 0);
+        assert_eq!(writer.write(&[0]).unwrap(), 1);
+        assert_eq!(writer.position(), 1);
+        assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
+        assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
+        assert_eq!(writer.position(), 8);
+        assert_eq!(writer.write(&[]).unwrap(), 0);
+        assert_eq!(writer.position(), 8);
+
+        assert_eq!(writer.write(&[8, 9]).unwrap(), 1);
+        assert_eq!(writer.write(&[10]).unwrap(), 0);
+    }
+    let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
+    assert_eq!(buf, b);
+}
+
+#[test]
+fn test_buf_writer_vectored() {
+    let mut buf = [0 as u8; 9];
+    {
+        let mut writer = Cursor::new(&mut buf[..]);
+        assert_eq!(writer.position(), 0);
+        assert_eq!(writer.write_vectored(&[IoSlice::new(&[0])]).unwrap(), 1);
+        assert_eq!(writer.position(), 1);
+        assert_eq!(
+            writer
+                .write_vectored(&[IoSlice::new(&[1, 2, 3]), IoSlice::new(&[4, 5, 6, 7])],)
+                .unwrap(),
+            7,
+        );
+        assert_eq!(writer.position(), 8);
+        assert_eq!(writer.write_vectored(&[]).unwrap(), 0);
+        assert_eq!(writer.position(), 8);
+
+        assert_eq!(writer.write_vectored(&[IoSlice::new(&[8, 9])]).unwrap(), 1);
+        assert_eq!(writer.write_vectored(&[IoSlice::new(&[10])]).unwrap(), 0);
+    }
+    let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
+    assert_eq!(buf, b);
+}
+
+#[test]
+fn test_buf_writer_seek() {
+    let mut buf = [0 as u8; 8];
+    {
+        let mut writer = Cursor::new(&mut buf[..]);
+        assert_eq!(writer.position(), 0);
+        assert_eq!(writer.write(&[1]).unwrap(), 1);
+        assert_eq!(writer.position(), 1);
+
+        assert_eq!(writer.seek(SeekFrom::Start(2)).unwrap(), 2);
+        assert_eq!(writer.position(), 2);
+        assert_eq!(writer.write(&[2]).unwrap(), 1);
+        assert_eq!(writer.position(), 3);
+
+        assert_eq!(writer.seek(SeekFrom::Current(-2)).unwrap(), 1);
+        assert_eq!(writer.position(), 1);
+        assert_eq!(writer.write(&[3]).unwrap(), 1);
+        assert_eq!(writer.position(), 2);
+
+        assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7);
+        assert_eq!(writer.position(), 7);
+        assert_eq!(writer.write(&[4]).unwrap(), 1);
+        assert_eq!(writer.position(), 8);
+    }
+    let b: &[_] = &[1, 3, 2, 0, 0, 0, 0, 4];
+    assert_eq!(buf, b);
+}
+
+#[test]
+fn test_buf_writer_error() {
+    let mut buf = [0 as u8; 2];
+    let mut writer = Cursor::new(&mut buf[..]);
+    assert_eq!(writer.write(&[0]).unwrap(), 1);
+    assert_eq!(writer.write(&[0, 0]).unwrap(), 1);
+    assert_eq!(writer.write(&[0, 0]).unwrap(), 0);
+}
+
+#[test]
+fn test_mem_reader() {
+    let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]);
+    let mut buf = [];
+    assert_eq!(reader.read(&mut buf).unwrap(), 0);
+    assert_eq!(reader.position(), 0);
+    let mut buf = [0];
+    assert_eq!(reader.read(&mut buf).unwrap(), 1);
+    assert_eq!(reader.position(), 1);
+    let b: &[_] = &[0];
+    assert_eq!(buf, b);
+    let mut buf = [0; 4];
+    assert_eq!(reader.read(&mut buf).unwrap(), 4);
+    assert_eq!(reader.position(), 5);
+    let b: &[_] = &[1, 2, 3, 4];
+    assert_eq!(buf, b);
+    assert_eq!(reader.read(&mut buf).unwrap(), 3);
+    let b: &[_] = &[5, 6, 7];
+    assert_eq!(&buf[..3], b);
+    assert_eq!(reader.read(&mut buf).unwrap(), 0);
+}
+
+#[test]
+fn test_mem_reader_vectored() {
+    let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]);
+    let mut buf = [];
+    assert_eq!(reader.read_vectored(&mut [IoSliceMut::new(&mut buf)]).unwrap(), 0);
+    assert_eq!(reader.position(), 0);
+    let mut buf = [0];
+    assert_eq!(
+        reader.read_vectored(&mut [IoSliceMut::new(&mut []), IoSliceMut::new(&mut buf),]).unwrap(),
+        1,
+    );
+    assert_eq!(reader.position(), 1);
+    let b: &[_] = &[0];
+    assert_eq!(buf, b);
+    let mut buf1 = [0; 4];
+    let mut buf2 = [0; 4];
+    assert_eq!(
+        reader
+            .read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2),])
+            .unwrap(),
+        7,
+    );
+    let b1: &[_] = &[1, 2, 3, 4];
+    let b2: &[_] = &[5, 6, 7];
+    assert_eq!(buf1, b1);
+    assert_eq!(&buf2[..3], b2);
+    assert_eq!(reader.read(&mut buf).unwrap(), 0);
+}
+
+#[test]
+fn test_boxed_slice_reader() {
+    let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice());
+    let mut buf = [];
+    assert_eq!(reader.read(&mut buf).unwrap(), 0);
+    assert_eq!(reader.position(), 0);
+    let mut buf = [0];
+    assert_eq!(reader.read(&mut buf).unwrap(), 1);
+    assert_eq!(reader.position(), 1);
+    let b: &[_] = &[0];
+    assert_eq!(buf, b);
+    let mut buf = [0; 4];
+    assert_eq!(reader.read(&mut buf).unwrap(), 4);
+    assert_eq!(reader.position(), 5);
+    let b: &[_] = &[1, 2, 3, 4];
+    assert_eq!(buf, b);
+    assert_eq!(reader.read(&mut buf).unwrap(), 3);
+    let b: &[_] = &[5, 6, 7];
+    assert_eq!(&buf[..3], b);
+    assert_eq!(reader.read(&mut buf).unwrap(), 0);
+}
+
+#[test]
+fn test_boxed_slice_reader_vectored() {
+    let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice());
+    let mut buf = [];
+    assert_eq!(reader.read_vectored(&mut [IoSliceMut::new(&mut buf)]).unwrap(), 0);
+    assert_eq!(reader.position(), 0);
+    let mut buf = [0];
+    assert_eq!(
+        reader.read_vectored(&mut [IoSliceMut::new(&mut []), IoSliceMut::new(&mut buf),]).unwrap(),
+        1,
+    );
+    assert_eq!(reader.position(), 1);
+    let b: &[_] = &[0];
+    assert_eq!(buf, b);
+    let mut buf1 = [0; 4];
+    let mut buf2 = [0; 4];
+    assert_eq!(
+        reader
+            .read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2)],)
+            .unwrap(),
+        7,
+    );
+    let b1: &[_] = &[1, 2, 3, 4];
+    let b2: &[_] = &[5, 6, 7];
+    assert_eq!(buf1, b1);
+    assert_eq!(&buf2[..3], b2);
+    assert_eq!(reader.read(&mut buf).unwrap(), 0);
+}
+
+#[test]
+fn read_to_end() {
+    let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]);
+    let mut v = Vec::new();
+    reader.read_to_end(&mut v).unwrap();
+    assert_eq!(v, [0, 1, 2, 3, 4, 5, 6, 7]);
+}
+
+#[test]
+fn test_slice_reader() {
+    let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
+    let reader = &mut &in_buf[..];
+    let mut buf = [];
+    assert_eq!(reader.read(&mut buf).unwrap(), 0);
+    let mut buf = [0];
+    assert_eq!(reader.read(&mut buf).unwrap(), 1);
+    assert_eq!(reader.len(), 7);
+    let b: &[_] = &[0];
+    assert_eq!(&buf[..], b);
+    let mut buf = [0; 4];
+    assert_eq!(reader.read(&mut buf).unwrap(), 4);
+    assert_eq!(reader.len(), 3);
+    let b: &[_] = &[1, 2, 3, 4];
+    assert_eq!(&buf[..], b);
+    assert_eq!(reader.read(&mut buf).unwrap(), 3);
+    let b: &[_] = &[5, 6, 7];
+    assert_eq!(&buf[..3], b);
+    assert_eq!(reader.read(&mut buf).unwrap(), 0);
+}
+
+#[test]
+fn test_slice_reader_vectored() {
+    let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
+    let reader = &mut &in_buf[..];
+    let mut buf = [];
+    assert_eq!(reader.read_vectored(&mut [IoSliceMut::new(&mut buf)]).unwrap(), 0);
+    let mut buf = [0];
+    assert_eq!(
+        reader.read_vectored(&mut [IoSliceMut::new(&mut []), IoSliceMut::new(&mut buf),]).unwrap(),
+        1,
+    );
+    assert_eq!(reader.len(), 7);
+    let b: &[_] = &[0];
+    assert_eq!(buf, b);
+    let mut buf1 = [0; 4];
+    let mut buf2 = [0; 4];
+    assert_eq!(
+        reader
+            .read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2)],)
+            .unwrap(),
+        7,
+    );
+    let b1: &[_] = &[1, 2, 3, 4];
+    let b2: &[_] = &[5, 6, 7];
+    assert_eq!(buf1, b1);
+    assert_eq!(&buf2[..3], b2);
+    assert_eq!(reader.read(&mut buf).unwrap(), 0);
+}
+
+#[test]
+fn test_read_exact() {
+    let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
+    let reader = &mut &in_buf[..];
+    let mut buf = [];
+    assert!(reader.read_exact(&mut buf).is_ok());
+    let mut buf = [8];
+    assert!(reader.read_exact(&mut buf).is_ok());
+    assert_eq!(buf[0], 0);
+    assert_eq!(reader.len(), 7);
+    let mut buf = [0, 0, 0, 0, 0, 0, 0];
+    assert!(reader.read_exact(&mut buf).is_ok());
+    assert_eq!(buf, [1, 2, 3, 4, 5, 6, 7]);
+    assert_eq!(reader.len(), 0);
+    let mut buf = [0];
+    assert!(reader.read_exact(&mut buf).is_err());
+}
+
+#[test]
+fn test_buf_reader() {
+    let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
+    let mut reader = Cursor::new(&in_buf[..]);
+    let mut buf = [];
+    assert_eq!(reader.read(&mut buf).unwrap(), 0);
+    assert_eq!(reader.position(), 0);
+    let mut buf = [0];
+    assert_eq!(reader.read(&mut buf).unwrap(), 1);
+    assert_eq!(reader.position(), 1);
+    let b: &[_] = &[0];
+    assert_eq!(buf, b);
+    let mut buf = [0; 4];
+    assert_eq!(reader.read(&mut buf).unwrap(), 4);
+    assert_eq!(reader.position(), 5);
+    let b: &[_] = &[1, 2, 3, 4];
+    assert_eq!(buf, b);
+    assert_eq!(reader.read(&mut buf).unwrap(), 3);
+    let b: &[_] = &[5, 6, 7];
+    assert_eq!(&buf[..3], b);
+    assert_eq!(reader.read(&mut buf).unwrap(), 0);
+}
+
+#[test]
+fn seek_past_end() {
+    let buf = [0xff];
+    let mut r = Cursor::new(&buf[..]);
+    assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
+    assert_eq!(r.read(&mut [0]).unwrap(), 0);
+
+    let mut r = Cursor::new(vec![10]);
+    assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
+    assert_eq!(r.read(&mut [0]).unwrap(), 0);
+
+    let mut buf = [0];
+    let mut r = Cursor::new(&mut buf[..]);
+    assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
+    assert_eq!(r.write(&[3]).unwrap(), 0);
+
+    let mut r = Cursor::new(vec![10].into_boxed_slice());
+    assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
+    assert_eq!(r.write(&[3]).unwrap(), 0);
+}
+
+#[test]
+fn seek_past_i64() {
+    let buf = [0xff];
+    let mut r = Cursor::new(&buf[..]);
+    assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6);
+    assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6);
+    assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006);
+    assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006);
+    assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err());
+    assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6);
+
+    let mut r = Cursor::new(vec![10]);
+    assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6);
+    assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6);
+    assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006);
+    assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006);
+    assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err());
+    assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6);
+
+    let mut buf = [0];
+    let mut r = Cursor::new(&mut buf[..]);
+    assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6);
+    assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6);
+    assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006);
+    assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006);
+    assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err());
+    assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6);
+
+    let mut r = Cursor::new(vec![10].into_boxed_slice());
+    assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6);
+    assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6);
+    assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006);
+    assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006);
+    assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err());
+    assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6);
+}
+
+#[test]
+fn seek_before_0() {
+    let buf = [0xff];
+    let mut r = Cursor::new(&buf[..]);
+    assert!(r.seek(SeekFrom::End(-2)).is_err());
+
+    let mut r = Cursor::new(vec![10]);
+    assert!(r.seek(SeekFrom::End(-2)).is_err());
+
+    let mut buf = [0];
+    let mut r = Cursor::new(&mut buf[..]);
+    assert!(r.seek(SeekFrom::End(-2)).is_err());
+
+    let mut r = Cursor::new(vec![10].into_boxed_slice());
+    assert!(r.seek(SeekFrom::End(-2)).is_err());
+}
+
+#[test]
+fn test_seekable_mem_writer() {
+    let mut writer = Cursor::new(Vec::<u8>::new());
+    assert_eq!(writer.position(), 0);
+    assert_eq!(writer.write(&[0]).unwrap(), 1);
+    assert_eq!(writer.position(), 1);
+    assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
+    assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
+    assert_eq!(writer.position(), 8);
+    let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
+    assert_eq!(&writer.get_ref()[..], b);
+
+    assert_eq!(writer.seek(SeekFrom::Start(0)).unwrap(), 0);
+    assert_eq!(writer.position(), 0);
+    assert_eq!(writer.write(&[3, 4]).unwrap(), 2);
+    let b: &[_] = &[3, 4, 2, 3, 4, 5, 6, 7];
+    assert_eq!(&writer.get_ref()[..], b);
+
+    assert_eq!(writer.seek(SeekFrom::Current(1)).unwrap(), 3);
+    assert_eq!(writer.write(&[0, 1]).unwrap(), 2);
+    let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 7];
+    assert_eq!(&writer.get_ref()[..], b);
+
+    assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7);
+    assert_eq!(writer.write(&[1, 2]).unwrap(), 2);
+    let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2];
+    assert_eq!(&writer.get_ref()[..], b);
+
+    assert_eq!(writer.seek(SeekFrom::End(1)).unwrap(), 10);
+    assert_eq!(writer.write(&[1]).unwrap(), 1);
+    let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1];
+    assert_eq!(&writer.get_ref()[..], b);
+}
+
+#[test]
+fn vec_seek_past_end() {
+    let mut r = Cursor::new(Vec::new());
+    assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
+    assert_eq!(r.write(&[3]).unwrap(), 1);
+}
+
+#[test]
+fn vec_seek_before_0() {
+    let mut r = Cursor::new(Vec::new());
+    assert!(r.seek(SeekFrom::End(-2)).is_err());
+}
+
+#[test]
+#[cfg(target_pointer_width = "32")]
+fn vec_seek_and_write_past_usize_max() {
+    let mut c = Cursor::new(Vec::new());
+    c.set_position(usize::MAX as u64 + 1);
+    assert!(c.write_all(&[1, 2, 3]).is_err());
+}
+
+#[test]
+fn test_partial_eq() {
+    assert_eq!(Cursor::new(Vec::<u8>::new()), Cursor::new(Vec::<u8>::new()));
+}
+
+#[test]
+fn test_eq() {
+    struct AssertEq<T: Eq>(pub T);
+
+    let _: AssertEq<Cursor<Vec<u8>>> = AssertEq(Cursor::new(Vec::new()));
+}
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
index e6eda2caf75..ba0f0a0cd71 100644
--- a/library/std/src/io/error.rs
+++ b/library/std/src/io/error.rs
@@ -1,3 +1,6 @@
+#[cfg(test)]
+mod tests;
+
 use crate::convert::From;
 use crate::error;
 use crate::fmt;
@@ -574,60 +577,3 @@ fn _assert_error_is_sync_send() {
     fn _is_sync_send<T: Sync + Send>() {}
     _is_sync_send::<Error>();
 }
-
-#[cfg(test)]
-mod test {
-    use super::{Custom, Error, ErrorKind, Repr};
-    use crate::error;
-    use crate::fmt;
-    use crate::sys::decode_error_kind;
-    use crate::sys::os::error_string;
-
-    #[test]
-    fn test_debug_error() {
-        let code = 6;
-        let msg = error_string(code);
-        let kind = decode_error_kind(code);
-        let err = Error {
-            repr: Repr::Custom(box Custom {
-                kind: ErrorKind::InvalidInput,
-                error: box Error { repr: super::Repr::Os(code) },
-            }),
-        };
-        let expected = format!(
-            "Custom {{ \
-             kind: InvalidInput, \
-             error: Os {{ \
-             code: {:?}, \
-             kind: {:?}, \
-             message: {:?} \
-             }} \
-             }}",
-            code, kind, msg
-        );
-        assert_eq!(format!("{:?}", err), expected);
-    }
-
-    #[test]
-    fn test_downcasting() {
-        #[derive(Debug)]
-        struct TestError;
-
-        impl fmt::Display for TestError {
-            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-                f.write_str("asdf")
-            }
-        }
-
-        impl error::Error for TestError {}
-
-        // we have to call all of these UFCS style right now since method
-        // resolution won't implicitly drop the Send+Sync bounds
-        let mut err = Error::new(ErrorKind::Other, TestError);
-        assert!(err.get_ref().unwrap().is::<TestError>());
-        assert_eq!("asdf", err.get_ref().unwrap().to_string());
-        assert!(err.get_mut().unwrap().is::<TestError>());
-        let extracted = err.into_inner().unwrap();
-        extracted.downcast::<TestError>().unwrap();
-    }
-}
diff --git a/library/std/src/io/error/tests.rs b/library/std/src/io/error/tests.rs
new file mode 100644
index 00000000000..0cce9368c80
--- /dev/null
+++ b/library/std/src/io/error/tests.rs
@@ -0,0 +1,53 @@
+use super::{Custom, Error, ErrorKind, Repr};
+use crate::error;
+use crate::fmt;
+use crate::sys::decode_error_kind;
+use crate::sys::os::error_string;
+
+#[test]
+fn test_debug_error() {
+    let code = 6;
+    let msg = error_string(code);
+    let kind = decode_error_kind(code);
+    let err = Error {
+        repr: Repr::Custom(box Custom {
+            kind: ErrorKind::InvalidInput,
+            error: box Error { repr: super::Repr::Os(code) },
+        }),
+    };
+    let expected = format!(
+        "Custom {{ \
+         kind: InvalidInput, \
+         error: Os {{ \
+         code: {:?}, \
+         kind: {:?}, \
+         message: {:?} \
+         }} \
+         }}",
+        code, kind, msg
+    );
+    assert_eq!(format!("{:?}", err), expected);
+}
+
+#[test]
+fn test_downcasting() {
+    #[derive(Debug)]
+    struct TestError;
+
+    impl fmt::Display for TestError {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            f.write_str("asdf")
+        }
+    }
+
+    impl error::Error for TestError {}
+
+    // we have to call all of these UFCS style right now since method
+    // resolution won't implicitly drop the Send+Sync bounds
+    let mut err = Error::new(ErrorKind::Other, TestError);
+    assert!(err.get_ref().unwrap().is::<TestError>());
+    assert_eq!("asdf", err.get_ref().unwrap().to_string());
+    assert!(err.get_mut().unwrap().is::<TestError>());
+    let extracted = err.into_inner().unwrap();
+    extracted.downcast::<TestError>().unwrap();
+}
diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs
index 01dff0b3eb3..e09e7ba978e 100644
--- a/library/std/src/io/impls.rs
+++ b/library/std/src/io/impls.rs
@@ -1,3 +1,6 @@
+#[cfg(test)]
+mod tests;
+
 use crate::cmp;
 use crate::fmt;
 use crate::io::{
@@ -397,64 +400,3 @@ impl Write for Vec<u8> {
         Ok(())
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use crate::io::prelude::*;
-
-    #[bench]
-    fn bench_read_slice(b: &mut test::Bencher) {
-        let buf = [5; 1024];
-        let mut dst = [0; 128];
-
-        b.iter(|| {
-            let mut rd = &buf[..];
-            for _ in 0..8 {
-                let _ = rd.read(&mut dst);
-                test::black_box(&dst);
-            }
-        })
-    }
-
-    #[bench]
-    fn bench_write_slice(b: &mut test::Bencher) {
-        let mut buf = [0; 1024];
-        let src = [5; 128];
-
-        b.iter(|| {
-            let mut wr = &mut buf[..];
-            for _ in 0..8 {
-                let _ = wr.write_all(&src);
-                test::black_box(&wr);
-            }
-        })
-    }
-
-    #[bench]
-    fn bench_read_vec(b: &mut test::Bencher) {
-        let buf = vec![5; 1024];
-        let mut dst = [0; 128];
-
-        b.iter(|| {
-            let mut rd = &buf[..];
-            for _ in 0..8 {
-                let _ = rd.read(&mut dst);
-                test::black_box(&dst);
-            }
-        })
-    }
-
-    #[bench]
-    fn bench_write_vec(b: &mut test::Bencher) {
-        let mut buf = Vec::with_capacity(1024);
-        let src = [5; 128];
-
-        b.iter(|| {
-            let mut wr = &mut buf[..];
-            for _ in 0..8 {
-                let _ = wr.write_all(&src);
-                test::black_box(&wr);
-            }
-        })
-    }
-}
diff --git a/library/std/src/io/impls/tests.rs b/library/std/src/io/impls/tests.rs
new file mode 100644
index 00000000000..d1cd84a67ad
--- /dev/null
+++ b/library/std/src/io/impls/tests.rs
@@ -0,0 +1,57 @@
+use crate::io::prelude::*;
+
+#[bench]
+fn bench_read_slice(b: &mut test::Bencher) {
+    let buf = [5; 1024];
+    let mut dst = [0; 128];
+
+    b.iter(|| {
+        let mut rd = &buf[..];
+        for _ in 0..8 {
+            let _ = rd.read(&mut dst);
+            test::black_box(&dst);
+        }
+    })
+}
+
+#[bench]
+fn bench_write_slice(b: &mut test::Bencher) {
+    let mut buf = [0; 1024];
+    let src = [5; 128];
+
+    b.iter(|| {
+        let mut wr = &mut buf[..];
+        for _ in 0..8 {
+            let _ = wr.write_all(&src);
+            test::black_box(&wr);
+        }
+    })
+}
+
+#[bench]
+fn bench_read_vec(b: &mut test::Bencher) {
+    let buf = vec![5; 1024];
+    let mut dst = [0; 128];
+
+    b.iter(|| {
+        let mut rd = &buf[..];
+        for _ in 0..8 {
+            let _ = rd.read(&mut dst);
+            test::black_box(&dst);
+        }
+    })
+}
+
+#[bench]
+fn bench_write_vec(b: &mut test::Bencher) {
+    let mut buf = Vec::with_capacity(1024);
+    let src = [5; 128];
+
+    b.iter(|| {
+        let mut wr = &mut buf[..];
+        for _ in 0..8 {
+            let _ = wr.write_all(&src);
+            test::black_box(&wr);
+        }
+    })
+}
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 462b696db40..adea8a804e3 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -249,6 +249,9 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+#[cfg(test)]
+mod tests;
+
 use crate::cmp;
 use crate::fmt;
 use crate::memchr;
@@ -2481,501 +2484,3 @@ impl<B: BufRead> Iterator for Lines<B> {
         }
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use super::{repeat, Cursor, SeekFrom};
-    use crate::cmp::{self, min};
-    use crate::io::prelude::*;
-    use crate::io::{self, IoSlice, IoSliceMut};
-    use crate::ops::Deref;
-
-    #[test]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    fn read_until() {
-        let mut buf = Cursor::new(&b"12"[..]);
-        let mut v = Vec::new();
-        assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 2);
-        assert_eq!(v, b"12");
-
-        let mut buf = Cursor::new(&b"1233"[..]);
-        let mut v = Vec::new();
-        assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 3);
-        assert_eq!(v, b"123");
-        v.truncate(0);
-        assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 1);
-        assert_eq!(v, b"3");
-        v.truncate(0);
-        assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 0);
-        assert_eq!(v, []);
-    }
-
-    #[test]
-    fn split() {
-        let buf = Cursor::new(&b"12"[..]);
-        let mut s = buf.split(b'3');
-        assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']);
-        assert!(s.next().is_none());
-
-        let buf = Cursor::new(&b"1233"[..]);
-        let mut s = buf.split(b'3');
-        assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']);
-        assert_eq!(s.next().unwrap().unwrap(), vec![]);
-        assert!(s.next().is_none());
-    }
-
-    #[test]
-    fn read_line() {
-        let mut buf = Cursor::new(&b"12"[..]);
-        let mut v = String::new();
-        assert_eq!(buf.read_line(&mut v).unwrap(), 2);
-        assert_eq!(v, "12");
-
-        let mut buf = Cursor::new(&b"12\n\n"[..]);
-        let mut v = String::new();
-        assert_eq!(buf.read_line(&mut v).unwrap(), 3);
-        assert_eq!(v, "12\n");
-        v.truncate(0);
-        assert_eq!(buf.read_line(&mut v).unwrap(), 1);
-        assert_eq!(v, "\n");
-        v.truncate(0);
-        assert_eq!(buf.read_line(&mut v).unwrap(), 0);
-        assert_eq!(v, "");
-    }
-
-    #[test]
-    fn lines() {
-        let buf = Cursor::new(&b"12\r"[..]);
-        let mut s = buf.lines();
-        assert_eq!(s.next().unwrap().unwrap(), "12\r".to_string());
-        assert!(s.next().is_none());
-
-        let buf = Cursor::new(&b"12\r\n\n"[..]);
-        let mut s = buf.lines();
-        assert_eq!(s.next().unwrap().unwrap(), "12".to_string());
-        assert_eq!(s.next().unwrap().unwrap(), "".to_string());
-        assert!(s.next().is_none());
-    }
-
-    #[test]
-    fn read_to_end() {
-        let mut c = Cursor::new(&b""[..]);
-        let mut v = Vec::new();
-        assert_eq!(c.read_to_end(&mut v).unwrap(), 0);
-        assert_eq!(v, []);
-
-        let mut c = Cursor::new(&b"1"[..]);
-        let mut v = Vec::new();
-        assert_eq!(c.read_to_end(&mut v).unwrap(), 1);
-        assert_eq!(v, b"1");
-
-        let cap = 1024 * 1024;
-        let data = (0..cap).map(|i| (i / 3) as u8).collect::<Vec<_>>();
-        let mut v = Vec::new();
-        let (a, b) = data.split_at(data.len() / 2);
-        assert_eq!(Cursor::new(a).read_to_end(&mut v).unwrap(), a.len());
-        assert_eq!(Cursor::new(b).read_to_end(&mut v).unwrap(), b.len());
-        assert_eq!(v, data);
-    }
-
-    #[test]
-    fn read_to_string() {
-        let mut c = Cursor::new(&b""[..]);
-        let mut v = String::new();
-        assert_eq!(c.read_to_string(&mut v).unwrap(), 0);
-        assert_eq!(v, "");
-
-        let mut c = Cursor::new(&b"1"[..]);
-        let mut v = String::new();
-        assert_eq!(c.read_to_string(&mut v).unwrap(), 1);
-        assert_eq!(v, "1");
-
-        let mut c = Cursor::new(&b"\xff"[..]);
-        let mut v = String::new();
-        assert!(c.read_to_string(&mut v).is_err());
-    }
-
-    #[test]
-    fn read_exact() {
-        let mut buf = [0; 4];
-
-        let mut c = Cursor::new(&b""[..]);
-        assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
-
-        let mut c = Cursor::new(&b"123"[..]).chain(Cursor::new(&b"456789"[..]));
-        c.read_exact(&mut buf).unwrap();
-        assert_eq!(&buf, b"1234");
-        c.read_exact(&mut buf).unwrap();
-        assert_eq!(&buf, b"5678");
-        assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
-    }
-
-    #[test]
-    fn read_exact_slice() {
-        let mut buf = [0; 4];
-
-        let mut c = &b""[..];
-        assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
-
-        let mut c = &b"123"[..];
-        assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
-        // make sure the optimized (early returning) method is being used
-        assert_eq!(&buf, &[0; 4]);
-
-        let mut c = &b"1234"[..];
-        c.read_exact(&mut buf).unwrap();
-        assert_eq!(&buf, b"1234");
-
-        let mut c = &b"56789"[..];
-        c.read_exact(&mut buf).unwrap();
-        assert_eq!(&buf, b"5678");
-        assert_eq!(c, b"9");
-    }
-
-    #[test]
-    fn take_eof() {
-        struct R;
-
-        impl Read for R {
-            fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
-                Err(io::Error::new(io::ErrorKind::Other, ""))
-            }
-        }
-        impl BufRead for R {
-            fn fill_buf(&mut self) -> io::Result<&[u8]> {
-                Err(io::Error::new(io::ErrorKind::Other, ""))
-            }
-            fn consume(&mut self, _amt: usize) {}
-        }
-
-        let mut buf = [0; 1];
-        assert_eq!(0, R.take(0).read(&mut buf).unwrap());
-        assert_eq!(b"", R.take(0).fill_buf().unwrap());
-    }
-
-    fn cmp_bufread<Br1: BufRead, Br2: BufRead>(mut br1: Br1, mut br2: Br2, exp: &[u8]) {
-        let mut cat = Vec::new();
-        loop {
-            let consume = {
-                let buf1 = br1.fill_buf().unwrap();
-                let buf2 = br2.fill_buf().unwrap();
-                let minlen = if buf1.len() < buf2.len() { buf1.len() } else { buf2.len() };
-                assert_eq!(buf1[..minlen], buf2[..minlen]);
-                cat.extend_from_slice(&buf1[..minlen]);
-                minlen
-            };
-            if consume == 0 {
-                break;
-            }
-            br1.consume(consume);
-            br2.consume(consume);
-        }
-        assert_eq!(br1.fill_buf().unwrap().len(), 0);
-        assert_eq!(br2.fill_buf().unwrap().len(), 0);
-        assert_eq!(&cat[..], &exp[..])
-    }
-
-    #[test]
-    fn chain_bufread() {
-        let testdata = b"ABCDEFGHIJKL";
-        let chain1 =
-            (&testdata[..3]).chain(&testdata[3..6]).chain(&testdata[6..9]).chain(&testdata[9..]);
-        let chain2 = (&testdata[..4]).chain(&testdata[4..8]).chain(&testdata[8..]);
-        cmp_bufread(chain1, chain2, &testdata[..]);
-    }
-
-    #[test]
-    fn chain_zero_length_read_is_not_eof() {
-        let a = b"A";
-        let b = b"B";
-        let mut s = String::new();
-        let mut chain = (&a[..]).chain(&b[..]);
-        chain.read(&mut []).unwrap();
-        chain.read_to_string(&mut s).unwrap();
-        assert_eq!("AB", s);
-    }
-
-    #[bench]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    fn bench_read_to_end(b: &mut test::Bencher) {
-        b.iter(|| {
-            let mut lr = repeat(1).take(10000000);
-            let mut vec = Vec::with_capacity(1024);
-            super::read_to_end(&mut lr, &mut vec)
-        });
-    }
-
-    #[test]
-    fn seek_len() -> io::Result<()> {
-        let mut c = Cursor::new(vec![0; 15]);
-        assert_eq!(c.stream_len()?, 15);
-
-        c.seek(SeekFrom::End(0))?;
-        let old_pos = c.stream_position()?;
-        assert_eq!(c.stream_len()?, 15);
-        assert_eq!(c.stream_position()?, old_pos);
-
-        c.seek(SeekFrom::Start(7))?;
-        c.seek(SeekFrom::Current(2))?;
-        let old_pos = c.stream_position()?;
-        assert_eq!(c.stream_len()?, 15);
-        assert_eq!(c.stream_position()?, old_pos);
-
-        Ok(())
-    }
-
-    #[test]
-    fn seek_position() -> io::Result<()> {
-        // All `asserts` are duplicated here to make sure the method does not
-        // change anything about the seek state.
-        let mut c = Cursor::new(vec![0; 15]);
-        assert_eq!(c.stream_position()?, 0);
-        assert_eq!(c.stream_position()?, 0);
-
-        c.seek(SeekFrom::End(0))?;
-        assert_eq!(c.stream_position()?, 15);
-        assert_eq!(c.stream_position()?, 15);
-
-        c.seek(SeekFrom::Start(7))?;
-        c.seek(SeekFrom::Current(2))?;
-        assert_eq!(c.stream_position()?, 9);
-        assert_eq!(c.stream_position()?, 9);
-
-        c.seek(SeekFrom::End(-3))?;
-        c.seek(SeekFrom::Current(1))?;
-        c.seek(SeekFrom::Current(-5))?;
-        assert_eq!(c.stream_position()?, 8);
-        assert_eq!(c.stream_position()?, 8);
-
-        Ok(())
-    }
-
-    // A simple example reader which uses the default implementation of
-    // read_to_end.
-    struct ExampleSliceReader<'a> {
-        slice: &'a [u8],
-    }
-
-    impl<'a> Read for ExampleSliceReader<'a> {
-        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-            let len = cmp::min(self.slice.len(), buf.len());
-            buf[..len].copy_from_slice(&self.slice[..len]);
-            self.slice = &self.slice[len..];
-            Ok(len)
-        }
-    }
-
-    #[test]
-    fn test_read_to_end_capacity() -> io::Result<()> {
-        let input = &b"foo"[..];
-
-        // read_to_end() generally needs to over-allocate, both for efficiency
-        // and so that it can distinguish EOF. Assert that this is the case
-        // with this simple ExampleSliceReader struct, which uses the default
-        // implementation of read_to_end. Even though vec1 is allocated with
-        // exactly enough capacity for the read, read_to_end will allocate more
-        // space here.
-        let mut vec1 = Vec::with_capacity(input.len());
-        ExampleSliceReader { slice: input }.read_to_end(&mut vec1)?;
-        assert_eq!(vec1.len(), input.len());
-        assert!(vec1.capacity() > input.len(), "allocated more");
-
-        // However, std::io::Take includes an implementation of read_to_end
-        // that will not allocate when the limit has already been reached. In
-        // this case, vec2 never grows.
-        let mut vec2 = Vec::with_capacity(input.len());
-        ExampleSliceReader { slice: input }.take(input.len() as u64).read_to_end(&mut vec2)?;
-        assert_eq!(vec2.len(), input.len());
-        assert_eq!(vec2.capacity(), input.len(), "did not allocate more");
-
-        Ok(())
-    }
-
-    #[test]
-    fn io_slice_mut_advance() {
-        let mut buf1 = [1; 8];
-        let mut buf2 = [2; 16];
-        let mut buf3 = [3; 8];
-        let mut bufs = &mut [
-            IoSliceMut::new(&mut buf1),
-            IoSliceMut::new(&mut buf2),
-            IoSliceMut::new(&mut buf3),
-        ][..];
-
-        // Only in a single buffer..
-        bufs = IoSliceMut::advance(bufs, 1);
-        assert_eq!(bufs[0].deref(), [1; 7].as_ref());
-        assert_eq!(bufs[1].deref(), [2; 16].as_ref());
-        assert_eq!(bufs[2].deref(), [3; 8].as_ref());
-
-        // Removing a buffer, leaving others as is.
-        bufs = IoSliceMut::advance(bufs, 7);
-        assert_eq!(bufs[0].deref(), [2; 16].as_ref());
-        assert_eq!(bufs[1].deref(), [3; 8].as_ref());
-
-        // Removing a buffer and removing from the next buffer.
-        bufs = IoSliceMut::advance(bufs, 18);
-        assert_eq!(bufs[0].deref(), [3; 6].as_ref());
-    }
-
-    #[test]
-    fn io_slice_mut_advance_empty_slice() {
-        let empty_bufs = &mut [][..];
-        // Shouldn't panic.
-        IoSliceMut::advance(empty_bufs, 1);
-    }
-
-    #[test]
-    fn io_slice_mut_advance_beyond_total_length() {
-        let mut buf1 = [1; 8];
-        let mut bufs = &mut [IoSliceMut::new(&mut buf1)][..];
-
-        // Going beyond the total length should be ok.
-        bufs = IoSliceMut::advance(bufs, 9);
-        assert!(bufs.is_empty());
-    }
-
-    #[test]
-    fn io_slice_advance() {
-        let buf1 = [1; 8];
-        let buf2 = [2; 16];
-        let buf3 = [3; 8];
-        let mut bufs = &mut [IoSlice::new(&buf1), IoSlice::new(&buf2), IoSlice::new(&buf3)][..];
-
-        // Only in a single buffer..
-        bufs = IoSlice::advance(bufs, 1);
-        assert_eq!(bufs[0].deref(), [1; 7].as_ref());
-        assert_eq!(bufs[1].deref(), [2; 16].as_ref());
-        assert_eq!(bufs[2].deref(), [3; 8].as_ref());
-
-        // Removing a buffer, leaving others as is.
-        bufs = IoSlice::advance(bufs, 7);
-        assert_eq!(bufs[0].deref(), [2; 16].as_ref());
-        assert_eq!(bufs[1].deref(), [3; 8].as_ref());
-
-        // Removing a buffer and removing from the next buffer.
-        bufs = IoSlice::advance(bufs, 18);
-        assert_eq!(bufs[0].deref(), [3; 6].as_ref());
-    }
-
-    #[test]
-    fn io_slice_advance_empty_slice() {
-        let empty_bufs = &mut [][..];
-        // Shouldn't panic.
-        IoSlice::advance(empty_bufs, 1);
-    }
-
-    #[test]
-    fn io_slice_advance_beyond_total_length() {
-        let buf1 = [1; 8];
-        let mut bufs = &mut [IoSlice::new(&buf1)][..];
-
-        // Going beyond the total length should be ok.
-        bufs = IoSlice::advance(bufs, 9);
-        assert!(bufs.is_empty());
-    }
-
-    /// Create a new writer that reads from at most `n_bufs` and reads
-    /// `per_call` bytes (in total) per call to write.
-    fn test_writer(n_bufs: usize, per_call: usize) -> TestWriter {
-        TestWriter { n_bufs, per_call, written: Vec::new() }
-    }
-
-    struct TestWriter {
-        n_bufs: usize,
-        per_call: usize,
-        written: Vec<u8>,
-    }
-
-    impl Write for TestWriter {
-        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-            self.write_vectored(&[IoSlice::new(buf)])
-        }
-
-        fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-            let mut left = self.per_call;
-            let mut written = 0;
-            for buf in bufs.iter().take(self.n_bufs) {
-                let n = min(left, buf.len());
-                self.written.extend_from_slice(&buf[0..n]);
-                left -= n;
-                written += n;
-            }
-            Ok(written)
-        }
-
-        fn flush(&mut self) -> io::Result<()> {
-            Ok(())
-        }
-    }
-
-    #[test]
-    fn test_writer_read_from_one_buf() {
-        let mut writer = test_writer(1, 2);
-
-        assert_eq!(writer.write(&[]).unwrap(), 0);
-        assert_eq!(writer.write_vectored(&[]).unwrap(), 0);
-
-        // Read at most 2 bytes.
-        assert_eq!(writer.write(&[1, 1, 1]).unwrap(), 2);
-        let bufs = &[IoSlice::new(&[2, 2, 2])];
-        assert_eq!(writer.write_vectored(bufs).unwrap(), 2);
-
-        // Only read from first buf.
-        let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4, 4])];
-        assert_eq!(writer.write_vectored(bufs).unwrap(), 1);
-
-        assert_eq!(writer.written, &[1, 1, 2, 2, 3]);
-    }
-
-    #[test]
-    fn test_writer_read_from_multiple_bufs() {
-        let mut writer = test_writer(3, 3);
-
-        // Read at most 3 bytes from two buffers.
-        let bufs = &[IoSlice::new(&[1]), IoSlice::new(&[2, 2, 2])];
-        assert_eq!(writer.write_vectored(bufs).unwrap(), 3);
-
-        // Read at most 3 bytes from three buffers.
-        let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4]), IoSlice::new(&[5, 5])];
-        assert_eq!(writer.write_vectored(bufs).unwrap(), 3);
-
-        assert_eq!(writer.written, &[1, 2, 2, 3, 4, 5]);
-    }
-
-    #[test]
-    fn test_write_all_vectored() {
-        #[rustfmt::skip] // Becomes unreadable otherwise.
-        let tests: Vec<(_, &'static [u8])> = vec![
-            (vec![], &[]),
-            (vec![IoSlice::new(&[]), IoSlice::new(&[])], &[]),
-            (vec![IoSlice::new(&[1])], &[1]),
-            (vec![IoSlice::new(&[1, 2])], &[1, 2]),
-            (vec![IoSlice::new(&[1, 2, 3])], &[1, 2, 3]),
-            (vec![IoSlice::new(&[1, 2, 3, 4])], &[1, 2, 3, 4]),
-            (vec![IoSlice::new(&[1, 2, 3, 4, 5])], &[1, 2, 3, 4, 5]),
-            (vec![IoSlice::new(&[1]), IoSlice::new(&[2])], &[1, 2]),
-            (vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2])], &[1, 2, 2]),
-            (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2])], &[1, 1, 2, 2]),
-            (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]),
-            (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]),
-            (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 1, 2, 2, 2]),
-            (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 2, 2, 2, 2]),
-            (vec![IoSlice::new(&[1, 1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 1, 2, 2, 2, 2]),
-            (vec![IoSlice::new(&[1]), IoSlice::new(&[2]), IoSlice::new(&[3])], &[1, 2, 3]),
-            (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3])], &[1, 1, 2, 2, 3, 3]),
-            (vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 2, 2, 3, 3, 3]),
-            (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 1, 1, 2, 2, 2, 3, 3, 3]),
-        ];
-
-        let writer_configs = &[(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)];
-
-        for (n_bufs, per_call) in writer_configs.iter().copied() {
-            for (mut input, wanted) in tests.clone().into_iter() {
-                let mut writer = test_writer(n_bufs, per_call);
-                assert!(writer.write_all_vectored(&mut *input).is_ok());
-                assert_eq!(&*writer.written, &*wanted);
-            }
-        }
-    }
-}
diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs
index 3943c66aad5..9974b65f1e1 100644
--- a/library/std/src/io/stdio.rs
+++ b/library/std/src/io/stdio.rs
@@ -1,5 +1,8 @@
 #![cfg_attr(test, allow(unused))]
 
+#[cfg(test)]
+mod tests;
+
 use crate::io::prelude::*;
 
 use crate::cell::RefCell;
@@ -920,54 +923,3 @@ pub fn _eprint(args: fmt::Arguments<'_>) {
 
 #[cfg(test)]
 pub use realstd::io::{_eprint, _print};
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::panic::{RefUnwindSafe, UnwindSafe};
-    use crate::thread;
-
-    #[test]
-    fn stdout_unwind_safe() {
-        assert_unwind_safe::<Stdout>();
-    }
-    #[test]
-    fn stdoutlock_unwind_safe() {
-        assert_unwind_safe::<StdoutLock<'_>>();
-        assert_unwind_safe::<StdoutLock<'static>>();
-    }
-    #[test]
-    fn stderr_unwind_safe() {
-        assert_unwind_safe::<Stderr>();
-    }
-    #[test]
-    fn stderrlock_unwind_safe() {
-        assert_unwind_safe::<StderrLock<'_>>();
-        assert_unwind_safe::<StderrLock<'static>>();
-    }
-
-    fn assert_unwind_safe<T: UnwindSafe + RefUnwindSafe>() {}
-
-    #[test]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    fn panic_doesnt_poison() {
-        thread::spawn(|| {
-            let _a = stdin();
-            let _a = _a.lock();
-            let _a = stdout();
-            let _a = _a.lock();
-            let _a = stderr();
-            let _a = _a.lock();
-            panic!();
-        })
-        .join()
-        .unwrap_err();
-
-        let _a = stdin();
-        let _a = _a.lock();
-        let _a = stdout();
-        let _a = _a.lock();
-        let _a = stderr();
-        let _a = _a.lock();
-    }
-}
diff --git a/library/std/src/io/stdio/tests.rs b/library/std/src/io/stdio/tests.rs
new file mode 100644
index 00000000000..04af500268f
--- /dev/null
+++ b/library/std/src/io/stdio/tests.rs
@@ -0,0 +1,47 @@
+use super::*;
+use crate::panic::{RefUnwindSafe, UnwindSafe};
+use crate::thread;
+
+#[test]
+fn stdout_unwind_safe() {
+    assert_unwind_safe::<Stdout>();
+}
+#[test]
+fn stdoutlock_unwind_safe() {
+    assert_unwind_safe::<StdoutLock<'_>>();
+    assert_unwind_safe::<StdoutLock<'static>>();
+}
+#[test]
+fn stderr_unwind_safe() {
+    assert_unwind_safe::<Stderr>();
+}
+#[test]
+fn stderrlock_unwind_safe() {
+    assert_unwind_safe::<StderrLock<'_>>();
+    assert_unwind_safe::<StderrLock<'static>>();
+}
+
+fn assert_unwind_safe<T: UnwindSafe + RefUnwindSafe>() {}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn panic_doesnt_poison() {
+    thread::spawn(|| {
+        let _a = stdin();
+        let _a = _a.lock();
+        let _a = stdout();
+        let _a = _a.lock();
+        let _a = stderr();
+        let _a = _a.lock();
+        panic!();
+    })
+    .join()
+    .unwrap_err();
+
+    let _a = stdin();
+    let _a = _a.lock();
+    let _a = stdout();
+    let _a = _a.lock();
+    let _a = stderr();
+    let _a = _a.lock();
+}
diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs
new file mode 100644
index 00000000000..913b28538b7
--- /dev/null
+++ b/library/std/src/io/tests.rs
@@ -0,0 +1,494 @@
+use super::{repeat, Cursor, SeekFrom};
+use crate::cmp::{self, min};
+use crate::io::prelude::*;
+use crate::io::{self, IoSlice, IoSliceMut};
+use crate::ops::Deref;
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn read_until() {
+    let mut buf = Cursor::new(&b"12"[..]);
+    let mut v = Vec::new();
+    assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 2);
+    assert_eq!(v, b"12");
+
+    let mut buf = Cursor::new(&b"1233"[..]);
+    let mut v = Vec::new();
+    assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 3);
+    assert_eq!(v, b"123");
+    v.truncate(0);
+    assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 1);
+    assert_eq!(v, b"3");
+    v.truncate(0);
+    assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 0);
+    assert_eq!(v, []);
+}
+
+#[test]
+fn split() {
+    let buf = Cursor::new(&b"12"[..]);
+    let mut s = buf.split(b'3');
+    assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']);
+    assert!(s.next().is_none());
+
+    let buf = Cursor::new(&b"1233"[..]);
+    let mut s = buf.split(b'3');
+    assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']);
+    assert_eq!(s.next().unwrap().unwrap(), vec![]);
+    assert!(s.next().is_none());
+}
+
+#[test]
+fn read_line() {
+    let mut buf = Cursor::new(&b"12"[..]);
+    let mut v = String::new();
+    assert_eq!(buf.read_line(&mut v).unwrap(), 2);
+    assert_eq!(v, "12");
+
+    let mut buf = Cursor::new(&b"12\n\n"[..]);
+    let mut v = String::new();
+    assert_eq!(buf.read_line(&mut v).unwrap(), 3);
+    assert_eq!(v, "12\n");
+    v.truncate(0);
+    assert_eq!(buf.read_line(&mut v).unwrap(), 1);
+    assert_eq!(v, "\n");
+    v.truncate(0);
+    assert_eq!(buf.read_line(&mut v).unwrap(), 0);
+    assert_eq!(v, "");
+}
+
+#[test]
+fn lines() {
+    let buf = Cursor::new(&b"12\r"[..]);
+    let mut s = buf.lines();
+    assert_eq!(s.next().unwrap().unwrap(), "12\r".to_string());
+    assert!(s.next().is_none());
+
+    let buf = Cursor::new(&b"12\r\n\n"[..]);
+    let mut s = buf.lines();
+    assert_eq!(s.next().unwrap().unwrap(), "12".to_string());
+    assert_eq!(s.next().unwrap().unwrap(), "".to_string());
+    assert!(s.next().is_none());
+}
+
+#[test]
+fn read_to_end() {
+    let mut c = Cursor::new(&b""[..]);
+    let mut v = Vec::new();
+    assert_eq!(c.read_to_end(&mut v).unwrap(), 0);
+    assert_eq!(v, []);
+
+    let mut c = Cursor::new(&b"1"[..]);
+    let mut v = Vec::new();
+    assert_eq!(c.read_to_end(&mut v).unwrap(), 1);
+    assert_eq!(v, b"1");
+
+    let cap = 1024 * 1024;
+    let data = (0..cap).map(|i| (i / 3) as u8).collect::<Vec<_>>();
+    let mut v = Vec::new();
+    let (a, b) = data.split_at(data.len() / 2);
+    assert_eq!(Cursor::new(a).read_to_end(&mut v).unwrap(), a.len());
+    assert_eq!(Cursor::new(b).read_to_end(&mut v).unwrap(), b.len());
+    assert_eq!(v, data);
+}
+
+#[test]
+fn read_to_string() {
+    let mut c = Cursor::new(&b""[..]);
+    let mut v = String::new();
+    assert_eq!(c.read_to_string(&mut v).unwrap(), 0);
+    assert_eq!(v, "");
+
+    let mut c = Cursor::new(&b"1"[..]);
+    let mut v = String::new();
+    assert_eq!(c.read_to_string(&mut v).unwrap(), 1);
+    assert_eq!(v, "1");
+
+    let mut c = Cursor::new(&b"\xff"[..]);
+    let mut v = String::new();
+    assert!(c.read_to_string(&mut v).is_err());
+}
+
+#[test]
+fn read_exact() {
+    let mut buf = [0; 4];
+
+    let mut c = Cursor::new(&b""[..]);
+    assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
+
+    let mut c = Cursor::new(&b"123"[..]).chain(Cursor::new(&b"456789"[..]));
+    c.read_exact(&mut buf).unwrap();
+    assert_eq!(&buf, b"1234");
+    c.read_exact(&mut buf).unwrap();
+    assert_eq!(&buf, b"5678");
+    assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
+}
+
+#[test]
+fn read_exact_slice() {
+    let mut buf = [0; 4];
+
+    let mut c = &b""[..];
+    assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
+
+    let mut c = &b"123"[..];
+    assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
+    // make sure the optimized (early returning) method is being used
+    assert_eq!(&buf, &[0; 4]);
+
+    let mut c = &b"1234"[..];
+    c.read_exact(&mut buf).unwrap();
+    assert_eq!(&buf, b"1234");
+
+    let mut c = &b"56789"[..];
+    c.read_exact(&mut buf).unwrap();
+    assert_eq!(&buf, b"5678");
+    assert_eq!(c, b"9");
+}
+
+#[test]
+fn take_eof() {
+    struct R;
+
+    impl Read for R {
+        fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
+            Err(io::Error::new(io::ErrorKind::Other, ""))
+        }
+    }
+    impl BufRead for R {
+        fn fill_buf(&mut self) -> io::Result<&[u8]> {
+            Err(io::Error::new(io::ErrorKind::Other, ""))
+        }
+        fn consume(&mut self, _amt: usize) {}
+    }
+
+    let mut buf = [0; 1];
+    assert_eq!(0, R.take(0).read(&mut buf).unwrap());
+    assert_eq!(b"", R.take(0).fill_buf().unwrap());
+}
+
+fn cmp_bufread<Br1: BufRead, Br2: BufRead>(mut br1: Br1, mut br2: Br2, exp: &[u8]) {
+    let mut cat = Vec::new();
+    loop {
+        let consume = {
+            let buf1 = br1.fill_buf().unwrap();
+            let buf2 = br2.fill_buf().unwrap();
+            let minlen = if buf1.len() < buf2.len() { buf1.len() } else { buf2.len() };
+            assert_eq!(buf1[..minlen], buf2[..minlen]);
+            cat.extend_from_slice(&buf1[..minlen]);
+            minlen
+        };
+        if consume == 0 {
+            break;
+        }
+        br1.consume(consume);
+        br2.consume(consume);
+    }
+    assert_eq!(br1.fill_buf().unwrap().len(), 0);
+    assert_eq!(br2.fill_buf().unwrap().len(), 0);
+    assert_eq!(&cat[..], &exp[..])
+}
+
+#[test]
+fn chain_bufread() {
+    let testdata = b"ABCDEFGHIJKL";
+    let chain1 =
+        (&testdata[..3]).chain(&testdata[3..6]).chain(&testdata[6..9]).chain(&testdata[9..]);
+    let chain2 = (&testdata[..4]).chain(&testdata[4..8]).chain(&testdata[8..]);
+    cmp_bufread(chain1, chain2, &testdata[..]);
+}
+
+#[test]
+fn chain_zero_length_read_is_not_eof() {
+    let a = b"A";
+    let b = b"B";
+    let mut s = String::new();
+    let mut chain = (&a[..]).chain(&b[..]);
+    chain.read(&mut []).unwrap();
+    chain.read_to_string(&mut s).unwrap();
+    assert_eq!("AB", s);
+}
+
+#[bench]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn bench_read_to_end(b: &mut test::Bencher) {
+    b.iter(|| {
+        let mut lr = repeat(1).take(10000000);
+        let mut vec = Vec::with_capacity(1024);
+        super::read_to_end(&mut lr, &mut vec)
+    });
+}
+
+#[test]
+fn seek_len() -> io::Result<()> {
+    let mut c = Cursor::new(vec![0; 15]);
+    assert_eq!(c.stream_len()?, 15);
+
+    c.seek(SeekFrom::End(0))?;
+    let old_pos = c.stream_position()?;
+    assert_eq!(c.stream_len()?, 15);
+    assert_eq!(c.stream_position()?, old_pos);
+
+    c.seek(SeekFrom::Start(7))?;
+    c.seek(SeekFrom::Current(2))?;
+    let old_pos = c.stream_position()?;
+    assert_eq!(c.stream_len()?, 15);
+    assert_eq!(c.stream_position()?, old_pos);
+
+    Ok(())
+}
+
+#[test]
+fn seek_position() -> io::Result<()> {
+    // All `asserts` are duplicated here to make sure the method does not
+    // change anything about the seek state.
+    let mut c = Cursor::new(vec![0; 15]);
+    assert_eq!(c.stream_position()?, 0);
+    assert_eq!(c.stream_position()?, 0);
+
+    c.seek(SeekFrom::End(0))?;
+    assert_eq!(c.stream_position()?, 15);
+    assert_eq!(c.stream_position()?, 15);
+
+    c.seek(SeekFrom::Start(7))?;
+    c.seek(SeekFrom::Current(2))?;
+    assert_eq!(c.stream_position()?, 9);
+    assert_eq!(c.stream_position()?, 9);
+
+    c.seek(SeekFrom::End(-3))?;
+    c.seek(SeekFrom::Current(1))?;
+    c.seek(SeekFrom::Current(-5))?;
+    assert_eq!(c.stream_position()?, 8);
+    assert_eq!(c.stream_position()?, 8);
+
+    Ok(())
+}
+
+// A simple example reader which uses the default implementation of
+// read_to_end.
+struct ExampleSliceReader<'a> {
+    slice: &'a [u8],
+}
+
+impl<'a> Read for ExampleSliceReader<'a> {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        let len = cmp::min(self.slice.len(), buf.len());
+        buf[..len].copy_from_slice(&self.slice[..len]);
+        self.slice = &self.slice[len..];
+        Ok(len)
+    }
+}
+
+#[test]
+fn test_read_to_end_capacity() -> io::Result<()> {
+    let input = &b"foo"[..];
+
+    // read_to_end() generally needs to over-allocate, both for efficiency
+    // and so that it can distinguish EOF. Assert that this is the case
+    // with this simple ExampleSliceReader struct, which uses the default
+    // implementation of read_to_end. Even though vec1 is allocated with
+    // exactly enough capacity for the read, read_to_end will allocate more
+    // space here.
+    let mut vec1 = Vec::with_capacity(input.len());
+    ExampleSliceReader { slice: input }.read_to_end(&mut vec1)?;
+    assert_eq!(vec1.len(), input.len());
+    assert!(vec1.capacity() > input.len(), "allocated more");
+
+    // However, std::io::Take includes an implementation of read_to_end
+    // that will not allocate when the limit has already been reached. In
+    // this case, vec2 never grows.
+    let mut vec2 = Vec::with_capacity(input.len());
+    ExampleSliceReader { slice: input }.take(input.len() as u64).read_to_end(&mut vec2)?;
+    assert_eq!(vec2.len(), input.len());
+    assert_eq!(vec2.capacity(), input.len(), "did not allocate more");
+
+    Ok(())
+}
+
+#[test]
+fn io_slice_mut_advance() {
+    let mut buf1 = [1; 8];
+    let mut buf2 = [2; 16];
+    let mut buf3 = [3; 8];
+    let mut bufs = &mut [
+        IoSliceMut::new(&mut buf1),
+        IoSliceMut::new(&mut buf2),
+        IoSliceMut::new(&mut buf3),
+    ][..];
+
+    // Only in a single buffer..
+    bufs = IoSliceMut::advance(bufs, 1);
+    assert_eq!(bufs[0].deref(), [1; 7].as_ref());
+    assert_eq!(bufs[1].deref(), [2; 16].as_ref());
+    assert_eq!(bufs[2].deref(), [3; 8].as_ref());
+
+    // Removing a buffer, leaving others as is.
+    bufs = IoSliceMut::advance(bufs, 7);
+    assert_eq!(bufs[0].deref(), [2; 16].as_ref());
+    assert_eq!(bufs[1].deref(), [3; 8].as_ref());
+
+    // Removing a buffer and removing from the next buffer.
+    bufs = IoSliceMut::advance(bufs, 18);
+    assert_eq!(bufs[0].deref(), [3; 6].as_ref());
+}
+
+#[test]
+fn io_slice_mut_advance_empty_slice() {
+    let empty_bufs = &mut [][..];
+    // Shouldn't panic.
+    IoSliceMut::advance(empty_bufs, 1);
+}
+
+#[test]
+fn io_slice_mut_advance_beyond_total_length() {
+    let mut buf1 = [1; 8];
+    let mut bufs = &mut [IoSliceMut::new(&mut buf1)][..];
+
+    // Going beyond the total length should be ok.
+    bufs = IoSliceMut::advance(bufs, 9);
+    assert!(bufs.is_empty());
+}
+
+#[test]
+fn io_slice_advance() {
+    let buf1 = [1; 8];
+    let buf2 = [2; 16];
+    let buf3 = [3; 8];
+    let mut bufs = &mut [IoSlice::new(&buf1), IoSlice::new(&buf2), IoSlice::new(&buf3)][..];
+
+    // Only in a single buffer..
+    bufs = IoSlice::advance(bufs, 1);
+    assert_eq!(bufs[0].deref(), [1; 7].as_ref());
+    assert_eq!(bufs[1].deref(), [2; 16].as_ref());
+    assert_eq!(bufs[2].deref(), [3; 8].as_ref());
+
+    // Removing a buffer, leaving others as is.
+    bufs = IoSlice::advance(bufs, 7);
+    assert_eq!(bufs[0].deref(), [2; 16].as_ref());
+    assert_eq!(bufs[1].deref(), [3; 8].as_ref());
+
+    // Removing a buffer and removing from the next buffer.
+    bufs = IoSlice::advance(bufs, 18);
+    assert_eq!(bufs[0].deref(), [3; 6].as_ref());
+}
+
+#[test]
+fn io_slice_advance_empty_slice() {
+    let empty_bufs = &mut [][..];
+    // Shouldn't panic.
+    IoSlice::advance(empty_bufs, 1);
+}
+
+#[test]
+fn io_slice_advance_beyond_total_length() {
+    let buf1 = [1; 8];
+    let mut bufs = &mut [IoSlice::new(&buf1)][..];
+
+    // Going beyond the total length should be ok.
+    bufs = IoSlice::advance(bufs, 9);
+    assert!(bufs.is_empty());
+}
+
+/// Create a new writer that reads from at most `n_bufs` and reads
+/// `per_call` bytes (in total) per call to write.
+fn test_writer(n_bufs: usize, per_call: usize) -> TestWriter {
+    TestWriter { n_bufs, per_call, written: Vec::new() }
+}
+
+struct TestWriter {
+    n_bufs: usize,
+    per_call: usize,
+    written: Vec<u8>,
+}
+
+impl Write for TestWriter {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.write_vectored(&[IoSlice::new(buf)])
+    }
+
+    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        let mut left = self.per_call;
+        let mut written = 0;
+        for buf in bufs.iter().take(self.n_bufs) {
+            let n = min(left, buf.len());
+            self.written.extend_from_slice(&buf[0..n]);
+            left -= n;
+            written += n;
+        }
+        Ok(written)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+#[test]
+fn test_writer_read_from_one_buf() {
+    let mut writer = test_writer(1, 2);
+
+    assert_eq!(writer.write(&[]).unwrap(), 0);
+    assert_eq!(writer.write_vectored(&[]).unwrap(), 0);
+
+    // Read at most 2 bytes.
+    assert_eq!(writer.write(&[1, 1, 1]).unwrap(), 2);
+    let bufs = &[IoSlice::new(&[2, 2, 2])];
+    assert_eq!(writer.write_vectored(bufs).unwrap(), 2);
+
+    // Only read from first buf.
+    let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4, 4])];
+    assert_eq!(writer.write_vectored(bufs).unwrap(), 1);
+
+    assert_eq!(writer.written, &[1, 1, 2, 2, 3]);
+}
+
+#[test]
+fn test_writer_read_from_multiple_bufs() {
+    let mut writer = test_writer(3, 3);
+
+    // Read at most 3 bytes from two buffers.
+    let bufs = &[IoSlice::new(&[1]), IoSlice::new(&[2, 2, 2])];
+    assert_eq!(writer.write_vectored(bufs).unwrap(), 3);
+
+    // Read at most 3 bytes from three buffers.
+    let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4]), IoSlice::new(&[5, 5])];
+    assert_eq!(writer.write_vectored(bufs).unwrap(), 3);
+
+    assert_eq!(writer.written, &[1, 2, 2, 3, 4, 5]);
+}
+
+#[test]
+fn test_write_all_vectored() {
+    #[rustfmt::skip] // Becomes unreadable otherwise.
+    let tests: Vec<(_, &'static [u8])> = vec![
+        (vec![], &[]),
+        (vec![IoSlice::new(&[]), IoSlice::new(&[])], &[]),
+        (vec![IoSlice::new(&[1])], &[1]),
+        (vec![IoSlice::new(&[1, 2])], &[1, 2]),
+        (vec![IoSlice::new(&[1, 2, 3])], &[1, 2, 3]),
+        (vec![IoSlice::new(&[1, 2, 3, 4])], &[1, 2, 3, 4]),
+        (vec![IoSlice::new(&[1, 2, 3, 4, 5])], &[1, 2, 3, 4, 5]),
+        (vec![IoSlice::new(&[1]), IoSlice::new(&[2])], &[1, 2]),
+        (vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2])], &[1, 2, 2]),
+        (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2])], &[1, 1, 2, 2]),
+        (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]),
+        (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]),
+        (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 1, 2, 2, 2]),
+        (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 2, 2, 2, 2]),
+        (vec![IoSlice::new(&[1, 1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 1, 2, 2, 2, 2]),
+        (vec![IoSlice::new(&[1]), IoSlice::new(&[2]), IoSlice::new(&[3])], &[1, 2, 3]),
+        (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3])], &[1, 1, 2, 2, 3, 3]),
+        (vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 2, 2, 3, 3, 3]),
+        (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 1, 1, 2, 2, 2, 3, 3, 3]),
+    ];
+
+    let writer_configs = &[(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)];
+
+    for (n_bufs, per_call) in writer_configs.iter().copied() {
+        for (mut input, wanted) in tests.clone().into_iter() {
+            let mut writer = test_writer(n_bufs, per_call);
+            assert!(writer.write_all_vectored(&mut *input).is_ok());
+            assert_eq!(&*writer.written, &*wanted);
+        }
+    }
+}
diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs
index a093b745b0c..44d2937ee1b 100644
--- a/library/std/src/io/util.rs
+++ b/library/std/src/io/util.rs
@@ -1,5 +1,8 @@
 #![allow(missing_copy_implementations)]
 
+#[cfg(test)]
+mod tests;
+
 use crate::fmt;
 use crate::io::{self, BufRead, ErrorKind, Initializer, IoSlice, IoSliceMut, Read, Write};
 use crate::mem::MaybeUninit;
@@ -49,24 +52,27 @@ where
     W: Write,
 {
     let mut buf = MaybeUninit::<[u8; super::DEFAULT_BUF_SIZE]>::uninit();
-    // FIXME(#53491): This is calling `get_mut` and `get_ref` on an uninitialized
-    // `MaybeUninit`. Revisit this once we decided whether that is valid or not.
-    // This is still technically undefined behavior due to creating a reference
-    // to uninitialized data, but within libstd we can rely on more guarantees
-    // than if this code were in an external lib.
+    // FIXME: #42788
+    //
+    //   - This creates a (mut) reference to a slice of
+    //     _uninitialized_ integers, which is **undefined behavior**
+    //
+    //   - Only the standard library gets to soundly "ignore" this,
+    //     based on its privileged knowledge of unstable rustc
+    //     internals;
     unsafe {
-        reader.initializer().initialize(buf.get_mut());
+        reader.initializer().initialize(buf.assume_init_mut());
     }
 
     let mut written = 0;
     loop {
-        let len = match reader.read(unsafe { buf.get_mut() }) {
+        let len = match reader.read(unsafe { buf.assume_init_mut() }) {
             Ok(0) => return Ok(written),
             Ok(len) => len,
             Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
             Err(e) => return Err(e),
         };
-        writer.write_all(unsafe { &buf.get_ref()[..len] })?;
+        writer.write_all(unsafe { &buf.assume_init_ref()[..len] })?;
         written += len as u64;
     }
 }
@@ -254,52 +260,3 @@ impl fmt::Debug for Sink {
         f.pad("Sink { .. }")
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use crate::io::prelude::*;
-    use crate::io::{copy, empty, repeat, sink};
-
-    #[test]
-    fn copy_copies() {
-        let mut r = repeat(0).take(4);
-        let mut w = sink();
-        assert_eq!(copy(&mut r, &mut w).unwrap(), 4);
-
-        let mut r = repeat(0).take(1 << 17);
-        assert_eq!(copy(&mut r as &mut dyn Read, &mut w as &mut dyn Write).unwrap(), 1 << 17);
-    }
-
-    #[test]
-    fn sink_sinks() {
-        let mut s = sink();
-        assert_eq!(s.write(&[]).unwrap(), 0);
-        assert_eq!(s.write(&[0]).unwrap(), 1);
-        assert_eq!(s.write(&[0; 1024]).unwrap(), 1024);
-        assert_eq!(s.by_ref().write(&[0; 1024]).unwrap(), 1024);
-    }
-
-    #[test]
-    fn empty_reads() {
-        let mut e = empty();
-        assert_eq!(e.read(&mut []).unwrap(), 0);
-        assert_eq!(e.read(&mut [0]).unwrap(), 0);
-        assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0);
-        assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0);
-    }
-
-    #[test]
-    fn repeat_repeats() {
-        let mut r = repeat(4);
-        let mut b = [0; 1024];
-        assert_eq!(r.read(&mut b).unwrap(), 1024);
-        assert!(b.iter().all(|b| *b == 4));
-    }
-
-    #[test]
-    fn take_some_bytes() {
-        assert_eq!(repeat(4).take(100).bytes().count(), 100);
-        assert_eq!(repeat(4).take(100).bytes().next().unwrap().unwrap(), 4);
-        assert_eq!(repeat(1).take(10).chain(repeat(2).take(10)).bytes().count(), 20);
-    }
-}
diff --git a/library/std/src/io/util/tests.rs b/library/std/src/io/util/tests.rs
new file mode 100644
index 00000000000..e5e32ecb405
--- /dev/null
+++ b/library/std/src/io/util/tests.rs
@@ -0,0 +1,45 @@
+use crate::io::prelude::*;
+use crate::io::{copy, empty, repeat, sink};
+
+#[test]
+fn copy_copies() {
+    let mut r = repeat(0).take(4);
+    let mut w = sink();
+    assert_eq!(copy(&mut r, &mut w).unwrap(), 4);
+
+    let mut r = repeat(0).take(1 << 17);
+    assert_eq!(copy(&mut r as &mut dyn Read, &mut w as &mut dyn Write).unwrap(), 1 << 17);
+}
+
+#[test]
+fn sink_sinks() {
+    let mut s = sink();
+    assert_eq!(s.write(&[]).unwrap(), 0);
+    assert_eq!(s.write(&[0]).unwrap(), 1);
+    assert_eq!(s.write(&[0; 1024]).unwrap(), 1024);
+    assert_eq!(s.by_ref().write(&[0; 1024]).unwrap(), 1024);
+}
+
+#[test]
+fn empty_reads() {
+    let mut e = empty();
+    assert_eq!(e.read(&mut []).unwrap(), 0);
+    assert_eq!(e.read(&mut [0]).unwrap(), 0);
+    assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0);
+    assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0);
+}
+
+#[test]
+fn repeat_repeats() {
+    let mut r = repeat(4);
+    let mut b = [0; 1024];
+    assert_eq!(r.read(&mut b).unwrap(), 1024);
+    assert!(b.iter().all(|b| *b == 4));
+}
+
+#[test]
+fn take_some_bytes() {
+    assert_eq!(repeat(4).take(100).bytes().count(), 100);
+    assert_eq!(repeat(4).take(100).bytes().next().unwrap().unwrap(), 4);
+    assert_eq!(repeat(1).take(10).chain(repeat(2).take(10)).bytes().count(), 20);
+}
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index af25c39fccf..54ce0e7b831 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -107,7 +107,7 @@ mod break_keyword {}
 /// Sometimes a certain value is used many times throughout a program, and it can become
 /// inconvenient to copy it over and over. What's more, it's not always possible or desirable to
 /// make it a variable that gets carried around to each function that needs it. In these cases, the
-/// `const` keyword provides a convenient alternative to code duplication.
+/// `const` keyword provides a convenient alternative to code duplication:
 ///
 /// ```rust
 /// const THING: u32 = 0xABAD1DEA;
@@ -115,10 +115,12 @@ mod break_keyword {}
 /// let foo = 123 + THING;
 /// ```
 ///
-/// Constants must be explicitly typed, unlike with `let` you can't ignore its type and let the
-/// compiler figure it out. Any constant value can be defined in a const, which in practice happens
-/// to be most things that would be reasonable to have a constant (barring `const fn`s). For
-/// example, you can't have a File as a `const`.
+/// Constants must be explicitly typed; unlike with `let`, you can't ignore their type and let the
+/// compiler figure it out. Any constant value can be defined in a `const`, which in practice happens
+/// to be most things that would be reasonable to have in a constant (barring `const fn`s). For
+/// example, you can't have a [`File`] as a `const`.
+///
+/// [`File`]: crate::fs::File
 ///
 /// The only lifetime allowed in a constant is `'static`, which is the lifetime that encompasses
 /// all others in a Rust program. For example, if you wanted to define a constant string, it would
@@ -128,7 +130,7 @@ mod break_keyword {}
 /// const WORDS: &'static str = "hello rust!";
 /// ```
 ///
-/// Thanks to static lifetime elision, you usually don't have to explicitly use 'static:
+/// Thanks to static lifetime elision, you usually don't have to explicitly use `'static`:
 ///
 /// ```rust
 /// const WORDS: &str = "hello convenience!";
@@ -136,19 +138,19 @@ mod break_keyword {}
 ///
 /// `const` items looks remarkably similar to `static` items, which introduces some confusion as
 /// to which one should be used at which times. To put it simply, constants are inlined wherever
-/// they're used, making using them identical to simply replacing the name of the const with its
-/// value. Static variables on the other hand point to a single location in memory, which all
+/// they're used, making using them identical to simply replacing the name of the `const` with its
+/// value. Static variables, on the other hand, point to a single location in memory, which all
 /// accesses share. This means that, unlike with constants, they can't have destructors, and act as
 /// a single value across the entire codebase.
 ///
-/// Constants, as with statics, should always be in SCREAMING_SNAKE_CASE.
+/// Constants, like statics, should always be in `SCREAMING_SNAKE_CASE`.
 ///
 /// The `const` keyword is also used in raw pointers in combination with `mut`, as seen in `*const
-/// T` and `*mut T`. More about that can be read at the [pointer] primitive part of the Rust docs.
+/// T` and `*mut T`. More about `const` as used in raw pointers can be read at the Rust docs for the [pointer primitive].
 ///
-/// For more detail on `const`, see the [Rust Book] or the [Reference]
+/// For more detail on `const`, see the [Rust Book] or the [Reference].
 ///
-/// [pointer]: primitive.pointer.html
+/// [pointer primitive]: primitive.pointer.html
 /// [Rust Book]:
 /// ../book/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants
 /// [Reference]: ../reference/items/constant-items.html
diff --git a/library/std/src/lazy.rs b/library/std/src/lazy.rs
index d0f27df5185..845e9d76a77 100644
--- a/library/std/src/lazy.rs
+++ b/library/std/src/lazy.rs
@@ -1,5 +1,8 @@
 //! Lazy values and one-time initialization of static data.
 
+#[cfg(test)]
+mod tests;
+
 use crate::{
     cell::{Cell, UnsafeCell},
     fmt,
@@ -376,13 +379,13 @@ impl<T> SyncOnceCell<T> {
     /// Safety: The value must be initialized
     unsafe fn get_unchecked(&self) -> &T {
         debug_assert!(self.is_initialized());
-        (&*self.value.get()).get_ref()
+        (&*self.value.get()).assume_init_ref()
     }
 
     /// Safety: The value must be initialized
     unsafe fn get_unchecked_mut(&mut self) -> &mut T {
         debug_assert!(self.is_initialized());
-        (&mut *self.value.get()).get_mut()
+        (&mut *self.value.get()).assume_init_mut()
     }
 }
 
@@ -506,333 +509,3 @@ impl<T: Default> Default for SyncLazy<T> {
         SyncLazy::new(T::default)
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use crate::{
-        lazy::{Lazy, SyncLazy, SyncOnceCell},
-        panic,
-        sync::{
-            atomic::{AtomicUsize, Ordering::SeqCst},
-            mpsc::channel,
-            Mutex,
-        },
-        thread,
-    };
-
-    #[test]
-    fn lazy_default() {
-        static CALLED: AtomicUsize = AtomicUsize::new(0);
-
-        struct Foo(u8);
-        impl Default for Foo {
-            fn default() -> Self {
-                CALLED.fetch_add(1, SeqCst);
-                Foo(42)
-            }
-        }
-
-        let lazy: Lazy<Mutex<Foo>> = <_>::default();
-
-        assert_eq!(CALLED.load(SeqCst), 0);
-
-        assert_eq!(lazy.lock().unwrap().0, 42);
-        assert_eq!(CALLED.load(SeqCst), 1);
-
-        lazy.lock().unwrap().0 = 21;
-
-        assert_eq!(lazy.lock().unwrap().0, 21);
-        assert_eq!(CALLED.load(SeqCst), 1);
-    }
-
-    #[test]
-    fn lazy_poisoning() {
-        let x: Lazy<String> = Lazy::new(|| panic!("kaboom"));
-        for _ in 0..2 {
-            let res = panic::catch_unwind(panic::AssertUnwindSafe(|| x.len()));
-            assert!(res.is_err());
-        }
-    }
-
-    fn spawn_and_wait<R: Send + 'static>(f: impl FnOnce() -> R + Send + 'static) -> R {
-        thread::spawn(f).join().unwrap()
-    }
-
-    #[test]
-    fn sync_once_cell() {
-        static ONCE_CELL: SyncOnceCell<i32> = SyncOnceCell::new();
-
-        assert!(ONCE_CELL.get().is_none());
-
-        spawn_and_wait(|| {
-            ONCE_CELL.get_or_init(|| 92);
-            assert_eq!(ONCE_CELL.get(), Some(&92));
-        });
-
-        ONCE_CELL.get_or_init(|| panic!("Kabom!"));
-        assert_eq!(ONCE_CELL.get(), Some(&92));
-    }
-
-    #[test]
-    fn sync_once_cell_get_mut() {
-        let mut c = SyncOnceCell::new();
-        assert!(c.get_mut().is_none());
-        c.set(90).unwrap();
-        *c.get_mut().unwrap() += 2;
-        assert_eq!(c.get_mut(), Some(&mut 92));
-    }
-
-    #[test]
-    fn sync_once_cell_get_unchecked() {
-        let c = SyncOnceCell::new();
-        c.set(92).unwrap();
-        unsafe {
-            assert_eq!(c.get_unchecked(), &92);
-        }
-    }
-
-    #[test]
-    fn sync_once_cell_drop() {
-        static DROP_CNT: AtomicUsize = AtomicUsize::new(0);
-        struct Dropper;
-        impl Drop for Dropper {
-            fn drop(&mut self) {
-                DROP_CNT.fetch_add(1, SeqCst);
-            }
-        }
-
-        let x = SyncOnceCell::new();
-        spawn_and_wait(move || {
-            x.get_or_init(|| Dropper);
-            assert_eq!(DROP_CNT.load(SeqCst), 0);
-            drop(x);
-        });
-
-        assert_eq!(DROP_CNT.load(SeqCst), 1);
-    }
-
-    #[test]
-    fn sync_once_cell_drop_empty() {
-        let x = SyncOnceCell::<String>::new();
-        drop(x);
-    }
-
-    #[test]
-    fn clone() {
-        let s = SyncOnceCell::new();
-        let c = s.clone();
-        assert!(c.get().is_none());
-
-        s.set("hello".to_string()).unwrap();
-        let c = s.clone();
-        assert_eq!(c.get().map(String::as_str), Some("hello"));
-    }
-
-    #[test]
-    fn get_or_try_init() {
-        let cell: SyncOnceCell<String> = SyncOnceCell::new();
-        assert!(cell.get().is_none());
-
-        let res = panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() }));
-        assert!(res.is_err());
-        assert!(!cell.is_initialized());
-        assert!(cell.get().is_none());
-
-        assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
-
-        assert_eq!(
-            cell.get_or_try_init(|| Ok::<_, ()>("hello".to_string())),
-            Ok(&"hello".to_string())
-        );
-        assert_eq!(cell.get(), Some(&"hello".to_string()));
-    }
-
-    #[test]
-    fn from_impl() {
-        assert_eq!(SyncOnceCell::from("value").get(), Some(&"value"));
-        assert_ne!(SyncOnceCell::from("foo").get(), Some(&"bar"));
-    }
-
-    #[test]
-    fn partialeq_impl() {
-        assert!(SyncOnceCell::from("value") == SyncOnceCell::from("value"));
-        assert!(SyncOnceCell::from("foo") != SyncOnceCell::from("bar"));
-
-        assert!(SyncOnceCell::<String>::new() == SyncOnceCell::new());
-        assert!(SyncOnceCell::<String>::new() != SyncOnceCell::from("value".to_owned()));
-    }
-
-    #[test]
-    fn into_inner() {
-        let cell: SyncOnceCell<String> = SyncOnceCell::new();
-        assert_eq!(cell.into_inner(), None);
-        let cell = SyncOnceCell::new();
-        cell.set("hello".to_string()).unwrap();
-        assert_eq!(cell.into_inner(), Some("hello".to_string()));
-    }
-
-    #[test]
-    fn sync_lazy_new() {
-        static CALLED: AtomicUsize = AtomicUsize::new(0);
-        static SYNC_LAZY: SyncLazy<i32> = SyncLazy::new(|| {
-            CALLED.fetch_add(1, SeqCst);
-            92
-        });
-
-        assert_eq!(CALLED.load(SeqCst), 0);
-
-        spawn_and_wait(|| {
-            let y = *SYNC_LAZY - 30;
-            assert_eq!(y, 62);
-            assert_eq!(CALLED.load(SeqCst), 1);
-        });
-
-        let y = *SYNC_LAZY - 30;
-        assert_eq!(y, 62);
-        assert_eq!(CALLED.load(SeqCst), 1);
-    }
-
-    #[test]
-    fn sync_lazy_default() {
-        static CALLED: AtomicUsize = AtomicUsize::new(0);
-
-        struct Foo(u8);
-        impl Default for Foo {
-            fn default() -> Self {
-                CALLED.fetch_add(1, SeqCst);
-                Foo(42)
-            }
-        }
-
-        let lazy: SyncLazy<Mutex<Foo>> = <_>::default();
-
-        assert_eq!(CALLED.load(SeqCst), 0);
-
-        assert_eq!(lazy.lock().unwrap().0, 42);
-        assert_eq!(CALLED.load(SeqCst), 1);
-
-        lazy.lock().unwrap().0 = 21;
-
-        assert_eq!(lazy.lock().unwrap().0, 21);
-        assert_eq!(CALLED.load(SeqCst), 1);
-    }
-
-    #[test]
-    fn static_sync_lazy() {
-        static XS: SyncLazy<Vec<i32>> = SyncLazy::new(|| {
-            let mut xs = Vec::new();
-            xs.push(1);
-            xs.push(2);
-            xs.push(3);
-            xs
-        });
-
-        spawn_and_wait(|| {
-            assert_eq!(&*XS, &vec![1, 2, 3]);
-        });
-
-        assert_eq!(&*XS, &vec![1, 2, 3]);
-    }
-
-    #[test]
-    fn static_sync_lazy_via_fn() {
-        fn xs() -> &'static Vec<i32> {
-            static XS: SyncOnceCell<Vec<i32>> = SyncOnceCell::new();
-            XS.get_or_init(|| {
-                let mut xs = Vec::new();
-                xs.push(1);
-                xs.push(2);
-                xs.push(3);
-                xs
-            })
-        }
-        assert_eq!(xs(), &vec![1, 2, 3]);
-    }
-
-    #[test]
-    fn sync_lazy_poisoning() {
-        let x: SyncLazy<String> = SyncLazy::new(|| panic!("kaboom"));
-        for _ in 0..2 {
-            let res = panic::catch_unwind(|| x.len());
-            assert!(res.is_err());
-        }
-    }
-
-    #[test]
-    fn is_sync_send() {
-        fn assert_traits<T: Send + Sync>() {}
-        assert_traits::<SyncOnceCell<String>>();
-        assert_traits::<SyncLazy<String>>();
-    }
-
-    #[test]
-    fn eval_once_macro() {
-        macro_rules! eval_once {
-            (|| -> $ty:ty {
-                $($body:tt)*
-            }) => {{
-                static ONCE_CELL: SyncOnceCell<$ty> = SyncOnceCell::new();
-                fn init() -> $ty {
-                    $($body)*
-                }
-                ONCE_CELL.get_or_init(init)
-            }};
-        }
-
-        let fib: &'static Vec<i32> = eval_once! {
-            || -> Vec<i32> {
-                let mut res = vec![1, 1];
-                for i in 0..10 {
-                    let next = res[i] + res[i + 1];
-                    res.push(next);
-                }
-                res
-            }
-        };
-        assert_eq!(fib[5], 8)
-    }
-
-    #[test]
-    fn sync_once_cell_does_not_leak_partially_constructed_boxes() {
-        static ONCE_CELL: SyncOnceCell<String> = SyncOnceCell::new();
-
-        let n_readers = 10;
-        let n_writers = 3;
-        const MSG: &str = "Hello, World";
-
-        let (tx, rx) = channel();
-
-        for _ in 0..n_readers {
-            let tx = tx.clone();
-            thread::spawn(move || {
-                loop {
-                    if let Some(msg) = ONCE_CELL.get() {
-                        tx.send(msg).unwrap();
-                        break;
-                    }
-                    #[cfg(target_env = "sgx")]
-                    crate::thread::yield_now();
-                }
-            });
-        }
-        for _ in 0..n_writers {
-            thread::spawn(move || {
-                let _ = ONCE_CELL.set(MSG.to_owned());
-            });
-        }
-
-        for _ in 0..n_readers {
-            let msg = rx.recv().unwrap();
-            assert_eq!(msg, MSG);
-        }
-    }
-
-    #[test]
-    fn dropck() {
-        let cell = SyncOnceCell::new();
-        {
-            let s = String::new();
-            cell.set(&s).unwrap();
-        }
-    }
-}
diff --git a/library/std/src/lazy/tests.rs b/library/std/src/lazy/tests.rs
new file mode 100644
index 00000000000..a170edbd997
--- /dev/null
+++ b/library/std/src/lazy/tests.rs
@@ -0,0 +1,323 @@
+use crate::{
+    lazy::{Lazy, SyncLazy, SyncOnceCell},
+    panic,
+    sync::{
+        atomic::{AtomicUsize, Ordering::SeqCst},
+        mpsc::channel,
+        Mutex,
+    },
+    thread,
+};
+
+#[test]
+fn lazy_default() {
+    static CALLED: AtomicUsize = AtomicUsize::new(0);
+
+    struct Foo(u8);
+    impl Default for Foo {
+        fn default() -> Self {
+            CALLED.fetch_add(1, SeqCst);
+            Foo(42)
+        }
+    }
+
+    let lazy: Lazy<Mutex<Foo>> = <_>::default();
+
+    assert_eq!(CALLED.load(SeqCst), 0);
+
+    assert_eq!(lazy.lock().unwrap().0, 42);
+    assert_eq!(CALLED.load(SeqCst), 1);
+
+    lazy.lock().unwrap().0 = 21;
+
+    assert_eq!(lazy.lock().unwrap().0, 21);
+    assert_eq!(CALLED.load(SeqCst), 1);
+}
+
+#[test]
+fn lazy_poisoning() {
+    let x: Lazy<String> = Lazy::new(|| panic!("kaboom"));
+    for _ in 0..2 {
+        let res = panic::catch_unwind(panic::AssertUnwindSafe(|| x.len()));
+        assert!(res.is_err());
+    }
+}
+
+fn spawn_and_wait<R: Send + 'static>(f: impl FnOnce() -> R + Send + 'static) -> R {
+    thread::spawn(f).join().unwrap()
+}
+
+#[test]
+fn sync_once_cell() {
+    static ONCE_CELL: SyncOnceCell<i32> = SyncOnceCell::new();
+
+    assert!(ONCE_CELL.get().is_none());
+
+    spawn_and_wait(|| {
+        ONCE_CELL.get_or_init(|| 92);
+        assert_eq!(ONCE_CELL.get(), Some(&92));
+    });
+
+    ONCE_CELL.get_or_init(|| panic!("Kabom!"));
+    assert_eq!(ONCE_CELL.get(), Some(&92));
+}
+
+#[test]
+fn sync_once_cell_get_mut() {
+    let mut c = SyncOnceCell::new();
+    assert!(c.get_mut().is_none());
+    c.set(90).unwrap();
+    *c.get_mut().unwrap() += 2;
+    assert_eq!(c.get_mut(), Some(&mut 92));
+}
+
+#[test]
+fn sync_once_cell_get_unchecked() {
+    let c = SyncOnceCell::new();
+    c.set(92).unwrap();
+    unsafe {
+        assert_eq!(c.get_unchecked(), &92);
+    }
+}
+
+#[test]
+fn sync_once_cell_drop() {
+    static DROP_CNT: AtomicUsize = AtomicUsize::new(0);
+    struct Dropper;
+    impl Drop for Dropper {
+        fn drop(&mut self) {
+            DROP_CNT.fetch_add(1, SeqCst);
+        }
+    }
+
+    let x = SyncOnceCell::new();
+    spawn_and_wait(move || {
+        x.get_or_init(|| Dropper);
+        assert_eq!(DROP_CNT.load(SeqCst), 0);
+        drop(x);
+    });
+
+    assert_eq!(DROP_CNT.load(SeqCst), 1);
+}
+
+#[test]
+fn sync_once_cell_drop_empty() {
+    let x = SyncOnceCell::<String>::new();
+    drop(x);
+}
+
+#[test]
+fn clone() {
+    let s = SyncOnceCell::new();
+    let c = s.clone();
+    assert!(c.get().is_none());
+
+    s.set("hello".to_string()).unwrap();
+    let c = s.clone();
+    assert_eq!(c.get().map(String::as_str), Some("hello"));
+}
+
+#[test]
+fn get_or_try_init() {
+    let cell: SyncOnceCell<String> = SyncOnceCell::new();
+    assert!(cell.get().is_none());
+
+    let res = panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() }));
+    assert!(res.is_err());
+    assert!(!cell.is_initialized());
+    assert!(cell.get().is_none());
+
+    assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
+
+    assert_eq!(cell.get_or_try_init(|| Ok::<_, ()>("hello".to_string())), Ok(&"hello".to_string()));
+    assert_eq!(cell.get(), Some(&"hello".to_string()));
+}
+
+#[test]
+fn from_impl() {
+    assert_eq!(SyncOnceCell::from("value").get(), Some(&"value"));
+    assert_ne!(SyncOnceCell::from("foo").get(), Some(&"bar"));
+}
+
+#[test]
+fn partialeq_impl() {
+    assert!(SyncOnceCell::from("value") == SyncOnceCell::from("value"));
+    assert!(SyncOnceCell::from("foo") != SyncOnceCell::from("bar"));
+
+    assert!(SyncOnceCell::<String>::new() == SyncOnceCell::new());
+    assert!(SyncOnceCell::<String>::new() != SyncOnceCell::from("value".to_owned()));
+}
+
+#[test]
+fn into_inner() {
+    let cell: SyncOnceCell<String> = SyncOnceCell::new();
+    assert_eq!(cell.into_inner(), None);
+    let cell = SyncOnceCell::new();
+    cell.set("hello".to_string()).unwrap();
+    assert_eq!(cell.into_inner(), Some("hello".to_string()));
+}
+
+#[test]
+fn sync_lazy_new() {
+    static CALLED: AtomicUsize = AtomicUsize::new(0);
+    static SYNC_LAZY: SyncLazy<i32> = SyncLazy::new(|| {
+        CALLED.fetch_add(1, SeqCst);
+        92
+    });
+
+    assert_eq!(CALLED.load(SeqCst), 0);
+
+    spawn_and_wait(|| {
+        let y = *SYNC_LAZY - 30;
+        assert_eq!(y, 62);
+        assert_eq!(CALLED.load(SeqCst), 1);
+    });
+
+    let y = *SYNC_LAZY - 30;
+    assert_eq!(y, 62);
+    assert_eq!(CALLED.load(SeqCst), 1);
+}
+
+#[test]
+fn sync_lazy_default() {
+    static CALLED: AtomicUsize = AtomicUsize::new(0);
+
+    struct Foo(u8);
+    impl Default for Foo {
+        fn default() -> Self {
+            CALLED.fetch_add(1, SeqCst);
+            Foo(42)
+        }
+    }
+
+    let lazy: SyncLazy<Mutex<Foo>> = <_>::default();
+
+    assert_eq!(CALLED.load(SeqCst), 0);
+
+    assert_eq!(lazy.lock().unwrap().0, 42);
+    assert_eq!(CALLED.load(SeqCst), 1);
+
+    lazy.lock().unwrap().0 = 21;
+
+    assert_eq!(lazy.lock().unwrap().0, 21);
+    assert_eq!(CALLED.load(SeqCst), 1);
+}
+
+#[test]
+fn static_sync_lazy() {
+    static XS: SyncLazy<Vec<i32>> = SyncLazy::new(|| {
+        let mut xs = Vec::new();
+        xs.push(1);
+        xs.push(2);
+        xs.push(3);
+        xs
+    });
+
+    spawn_and_wait(|| {
+        assert_eq!(&*XS, &vec![1, 2, 3]);
+    });
+
+    assert_eq!(&*XS, &vec![1, 2, 3]);
+}
+
+#[test]
+fn static_sync_lazy_via_fn() {
+    fn xs() -> &'static Vec<i32> {
+        static XS: SyncOnceCell<Vec<i32>> = SyncOnceCell::new();
+        XS.get_or_init(|| {
+            let mut xs = Vec::new();
+            xs.push(1);
+            xs.push(2);
+            xs.push(3);
+            xs
+        })
+    }
+    assert_eq!(xs(), &vec![1, 2, 3]);
+}
+
+#[test]
+fn sync_lazy_poisoning() {
+    let x: SyncLazy<String> = SyncLazy::new(|| panic!("kaboom"));
+    for _ in 0..2 {
+        let res = panic::catch_unwind(|| x.len());
+        assert!(res.is_err());
+    }
+}
+
+#[test]
+fn is_sync_send() {
+    fn assert_traits<T: Send + Sync>() {}
+    assert_traits::<SyncOnceCell<String>>();
+    assert_traits::<SyncLazy<String>>();
+}
+
+#[test]
+fn eval_once_macro() {
+    macro_rules! eval_once {
+        (|| -> $ty:ty {
+            $($body:tt)*
+        }) => {{
+            static ONCE_CELL: SyncOnceCell<$ty> = SyncOnceCell::new();
+            fn init() -> $ty {
+                $($body)*
+            }
+            ONCE_CELL.get_or_init(init)
+        }};
+    }
+
+    let fib: &'static Vec<i32> = eval_once! {
+        || -> Vec<i32> {
+            let mut res = vec![1, 1];
+            for i in 0..10 {
+                let next = res[i] + res[i + 1];
+                res.push(next);
+            }
+            res
+        }
+    };
+    assert_eq!(fib[5], 8)
+}
+
+#[test]
+fn sync_once_cell_does_not_leak_partially_constructed_boxes() {
+    static ONCE_CELL: SyncOnceCell<String> = SyncOnceCell::new();
+
+    let n_readers = 10;
+    let n_writers = 3;
+    const MSG: &str = "Hello, World";
+
+    let (tx, rx) = channel();
+
+    for _ in 0..n_readers {
+        let tx = tx.clone();
+        thread::spawn(move || {
+            loop {
+                if let Some(msg) = ONCE_CELL.get() {
+                    tx.send(msg).unwrap();
+                    break;
+                }
+                #[cfg(target_env = "sgx")]
+                crate::thread::yield_now();
+            }
+        });
+    }
+    for _ in 0..n_writers {
+        thread::spawn(move || {
+            let _ = ONCE_CELL.set(MSG.to_owned());
+        });
+    }
+
+    for _ in 0..n_readers {
+        let msg = rx.recv().unwrap();
+        assert_eq!(msg, MSG);
+    }
+}
+
+#[test]
+fn dropck() {
+    let cell = SyncOnceCell::new();
+    {
+        let s = String::new();
+        cell.set(&s).unwrap();
+    }
+}
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 0797585e3df..dc57c1c1f44 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -238,7 +238,9 @@
 #![feature(concat_idents)]
 #![feature(const_cstr_unchecked)]
 #![feature(const_fn_transmute)]
+#![feature(const_ipv6)]
 #![feature(const_raw_ptr_deref)]
+#![feature(const_ipv4)]
 #![feature(container_error_extra)]
 #![feature(core_intrinsics)]
 #![feature(custom_test_frameworks)]
diff --git a/library/std/src/memchr.rs b/library/std/src/memchr.rs
index d69294b2d20..86a08f75a8d 100644
--- a/library/std/src/memchr.rs
+++ b/library/std/src/memchr.rs
@@ -1,6 +1,9 @@
 // Original implementation taken from rust-memchr.
 // Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
 
+#[cfg(test)]
+mod tests;
+
 /// A safe interface to `memchr`.
 ///
 /// Returns the index corresponding to the first occurrence of `needle` in
@@ -44,90 +47,3 @@ pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
 pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
     crate::sys::memchr::memrchr(needle, haystack)
 }
-
-#[cfg(test)]
-mod tests {
-    // test the implementations for the current platform
-    use super::{memchr, memrchr};
-
-    #[test]
-    fn matches_one() {
-        assert_eq!(Some(0), memchr(b'a', b"a"));
-    }
-
-    #[test]
-    fn matches_begin() {
-        assert_eq!(Some(0), memchr(b'a', b"aaaa"));
-    }
-
-    #[test]
-    fn matches_end() {
-        assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
-    }
-
-    #[test]
-    fn matches_nul() {
-        assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
-    }
-
-    #[test]
-    fn matches_past_nul() {
-        assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
-    }
-
-    #[test]
-    fn no_match_empty() {
-        assert_eq!(None, memchr(b'a', b""));
-    }
-
-    #[test]
-    fn no_match() {
-        assert_eq!(None, memchr(b'a', b"xyz"));
-    }
-
-    #[test]
-    fn matches_one_reversed() {
-        assert_eq!(Some(0), memrchr(b'a', b"a"));
-    }
-
-    #[test]
-    fn matches_begin_reversed() {
-        assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
-    }
-
-    #[test]
-    fn matches_end_reversed() {
-        assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
-    }
-
-    #[test]
-    fn matches_nul_reversed() {
-        assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
-    }
-
-    #[test]
-    fn matches_past_nul_reversed() {
-        assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
-    }
-
-    #[test]
-    fn no_match_empty_reversed() {
-        assert_eq!(None, memrchr(b'a', b""));
-    }
-
-    #[test]
-    fn no_match_reversed() {
-        assert_eq!(None, memrchr(b'a', b"xyz"));
-    }
-
-    #[test]
-    fn each_alignment() {
-        let mut data = [1u8; 64];
-        let needle = 2;
-        let pos = 40;
-        data[pos] = needle;
-        for start in 0..16 {
-            assert_eq!(Some(pos - start), memchr(needle, &data[start..]));
-        }
-    }
-}
diff --git a/library/std/src/memchr/tests.rs b/library/std/src/memchr/tests.rs
new file mode 100644
index 00000000000..557d749c7f6
--- /dev/null
+++ b/library/std/src/memchr/tests.rs
@@ -0,0 +1,86 @@
+// Original implementation taken from rust-memchr.
+// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
+
+// test the implementations for the current platform
+use super::{memchr, memrchr};
+
+#[test]
+fn matches_one() {
+    assert_eq!(Some(0), memchr(b'a', b"a"));
+}
+
+#[test]
+fn matches_begin() {
+    assert_eq!(Some(0), memchr(b'a', b"aaaa"));
+}
+
+#[test]
+fn matches_end() {
+    assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
+}
+
+#[test]
+fn matches_nul() {
+    assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
+}
+
+#[test]
+fn matches_past_nul() {
+    assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
+}
+
+#[test]
+fn no_match_empty() {
+    assert_eq!(None, memchr(b'a', b""));
+}
+
+#[test]
+fn no_match() {
+    assert_eq!(None, memchr(b'a', b"xyz"));
+}
+
+#[test]
+fn matches_one_reversed() {
+    assert_eq!(Some(0), memrchr(b'a', b"a"));
+}
+
+#[test]
+fn matches_begin_reversed() {
+    assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
+}
+
+#[test]
+fn matches_end_reversed() {
+    assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
+}
+
+#[test]
+fn matches_nul_reversed() {
+    assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
+}
+
+#[test]
+fn matches_past_nul_reversed() {
+    assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
+}
+
+#[test]
+fn no_match_empty_reversed() {
+    assert_eq!(None, memrchr(b'a', b""));
+}
+
+#[test]
+fn no_match_reversed() {
+    assert_eq!(None, memrchr(b'a', b"xyz"));
+}
+
+#[test]
+fn each_alignment() {
+    let mut data = [1u8; 64];
+    let needle = 2;
+    let pos = 40;
+    data[pos] = needle;
+    for start in 0..16 {
+        assert_eq!(Some(pos - start), memchr(needle, &data[start..]));
+    }
+}
diff --git a/library/std/src/net/addr.rs b/library/std/src/net/addr.rs
index d7d96862b21..499b1137dcb 100644
--- a/library/std/src/net/addr.rs
+++ b/library/std/src/net/addr.rs
@@ -1,3 +1,6 @@
+#[cfg(all(test, not(target_os = "emscripten")))]
+mod tests;
+
 use crate::cmp::Ordering;
 use crate::convert::TryInto;
 use crate::fmt;
@@ -210,8 +213,6 @@ impl SocketAddr {
     ///
     /// [IP address]: IpAddr
     /// [`IPv4` address]: IpAddr::V4
-    /// [`false`]: ../../std/primitive.bool.html
-    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -232,8 +233,6 @@ impl SocketAddr {
     ///
     /// [IP address]: IpAddr
     /// [`IPv6` address]: IpAddr::V6
-    /// [`false`]: ../../std/primitive.bool.html
-    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -991,236 +990,3 @@ impl ToSocketAddrs for String {
         (&**self).to_socket_addrs()
     }
 }
-
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod tests {
-    use crate::net::test::{sa4, sa6, tsa};
-    use crate::net::*;
-
-    #[test]
-    fn to_socket_addr_ipaddr_u16() {
-        let a = Ipv4Addr::new(77, 88, 21, 11);
-        let p = 12345;
-        let e = SocketAddr::V4(SocketAddrV4::new(a, p));
-        assert_eq!(Ok(vec![e]), tsa((a, p)));
-    }
-
-    #[test]
-    fn to_socket_addr_str_u16() {
-        let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352);
-        assert_eq!(Ok(vec![a]), tsa(("77.88.21.11", 24352)));
-
-        let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53);
-        assert_eq!(Ok(vec![a]), tsa(("2a02:6b8:0:1::1", 53)));
-
-        let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924);
-        #[cfg(not(target_env = "sgx"))]
-        assert!(tsa(("localhost", 23924)).unwrap().contains(&a));
-        #[cfg(target_env = "sgx")]
-        let _ = a;
-    }
-
-    #[test]
-    fn to_socket_addr_str() {
-        let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352);
-        assert_eq!(Ok(vec![a]), tsa("77.88.21.11:24352"));
-
-        let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53);
-        assert_eq!(Ok(vec![a]), tsa("[2a02:6b8:0:1::1]:53"));
-
-        let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924);
-        #[cfg(not(target_env = "sgx"))]
-        assert!(tsa("localhost:23924").unwrap().contains(&a));
-        #[cfg(target_env = "sgx")]
-        let _ = a;
-    }
-
-    #[test]
-    fn to_socket_addr_string() {
-        let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352);
-        assert_eq!(Ok(vec![a]), tsa(&*format!("{}:{}", "77.88.21.11", "24352")));
-        assert_eq!(Ok(vec![a]), tsa(&format!("{}:{}", "77.88.21.11", "24352")));
-        assert_eq!(Ok(vec![a]), tsa(format!("{}:{}", "77.88.21.11", "24352")));
-
-        let s = format!("{}:{}", "77.88.21.11", "24352");
-        assert_eq!(Ok(vec![a]), tsa(s));
-        // s has been moved into the tsa call
-    }
-
-    #[test]
-    fn bind_udp_socket_bad() {
-        // rust-lang/rust#53957: This is a regression test for a parsing problem
-        // discovered as part of issue rust-lang/rust#23076, where we were
-        // incorrectly parsing invalid input and then that would result in a
-        // successful `UdpSocket` binding when we would expect failure.
-        //
-        // At one time, this test was written as a call to `tsa` with
-        // INPUT_23076. However, that structure yields an unreliable test,
-        // because it ends up passing junk input to the DNS server, and some DNS
-        // servers will respond with `Ok` to such input, with the ip address of
-        // the DNS server itself.
-        //
-        // This form of the test is more robust: even when the DNS server
-        // returns its own address, it is still an error to bind a UDP socket to
-        // a non-local address, and so we still get an error here in that case.
-
-        const INPUT_23076: &'static str = "1200::AB00:1234::2552:7777:1313:34300";
-
-        assert!(crate::net::UdpSocket::bind(INPUT_23076).is_err())
-    }
-
-    #[test]
-    fn set_ip() {
-        fn ip4(low: u8) -> Ipv4Addr {
-            Ipv4Addr::new(77, 88, 21, low)
-        }
-        fn ip6(low: u16) -> Ipv6Addr {
-            Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, low)
-        }
-
-        let mut v4 = SocketAddrV4::new(ip4(11), 80);
-        assert_eq!(v4.ip(), &ip4(11));
-        v4.set_ip(ip4(12));
-        assert_eq!(v4.ip(), &ip4(12));
-
-        let mut addr = SocketAddr::V4(v4);
-        assert_eq!(addr.ip(), IpAddr::V4(ip4(12)));
-        addr.set_ip(IpAddr::V4(ip4(13)));
-        assert_eq!(addr.ip(), IpAddr::V4(ip4(13)));
-        addr.set_ip(IpAddr::V6(ip6(14)));
-        assert_eq!(addr.ip(), IpAddr::V6(ip6(14)));
-
-        let mut v6 = SocketAddrV6::new(ip6(1), 80, 0, 0);
-        assert_eq!(v6.ip(), &ip6(1));
-        v6.set_ip(ip6(2));
-        assert_eq!(v6.ip(), &ip6(2));
-
-        let mut addr = SocketAddr::V6(v6);
-        assert_eq!(addr.ip(), IpAddr::V6(ip6(2)));
-        addr.set_ip(IpAddr::V6(ip6(3)));
-        assert_eq!(addr.ip(), IpAddr::V6(ip6(3)));
-        addr.set_ip(IpAddr::V4(ip4(4)));
-        assert_eq!(addr.ip(), IpAddr::V4(ip4(4)));
-    }
-
-    #[test]
-    fn set_port() {
-        let mut v4 = SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80);
-        assert_eq!(v4.port(), 80);
-        v4.set_port(443);
-        assert_eq!(v4.port(), 443);
-
-        let mut addr = SocketAddr::V4(v4);
-        assert_eq!(addr.port(), 443);
-        addr.set_port(8080);
-        assert_eq!(addr.port(), 8080);
-
-        let mut v6 = SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 80, 0, 0);
-        assert_eq!(v6.port(), 80);
-        v6.set_port(443);
-        assert_eq!(v6.port(), 443);
-
-        let mut addr = SocketAddr::V6(v6);
-        assert_eq!(addr.port(), 443);
-        addr.set_port(8080);
-        assert_eq!(addr.port(), 8080);
-    }
-
-    #[test]
-    fn set_flowinfo() {
-        let mut v6 = SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 80, 10, 0);
-        assert_eq!(v6.flowinfo(), 10);
-        v6.set_flowinfo(20);
-        assert_eq!(v6.flowinfo(), 20);
-    }
-
-    #[test]
-    fn set_scope_id() {
-        let mut v6 = SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 80, 0, 10);
-        assert_eq!(v6.scope_id(), 10);
-        v6.set_scope_id(20);
-        assert_eq!(v6.scope_id(), 20);
-    }
-
-    #[test]
-    fn is_v4() {
-        let v4 = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80));
-        assert!(v4.is_ipv4());
-        assert!(!v4.is_ipv6());
-    }
-
-    #[test]
-    fn is_v6() {
-        let v6 = SocketAddr::V6(SocketAddrV6::new(
-            Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1),
-            80,
-            10,
-            0,
-        ));
-        assert!(!v6.is_ipv4());
-        assert!(v6.is_ipv6());
-    }
-
-    #[test]
-    fn socket_v4_to_str() {
-        let socket = SocketAddrV4::new(Ipv4Addr::new(192, 168, 0, 1), 8080);
-
-        assert_eq!(format!("{}", socket), "192.168.0.1:8080");
-        assert_eq!(format!("{:<20}", socket), "192.168.0.1:8080    ");
-        assert_eq!(format!("{:>20}", socket), "    192.168.0.1:8080");
-        assert_eq!(format!("{:^20}", socket), "  192.168.0.1:8080  ");
-        assert_eq!(format!("{:.10}", socket), "192.168.0.");
-    }
-
-    #[test]
-    fn socket_v6_to_str() {
-        let socket: SocketAddrV6 = "[2a02:6b8:0:1::1]:53".parse().unwrap();
-
-        assert_eq!(format!("{}", socket), "[2a02:6b8:0:1::1]:53");
-        assert_eq!(format!("{:<24}", socket), "[2a02:6b8:0:1::1]:53    ");
-        assert_eq!(format!("{:>24}", socket), "    [2a02:6b8:0:1::1]:53");
-        assert_eq!(format!("{:^24}", socket), "  [2a02:6b8:0:1::1]:53  ");
-        assert_eq!(format!("{:.15}", socket), "[2a02:6b8:0:1::");
-    }
-
-    #[test]
-    fn compare() {
-        let v4_1 = "224.120.45.1:23456".parse::<SocketAddrV4>().unwrap();
-        let v4_2 = "224.210.103.5:12345".parse::<SocketAddrV4>().unwrap();
-        let v4_3 = "224.210.103.5:23456".parse::<SocketAddrV4>().unwrap();
-        let v6_1 = "[2001:db8:f00::1002]:23456".parse::<SocketAddrV6>().unwrap();
-        let v6_2 = "[2001:db8:f00::2001]:12345".parse::<SocketAddrV6>().unwrap();
-        let v6_3 = "[2001:db8:f00::2001]:23456".parse::<SocketAddrV6>().unwrap();
-
-        // equality
-        assert_eq!(v4_1, v4_1);
-        assert_eq!(v6_1, v6_1);
-        assert_eq!(SocketAddr::V4(v4_1), SocketAddr::V4(v4_1));
-        assert_eq!(SocketAddr::V6(v6_1), SocketAddr::V6(v6_1));
-        assert!(v4_1 != v4_2);
-        assert!(v6_1 != v6_2);
-
-        // compare different addresses
-        assert!(v4_1 < v4_2);
-        assert!(v6_1 < v6_2);
-        assert!(v4_2 > v4_1);
-        assert!(v6_2 > v6_1);
-
-        // compare the same address with different ports
-        assert!(v4_2 < v4_3);
-        assert!(v6_2 < v6_3);
-        assert!(v4_3 > v4_2);
-        assert!(v6_3 > v6_2);
-
-        // compare different addresses with the same port
-        assert!(v4_1 < v4_3);
-        assert!(v6_1 < v6_3);
-        assert!(v4_3 > v4_1);
-        assert!(v6_3 > v6_1);
-
-        // compare with an inferred right-hand side
-        assert_eq!(v4_1, "224.120.45.1:23456".parse().unwrap());
-        assert_eq!(v6_1, "[2001:db8:f00::1002]:23456".parse().unwrap());
-        assert_eq!(SocketAddr::V4(v4_1), "224.120.45.1:23456".parse().unwrap());
-    }
-}
diff --git a/library/std/src/net/addr/tests.rs b/library/std/src/net/addr/tests.rs
new file mode 100644
index 00000000000..cee9087e13b
--- /dev/null
+++ b/library/std/src/net/addr/tests.rs
@@ -0,0 +1,229 @@
+use crate::net::test::{sa4, sa6, tsa};
+use crate::net::*;
+
+#[test]
+fn to_socket_addr_ipaddr_u16() {
+    let a = Ipv4Addr::new(77, 88, 21, 11);
+    let p = 12345;
+    let e = SocketAddr::V4(SocketAddrV4::new(a, p));
+    assert_eq!(Ok(vec![e]), tsa((a, p)));
+}
+
+#[test]
+fn to_socket_addr_str_u16() {
+    let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352);
+    assert_eq!(Ok(vec![a]), tsa(("77.88.21.11", 24352)));
+
+    let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53);
+    assert_eq!(Ok(vec![a]), tsa(("2a02:6b8:0:1::1", 53)));
+
+    let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924);
+    #[cfg(not(target_env = "sgx"))]
+    assert!(tsa(("localhost", 23924)).unwrap().contains(&a));
+    #[cfg(target_env = "sgx")]
+    let _ = a;
+}
+
+#[test]
+fn to_socket_addr_str() {
+    let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352);
+    assert_eq!(Ok(vec![a]), tsa("77.88.21.11:24352"));
+
+    let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53);
+    assert_eq!(Ok(vec![a]), tsa("[2a02:6b8:0:1::1]:53"));
+
+    let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924);
+    #[cfg(not(target_env = "sgx"))]
+    assert!(tsa("localhost:23924").unwrap().contains(&a));
+    #[cfg(target_env = "sgx")]
+    let _ = a;
+}
+
+#[test]
+fn to_socket_addr_string() {
+    let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352);
+    assert_eq!(Ok(vec![a]), tsa(&*format!("{}:{}", "77.88.21.11", "24352")));
+    assert_eq!(Ok(vec![a]), tsa(&format!("{}:{}", "77.88.21.11", "24352")));
+    assert_eq!(Ok(vec![a]), tsa(format!("{}:{}", "77.88.21.11", "24352")));
+
+    let s = format!("{}:{}", "77.88.21.11", "24352");
+    assert_eq!(Ok(vec![a]), tsa(s));
+    // s has been moved into the tsa call
+}
+
+#[test]
+fn bind_udp_socket_bad() {
+    // rust-lang/rust#53957: This is a regression test for a parsing problem
+    // discovered as part of issue rust-lang/rust#23076, where we were
+    // incorrectly parsing invalid input and then that would result in a
+    // successful `UdpSocket` binding when we would expect failure.
+    //
+    // At one time, this test was written as a call to `tsa` with
+    // INPUT_23076. However, that structure yields an unreliable test,
+    // because it ends up passing junk input to the DNS server, and some DNS
+    // servers will respond with `Ok` to such input, with the ip address of
+    // the DNS server itself.
+    //
+    // This form of the test is more robust: even when the DNS server
+    // returns its own address, it is still an error to bind a UDP socket to
+    // a non-local address, and so we still get an error here in that case.
+
+    const INPUT_23076: &'static str = "1200::AB00:1234::2552:7777:1313:34300";
+
+    assert!(crate::net::UdpSocket::bind(INPUT_23076).is_err())
+}
+
+#[test]
+fn set_ip() {
+    fn ip4(low: u8) -> Ipv4Addr {
+        Ipv4Addr::new(77, 88, 21, low)
+    }
+    fn ip6(low: u16) -> Ipv6Addr {
+        Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, low)
+    }
+
+    let mut v4 = SocketAddrV4::new(ip4(11), 80);
+    assert_eq!(v4.ip(), &ip4(11));
+    v4.set_ip(ip4(12));
+    assert_eq!(v4.ip(), &ip4(12));
+
+    let mut addr = SocketAddr::V4(v4);
+    assert_eq!(addr.ip(), IpAddr::V4(ip4(12)));
+    addr.set_ip(IpAddr::V4(ip4(13)));
+    assert_eq!(addr.ip(), IpAddr::V4(ip4(13)));
+    addr.set_ip(IpAddr::V6(ip6(14)));
+    assert_eq!(addr.ip(), IpAddr::V6(ip6(14)));
+
+    let mut v6 = SocketAddrV6::new(ip6(1), 80, 0, 0);
+    assert_eq!(v6.ip(), &ip6(1));
+    v6.set_ip(ip6(2));
+    assert_eq!(v6.ip(), &ip6(2));
+
+    let mut addr = SocketAddr::V6(v6);
+    assert_eq!(addr.ip(), IpAddr::V6(ip6(2)));
+    addr.set_ip(IpAddr::V6(ip6(3)));
+    assert_eq!(addr.ip(), IpAddr::V6(ip6(3)));
+    addr.set_ip(IpAddr::V4(ip4(4)));
+    assert_eq!(addr.ip(), IpAddr::V4(ip4(4)));
+}
+
+#[test]
+fn set_port() {
+    let mut v4 = SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80);
+    assert_eq!(v4.port(), 80);
+    v4.set_port(443);
+    assert_eq!(v4.port(), 443);
+
+    let mut addr = SocketAddr::V4(v4);
+    assert_eq!(addr.port(), 443);
+    addr.set_port(8080);
+    assert_eq!(addr.port(), 8080);
+
+    let mut v6 = SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 80, 0, 0);
+    assert_eq!(v6.port(), 80);
+    v6.set_port(443);
+    assert_eq!(v6.port(), 443);
+
+    let mut addr = SocketAddr::V6(v6);
+    assert_eq!(addr.port(), 443);
+    addr.set_port(8080);
+    assert_eq!(addr.port(), 8080);
+}
+
+#[test]
+fn set_flowinfo() {
+    let mut v6 = SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 80, 10, 0);
+    assert_eq!(v6.flowinfo(), 10);
+    v6.set_flowinfo(20);
+    assert_eq!(v6.flowinfo(), 20);
+}
+
+#[test]
+fn set_scope_id() {
+    let mut v6 = SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 80, 0, 10);
+    assert_eq!(v6.scope_id(), 10);
+    v6.set_scope_id(20);
+    assert_eq!(v6.scope_id(), 20);
+}
+
+#[test]
+fn is_v4() {
+    let v4 = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80));
+    assert!(v4.is_ipv4());
+    assert!(!v4.is_ipv6());
+}
+
+#[test]
+fn is_v6() {
+    let v6 = SocketAddr::V6(SocketAddrV6::new(
+        Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1),
+        80,
+        10,
+        0,
+    ));
+    assert!(!v6.is_ipv4());
+    assert!(v6.is_ipv6());
+}
+
+#[test]
+fn socket_v4_to_str() {
+    let socket = SocketAddrV4::new(Ipv4Addr::new(192, 168, 0, 1), 8080);
+
+    assert_eq!(format!("{}", socket), "192.168.0.1:8080");
+    assert_eq!(format!("{:<20}", socket), "192.168.0.1:8080    ");
+    assert_eq!(format!("{:>20}", socket), "    192.168.0.1:8080");
+    assert_eq!(format!("{:^20}", socket), "  192.168.0.1:8080  ");
+    assert_eq!(format!("{:.10}", socket), "192.168.0.");
+}
+
+#[test]
+fn socket_v6_to_str() {
+    let socket: SocketAddrV6 = "[2a02:6b8:0:1::1]:53".parse().unwrap();
+
+    assert_eq!(format!("{}", socket), "[2a02:6b8:0:1::1]:53");
+    assert_eq!(format!("{:<24}", socket), "[2a02:6b8:0:1::1]:53    ");
+    assert_eq!(format!("{:>24}", socket), "    [2a02:6b8:0:1::1]:53");
+    assert_eq!(format!("{:^24}", socket), "  [2a02:6b8:0:1::1]:53  ");
+    assert_eq!(format!("{:.15}", socket), "[2a02:6b8:0:1::");
+}
+
+#[test]
+fn compare() {
+    let v4_1 = "224.120.45.1:23456".parse::<SocketAddrV4>().unwrap();
+    let v4_2 = "224.210.103.5:12345".parse::<SocketAddrV4>().unwrap();
+    let v4_3 = "224.210.103.5:23456".parse::<SocketAddrV4>().unwrap();
+    let v6_1 = "[2001:db8:f00::1002]:23456".parse::<SocketAddrV6>().unwrap();
+    let v6_2 = "[2001:db8:f00::2001]:12345".parse::<SocketAddrV6>().unwrap();
+    let v6_3 = "[2001:db8:f00::2001]:23456".parse::<SocketAddrV6>().unwrap();
+
+    // equality
+    assert_eq!(v4_1, v4_1);
+    assert_eq!(v6_1, v6_1);
+    assert_eq!(SocketAddr::V4(v4_1), SocketAddr::V4(v4_1));
+    assert_eq!(SocketAddr::V6(v6_1), SocketAddr::V6(v6_1));
+    assert!(v4_1 != v4_2);
+    assert!(v6_1 != v6_2);
+
+    // compare different addresses
+    assert!(v4_1 < v4_2);
+    assert!(v6_1 < v6_2);
+    assert!(v4_2 > v4_1);
+    assert!(v6_2 > v6_1);
+
+    // compare the same address with different ports
+    assert!(v4_2 < v4_3);
+    assert!(v6_2 < v6_3);
+    assert!(v4_3 > v4_2);
+    assert!(v6_3 > v6_2);
+
+    // compare different addresses with the same port
+    assert!(v4_1 < v4_3);
+    assert!(v6_1 < v6_3);
+    assert!(v4_3 > v4_1);
+    assert!(v6_3 > v6_1);
+
+    // compare with an inferred right-hand side
+    assert_eq!(v4_1, "224.120.45.1:23456".parse().unwrap());
+    assert_eq!(v6_1, "[2001:db8:f00::1002]:23456".parse().unwrap());
+    assert_eq!(SocketAddr::V4(v4_1), "224.120.45.1:23456".parse().unwrap());
+}
diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs
index 85bb6b60e68..e2fc7edb87e 100644
--- a/library/std/src/net/ip.rs
+++ b/library/std/src/net/ip.rs
@@ -6,6 +6,10 @@
     issue = "27709"
 )]
 
+// Tests for this module
+#[cfg(all(test, not(target_os = "emscripten")))]
+mod tests;
+
 use crate::cmp::Ordering;
 use crate::fmt::{self, Write as FmtWrite};
 use crate::hash;
@@ -136,8 +140,6 @@ impl IpAddr {
     /// See the documentation for [`Ipv4Addr::is_unspecified()`] and
     /// [`Ipv6Addr::is_unspecified()`] for more details.
     ///
-    /// [`true`]: ../../std/primitive.bool.html
-    ///
     /// # Examples
     ///
     /// ```
@@ -159,8 +161,6 @@ impl IpAddr {
     /// See the documentation for [`Ipv4Addr::is_loopback()`] and
     /// [`Ipv6Addr::is_loopback()`] for more details.
     ///
-    /// [`true`]: ../../std/primitive.bool.html
-    ///
     /// # Examples
     ///
     /// ```
@@ -182,8 +182,6 @@ impl IpAddr {
     /// See the documentation for [`Ipv4Addr::is_global()`] and
     /// [`Ipv6Addr::is_global()`] for more details.
     ///
-    /// [`true`]: ../../std/primitive.bool.html
-    ///
     /// # Examples
     ///
     /// ```
@@ -206,8 +204,6 @@ impl IpAddr {
     /// See the documentation for [`Ipv4Addr::is_multicast()`] and
     /// [`Ipv6Addr::is_multicast()`] for more details.
     ///
-    /// [`true`]: ../../std/primitive.bool.html
-    ///
     /// # Examples
     ///
     /// ```
@@ -229,8 +225,6 @@ impl IpAddr {
     /// See the documentation for [`Ipv4Addr::is_documentation()`] and
     /// [`Ipv6Addr::is_documentation()`] for more details.
     ///
-    /// [`true`]: ../../std/primitive.bool.html
-    ///
     /// # Examples
     ///
     /// ```
@@ -254,8 +248,6 @@ impl IpAddr {
     /// Returns [`true`] if this address is an [`IPv4` address], and [`false`]
     /// otherwise.
     ///
-    /// [`true`]: ../../std/primitive.bool.html
-    /// [`false`]: ../../std/primitive.bool.html
     /// [`IPv4` address]: IpAddr::V4
     ///
     /// # Examples
@@ -274,8 +266,6 @@ impl IpAddr {
     /// Returns [`true`] if this address is an [`IPv6` address], and [`false`]
     /// otherwise.
     ///
-    /// [`true`]: ../../std/primitive.bool.html
-    /// [`false`]: ../../std/primitive.bool.html
     /// [`IPv6` address]: IpAddr::V6
     ///
     /// # Examples
@@ -361,8 +351,9 @@ impl Ipv4Addr {
     /// let addr = Ipv4Addr::new(127, 0, 0, 1);
     /// assert_eq!(addr.octets(), [127, 0, 0, 1]);
     /// ```
+    #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn octets(&self) -> [u8; 4] {
+    pub const fn octets(&self) -> [u8; 4] {
         // This returns the order we want because s_addr is stored in big-endian.
         self.inner.s_addr.to_ne_bytes()
     }
@@ -372,7 +363,6 @@ impl Ipv4Addr {
     /// This property is defined in _UNIX Network Programming, Second Edition_,
     /// W. Richard Stevens, p. 891; see also [ip7].
     ///
-    /// [`true`]: ../../std/primitive.bool.html
     /// [ip7]: http://man7.org/linux/man-pages/man7/ip.7.html
     ///
     /// # Examples
@@ -393,7 +383,6 @@ impl Ipv4Addr {
     ///
     /// This property is defined by [IETF RFC 1122].
     ///
-    /// [`true`]: ../../std/primitive.bool.html
     /// [IETF RFC 1122]: https://tools.ietf.org/html/rfc1122
     ///
     /// # Examples
@@ -404,8 +393,9 @@ impl Ipv4Addr {
     /// assert_eq!(Ipv4Addr::new(127, 0, 0, 1).is_loopback(), true);
     /// assert_eq!(Ipv4Addr::new(45, 22, 13, 197).is_loopback(), false);
     /// ```
+    #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
     #[stable(since = "1.7.0", feature = "ip_17")]
-    pub fn is_loopback(&self) -> bool {
+    pub const fn is_loopback(&self) -> bool {
         self.octets()[0] == 127
     }
 
@@ -417,7 +407,6 @@ impl Ipv4Addr {
     ///  - 172.16.0.0/12
     ///  - 192.168.0.0/16
     ///
-    /// [`true`]: ../../std/primitive.bool.html
     /// [IETF RFC 1918]: https://tools.ietf.org/html/rfc1918
     ///
     /// # Examples
@@ -433,8 +422,9 @@ impl Ipv4Addr {
     /// assert_eq!(Ipv4Addr::new(192, 168, 0, 2).is_private(), true);
     /// assert_eq!(Ipv4Addr::new(192, 169, 0, 2).is_private(), false);
     /// ```
+    #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
     #[stable(since = "1.7.0", feature = "ip_17")]
-    pub fn is_private(&self) -> bool {
+    pub const fn is_private(&self) -> bool {
         match self.octets() {
             [10, ..] => true,
             [172, b, ..] if b >= 16 && b <= 31 => true,
@@ -447,7 +437,6 @@ impl Ipv4Addr {
     ///
     /// This property is defined by [IETF RFC 3927].
     ///
-    /// [`true`]: ../../std/primitive.bool.html
     /// [IETF RFC 3927]: https://tools.ietf.org/html/rfc3927
     ///
     /// # Examples
@@ -459,8 +448,9 @@ impl Ipv4Addr {
     /// assert_eq!(Ipv4Addr::new(169, 254, 10, 65).is_link_local(), true);
     /// assert_eq!(Ipv4Addr::new(16, 89, 10, 65).is_link_local(), false);
     /// ```
+    #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
     #[stable(since = "1.7.0", feature = "ip_17")]
-    pub fn is_link_local(&self) -> bool {
+    pub const fn is_link_local(&self) -> bool {
         match self.octets() {
             [169, 254, ..] => true,
             _ => false,
@@ -486,8 +476,6 @@ impl Ipv4Addr {
     /// - addresses reserved for networking devices benchmarking (see
     /// [`Ipv4Addr::is_benchmarking()`])
     ///
-    /// [`true`]: ../../std/primitive.bool.html
-    /// [`false`]: ../../std/primitive.bool.html
     /// [ipv4-sr]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
     ///
     /// # Examples
@@ -538,10 +526,13 @@ impl Ipv4Addr {
     /// assert_eq!(Ipv4Addr::new(1, 1, 1, 1).is_global(), true);
     /// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true);
     /// ```
-    pub fn is_global(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
+    pub const fn is_global(&self) -> bool {
         // check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two
         // globally routable addresses in the 192.0.0.0/24 range.
-        if u32::from(*self) == 0xc0000009 || u32::from(*self) == 0xc000000a {
+        if u32::from_be_bytes(self.octets()) == 0xc0000009
+            || u32::from_be_bytes(self.octets()) == 0xc000000a
+        {
             return true;
         }
         !self.is_private()
@@ -560,7 +551,6 @@ impl Ipv4Addr {
     /// Returns [`true`] if this address is part of the Shared Address Space defined in
     /// [IETF RFC 6598] (`100.64.0.0/10`).
     ///
-    /// [`true`]: ../../std/primitive.bool.html
     /// [IETF RFC 6598]: https://tools.ietf.org/html/rfc6598
     ///
     /// # Examples
@@ -573,7 +563,8 @@ impl Ipv4Addr {
     /// assert_eq!(Ipv4Addr::new(100, 127, 255, 255).is_shared(), true);
     /// assert_eq!(Ipv4Addr::new(100, 128, 0, 0).is_shared(), false);
     /// ```
-    pub fn is_shared(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
+    pub const fn is_shared(&self) -> bool {
         self.octets()[0] == 100 && (self.octets()[1] & 0b1100_0000 == 0b0100_0000)
     }
 
@@ -586,7 +577,6 @@ impl Ipv4Addr {
     /// - `192.0.0.9/32` is the "Port Control Protocol Anycast" (see [IETF RFC 7723])
     /// - `192.0.0.10/32` is used for NAT traversal (see [IETF RFC 8155])
     ///
-    /// [`true`]: ../../std/primitive.bool.html
     /// [IETF RFC 6890]: https://tools.ietf.org/html/rfc6890
     /// [IETF RFC 7600]: https://tools.ietf.org/html/rfc7600
     /// [IETF RFC 7723]: https://tools.ietf.org/html/rfc7723
@@ -605,7 +595,8 @@ impl Ipv4Addr {
     /// assert_eq!(Ipv4Addr::new(192, 0, 1, 0).is_ietf_protocol_assignment(), false);
     /// assert_eq!(Ipv4Addr::new(191, 255, 255, 255).is_ietf_protocol_assignment(), false);
     /// ```
-    pub fn is_ietf_protocol_assignment(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
+    pub const fn is_ietf_protocol_assignment(&self) -> bool {
         self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0
     }
 
@@ -613,7 +604,6 @@ impl Ipv4Addr {
     /// network devices benchmarking. This range is defined in [IETF RFC 2544] as `192.18.0.0`
     /// through `198.19.255.255` but [errata 423] corrects it to `198.18.0.0/15`.
     ///
-    /// [`true`]: ../../std/primitive.bool.html
     /// [IETF RFC 2544]: https://tools.ietf.org/html/rfc2544
     /// [errata 423]: https://www.rfc-editor.org/errata/eid423
     ///
@@ -628,7 +618,8 @@ impl Ipv4Addr {
     /// assert_eq!(Ipv4Addr::new(198, 19, 255, 255).is_benchmarking(), true);
     /// assert_eq!(Ipv4Addr::new(198, 20, 0, 0).is_benchmarking(), false);
     /// ```
-    pub fn is_benchmarking(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
+    pub const fn is_benchmarking(&self) -> bool {
         self.octets()[0] == 198 && (self.octets()[1] & 0xfe) == 18
     }
 
@@ -637,7 +628,6 @@ impl Ipv4Addr {
     /// broadcast address `255.255.255.255`, but this implementation explicitly excludes it, since
     /// it is obviously not reserved for future use.
     ///
-    /// [`true`]: ../../std/primitive.bool.html
     /// [IETF RFC 1112]: https://tools.ietf.org/html/rfc1112
     ///
     /// # Warning
@@ -660,7 +650,8 @@ impl Ipv4Addr {
     /// // The broadcast address is not considered as reserved for future use by this implementation
     /// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_reserved(), false);
     /// ```
-    pub fn is_reserved(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
+    pub const fn is_reserved(&self) -> bool {
         self.octets()[0] & 240 == 240 && !self.is_broadcast()
     }
 
@@ -669,7 +660,6 @@ impl Ipv4Addr {
     /// Multicast addresses have a most significant octet between 224 and 239,
     /// and is defined by [IETF RFC 5771].
     ///
-    /// [`true`]: ../../std/primitive.bool.html
     /// [IETF RFC 5771]: https://tools.ietf.org/html/rfc5771
     ///
     /// # Examples
@@ -681,8 +671,9 @@ impl Ipv4Addr {
     /// assert_eq!(Ipv4Addr::new(236, 168, 10, 65).is_multicast(), true);
     /// assert_eq!(Ipv4Addr::new(172, 16, 10, 65).is_multicast(), false);
     /// ```
+    #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
     #[stable(since = "1.7.0", feature = "ip_17")]
-    pub fn is_multicast(&self) -> bool {
+    pub const fn is_multicast(&self) -> bool {
         self.octets()[0] >= 224 && self.octets()[0] <= 239
     }
 
@@ -690,7 +681,6 @@ impl Ipv4Addr {
     ///
     /// A broadcast address has all octets set to 255 as defined in [IETF RFC 919].
     ///
-    /// [`true`]: ../../std/primitive.bool.html
     /// [IETF RFC 919]: https://tools.ietf.org/html/rfc919
     ///
     /// # Examples
@@ -701,9 +691,10 @@ impl Ipv4Addr {
     /// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_broadcast(), true);
     /// assert_eq!(Ipv4Addr::new(236, 168, 10, 65).is_broadcast(), false);
     /// ```
+    #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
     #[stable(since = "1.7.0", feature = "ip_17")]
-    pub fn is_broadcast(&self) -> bool {
-        self == &Self::BROADCAST
+    pub const fn is_broadcast(&self) -> bool {
+        u32::from_be_bytes(self.octets()) == u32::from_be_bytes(Self::BROADCAST.octets())
     }
 
     /// Returns [`true`] if this address is in a range designated for documentation.
@@ -714,7 +705,6 @@ impl Ipv4Addr {
     /// - 198.51.100.0/24 (TEST-NET-2)
     /// - 203.0.113.0/24 (TEST-NET-3)
     ///
-    /// [`true`]: ../../std/primitive.bool.html
     /// [IETF RFC 5737]: https://tools.ietf.org/html/rfc5737
     ///
     /// # Examples
@@ -727,8 +717,9 @@ impl Ipv4Addr {
     /// assert_eq!(Ipv4Addr::new(203, 0, 113, 6).is_documentation(), true);
     /// assert_eq!(Ipv4Addr::new(193, 34, 17, 19).is_documentation(), false);
     /// ```
+    #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
     #[stable(since = "1.7.0", feature = "ip_17")]
-    pub fn is_documentation(&self) -> bool {
+    pub const fn is_documentation(&self) -> bool {
         match self.octets() {
             [192, 0, 2, _] => true,
             [198, 51, 100, _] => true,
@@ -741,6 +732,9 @@ impl Ipv4Addr {
     ///
     /// a.b.c.d becomes ::a.b.c.d
     ///
+    /// This isn't typically the method you want; these addresses don't typically
+    /// function on modern systems. Use `to_ipv6_mapped` instead.
+    ///
     /// [`IPv6` address]: Ipv6Addr
     ///
     /// # Examples
@@ -753,10 +747,13 @@ impl Ipv4Addr {
     ///     Ipv6Addr::new(0, 0, 0, 0, 0, 0, 49152, 767)
     /// );
     /// ```
+    #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn to_ipv6_compatible(&self) -> Ipv6Addr {
+    pub const fn to_ipv6_compatible(&self) -> Ipv6Addr {
         let [a, b, c, d] = self.octets();
-        Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d])
+        Ipv6Addr {
+            inner: c::in6_addr { s6_addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d] },
+        }
     }
 
     /// Converts this address to an IPv4-mapped [`IPv6` address].
@@ -773,10 +770,13 @@ impl Ipv4Addr {
     /// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).to_ipv6_mapped(),
     ///            Ipv6Addr::new(0, 0, 0, 0, 0, 65535, 49152, 767));
     /// ```
+    #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn to_ipv6_mapped(&self) -> Ipv6Addr {
+    pub const fn to_ipv6_mapped(&self) -> Ipv6Addr {
         let [a, b, c, d] = self.octets();
-        Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d])
+        Ipv6Addr {
+            inner: c::in6_addr { s6_addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d] },
+        }
     }
 }
 
@@ -1098,8 +1098,9 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).segments(),
     ///            [0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff]);
     /// ```
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn segments(&self) -> [u16; 8] {
+    pub const fn segments(&self) -> [u16; 8] {
         // All elements in `s6_addr` must be big endian.
         // SAFETY: `[u8; 16]` is always safe to transmute to `[u16; 8]`.
         let [a, b, c, d, e, f, g, h] = unsafe { transmute::<_, [u16; 8]>(self.inner.s6_addr) };
@@ -1120,7 +1121,6 @@ impl Ipv6Addr {
     ///
     /// This property is defined in [IETF RFC 4291].
     ///
-    /// [`true`]: ../../std/primitive.bool.html
     /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
     ///
     /// # Examples
@@ -1131,16 +1131,16 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unspecified(), false);
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0).is_unspecified(), true);
     /// ```
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[stable(since = "1.7.0", feature = "ip_17")]
-    pub fn is_unspecified(&self) -> bool {
-        self.segments() == [0, 0, 0, 0, 0, 0, 0, 0]
+    pub const fn is_unspecified(&self) -> bool {
+        u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::UNSPECIFIED.octets())
     }
 
     /// Returns [`true`] if this is a loopback address (::1).
     ///
     /// This property is defined in [IETF RFC 4291].
     ///
-    /// [`true`]: ../../std/primitive.bool.html
     /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
     ///
     /// # Examples
@@ -1151,9 +1151,10 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_loopback(), false);
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_loopback(), true);
     /// ```
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[stable(since = "1.7.0", feature = "ip_17")]
-    pub fn is_loopback(&self) -> bool {
-        self.segments() == [0, 0, 0, 0, 0, 0, 0, 1]
+    pub const fn is_loopback(&self) -> bool {
+        u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::LOCALHOST.octets())
     }
 
     /// Returns [`true`] if the address appears to be globally routable.
@@ -1164,9 +1165,6 @@ impl Ipv6Addr {
     /// - link-local and unique local unicast addresses
     /// - interface-, link-, realm-, admin- and site-local multicast addresses
     ///
-    /// [`true`]: ../../std/primitive.bool.html
-    /// [`false`]: ../../std/primitive.bool.html
-    ///
     /// # Examples
     ///
     /// ```
@@ -1178,7 +1176,8 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_global(), false);
     /// assert_eq!(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1).is_global(), true);
     /// ```
-    pub fn is_global(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    pub const fn is_global(&self) -> bool {
         match self.multicast_scope() {
             Some(Ipv6MulticastScope::Global) => true,
             None => self.is_unicast_global(),
@@ -1192,8 +1191,6 @@ impl Ipv6Addr {
     ///
     /// [IETF RFC 4193]: https://tools.ietf.org/html/rfc4193
     ///
-    /// [`true`]: ../../std/primitive.bool.html
-    ///
     /// # Examples
     ///
     /// ```
@@ -1204,7 +1201,8 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unique_local(), false);
     /// assert_eq!(Ipv6Addr::new(0xfc02, 0, 0, 0, 0, 0, 0, 0).is_unique_local(), true);
     /// ```
-    pub fn is_unique_local(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    pub const fn is_unique_local(&self) -> bool {
         (self.segments()[0] & 0xfe00) == 0xfc00
     }
 
@@ -1225,8 +1223,6 @@ impl Ipv6Addr {
     /// addresses such as `fe80:0:0:1::` or `fe81::` as unicast link-local addresses for example.
     /// If you need a less strict validation use [`Ipv6Addr::is_unicast_link_local()`] instead.
     ///
-    /// [`true`]: ../../std/primitive.bool.html
-    ///
     /// # Examples
     ///
     /// ```
@@ -1259,7 +1255,8 @@ impl Ipv6Addr {
     /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
     /// [IETF RFC 4291 section 2.5.6]: https://tools.ietf.org/html/rfc4291#section-2.5.6
     /// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406
-    pub fn is_unicast_link_local_strict(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    pub const fn is_unicast_link_local_strict(&self) -> bool {
         (self.segments()[0] & 0xffff) == 0xfe80
             && (self.segments()[1] & 0xffff) == 0
             && (self.segments()[2] & 0xffff) == 0
@@ -1284,8 +1281,6 @@ impl Ipv6Addr {
     /// If you need a strict validation fully compliant with the RFC, use
     /// [`Ipv6Addr::is_unicast_link_local_strict()`] instead.
     ///
-    /// [`true`]: ../../std/primitive.bool.html
-    ///
     /// # Examples
     ///
     /// ```
@@ -1316,7 +1311,8 @@ impl Ipv6Addr {
     ///
     /// [IETF RFC 4291 section 2.4]: https://tools.ietf.org/html/rfc4291#section-2.4
     /// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406
-    pub fn is_unicast_link_local(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    pub const fn is_unicast_link_local(&self) -> bool {
         (self.segments()[0] & 0xffc0) == 0xfe80
     }
 
@@ -1331,7 +1327,6 @@ impl Ipv6Addr {
     /// +----------+-------------------------+----------------------------+
     /// ```
     ///
-    /// [`true`]: ../../std/primitive.bool.html
     /// [RFC 4291 section 2.5.7]: https://tools.ietf.org/html/rfc4291#section-2.5.7
     ///
     /// # Examples
@@ -1355,7 +1350,8 @@ impl Ipv6Addr {
     /// addresses.
     ///
     /// [RFC 3879]: https://tools.ietf.org/html/rfc3879
-    pub fn is_unicast_site_local(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    pub const fn is_unicast_site_local(&self) -> bool {
         (self.segments()[0] & 0xffc0) == 0xfec0
     }
 
@@ -1364,7 +1360,6 @@ impl Ipv6Addr {
     ///
     /// This property is defined in [IETF RFC 3849].
     ///
-    /// [`true`]: ../../std/primitive.bool.html
     /// [IETF RFC 3849]: https://tools.ietf.org/html/rfc3849
     ///
     /// # Examples
@@ -1377,7 +1372,8 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_documentation(), false);
     /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_documentation(), true);
     /// ```
-    pub fn is_documentation(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    pub const fn is_documentation(&self) -> bool {
         (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8)
     }
 
@@ -1399,7 +1395,6 @@ impl Ipv6Addr {
     /// Global Unicast).
     /// ```
     ///
-    /// [`true`]: ../../std/primitive.bool.html
     /// [RFC 4291 section 2.5.7]: https://tools.ietf.org/html/rfc4291#section-2.5.7
     ///
     /// # Examples
@@ -1412,7 +1407,8 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_unicast_global(), false);
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_global(), true);
     /// ```
-    pub fn is_unicast_global(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    pub const fn is_unicast_global(&self) -> bool {
         !self.is_multicast()
             && !self.is_loopback()
             && !self.is_unicast_link_local()
@@ -1436,7 +1432,8 @@ impl Ipv6Addr {
     /// );
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).multicast_scope(), None);
     /// ```
-    pub fn multicast_scope(&self) -> Option<Ipv6MulticastScope> {
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    pub const fn multicast_scope(&self) -> Option<Ipv6MulticastScope> {
         if self.is_multicast() {
             match self.segments()[0] & 0x000f {
                 1 => Some(Ipv6MulticastScope::InterfaceLocal),
@@ -1457,7 +1454,6 @@ impl Ipv6Addr {
     ///
     /// This property is defined by [IETF RFC 4291].
     ///
-    /// [`true`]: ../../std/primitive.bool.html
     /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
     ///
     /// # Examples
@@ -1468,8 +1464,9 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).is_multicast(), true);
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_multicast(), false);
     /// ```
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[stable(since = "1.7.0", feature = "ip_17")]
-    pub fn is_multicast(&self) -> bool {
+    pub const fn is_multicast(&self) -> bool {
         (self.segments()[0] & 0xff00) == 0xff00
     }
 
@@ -1494,7 +1491,8 @@ impl Ipv6Addr {
     ///            Some(Ipv4Addr::new(192, 10, 2, 255)));
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_ipv4_mapped(), None);
     /// ```
-    pub fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> {
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    pub const fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> {
         match self.octets() {
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, a, b, c, d] => {
                 Some(Ipv4Addr::new(a, b, c, d))
@@ -1521,8 +1519,9 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_ipv4(),
     ///            Some(Ipv4Addr::new(0, 0, 0, 1)));
     /// ```
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn to_ipv4(&self) -> Option<Ipv4Addr> {
+    pub const fn to_ipv4(&self) -> Option<Ipv4Addr> {
         if let [0, 0, 0, 0, 0, 0 | 0xffff, ab, cd] = self.segments() {
             let [a, b] = ab.to_be_bytes();
             let [c, d] = cd.to_be_bytes();
@@ -1895,862 +1894,3 @@ impl From<[u16; 8]> for IpAddr {
         IpAddr::V6(Ipv6Addr::from(segments))
     }
 }
-
-// Tests for this module
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod tests {
-    use crate::net::test::{sa4, sa6, tsa};
-    use crate::net::*;
-    use crate::str::FromStr;
-
-    #[test]
-    fn test_from_str_ipv4() {
-        assert_eq!(Ok(Ipv4Addr::new(127, 0, 0, 1)), "127.0.0.1".parse());
-        assert_eq!(Ok(Ipv4Addr::new(255, 255, 255, 255)), "255.255.255.255".parse());
-        assert_eq!(Ok(Ipv4Addr::new(0, 0, 0, 0)), "0.0.0.0".parse());
-
-        // out of range
-        let none: Option<Ipv4Addr> = "256.0.0.1".parse().ok();
-        assert_eq!(None, none);
-        // too short
-        let none: Option<Ipv4Addr> = "255.0.0".parse().ok();
-        assert_eq!(None, none);
-        // too long
-        let none: Option<Ipv4Addr> = "255.0.0.1.2".parse().ok();
-        assert_eq!(None, none);
-        // no number between dots
-        let none: Option<Ipv4Addr> = "255.0..1".parse().ok();
-        assert_eq!(None, none);
-    }
-
-    #[test]
-    fn test_from_str_ipv6() {
-        assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)), "0:0:0:0:0:0:0:0".parse());
-        assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), "0:0:0:0:0:0:0:1".parse());
-
-        assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), "::1".parse());
-        assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)), "::".parse());
-
-        assert_eq!(
-            Ok(Ipv6Addr::new(0x2a02, 0x6b8, 0, 0, 0, 0, 0x11, 0x11)),
-            "2a02:6b8::11:11".parse()
-        );
-
-        // too long group
-        let none: Option<Ipv6Addr> = "::00000".parse().ok();
-        assert_eq!(None, none);
-        // too short
-        let none: Option<Ipv6Addr> = "1:2:3:4:5:6:7".parse().ok();
-        assert_eq!(None, none);
-        // too long
-        let none: Option<Ipv6Addr> = "1:2:3:4:5:6:7:8:9".parse().ok();
-        assert_eq!(None, none);
-        // triple colon
-        let none: Option<Ipv6Addr> = "1:2:::6:7:8".parse().ok();
-        assert_eq!(None, none);
-        // two double colons
-        let none: Option<Ipv6Addr> = "1:2::6::8".parse().ok();
-        assert_eq!(None, none);
-        // `::` indicating zero groups of zeros
-        let none: Option<Ipv6Addr> = "1:2:3:4::5:6:7:8".parse().ok();
-        assert_eq!(None, none);
-    }
-
-    #[test]
-    fn test_from_str_ipv4_in_ipv6() {
-        assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 49152, 545)), "::192.0.2.33".parse());
-        assert_eq!(
-            Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0xFFFF, 49152, 545)),
-            "::FFFF:192.0.2.33".parse()
-        );
-        assert_eq!(
-            Ok(Ipv6Addr::new(0x64, 0xff9b, 0, 0, 0, 0, 49152, 545)),
-            "64:ff9b::192.0.2.33".parse()
-        );
-        assert_eq!(
-            Ok(Ipv6Addr::new(0x2001, 0xdb8, 0x122, 0xc000, 0x2, 0x2100, 49152, 545)),
-            "2001:db8:122:c000:2:2100:192.0.2.33".parse()
-        );
-
-        // colon after v4
-        let none: Option<Ipv4Addr> = "::127.0.0.1:".parse().ok();
-        assert_eq!(None, none);
-        // not enough groups
-        let none: Option<Ipv6Addr> = "1.2.3.4.5:127.0.0.1".parse().ok();
-        assert_eq!(None, none);
-        // too many groups
-        let none: Option<Ipv6Addr> = "1.2.3.4.5:6:7:127.0.0.1".parse().ok();
-        assert_eq!(None, none);
-    }
-
-    #[test]
-    fn test_from_str_socket_addr() {
-        assert_eq!(Ok(sa4(Ipv4Addr::new(77, 88, 21, 11), 80)), "77.88.21.11:80".parse());
-        assert_eq!(
-            Ok(SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80)),
-            "77.88.21.11:80".parse()
-        );
-        assert_eq!(
-            Ok(sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53)),
-            "[2a02:6b8:0:1::1]:53".parse()
-        );
-        assert_eq!(
-            Ok(SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53, 0, 0)),
-            "[2a02:6b8:0:1::1]:53".parse()
-        );
-        assert_eq!(
-            Ok(sa6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x7F00, 1), 22)),
-            "[::127.0.0.1]:22".parse()
-        );
-        assert_eq!(
-            Ok(SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x7F00, 1), 22, 0, 0)),
-            "[::127.0.0.1]:22".parse()
-        );
-
-        // without port
-        let none: Option<SocketAddr> = "127.0.0.1".parse().ok();
-        assert_eq!(None, none);
-        // without port
-        let none: Option<SocketAddr> = "127.0.0.1:".parse().ok();
-        assert_eq!(None, none);
-        // wrong brackets around v4
-        let none: Option<SocketAddr> = "[127.0.0.1]:22".parse().ok();
-        assert_eq!(None, none);
-        // port out of range
-        let none: Option<SocketAddr> = "127.0.0.1:123456".parse().ok();
-        assert_eq!(None, none);
-    }
-
-    #[test]
-    fn ipv4_addr_to_string() {
-        assert_eq!(Ipv4Addr::new(127, 0, 0, 1).to_string(), "127.0.0.1");
-        // Short address
-        assert_eq!(Ipv4Addr::new(1, 1, 1, 1).to_string(), "1.1.1.1");
-        // Long address
-        assert_eq!(Ipv4Addr::new(127, 127, 127, 127).to_string(), "127.127.127.127");
-
-        // Test padding
-        assert_eq!(&format!("{:16}", Ipv4Addr::new(1, 1, 1, 1)), "1.1.1.1         ");
-        assert_eq!(&format!("{:>16}", Ipv4Addr::new(1, 1, 1, 1)), "         1.1.1.1");
-    }
-
-    #[test]
-    fn ipv6_addr_to_string() {
-        // ipv4-mapped address
-        let a1 = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x280);
-        assert_eq!(a1.to_string(), "::ffff:192.0.2.128");
-
-        // ipv4-compatible address
-        let a1 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc000, 0x280);
-        assert_eq!(a1.to_string(), "::192.0.2.128");
-
-        // v6 address with no zero segments
-        assert_eq!(Ipv6Addr::new(8, 9, 10, 11, 12, 13, 14, 15).to_string(), "8:9:a:b:c:d:e:f");
-
-        // longest possible IPv6 length
-        assert_eq!(
-            Ipv6Addr::new(0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888)
-                .to_string(),
-            "1111:2222:3333:4444:5555:6666:7777:8888"
-        );
-        // padding
-        assert_eq!(
-            &format!("{:20}", Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8)),
-            "1:2:3:4:5:6:7:8     "
-        );
-        assert_eq!(
-            &format!("{:>20}", Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8)),
-            "     1:2:3:4:5:6:7:8"
-        );
-
-        // reduce a single run of zeros
-        assert_eq!(
-            "ae::ffff:102:304",
-            Ipv6Addr::new(0xae, 0, 0, 0, 0, 0xffff, 0x0102, 0x0304).to_string()
-        );
-
-        // don't reduce just a single zero segment
-        assert_eq!("1:2:3:4:5:6:0:8", Ipv6Addr::new(1, 2, 3, 4, 5, 6, 0, 8).to_string());
-
-        // 'any' address
-        assert_eq!("::", Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0).to_string());
-
-        // loopback address
-        assert_eq!("::1", Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_string());
-
-        // ends in zeros
-        assert_eq!("1::", Ipv6Addr::new(1, 0, 0, 0, 0, 0, 0, 0).to_string());
-
-        // two runs of zeros, second one is longer
-        assert_eq!("1:0:0:4::8", Ipv6Addr::new(1, 0, 0, 4, 0, 0, 0, 8).to_string());
-
-        // two runs of zeros, equal length
-        assert_eq!("1::4:5:0:0:8", Ipv6Addr::new(1, 0, 0, 4, 5, 0, 0, 8).to_string());
-    }
-
-    #[test]
-    fn ipv4_to_ipv6() {
-        assert_eq!(
-            Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678),
-            Ipv4Addr::new(0x12, 0x34, 0x56, 0x78).to_ipv6_mapped()
-        );
-        assert_eq!(
-            Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x1234, 0x5678),
-            Ipv4Addr::new(0x12, 0x34, 0x56, 0x78).to_ipv6_compatible()
-        );
-    }
-
-    #[test]
-    fn ipv6_to_ipv4_mapped() {
-        assert_eq!(
-            Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678).to_ipv4_mapped(),
-            Some(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78))
-        );
-        assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x1234, 0x5678).to_ipv4_mapped(), None);
-    }
-
-    #[test]
-    fn ipv6_to_ipv4() {
-        assert_eq!(
-            Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678).to_ipv4(),
-            Some(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78))
-        );
-        assert_eq!(
-            Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x1234, 0x5678).to_ipv4(),
-            Some(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78))
-        );
-        assert_eq!(Ipv6Addr::new(0, 0, 1, 0, 0, 0, 0x1234, 0x5678).to_ipv4(), None);
-    }
-
-    #[test]
-    fn ip_properties() {
-        macro_rules! ip {
-            ($s:expr) => {
-                IpAddr::from_str($s).unwrap()
-            };
-        }
-
-        macro_rules! check {
-            ($s:expr) => {
-                check!($s, 0);
-            };
-
-            ($s:expr, $mask:expr) => {{
-                let unspec: u8 = 1 << 0;
-                let loopback: u8 = 1 << 1;
-                let global: u8 = 1 << 2;
-                let multicast: u8 = 1 << 3;
-                let doc: u8 = 1 << 4;
-
-                if ($mask & unspec) == unspec {
-                    assert!(ip!($s).is_unspecified());
-                } else {
-                    assert!(!ip!($s).is_unspecified());
-                }
-
-                if ($mask & loopback) == loopback {
-                    assert!(ip!($s).is_loopback());
-                } else {
-                    assert!(!ip!($s).is_loopback());
-                }
-
-                if ($mask & global) == global {
-                    assert!(ip!($s).is_global());
-                } else {
-                    assert!(!ip!($s).is_global());
-                }
-
-                if ($mask & multicast) == multicast {
-                    assert!(ip!($s).is_multicast());
-                } else {
-                    assert!(!ip!($s).is_multicast());
-                }
-
-                if ($mask & doc) == doc {
-                    assert!(ip!($s).is_documentation());
-                } else {
-                    assert!(!ip!($s).is_documentation());
-                }
-            }};
-        }
-
-        let unspec: u8 = 1 << 0;
-        let loopback: u8 = 1 << 1;
-        let global: u8 = 1 << 2;
-        let multicast: u8 = 1 << 3;
-        let doc: u8 = 1 << 4;
-
-        check!("0.0.0.0", unspec);
-        check!("0.0.0.1");
-        check!("0.1.0.0");
-        check!("10.9.8.7");
-        check!("127.1.2.3", loopback);
-        check!("172.31.254.253");
-        check!("169.254.253.242");
-        check!("192.0.2.183", doc);
-        check!("192.1.2.183", global);
-        check!("192.168.254.253");
-        check!("198.51.100.0", doc);
-        check!("203.0.113.0", doc);
-        check!("203.2.113.0", global);
-        check!("224.0.0.0", global | multicast);
-        check!("239.255.255.255", global | multicast);
-        check!("255.255.255.255");
-        // make sure benchmarking addresses are not global
-        check!("198.18.0.0");
-        check!("198.18.54.2");
-        check!("198.19.255.255");
-        // make sure addresses reserved for protocol assignment are not global
-        check!("192.0.0.0");
-        check!("192.0.0.255");
-        check!("192.0.0.100");
-        // make sure reserved addresses are not global
-        check!("240.0.0.0");
-        check!("251.54.1.76");
-        check!("254.255.255.255");
-        // make sure shared addresses are not global
-        check!("100.64.0.0");
-        check!("100.127.255.255");
-        check!("100.100.100.0");
-
-        check!("::", unspec);
-        check!("::1", loopback);
-        check!("::0.0.0.2", global);
-        check!("1::", global);
-        check!("fc00::");
-        check!("fdff:ffff::");
-        check!("fe80:ffff::");
-        check!("febf:ffff::");
-        check!("fec0::", global);
-        check!("ff01::", multicast);
-        check!("ff02::", multicast);
-        check!("ff03::", multicast);
-        check!("ff04::", multicast);
-        check!("ff05::", multicast);
-        check!("ff08::", multicast);
-        check!("ff0e::", global | multicast);
-        check!("2001:db8:85a3::8a2e:370:7334", doc);
-        check!("102:304:506:708:90a:b0c:d0e:f10", global);
-    }
-
-    #[test]
-    fn ipv4_properties() {
-        macro_rules! ip {
-            ($s:expr) => {
-                Ipv4Addr::from_str($s).unwrap()
-            };
-        }
-
-        macro_rules! check {
-            ($s:expr) => {
-                check!($s, 0);
-            };
-
-            ($s:expr, $mask:expr) => {{
-                let unspec: u16 = 1 << 0;
-                let loopback: u16 = 1 << 1;
-                let private: u16 = 1 << 2;
-                let link_local: u16 = 1 << 3;
-                let global: u16 = 1 << 4;
-                let multicast: u16 = 1 << 5;
-                let broadcast: u16 = 1 << 6;
-                let documentation: u16 = 1 << 7;
-                let benchmarking: u16 = 1 << 8;
-                let ietf_protocol_assignment: u16 = 1 << 9;
-                let reserved: u16 = 1 << 10;
-                let shared: u16 = 1 << 11;
-
-                if ($mask & unspec) == unspec {
-                    assert!(ip!($s).is_unspecified());
-                } else {
-                    assert!(!ip!($s).is_unspecified());
-                }
-
-                if ($mask & loopback) == loopback {
-                    assert!(ip!($s).is_loopback());
-                } else {
-                    assert!(!ip!($s).is_loopback());
-                }
-
-                if ($mask & private) == private {
-                    assert!(ip!($s).is_private());
-                } else {
-                    assert!(!ip!($s).is_private());
-                }
-
-                if ($mask & link_local) == link_local {
-                    assert!(ip!($s).is_link_local());
-                } else {
-                    assert!(!ip!($s).is_link_local());
-                }
-
-                if ($mask & global) == global {
-                    assert!(ip!($s).is_global());
-                } else {
-                    assert!(!ip!($s).is_global());
-                }
-
-                if ($mask & multicast) == multicast {
-                    assert!(ip!($s).is_multicast());
-                } else {
-                    assert!(!ip!($s).is_multicast());
-                }
-
-                if ($mask & broadcast) == broadcast {
-                    assert!(ip!($s).is_broadcast());
-                } else {
-                    assert!(!ip!($s).is_broadcast());
-                }
-
-                if ($mask & documentation) == documentation {
-                    assert!(ip!($s).is_documentation());
-                } else {
-                    assert!(!ip!($s).is_documentation());
-                }
-
-                if ($mask & benchmarking) == benchmarking {
-                    assert!(ip!($s).is_benchmarking());
-                } else {
-                    assert!(!ip!($s).is_benchmarking());
-                }
-
-                if ($mask & ietf_protocol_assignment) == ietf_protocol_assignment {
-                    assert!(ip!($s).is_ietf_protocol_assignment());
-                } else {
-                    assert!(!ip!($s).is_ietf_protocol_assignment());
-                }
-
-                if ($mask & reserved) == reserved {
-                    assert!(ip!($s).is_reserved());
-                } else {
-                    assert!(!ip!($s).is_reserved());
-                }
-
-                if ($mask & shared) == shared {
-                    assert!(ip!($s).is_shared());
-                } else {
-                    assert!(!ip!($s).is_shared());
-                }
-            }};
-        }
-
-        let unspec: u16 = 1 << 0;
-        let loopback: u16 = 1 << 1;
-        let private: u16 = 1 << 2;
-        let link_local: u16 = 1 << 3;
-        let global: u16 = 1 << 4;
-        let multicast: u16 = 1 << 5;
-        let broadcast: u16 = 1 << 6;
-        let documentation: u16 = 1 << 7;
-        let benchmarking: u16 = 1 << 8;
-        let ietf_protocol_assignment: u16 = 1 << 9;
-        let reserved: u16 = 1 << 10;
-        let shared: u16 = 1 << 11;
-
-        check!("0.0.0.0", unspec);
-        check!("0.0.0.1");
-        check!("0.1.0.0");
-        check!("10.9.8.7", private);
-        check!("127.1.2.3", loopback);
-        check!("172.31.254.253", private);
-        check!("169.254.253.242", link_local);
-        check!("192.0.2.183", documentation);
-        check!("192.1.2.183", global);
-        check!("192.168.254.253", private);
-        check!("198.51.100.0", documentation);
-        check!("203.0.113.0", documentation);
-        check!("203.2.113.0", global);
-        check!("224.0.0.0", global | multicast);
-        check!("239.255.255.255", global | multicast);
-        check!("255.255.255.255", broadcast);
-        check!("198.18.0.0", benchmarking);
-        check!("198.18.54.2", benchmarking);
-        check!("198.19.255.255", benchmarking);
-        check!("192.0.0.0", ietf_protocol_assignment);
-        check!("192.0.0.255", ietf_protocol_assignment);
-        check!("192.0.0.100", ietf_protocol_assignment);
-        check!("240.0.0.0", reserved);
-        check!("251.54.1.76", reserved);
-        check!("254.255.255.255", reserved);
-        check!("100.64.0.0", shared);
-        check!("100.127.255.255", shared);
-        check!("100.100.100.0", shared);
-    }
-
-    #[test]
-    fn ipv6_properties() {
-        macro_rules! ip {
-            ($s:expr) => {
-                Ipv6Addr::from_str($s).unwrap()
-            };
-        }
-
-        macro_rules! check {
-            ($s:expr, &[$($octet:expr),*], $mask:expr) => {
-                assert_eq!($s, ip!($s).to_string());
-                let octets = &[$($octet),*];
-                assert_eq!(&ip!($s).octets(), octets);
-                assert_eq!(Ipv6Addr::from(*octets), ip!($s));
-
-                let unspecified: u16 = 1 << 0;
-                let loopback: u16 = 1 << 1;
-                let unique_local: u16 = 1 << 2;
-                let global: u16 = 1 << 3;
-                let unicast_link_local: u16 = 1 << 4;
-                let unicast_link_local_strict: u16 = 1 << 5;
-                let unicast_site_local: u16 = 1 << 6;
-                let unicast_global: u16 = 1 << 7;
-                let documentation: u16 = 1 << 8;
-                let multicast_interface_local: u16 = 1 << 9;
-                let multicast_link_local: u16 = 1 << 10;
-                let multicast_realm_local: u16 = 1 << 11;
-                let multicast_admin_local: u16 = 1 << 12;
-                let multicast_site_local: u16 = 1 << 13;
-                let multicast_organization_local: u16 = 1 << 14;
-                let multicast_global: u16 = 1 << 15;
-                let multicast: u16 = multicast_interface_local
-                    | multicast_admin_local
-                    | multicast_global
-                    | multicast_link_local
-                    | multicast_realm_local
-                    | multicast_site_local
-                    | multicast_organization_local;
-
-                if ($mask & unspecified) == unspecified {
-                    assert!(ip!($s).is_unspecified());
-                } else {
-                    assert!(!ip!($s).is_unspecified());
-                }
-                if ($mask & loopback) == loopback {
-                    assert!(ip!($s).is_loopback());
-                } else {
-                    assert!(!ip!($s).is_loopback());
-                }
-                if ($mask & unique_local) == unique_local {
-                    assert!(ip!($s).is_unique_local());
-                } else {
-                    assert!(!ip!($s).is_unique_local());
-                }
-                if ($mask & global) == global {
-                    assert!(ip!($s).is_global());
-                } else {
-                    assert!(!ip!($s).is_global());
-                }
-                if ($mask & unicast_link_local) == unicast_link_local {
-                    assert!(ip!($s).is_unicast_link_local());
-                } else {
-                    assert!(!ip!($s).is_unicast_link_local());
-                }
-                if ($mask & unicast_link_local_strict) == unicast_link_local_strict {
-                    assert!(ip!($s).is_unicast_link_local_strict());
-                } else {
-                    assert!(!ip!($s).is_unicast_link_local_strict());
-                }
-                if ($mask & unicast_site_local) == unicast_site_local {
-                    assert!(ip!($s).is_unicast_site_local());
-                } else {
-                    assert!(!ip!($s).is_unicast_site_local());
-                }
-                if ($mask & unicast_global) == unicast_global {
-                    assert!(ip!($s).is_unicast_global());
-                } else {
-                    assert!(!ip!($s).is_unicast_global());
-                }
-                if ($mask & documentation) == documentation {
-                    assert!(ip!($s).is_documentation());
-                } else {
-                    assert!(!ip!($s).is_documentation());
-                }
-                if ($mask & multicast) != 0 {
-                    assert!(ip!($s).multicast_scope().is_some());
-                    assert!(ip!($s).is_multicast());
-                } else {
-                    assert!(ip!($s).multicast_scope().is_none());
-                    assert!(!ip!($s).is_multicast());
-                }
-                if ($mask & multicast_interface_local) == multicast_interface_local {
-                    assert_eq!(ip!($s).multicast_scope().unwrap(),
-                               Ipv6MulticastScope::InterfaceLocal);
-                }
-                if ($mask & multicast_link_local) == multicast_link_local {
-                    assert_eq!(ip!($s).multicast_scope().unwrap(),
-                               Ipv6MulticastScope::LinkLocal);
-                }
-                if ($mask & multicast_realm_local) == multicast_realm_local {
-                    assert_eq!(ip!($s).multicast_scope().unwrap(),
-                               Ipv6MulticastScope::RealmLocal);
-                }
-                if ($mask & multicast_admin_local) == multicast_admin_local {
-                    assert_eq!(ip!($s).multicast_scope().unwrap(),
-                               Ipv6MulticastScope::AdminLocal);
-                }
-                if ($mask & multicast_site_local) == multicast_site_local {
-                    assert_eq!(ip!($s).multicast_scope().unwrap(),
-                               Ipv6MulticastScope::SiteLocal);
-                }
-                if ($mask & multicast_organization_local) == multicast_organization_local {
-                    assert_eq!(ip!($s).multicast_scope().unwrap(),
-                               Ipv6MulticastScope::OrganizationLocal);
-                }
-                if ($mask & multicast_global) == multicast_global {
-                    assert_eq!(ip!($s).multicast_scope().unwrap(),
-                               Ipv6MulticastScope::Global);
-                }
-            }
-        }
-
-        let unspecified: u16 = 1 << 0;
-        let loopback: u16 = 1 << 1;
-        let unique_local: u16 = 1 << 2;
-        let global: u16 = 1 << 3;
-        let unicast_link_local: u16 = 1 << 4;
-        let unicast_link_local_strict: u16 = 1 << 5;
-        let unicast_site_local: u16 = 1 << 6;
-        let unicast_global: u16 = 1 << 7;
-        let documentation: u16 = 1 << 8;
-        let multicast_interface_local: u16 = 1 << 9;
-        let multicast_link_local: u16 = 1 << 10;
-        let multicast_realm_local: u16 = 1 << 11;
-        let multicast_admin_local: u16 = 1 << 12;
-        let multicast_site_local: u16 = 1 << 13;
-        let multicast_organization_local: u16 = 1 << 14;
-        let multicast_global: u16 = 1 << 15;
-
-        check!("::", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unspecified);
-
-        check!("::1", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], loopback);
-
-        check!(
-            "::0.0.0.2",
-            &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
-            global | unicast_global
-        );
-
-        check!("1::", &[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], global | unicast_global);
-
-        check!("fc00::", &[0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unique_local);
-
-        check!(
-            "fdff:ffff::",
-            &[0xfd, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            unique_local
-        );
-
-        check!(
-            "fe80:ffff::",
-            &[0xfe, 0x80, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            unicast_link_local
-        );
-
-        check!(
-            "fe80::",
-            &[0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            unicast_link_local | unicast_link_local_strict
-        );
-
-        check!(
-            "febf:ffff::",
-            &[0xfe, 0xbf, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            unicast_link_local
-        );
-
-        check!(
-            "febf::",
-            &[0xfe, 0xbf, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            unicast_link_local
-        );
-
-        check!(
-            "febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
-            &[
-                0xfe, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-                0xff, 0xff
-            ],
-            unicast_link_local
-        );
-
-        check!(
-            "fe80::ffff:ffff:ffff:ffff",
-            &[
-                0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-                0xff, 0xff
-            ],
-            unicast_link_local | unicast_link_local_strict
-        );
-
-        check!(
-            "fe80:0:0:1::",
-            &[0xfe, 0x80, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
-            unicast_link_local
-        );
-
-        check!(
-            "fec0::",
-            &[0xfe, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            unicast_site_local | unicast_global | global
-        );
-
-        check!(
-            "ff01::",
-            &[0xff, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            multicast_interface_local
-        );
-
-        check!(
-            "ff02::",
-            &[0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            multicast_link_local
-        );
-
-        check!(
-            "ff03::",
-            &[0xff, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            multicast_realm_local
-        );
-
-        check!(
-            "ff04::",
-            &[0xff, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            multicast_admin_local
-        );
-
-        check!(
-            "ff05::",
-            &[0xff, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            multicast_site_local
-        );
-
-        check!(
-            "ff08::",
-            &[0xff, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            multicast_organization_local
-        );
-
-        check!(
-            "ff0e::",
-            &[0xff, 0xe, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            multicast_global | global
-        );
-
-        check!(
-            "2001:db8:85a3::8a2e:370:7334",
-            &[0x20, 1, 0xd, 0xb8, 0x85, 0xa3, 0, 0, 0, 0, 0x8a, 0x2e, 3, 0x70, 0x73, 0x34],
-            documentation
-        );
-
-        check!(
-            "102:304:506:708:90a:b0c:d0e:f10",
-            &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
-            global | unicast_global
-        );
-    }
-
-    #[test]
-    fn to_socket_addr_socketaddr() {
-        let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 12345);
-        assert_eq!(Ok(vec![a]), tsa(a));
-    }
-
-    #[test]
-    fn test_ipv4_to_int() {
-        let a = Ipv4Addr::new(0x11, 0x22, 0x33, 0x44);
-        assert_eq!(u32::from(a), 0x11223344);
-    }
-
-    #[test]
-    fn test_int_to_ipv4() {
-        let a = Ipv4Addr::new(0x11, 0x22, 0x33, 0x44);
-        assert_eq!(Ipv4Addr::from(0x11223344), a);
-    }
-
-    #[test]
-    fn test_ipv6_to_int() {
-        let a = Ipv6Addr::new(0x1122, 0x3344, 0x5566, 0x7788, 0x99aa, 0xbbcc, 0xddee, 0xff11);
-        assert_eq!(u128::from(a), 0x112233445566778899aabbccddeeff11u128);
-    }
-
-    #[test]
-    fn test_int_to_ipv6() {
-        let a = Ipv6Addr::new(0x1122, 0x3344, 0x5566, 0x7788, 0x99aa, 0xbbcc, 0xddee, 0xff11);
-        assert_eq!(Ipv6Addr::from(0x112233445566778899aabbccddeeff11u128), a);
-    }
-
-    #[test]
-    fn ipv4_from_constructors() {
-        assert_eq!(Ipv4Addr::LOCALHOST, Ipv4Addr::new(127, 0, 0, 1));
-        assert!(Ipv4Addr::LOCALHOST.is_loopback());
-        assert_eq!(Ipv4Addr::UNSPECIFIED, Ipv4Addr::new(0, 0, 0, 0));
-        assert!(Ipv4Addr::UNSPECIFIED.is_unspecified());
-        assert_eq!(Ipv4Addr::BROADCAST, Ipv4Addr::new(255, 255, 255, 255));
-        assert!(Ipv4Addr::BROADCAST.is_broadcast());
-    }
-
-    #[test]
-    fn ipv6_from_contructors() {
-        assert_eq!(Ipv6Addr::LOCALHOST, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
-        assert!(Ipv6Addr::LOCALHOST.is_loopback());
-        assert_eq!(Ipv6Addr::UNSPECIFIED, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
-        assert!(Ipv6Addr::UNSPECIFIED.is_unspecified());
-    }
-
-    #[test]
-    fn ipv4_from_octets() {
-        assert_eq!(Ipv4Addr::from([127, 0, 0, 1]), Ipv4Addr::new(127, 0, 0, 1))
-    }
-
-    #[test]
-    fn ipv6_from_segments() {
-        let from_u16s =
-            Ipv6Addr::from([0x0011, 0x2233, 0x4455, 0x6677, 0x8899, 0xaabb, 0xccdd, 0xeeff]);
-        let new = Ipv6Addr::new(0x0011, 0x2233, 0x4455, 0x6677, 0x8899, 0xaabb, 0xccdd, 0xeeff);
-        assert_eq!(new, from_u16s);
-    }
-
-    #[test]
-    fn ipv6_from_octets() {
-        let from_u16s =
-            Ipv6Addr::from([0x0011, 0x2233, 0x4455, 0x6677, 0x8899, 0xaabb, 0xccdd, 0xeeff]);
-        let from_u8s = Ipv6Addr::from([
-            0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd,
-            0xee, 0xff,
-        ]);
-        assert_eq!(from_u16s, from_u8s);
-    }
-
-    #[test]
-    fn cmp() {
-        let v41 = Ipv4Addr::new(100, 64, 3, 3);
-        let v42 = Ipv4Addr::new(192, 0, 2, 2);
-        let v61 = "2001:db8:f00::1002".parse::<Ipv6Addr>().unwrap();
-        let v62 = "2001:db8:f00::2001".parse::<Ipv6Addr>().unwrap();
-        assert!(v41 < v42);
-        assert!(v61 < v62);
-
-        assert_eq!(v41, IpAddr::V4(v41));
-        assert_eq!(v61, IpAddr::V6(v61));
-        assert!(v41 != IpAddr::V4(v42));
-        assert!(v61 != IpAddr::V6(v62));
-
-        assert!(v41 < IpAddr::V4(v42));
-        assert!(v61 < IpAddr::V6(v62));
-        assert!(IpAddr::V4(v41) < v42);
-        assert!(IpAddr::V6(v61) < v62);
-
-        assert!(v41 < IpAddr::V6(v61));
-        assert!(IpAddr::V4(v41) < v61);
-    }
-
-    #[test]
-    fn is_v4() {
-        let ip = IpAddr::V4(Ipv4Addr::new(100, 64, 3, 3));
-        assert!(ip.is_ipv4());
-        assert!(!ip.is_ipv6());
-    }
-
-    #[test]
-    fn is_v6() {
-        let ip = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678));
-        assert!(!ip.is_ipv4());
-        assert!(ip.is_ipv6());
-    }
-}
diff --git a/library/std/src/net/ip/tests.rs b/library/std/src/net/ip/tests.rs
new file mode 100644
index 00000000000..a2fba4b4cca
--- /dev/null
+++ b/library/std/src/net/ip/tests.rs
@@ -0,0 +1,811 @@
+use crate::net::test::{sa4, sa6, tsa};
+use crate::net::*;
+use crate::str::FromStr;
+
+#[test]
+fn test_from_str_ipv4() {
+    assert_eq!(Ok(Ipv4Addr::new(127, 0, 0, 1)), "127.0.0.1".parse());
+    assert_eq!(Ok(Ipv4Addr::new(255, 255, 255, 255)), "255.255.255.255".parse());
+    assert_eq!(Ok(Ipv4Addr::new(0, 0, 0, 0)), "0.0.0.0".parse());
+
+    // out of range
+    let none: Option<Ipv4Addr> = "256.0.0.1".parse().ok();
+    assert_eq!(None, none);
+    // too short
+    let none: Option<Ipv4Addr> = "255.0.0".parse().ok();
+    assert_eq!(None, none);
+    // too long
+    let none: Option<Ipv4Addr> = "255.0.0.1.2".parse().ok();
+    assert_eq!(None, none);
+    // no number between dots
+    let none: Option<Ipv4Addr> = "255.0..1".parse().ok();
+    assert_eq!(None, none);
+}
+
+#[test]
+fn test_from_str_ipv6() {
+    assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)), "0:0:0:0:0:0:0:0".parse());
+    assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), "0:0:0:0:0:0:0:1".parse());
+
+    assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), "::1".parse());
+    assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)), "::".parse());
+
+    assert_eq!(Ok(Ipv6Addr::new(0x2a02, 0x6b8, 0, 0, 0, 0, 0x11, 0x11)), "2a02:6b8::11:11".parse());
+
+    // too long group
+    let none: Option<Ipv6Addr> = "::00000".parse().ok();
+    assert_eq!(None, none);
+    // too short
+    let none: Option<Ipv6Addr> = "1:2:3:4:5:6:7".parse().ok();
+    assert_eq!(None, none);
+    // too long
+    let none: Option<Ipv6Addr> = "1:2:3:4:5:6:7:8:9".parse().ok();
+    assert_eq!(None, none);
+    // triple colon
+    let none: Option<Ipv6Addr> = "1:2:::6:7:8".parse().ok();
+    assert_eq!(None, none);
+    // two double colons
+    let none: Option<Ipv6Addr> = "1:2::6::8".parse().ok();
+    assert_eq!(None, none);
+    // `::` indicating zero groups of zeros
+    let none: Option<Ipv6Addr> = "1:2:3:4::5:6:7:8".parse().ok();
+    assert_eq!(None, none);
+}
+
+#[test]
+fn test_from_str_ipv4_in_ipv6() {
+    assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 49152, 545)), "::192.0.2.33".parse());
+    assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0xFFFF, 49152, 545)), "::FFFF:192.0.2.33".parse());
+    assert_eq!(
+        Ok(Ipv6Addr::new(0x64, 0xff9b, 0, 0, 0, 0, 49152, 545)),
+        "64:ff9b::192.0.2.33".parse()
+    );
+    assert_eq!(
+        Ok(Ipv6Addr::new(0x2001, 0xdb8, 0x122, 0xc000, 0x2, 0x2100, 49152, 545)),
+        "2001:db8:122:c000:2:2100:192.0.2.33".parse()
+    );
+
+    // colon after v4
+    let none: Option<Ipv4Addr> = "::127.0.0.1:".parse().ok();
+    assert_eq!(None, none);
+    // not enough groups
+    let none: Option<Ipv6Addr> = "1.2.3.4.5:127.0.0.1".parse().ok();
+    assert_eq!(None, none);
+    // too many groups
+    let none: Option<Ipv6Addr> = "1.2.3.4.5:6:7:127.0.0.1".parse().ok();
+    assert_eq!(None, none);
+}
+
+#[test]
+fn test_from_str_socket_addr() {
+    assert_eq!(Ok(sa4(Ipv4Addr::new(77, 88, 21, 11), 80)), "77.88.21.11:80".parse());
+    assert_eq!(Ok(SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80)), "77.88.21.11:80".parse());
+    assert_eq!(
+        Ok(sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53)),
+        "[2a02:6b8:0:1::1]:53".parse()
+    );
+    assert_eq!(
+        Ok(SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53, 0, 0)),
+        "[2a02:6b8:0:1::1]:53".parse()
+    );
+    assert_eq!(Ok(sa6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x7F00, 1), 22)), "[::127.0.0.1]:22".parse());
+    assert_eq!(
+        Ok(SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x7F00, 1), 22, 0, 0)),
+        "[::127.0.0.1]:22".parse()
+    );
+
+    // without port
+    let none: Option<SocketAddr> = "127.0.0.1".parse().ok();
+    assert_eq!(None, none);
+    // without port
+    let none: Option<SocketAddr> = "127.0.0.1:".parse().ok();
+    assert_eq!(None, none);
+    // wrong brackets around v4
+    let none: Option<SocketAddr> = "[127.0.0.1]:22".parse().ok();
+    assert_eq!(None, none);
+    // port out of range
+    let none: Option<SocketAddr> = "127.0.0.1:123456".parse().ok();
+    assert_eq!(None, none);
+}
+
+#[test]
+fn ipv4_addr_to_string() {
+    assert_eq!(Ipv4Addr::new(127, 0, 0, 1).to_string(), "127.0.0.1");
+    // Short address
+    assert_eq!(Ipv4Addr::new(1, 1, 1, 1).to_string(), "1.1.1.1");
+    // Long address
+    assert_eq!(Ipv4Addr::new(127, 127, 127, 127).to_string(), "127.127.127.127");
+
+    // Test padding
+    assert_eq!(&format!("{:16}", Ipv4Addr::new(1, 1, 1, 1)), "1.1.1.1         ");
+    assert_eq!(&format!("{:>16}", Ipv4Addr::new(1, 1, 1, 1)), "         1.1.1.1");
+}
+
+#[test]
+fn ipv6_addr_to_string() {
+    // ipv4-mapped address
+    let a1 = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x280);
+    assert_eq!(a1.to_string(), "::ffff:192.0.2.128");
+
+    // ipv4-compatible address
+    let a1 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc000, 0x280);
+    assert_eq!(a1.to_string(), "::192.0.2.128");
+
+    // v6 address with no zero segments
+    assert_eq!(Ipv6Addr::new(8, 9, 10, 11, 12, 13, 14, 15).to_string(), "8:9:a:b:c:d:e:f");
+
+    // longest possible IPv6 length
+    assert_eq!(
+        Ipv6Addr::new(0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888).to_string(),
+        "1111:2222:3333:4444:5555:6666:7777:8888"
+    );
+    // padding
+    assert_eq!(&format!("{:20}", Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8)), "1:2:3:4:5:6:7:8     ");
+    assert_eq!(&format!("{:>20}", Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8)), "     1:2:3:4:5:6:7:8");
+
+    // reduce a single run of zeros
+    assert_eq!(
+        "ae::ffff:102:304",
+        Ipv6Addr::new(0xae, 0, 0, 0, 0, 0xffff, 0x0102, 0x0304).to_string()
+    );
+
+    // don't reduce just a single zero segment
+    assert_eq!("1:2:3:4:5:6:0:8", Ipv6Addr::new(1, 2, 3, 4, 5, 6, 0, 8).to_string());
+
+    // 'any' address
+    assert_eq!("::", Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0).to_string());
+
+    // loopback address
+    assert_eq!("::1", Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_string());
+
+    // ends in zeros
+    assert_eq!("1::", Ipv6Addr::new(1, 0, 0, 0, 0, 0, 0, 0).to_string());
+
+    // two runs of zeros, second one is longer
+    assert_eq!("1:0:0:4::8", Ipv6Addr::new(1, 0, 0, 4, 0, 0, 0, 8).to_string());
+
+    // two runs of zeros, equal length
+    assert_eq!("1::4:5:0:0:8", Ipv6Addr::new(1, 0, 0, 4, 5, 0, 0, 8).to_string());
+}
+
+#[test]
+fn ipv4_to_ipv6() {
+    assert_eq!(
+        Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678),
+        Ipv4Addr::new(0x12, 0x34, 0x56, 0x78).to_ipv6_mapped()
+    );
+    assert_eq!(
+        Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x1234, 0x5678),
+        Ipv4Addr::new(0x12, 0x34, 0x56, 0x78).to_ipv6_compatible()
+    );
+}
+
+#[test]
+fn ipv6_to_ipv4_mapped() {
+    assert_eq!(
+        Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678).to_ipv4_mapped(),
+        Some(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78))
+    );
+    assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x1234, 0x5678).to_ipv4_mapped(), None);
+}
+
+#[test]
+fn ipv6_to_ipv4() {
+    assert_eq!(
+        Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678).to_ipv4(),
+        Some(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78))
+    );
+    assert_eq!(
+        Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x1234, 0x5678).to_ipv4(),
+        Some(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78))
+    );
+    assert_eq!(Ipv6Addr::new(0, 0, 1, 0, 0, 0, 0x1234, 0x5678).to_ipv4(), None);
+}
+
+#[test]
+fn ip_properties() {
+    macro_rules! ip {
+        ($s:expr) => {
+            IpAddr::from_str($s).unwrap()
+        };
+    }
+
+    macro_rules! check {
+        ($s:expr) => {
+            check!($s, 0);
+        };
+
+        ($s:expr, $mask:expr) => {{
+            let unspec: u8 = 1 << 0;
+            let loopback: u8 = 1 << 1;
+            let global: u8 = 1 << 2;
+            let multicast: u8 = 1 << 3;
+            let doc: u8 = 1 << 4;
+
+            if ($mask & unspec) == unspec {
+                assert!(ip!($s).is_unspecified());
+            } else {
+                assert!(!ip!($s).is_unspecified());
+            }
+
+            if ($mask & loopback) == loopback {
+                assert!(ip!($s).is_loopback());
+            } else {
+                assert!(!ip!($s).is_loopback());
+            }
+
+            if ($mask & global) == global {
+                assert!(ip!($s).is_global());
+            } else {
+                assert!(!ip!($s).is_global());
+            }
+
+            if ($mask & multicast) == multicast {
+                assert!(ip!($s).is_multicast());
+            } else {
+                assert!(!ip!($s).is_multicast());
+            }
+
+            if ($mask & doc) == doc {
+                assert!(ip!($s).is_documentation());
+            } else {
+                assert!(!ip!($s).is_documentation());
+            }
+        }};
+    }
+
+    let unspec: u8 = 1 << 0;
+    let loopback: u8 = 1 << 1;
+    let global: u8 = 1 << 2;
+    let multicast: u8 = 1 << 3;
+    let doc: u8 = 1 << 4;
+
+    check!("0.0.0.0", unspec);
+    check!("0.0.0.1");
+    check!("0.1.0.0");
+    check!("10.9.8.7");
+    check!("127.1.2.3", loopback);
+    check!("172.31.254.253");
+    check!("169.254.253.242");
+    check!("192.0.2.183", doc);
+    check!("192.1.2.183", global);
+    check!("192.168.254.253");
+    check!("198.51.100.0", doc);
+    check!("203.0.113.0", doc);
+    check!("203.2.113.0", global);
+    check!("224.0.0.0", global | multicast);
+    check!("239.255.255.255", global | multicast);
+    check!("255.255.255.255");
+    // make sure benchmarking addresses are not global
+    check!("198.18.0.0");
+    check!("198.18.54.2");
+    check!("198.19.255.255");
+    // make sure addresses reserved for protocol assignment are not global
+    check!("192.0.0.0");
+    check!("192.0.0.255");
+    check!("192.0.0.100");
+    // make sure reserved addresses are not global
+    check!("240.0.0.0");
+    check!("251.54.1.76");
+    check!("254.255.255.255");
+    // make sure shared addresses are not global
+    check!("100.64.0.0");
+    check!("100.127.255.255");
+    check!("100.100.100.0");
+
+    check!("::", unspec);
+    check!("::1", loopback);
+    check!("::0.0.0.2", global);
+    check!("1::", global);
+    check!("fc00::");
+    check!("fdff:ffff::");
+    check!("fe80:ffff::");
+    check!("febf:ffff::");
+    check!("fec0::", global);
+    check!("ff01::", multicast);
+    check!("ff02::", multicast);
+    check!("ff03::", multicast);
+    check!("ff04::", multicast);
+    check!("ff05::", multicast);
+    check!("ff08::", multicast);
+    check!("ff0e::", global | multicast);
+    check!("2001:db8:85a3::8a2e:370:7334", doc);
+    check!("102:304:506:708:90a:b0c:d0e:f10", global);
+}
+
+#[test]
+fn ipv4_properties() {
+    macro_rules! ip {
+        ($s:expr) => {
+            Ipv4Addr::from_str($s).unwrap()
+        };
+    }
+
+    macro_rules! check {
+        ($s:expr) => {
+            check!($s, 0);
+        };
+
+        ($s:expr, $mask:expr) => {{
+            let unspec: u16 = 1 << 0;
+            let loopback: u16 = 1 << 1;
+            let private: u16 = 1 << 2;
+            let link_local: u16 = 1 << 3;
+            let global: u16 = 1 << 4;
+            let multicast: u16 = 1 << 5;
+            let broadcast: u16 = 1 << 6;
+            let documentation: u16 = 1 << 7;
+            let benchmarking: u16 = 1 << 8;
+            let ietf_protocol_assignment: u16 = 1 << 9;
+            let reserved: u16 = 1 << 10;
+            let shared: u16 = 1 << 11;
+
+            if ($mask & unspec) == unspec {
+                assert!(ip!($s).is_unspecified());
+            } else {
+                assert!(!ip!($s).is_unspecified());
+            }
+
+            if ($mask & loopback) == loopback {
+                assert!(ip!($s).is_loopback());
+            } else {
+                assert!(!ip!($s).is_loopback());
+            }
+
+            if ($mask & private) == private {
+                assert!(ip!($s).is_private());
+            } else {
+                assert!(!ip!($s).is_private());
+            }
+
+            if ($mask & link_local) == link_local {
+                assert!(ip!($s).is_link_local());
+            } else {
+                assert!(!ip!($s).is_link_local());
+            }
+
+            if ($mask & global) == global {
+                assert!(ip!($s).is_global());
+            } else {
+                assert!(!ip!($s).is_global());
+            }
+
+            if ($mask & multicast) == multicast {
+                assert!(ip!($s).is_multicast());
+            } else {
+                assert!(!ip!($s).is_multicast());
+            }
+
+            if ($mask & broadcast) == broadcast {
+                assert!(ip!($s).is_broadcast());
+            } else {
+                assert!(!ip!($s).is_broadcast());
+            }
+
+            if ($mask & documentation) == documentation {
+                assert!(ip!($s).is_documentation());
+            } else {
+                assert!(!ip!($s).is_documentation());
+            }
+
+            if ($mask & benchmarking) == benchmarking {
+                assert!(ip!($s).is_benchmarking());
+            } else {
+                assert!(!ip!($s).is_benchmarking());
+            }
+
+            if ($mask & ietf_protocol_assignment) == ietf_protocol_assignment {
+                assert!(ip!($s).is_ietf_protocol_assignment());
+            } else {
+                assert!(!ip!($s).is_ietf_protocol_assignment());
+            }
+
+            if ($mask & reserved) == reserved {
+                assert!(ip!($s).is_reserved());
+            } else {
+                assert!(!ip!($s).is_reserved());
+            }
+
+            if ($mask & shared) == shared {
+                assert!(ip!($s).is_shared());
+            } else {
+                assert!(!ip!($s).is_shared());
+            }
+        }};
+    }
+
+    let unspec: u16 = 1 << 0;
+    let loopback: u16 = 1 << 1;
+    let private: u16 = 1 << 2;
+    let link_local: u16 = 1 << 3;
+    let global: u16 = 1 << 4;
+    let multicast: u16 = 1 << 5;
+    let broadcast: u16 = 1 << 6;
+    let documentation: u16 = 1 << 7;
+    let benchmarking: u16 = 1 << 8;
+    let ietf_protocol_assignment: u16 = 1 << 9;
+    let reserved: u16 = 1 << 10;
+    let shared: u16 = 1 << 11;
+
+    check!("0.0.0.0", unspec);
+    check!("0.0.0.1");
+    check!("0.1.0.0");
+    check!("10.9.8.7", private);
+    check!("127.1.2.3", loopback);
+    check!("172.31.254.253", private);
+    check!("169.254.253.242", link_local);
+    check!("192.0.2.183", documentation);
+    check!("192.1.2.183", global);
+    check!("192.168.254.253", private);
+    check!("198.51.100.0", documentation);
+    check!("203.0.113.0", documentation);
+    check!("203.2.113.0", global);
+    check!("224.0.0.0", global | multicast);
+    check!("239.255.255.255", global | multicast);
+    check!("255.255.255.255", broadcast);
+    check!("198.18.0.0", benchmarking);
+    check!("198.18.54.2", benchmarking);
+    check!("198.19.255.255", benchmarking);
+    check!("192.0.0.0", ietf_protocol_assignment);
+    check!("192.0.0.255", ietf_protocol_assignment);
+    check!("192.0.0.100", ietf_protocol_assignment);
+    check!("240.0.0.0", reserved);
+    check!("251.54.1.76", reserved);
+    check!("254.255.255.255", reserved);
+    check!("100.64.0.0", shared);
+    check!("100.127.255.255", shared);
+    check!("100.100.100.0", shared);
+}
+
+#[test]
+fn ipv6_properties() {
+    macro_rules! ip {
+        ($s:expr) => {
+            Ipv6Addr::from_str($s).unwrap()
+        };
+    }
+
+    macro_rules! check {
+        ($s:expr, &[$($octet:expr),*], $mask:expr) => {
+            assert_eq!($s, ip!($s).to_string());
+            let octets = &[$($octet),*];
+            assert_eq!(&ip!($s).octets(), octets);
+            assert_eq!(Ipv6Addr::from(*octets), ip!($s));
+
+            let unspecified: u16 = 1 << 0;
+            let loopback: u16 = 1 << 1;
+            let unique_local: u16 = 1 << 2;
+            let global: u16 = 1 << 3;
+            let unicast_link_local: u16 = 1 << 4;
+            let unicast_link_local_strict: u16 = 1 << 5;
+            let unicast_site_local: u16 = 1 << 6;
+            let unicast_global: u16 = 1 << 7;
+            let documentation: u16 = 1 << 8;
+            let multicast_interface_local: u16 = 1 << 9;
+            let multicast_link_local: u16 = 1 << 10;
+            let multicast_realm_local: u16 = 1 << 11;
+            let multicast_admin_local: u16 = 1 << 12;
+            let multicast_site_local: u16 = 1 << 13;
+            let multicast_organization_local: u16 = 1 << 14;
+            let multicast_global: u16 = 1 << 15;
+            let multicast: u16 = multicast_interface_local
+                | multicast_admin_local
+                | multicast_global
+                | multicast_link_local
+                | multicast_realm_local
+                | multicast_site_local
+                | multicast_organization_local;
+
+            if ($mask & unspecified) == unspecified {
+                assert!(ip!($s).is_unspecified());
+            } else {
+                assert!(!ip!($s).is_unspecified());
+            }
+            if ($mask & loopback) == loopback {
+                assert!(ip!($s).is_loopback());
+            } else {
+                assert!(!ip!($s).is_loopback());
+            }
+            if ($mask & unique_local) == unique_local {
+                assert!(ip!($s).is_unique_local());
+            } else {
+                assert!(!ip!($s).is_unique_local());
+            }
+            if ($mask & global) == global {
+                assert!(ip!($s).is_global());
+            } else {
+                assert!(!ip!($s).is_global());
+            }
+            if ($mask & unicast_link_local) == unicast_link_local {
+                assert!(ip!($s).is_unicast_link_local());
+            } else {
+                assert!(!ip!($s).is_unicast_link_local());
+            }
+            if ($mask & unicast_link_local_strict) == unicast_link_local_strict {
+                assert!(ip!($s).is_unicast_link_local_strict());
+            } else {
+                assert!(!ip!($s).is_unicast_link_local_strict());
+            }
+            if ($mask & unicast_site_local) == unicast_site_local {
+                assert!(ip!($s).is_unicast_site_local());
+            } else {
+                assert!(!ip!($s).is_unicast_site_local());
+            }
+            if ($mask & unicast_global) == unicast_global {
+                assert!(ip!($s).is_unicast_global());
+            } else {
+                assert!(!ip!($s).is_unicast_global());
+            }
+            if ($mask & documentation) == documentation {
+                assert!(ip!($s).is_documentation());
+            } else {
+                assert!(!ip!($s).is_documentation());
+            }
+            if ($mask & multicast) != 0 {
+                assert!(ip!($s).multicast_scope().is_some());
+                assert!(ip!($s).is_multicast());
+            } else {
+                assert!(ip!($s).multicast_scope().is_none());
+                assert!(!ip!($s).is_multicast());
+            }
+            if ($mask & multicast_interface_local) == multicast_interface_local {
+                assert_eq!(ip!($s).multicast_scope().unwrap(),
+                           Ipv6MulticastScope::InterfaceLocal);
+            }
+            if ($mask & multicast_link_local) == multicast_link_local {
+                assert_eq!(ip!($s).multicast_scope().unwrap(),
+                           Ipv6MulticastScope::LinkLocal);
+            }
+            if ($mask & multicast_realm_local) == multicast_realm_local {
+                assert_eq!(ip!($s).multicast_scope().unwrap(),
+                           Ipv6MulticastScope::RealmLocal);
+            }
+            if ($mask & multicast_admin_local) == multicast_admin_local {
+                assert_eq!(ip!($s).multicast_scope().unwrap(),
+                           Ipv6MulticastScope::AdminLocal);
+            }
+            if ($mask & multicast_site_local) == multicast_site_local {
+                assert_eq!(ip!($s).multicast_scope().unwrap(),
+                           Ipv6MulticastScope::SiteLocal);
+            }
+            if ($mask & multicast_organization_local) == multicast_organization_local {
+                assert_eq!(ip!($s).multicast_scope().unwrap(),
+                           Ipv6MulticastScope::OrganizationLocal);
+            }
+            if ($mask & multicast_global) == multicast_global {
+                assert_eq!(ip!($s).multicast_scope().unwrap(),
+                           Ipv6MulticastScope::Global);
+            }
+        }
+    }
+
+    let unspecified: u16 = 1 << 0;
+    let loopback: u16 = 1 << 1;
+    let unique_local: u16 = 1 << 2;
+    let global: u16 = 1 << 3;
+    let unicast_link_local: u16 = 1 << 4;
+    let unicast_link_local_strict: u16 = 1 << 5;
+    let unicast_site_local: u16 = 1 << 6;
+    let unicast_global: u16 = 1 << 7;
+    let documentation: u16 = 1 << 8;
+    let multicast_interface_local: u16 = 1 << 9;
+    let multicast_link_local: u16 = 1 << 10;
+    let multicast_realm_local: u16 = 1 << 11;
+    let multicast_admin_local: u16 = 1 << 12;
+    let multicast_site_local: u16 = 1 << 13;
+    let multicast_organization_local: u16 = 1 << 14;
+    let multicast_global: u16 = 1 << 15;
+
+    check!("::", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unspecified);
+
+    check!("::1", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], loopback);
+
+    check!("::0.0.0.2", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], global | unicast_global);
+
+    check!("1::", &[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], global | unicast_global);
+
+    check!("fc00::", &[0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unique_local);
+
+    check!(
+        "fdff:ffff::",
+        &[0xfd, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        unique_local
+    );
+
+    check!(
+        "fe80:ffff::",
+        &[0xfe, 0x80, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        unicast_link_local
+    );
+
+    check!(
+        "fe80::",
+        &[0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        unicast_link_local | unicast_link_local_strict
+    );
+
+    check!(
+        "febf:ffff::",
+        &[0xfe, 0xbf, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        unicast_link_local
+    );
+
+    check!("febf::", &[0xfe, 0xbf, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unicast_link_local);
+
+    check!(
+        "febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
+        &[
+            0xfe, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+            0xff, 0xff
+        ],
+        unicast_link_local
+    );
+
+    check!(
+        "fe80::ffff:ffff:ffff:ffff",
+        &[
+            0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+            0xff, 0xff
+        ],
+        unicast_link_local | unicast_link_local_strict
+    );
+
+    check!(
+        "fe80:0:0:1::",
+        &[0xfe, 0x80, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
+        unicast_link_local
+    );
+
+    check!(
+        "fec0::",
+        &[0xfe, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        unicast_site_local | unicast_global | global
+    );
+
+    check!(
+        "ff01::",
+        &[0xff, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        multicast_interface_local
+    );
+
+    check!("ff02::", &[0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], multicast_link_local);
+
+    check!("ff03::", &[0xff, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], multicast_realm_local);
+
+    check!("ff04::", &[0xff, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], multicast_admin_local);
+
+    check!("ff05::", &[0xff, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], multicast_site_local);
+
+    check!(
+        "ff08::",
+        &[0xff, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        multicast_organization_local
+    );
+
+    check!(
+        "ff0e::",
+        &[0xff, 0xe, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        multicast_global | global
+    );
+
+    check!(
+        "2001:db8:85a3::8a2e:370:7334",
+        &[0x20, 1, 0xd, 0xb8, 0x85, 0xa3, 0, 0, 0, 0, 0x8a, 0x2e, 3, 0x70, 0x73, 0x34],
+        documentation
+    );
+
+    check!(
+        "102:304:506:708:90a:b0c:d0e:f10",
+        &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
+        global | unicast_global
+    );
+}
+
+#[test]
+fn to_socket_addr_socketaddr() {
+    let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 12345);
+    assert_eq!(Ok(vec![a]), tsa(a));
+}
+
+#[test]
+fn test_ipv4_to_int() {
+    let a = Ipv4Addr::new(0x11, 0x22, 0x33, 0x44);
+    assert_eq!(u32::from(a), 0x11223344);
+}
+
+#[test]
+fn test_int_to_ipv4() {
+    let a = Ipv4Addr::new(0x11, 0x22, 0x33, 0x44);
+    assert_eq!(Ipv4Addr::from(0x11223344), a);
+}
+
+#[test]
+fn test_ipv6_to_int() {
+    let a = Ipv6Addr::new(0x1122, 0x3344, 0x5566, 0x7788, 0x99aa, 0xbbcc, 0xddee, 0xff11);
+    assert_eq!(u128::from(a), 0x112233445566778899aabbccddeeff11u128);
+}
+
+#[test]
+fn test_int_to_ipv6() {
+    let a = Ipv6Addr::new(0x1122, 0x3344, 0x5566, 0x7788, 0x99aa, 0xbbcc, 0xddee, 0xff11);
+    assert_eq!(Ipv6Addr::from(0x112233445566778899aabbccddeeff11u128), a);
+}
+
+#[test]
+fn ipv4_from_constructors() {
+    assert_eq!(Ipv4Addr::LOCALHOST, Ipv4Addr::new(127, 0, 0, 1));
+    assert!(Ipv4Addr::LOCALHOST.is_loopback());
+    assert_eq!(Ipv4Addr::UNSPECIFIED, Ipv4Addr::new(0, 0, 0, 0));
+    assert!(Ipv4Addr::UNSPECIFIED.is_unspecified());
+    assert_eq!(Ipv4Addr::BROADCAST, Ipv4Addr::new(255, 255, 255, 255));
+    assert!(Ipv4Addr::BROADCAST.is_broadcast());
+}
+
+#[test]
+fn ipv6_from_contructors() {
+    assert_eq!(Ipv6Addr::LOCALHOST, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
+    assert!(Ipv6Addr::LOCALHOST.is_loopback());
+    assert_eq!(Ipv6Addr::UNSPECIFIED, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
+    assert!(Ipv6Addr::UNSPECIFIED.is_unspecified());
+}
+
+#[test]
+fn ipv4_from_octets() {
+    assert_eq!(Ipv4Addr::from([127, 0, 0, 1]), Ipv4Addr::new(127, 0, 0, 1))
+}
+
+#[test]
+fn ipv6_from_segments() {
+    let from_u16s =
+        Ipv6Addr::from([0x0011, 0x2233, 0x4455, 0x6677, 0x8899, 0xaabb, 0xccdd, 0xeeff]);
+    let new = Ipv6Addr::new(0x0011, 0x2233, 0x4455, 0x6677, 0x8899, 0xaabb, 0xccdd, 0xeeff);
+    assert_eq!(new, from_u16s);
+}
+
+#[test]
+fn ipv6_from_octets() {
+    let from_u16s =
+        Ipv6Addr::from([0x0011, 0x2233, 0x4455, 0x6677, 0x8899, 0xaabb, 0xccdd, 0xeeff]);
+    let from_u8s = Ipv6Addr::from([
+        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
+        0xff,
+    ]);
+    assert_eq!(from_u16s, from_u8s);
+}
+
+#[test]
+fn cmp() {
+    let v41 = Ipv4Addr::new(100, 64, 3, 3);
+    let v42 = Ipv4Addr::new(192, 0, 2, 2);
+    let v61 = "2001:db8:f00::1002".parse::<Ipv6Addr>().unwrap();
+    let v62 = "2001:db8:f00::2001".parse::<Ipv6Addr>().unwrap();
+    assert!(v41 < v42);
+    assert!(v61 < v62);
+
+    assert_eq!(v41, IpAddr::V4(v41));
+    assert_eq!(v61, IpAddr::V6(v61));
+    assert!(v41 != IpAddr::V4(v42));
+    assert!(v61 != IpAddr::V6(v62));
+
+    assert!(v41 < IpAddr::V4(v42));
+    assert!(v61 < IpAddr::V6(v62));
+    assert!(IpAddr::V4(v41) < v42);
+    assert!(IpAddr::V6(v61) < v62);
+
+    assert!(v41 < IpAddr::V6(v61));
+    assert!(IpAddr::V4(v41) < v61);
+}
+
+#[test]
+fn is_v4() {
+    let ip = IpAddr::V4(Ipv4Addr::new(100, 64, 3, 3));
+    assert!(ip.is_ipv4());
+    assert!(!ip.is_ipv6());
+}
+
+#[test]
+fn is_v6() {
+    let ip = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678));
+    assert!(!ip.is_ipv4());
+    assert!(ip.is_ipv6());
+}
diff --git a/library/std/src/net/parser.rs b/library/std/src/net/parser.rs
index a425aca5a64..0570a7c41bf 100644
--- a/library/std/src/net/parser.rs
+++ b/library/std/src/net/parser.rs
@@ -3,6 +3,9 @@
 //! This module is "publicly exported" through the `FromStr` implementations
 //! below.
 
+#[cfg(test)]
+mod tests;
+
 use crate::error::Error;
 use crate::fmt;
 use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
@@ -321,146 +324,3 @@ impl Error for AddrParseError {
         "invalid IP address syntax"
     }
 }
-
-#[cfg(test)]
-mod tests {
-    // FIXME: These tests are all excellent candidates for AFL fuzz testing
-    use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
-    use crate::str::FromStr;
-
-    const PORT: u16 = 8080;
-
-    const IPV4: Ipv4Addr = Ipv4Addr::new(192, 168, 0, 1);
-    const IPV4_STR: &str = "192.168.0.1";
-    const IPV4_STR_PORT: &str = "192.168.0.1:8080";
-
-    const IPV6: Ipv6Addr = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0xc0a8, 0x1);
-    const IPV6_STR_FULL: &str = "2001:db8:0:0:0:0:c0a8:1";
-    const IPV6_STR_COMPRESS: &str = "2001:db8::c0a8:1";
-    const IPV6_STR_V4: &str = "2001:db8::192.168.0.1";
-    const IPV6_STR_PORT: &str = "[2001:db8::c0a8:1]:8080";
-
-    #[test]
-    fn parse_ipv4() {
-        let result: Ipv4Addr = IPV4_STR.parse().unwrap();
-        assert_eq!(result, IPV4);
-
-        assert!(Ipv4Addr::from_str(IPV4_STR_PORT).is_err());
-        assert!(Ipv4Addr::from_str(IPV6_STR_FULL).is_err());
-        assert!(Ipv4Addr::from_str(IPV6_STR_COMPRESS).is_err());
-        assert!(Ipv4Addr::from_str(IPV6_STR_V4).is_err());
-        assert!(Ipv4Addr::from_str(IPV6_STR_PORT).is_err());
-    }
-
-    #[test]
-    fn parse_ipv6() {
-        let result: Ipv6Addr = IPV6_STR_FULL.parse().unwrap();
-        assert_eq!(result, IPV6);
-
-        let result: Ipv6Addr = IPV6_STR_COMPRESS.parse().unwrap();
-        assert_eq!(result, IPV6);
-
-        let result: Ipv6Addr = IPV6_STR_V4.parse().unwrap();
-        assert_eq!(result, IPV6);
-
-        assert!(Ipv6Addr::from_str(IPV4_STR).is_err());
-        assert!(Ipv6Addr::from_str(IPV4_STR_PORT).is_err());
-        assert!(Ipv6Addr::from_str(IPV6_STR_PORT).is_err());
-    }
-
-    #[test]
-    fn parse_ip() {
-        let result: IpAddr = IPV4_STR.parse().unwrap();
-        assert_eq!(result, IpAddr::from(IPV4));
-
-        let result: IpAddr = IPV6_STR_FULL.parse().unwrap();
-        assert_eq!(result, IpAddr::from(IPV6));
-
-        let result: IpAddr = IPV6_STR_COMPRESS.parse().unwrap();
-        assert_eq!(result, IpAddr::from(IPV6));
-
-        let result: IpAddr = IPV6_STR_V4.parse().unwrap();
-        assert_eq!(result, IpAddr::from(IPV6));
-
-        assert!(IpAddr::from_str(IPV4_STR_PORT).is_err());
-        assert!(IpAddr::from_str(IPV6_STR_PORT).is_err());
-    }
-
-    #[test]
-    fn parse_socket_v4() {
-        let result: SocketAddrV4 = IPV4_STR_PORT.parse().unwrap();
-        assert_eq!(result, SocketAddrV4::new(IPV4, PORT));
-
-        assert!(SocketAddrV4::from_str(IPV4_STR).is_err());
-        assert!(SocketAddrV4::from_str(IPV6_STR_FULL).is_err());
-        assert!(SocketAddrV4::from_str(IPV6_STR_COMPRESS).is_err());
-        assert!(SocketAddrV4::from_str(IPV6_STR_V4).is_err());
-        assert!(SocketAddrV4::from_str(IPV6_STR_PORT).is_err());
-    }
-
-    #[test]
-    fn parse_socket_v6() {
-        let result: SocketAddrV6 = IPV6_STR_PORT.parse().unwrap();
-        assert_eq!(result, SocketAddrV6::new(IPV6, PORT, 0, 0));
-
-        assert!(SocketAddrV6::from_str(IPV4_STR).is_err());
-        assert!(SocketAddrV6::from_str(IPV4_STR_PORT).is_err());
-        assert!(SocketAddrV6::from_str(IPV6_STR_FULL).is_err());
-        assert!(SocketAddrV6::from_str(IPV6_STR_COMPRESS).is_err());
-        assert!(SocketAddrV6::from_str(IPV6_STR_V4).is_err());
-    }
-
-    #[test]
-    fn parse_socket() {
-        let result: SocketAddr = IPV4_STR_PORT.parse().unwrap();
-        assert_eq!(result, SocketAddr::from((IPV4, PORT)));
-
-        let result: SocketAddr = IPV6_STR_PORT.parse().unwrap();
-        assert_eq!(result, SocketAddr::from((IPV6, PORT)));
-
-        assert!(SocketAddr::from_str(IPV4_STR).is_err());
-        assert!(SocketAddr::from_str(IPV6_STR_FULL).is_err());
-        assert!(SocketAddr::from_str(IPV6_STR_COMPRESS).is_err());
-        assert!(SocketAddr::from_str(IPV6_STR_V4).is_err());
-    }
-
-    #[test]
-    fn ipv6_corner_cases() {
-        let result: Ipv6Addr = "1::".parse().unwrap();
-        assert_eq!(result, Ipv6Addr::new(1, 0, 0, 0, 0, 0, 0, 0));
-
-        let result: Ipv6Addr = "1:1::".parse().unwrap();
-        assert_eq!(result, Ipv6Addr::new(1, 1, 0, 0, 0, 0, 0, 0));
-
-        let result: Ipv6Addr = "::1".parse().unwrap();
-        assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
-
-        let result: Ipv6Addr = "::1:1".parse().unwrap();
-        assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 1, 1));
-
-        let result: Ipv6Addr = "::".parse().unwrap();
-        assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
-
-        let result: Ipv6Addr = "::192.168.0.1".parse().unwrap();
-        assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc0a8, 0x1));
-
-        let result: Ipv6Addr = "::1:192.168.0.1".parse().unwrap();
-        assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 1, 0xc0a8, 0x1));
-
-        let result: Ipv6Addr = "1:1:1:1:1:1:192.168.0.1".parse().unwrap();
-        assert_eq!(result, Ipv6Addr::new(1, 1, 1, 1, 1, 1, 0xc0a8, 0x1));
-    }
-
-    // Things that might not seem like failures but are
-    #[test]
-    fn ipv6_corner_failures() {
-        // No IP address before the ::
-        assert!(Ipv6Addr::from_str("1:192.168.0.1::").is_err());
-
-        // :: must have at least 1 set of zeroes
-        assert!(Ipv6Addr::from_str("1:1:1:1::1:1:1:1").is_err());
-
-        // Need brackets for a port
-        assert!(SocketAddrV6::from_str("1:1:1:1:1:1:1:1:8080").is_err());
-    }
-}
diff --git a/library/std/src/net/parser/tests.rs b/library/std/src/net/parser/tests.rs
new file mode 100644
index 00000000000..ecf5a782c0c
--- /dev/null
+++ b/library/std/src/net/parser/tests.rs
@@ -0,0 +1,139 @@
+// FIXME: These tests are all excellent candidates for AFL fuzz testing
+use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
+use crate::str::FromStr;
+
+const PORT: u16 = 8080;
+
+const IPV4: Ipv4Addr = Ipv4Addr::new(192, 168, 0, 1);
+const IPV4_STR: &str = "192.168.0.1";
+const IPV4_STR_PORT: &str = "192.168.0.1:8080";
+
+const IPV6: Ipv6Addr = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0xc0a8, 0x1);
+const IPV6_STR_FULL: &str = "2001:db8:0:0:0:0:c0a8:1";
+const IPV6_STR_COMPRESS: &str = "2001:db8::c0a8:1";
+const IPV6_STR_V4: &str = "2001:db8::192.168.0.1";
+const IPV6_STR_PORT: &str = "[2001:db8::c0a8:1]:8080";
+
+#[test]
+fn parse_ipv4() {
+    let result: Ipv4Addr = IPV4_STR.parse().unwrap();
+    assert_eq!(result, IPV4);
+
+    assert!(Ipv4Addr::from_str(IPV4_STR_PORT).is_err());
+    assert!(Ipv4Addr::from_str(IPV6_STR_FULL).is_err());
+    assert!(Ipv4Addr::from_str(IPV6_STR_COMPRESS).is_err());
+    assert!(Ipv4Addr::from_str(IPV6_STR_V4).is_err());
+    assert!(Ipv4Addr::from_str(IPV6_STR_PORT).is_err());
+}
+
+#[test]
+fn parse_ipv6() {
+    let result: Ipv6Addr = IPV6_STR_FULL.parse().unwrap();
+    assert_eq!(result, IPV6);
+
+    let result: Ipv6Addr = IPV6_STR_COMPRESS.parse().unwrap();
+    assert_eq!(result, IPV6);
+
+    let result: Ipv6Addr = IPV6_STR_V4.parse().unwrap();
+    assert_eq!(result, IPV6);
+
+    assert!(Ipv6Addr::from_str(IPV4_STR).is_err());
+    assert!(Ipv6Addr::from_str(IPV4_STR_PORT).is_err());
+    assert!(Ipv6Addr::from_str(IPV6_STR_PORT).is_err());
+}
+
+#[test]
+fn parse_ip() {
+    let result: IpAddr = IPV4_STR.parse().unwrap();
+    assert_eq!(result, IpAddr::from(IPV4));
+
+    let result: IpAddr = IPV6_STR_FULL.parse().unwrap();
+    assert_eq!(result, IpAddr::from(IPV6));
+
+    let result: IpAddr = IPV6_STR_COMPRESS.parse().unwrap();
+    assert_eq!(result, IpAddr::from(IPV6));
+
+    let result: IpAddr = IPV6_STR_V4.parse().unwrap();
+    assert_eq!(result, IpAddr::from(IPV6));
+
+    assert!(IpAddr::from_str(IPV4_STR_PORT).is_err());
+    assert!(IpAddr::from_str(IPV6_STR_PORT).is_err());
+}
+
+#[test]
+fn parse_socket_v4() {
+    let result: SocketAddrV4 = IPV4_STR_PORT.parse().unwrap();
+    assert_eq!(result, SocketAddrV4::new(IPV4, PORT));
+
+    assert!(SocketAddrV4::from_str(IPV4_STR).is_err());
+    assert!(SocketAddrV4::from_str(IPV6_STR_FULL).is_err());
+    assert!(SocketAddrV4::from_str(IPV6_STR_COMPRESS).is_err());
+    assert!(SocketAddrV4::from_str(IPV6_STR_V4).is_err());
+    assert!(SocketAddrV4::from_str(IPV6_STR_PORT).is_err());
+}
+
+#[test]
+fn parse_socket_v6() {
+    let result: SocketAddrV6 = IPV6_STR_PORT.parse().unwrap();
+    assert_eq!(result, SocketAddrV6::new(IPV6, PORT, 0, 0));
+
+    assert!(SocketAddrV6::from_str(IPV4_STR).is_err());
+    assert!(SocketAddrV6::from_str(IPV4_STR_PORT).is_err());
+    assert!(SocketAddrV6::from_str(IPV6_STR_FULL).is_err());
+    assert!(SocketAddrV6::from_str(IPV6_STR_COMPRESS).is_err());
+    assert!(SocketAddrV6::from_str(IPV6_STR_V4).is_err());
+}
+
+#[test]
+fn parse_socket() {
+    let result: SocketAddr = IPV4_STR_PORT.parse().unwrap();
+    assert_eq!(result, SocketAddr::from((IPV4, PORT)));
+
+    let result: SocketAddr = IPV6_STR_PORT.parse().unwrap();
+    assert_eq!(result, SocketAddr::from((IPV6, PORT)));
+
+    assert!(SocketAddr::from_str(IPV4_STR).is_err());
+    assert!(SocketAddr::from_str(IPV6_STR_FULL).is_err());
+    assert!(SocketAddr::from_str(IPV6_STR_COMPRESS).is_err());
+    assert!(SocketAddr::from_str(IPV6_STR_V4).is_err());
+}
+
+#[test]
+fn ipv6_corner_cases() {
+    let result: Ipv6Addr = "1::".parse().unwrap();
+    assert_eq!(result, Ipv6Addr::new(1, 0, 0, 0, 0, 0, 0, 0));
+
+    let result: Ipv6Addr = "1:1::".parse().unwrap();
+    assert_eq!(result, Ipv6Addr::new(1, 1, 0, 0, 0, 0, 0, 0));
+
+    let result: Ipv6Addr = "::1".parse().unwrap();
+    assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
+
+    let result: Ipv6Addr = "::1:1".parse().unwrap();
+    assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 1, 1));
+
+    let result: Ipv6Addr = "::".parse().unwrap();
+    assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
+
+    let result: Ipv6Addr = "::192.168.0.1".parse().unwrap();
+    assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc0a8, 0x1));
+
+    let result: Ipv6Addr = "::1:192.168.0.1".parse().unwrap();
+    assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 1, 0xc0a8, 0x1));
+
+    let result: Ipv6Addr = "1:1:1:1:1:1:192.168.0.1".parse().unwrap();
+    assert_eq!(result, Ipv6Addr::new(1, 1, 1, 1, 1, 1, 0xc0a8, 0x1));
+}
+
+// Things that might not seem like failures but are
+#[test]
+fn ipv6_corner_failures() {
+    // No IP address before the ::
+    assert!(Ipv6Addr::from_str("1:192.168.0.1::").is_err());
+
+    // :: must have at least 1 set of zeroes
+    assert!(Ipv6Addr::from_str("1:1:1:1::1:1:1:1").is_err());
+
+    // Need brackets for a port
+    assert!(SocketAddrV6::from_str("1:1:1:1:1:1:1:1:8080").is_err());
+}
diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs
index a76c9c46c05..58c6343ea34 100644
--- a/library/std/src/net/tcp.rs
+++ b/library/std/src/net/tcp.rs
@@ -1,4 +1,8 @@
 #![deny(unsafe_op_in_unsafe_fn)]
+
+#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))]
+mod tests;
+
 use crate::io::prelude::*;
 
 use crate::fmt;
@@ -936,869 +940,3 @@ impl fmt::Debug for TcpListener {
         self.0.fmt(f)
     }
 }
-
-#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))]
-mod tests {
-    use crate::fmt;
-    use crate::io::prelude::*;
-    use crate::io::{ErrorKind, IoSlice, IoSliceMut};
-    use crate::net::test::{next_test_ip4, next_test_ip6};
-    use crate::net::*;
-    use crate::sync::mpsc::channel;
-    use crate::thread;
-    use crate::time::{Duration, Instant};
-
-    fn each_ip(f: &mut dyn FnMut(SocketAddr)) {
-        f(next_test_ip4());
-        f(next_test_ip6());
-    }
-
-    macro_rules! t {
-        ($e:expr) => {
-            match $e {
-                Ok(t) => t,
-                Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
-            }
-        };
-    }
-
-    #[test]
-    fn bind_error() {
-        match TcpListener::bind("1.1.1.1:9999") {
-            Ok(..) => panic!(),
-            Err(e) => assert_eq!(e.kind(), ErrorKind::AddrNotAvailable),
-        }
-    }
-
-    #[test]
-    fn connect_error() {
-        match TcpStream::connect("0.0.0.0:1") {
-            Ok(..) => panic!(),
-            Err(e) => assert!(
-                e.kind() == ErrorKind::ConnectionRefused
-                    || e.kind() == ErrorKind::InvalidInput
-                    || e.kind() == ErrorKind::AddrInUse
-                    || e.kind() == ErrorKind::AddrNotAvailable,
-                "bad error: {} {:?}",
-                e,
-                e.kind()
-            ),
-        }
-    }
-
-    #[test]
-    fn listen_localhost() {
-        let socket_addr = next_test_ip4();
-        let listener = t!(TcpListener::bind(&socket_addr));
-
-        let _t = thread::spawn(move || {
-            let mut stream = t!(TcpStream::connect(&("localhost", socket_addr.port())));
-            t!(stream.write(&[144]));
-        });
-
-        let mut stream = t!(listener.accept()).0;
-        let mut buf = [0];
-        t!(stream.read(&mut buf));
-        assert!(buf[0] == 144);
-    }
-
-    #[test]
-    fn connect_loopback() {
-        each_ip(&mut |addr| {
-            let acceptor = t!(TcpListener::bind(&addr));
-
-            let _t = thread::spawn(move || {
-                let host = match addr {
-                    SocketAddr::V4(..) => "127.0.0.1",
-                    SocketAddr::V6(..) => "::1",
-                };
-                let mut stream = t!(TcpStream::connect(&(host, addr.port())));
-                t!(stream.write(&[66]));
-            });
-
-            let mut stream = t!(acceptor.accept()).0;
-            let mut buf = [0];
-            t!(stream.read(&mut buf));
-            assert!(buf[0] == 66);
-        })
-    }
-
-    #[test]
-    fn smoke_test() {
-        each_ip(&mut |addr| {
-            let acceptor = t!(TcpListener::bind(&addr));
-
-            let (tx, rx) = channel();
-            let _t = thread::spawn(move || {
-                let mut stream = t!(TcpStream::connect(&addr));
-                t!(stream.write(&[99]));
-                tx.send(t!(stream.local_addr())).unwrap();
-            });
-
-            let (mut stream, addr) = t!(acceptor.accept());
-            let mut buf = [0];
-            t!(stream.read(&mut buf));
-            assert!(buf[0] == 99);
-            assert_eq!(addr, t!(rx.recv()));
-        })
-    }
-
-    #[test]
-    fn read_eof() {
-        each_ip(&mut |addr| {
-            let acceptor = t!(TcpListener::bind(&addr));
-
-            let _t = thread::spawn(move || {
-                let _stream = t!(TcpStream::connect(&addr));
-                // Close
-            });
-
-            let mut stream = t!(acceptor.accept()).0;
-            let mut buf = [0];
-            let nread = t!(stream.read(&mut buf));
-            assert_eq!(nread, 0);
-            let nread = t!(stream.read(&mut buf));
-            assert_eq!(nread, 0);
-        })
-    }
-
-    #[test]
-    fn write_close() {
-        each_ip(&mut |addr| {
-            let acceptor = t!(TcpListener::bind(&addr));
-
-            let (tx, rx) = channel();
-            let _t = thread::spawn(move || {
-                drop(t!(TcpStream::connect(&addr)));
-                tx.send(()).unwrap();
-            });
-
-            let mut stream = t!(acceptor.accept()).0;
-            rx.recv().unwrap();
-            let buf = [0];
-            match stream.write(&buf) {
-                Ok(..) => {}
-                Err(e) => {
-                    assert!(
-                        e.kind() == ErrorKind::ConnectionReset
-                            || e.kind() == ErrorKind::BrokenPipe
-                            || e.kind() == ErrorKind::ConnectionAborted,
-                        "unknown error: {}",
-                        e
-                    );
-                }
-            }
-        })
-    }
-
-    #[test]
-    fn multiple_connect_serial() {
-        each_ip(&mut |addr| {
-            let max = 10;
-            let acceptor = t!(TcpListener::bind(&addr));
-
-            let _t = thread::spawn(move || {
-                for _ in 0..max {
-                    let mut stream = t!(TcpStream::connect(&addr));
-                    t!(stream.write(&[99]));
-                }
-            });
-
-            for stream in acceptor.incoming().take(max) {
-                let mut stream = t!(stream);
-                let mut buf = [0];
-                t!(stream.read(&mut buf));
-                assert_eq!(buf[0], 99);
-            }
-        })
-    }
-
-    #[test]
-    fn multiple_connect_interleaved_greedy_schedule() {
-        const MAX: usize = 10;
-        each_ip(&mut |addr| {
-            let acceptor = t!(TcpListener::bind(&addr));
-
-            let _t = thread::spawn(move || {
-                let acceptor = acceptor;
-                for (i, stream) in acceptor.incoming().enumerate().take(MAX) {
-                    // Start another thread to handle the connection
-                    let _t = thread::spawn(move || {
-                        let mut stream = t!(stream);
-                        let mut buf = [0];
-                        t!(stream.read(&mut buf));
-                        assert!(buf[0] == i as u8);
-                    });
-                }
-            });
-
-            connect(0, addr);
-        });
-
-        fn connect(i: usize, addr: SocketAddr) {
-            if i == MAX {
-                return;
-            }
-
-            let t = thread::spawn(move || {
-                let mut stream = t!(TcpStream::connect(&addr));
-                // Connect again before writing
-                connect(i + 1, addr);
-                t!(stream.write(&[i as u8]));
-            });
-            t.join().ok().expect("thread panicked");
-        }
-    }
-
-    #[test]
-    fn multiple_connect_interleaved_lazy_schedule() {
-        const MAX: usize = 10;
-        each_ip(&mut |addr| {
-            let acceptor = t!(TcpListener::bind(&addr));
-
-            let _t = thread::spawn(move || {
-                for stream in acceptor.incoming().take(MAX) {
-                    // Start another thread to handle the connection
-                    let _t = thread::spawn(move || {
-                        let mut stream = t!(stream);
-                        let mut buf = [0];
-                        t!(stream.read(&mut buf));
-                        assert!(buf[0] == 99);
-                    });
-                }
-            });
-
-            connect(0, addr);
-        });
-
-        fn connect(i: usize, addr: SocketAddr) {
-            if i == MAX {
-                return;
-            }
-
-            let t = thread::spawn(move || {
-                let mut stream = t!(TcpStream::connect(&addr));
-                connect(i + 1, addr);
-                t!(stream.write(&[99]));
-            });
-            t.join().ok().expect("thread panicked");
-        }
-    }
-
-    #[test]
-    fn socket_and_peer_name() {
-        each_ip(&mut |addr| {
-            let listener = t!(TcpListener::bind(&addr));
-            let so_name = t!(listener.local_addr());
-            assert_eq!(addr, so_name);
-            let _t = thread::spawn(move || {
-                t!(listener.accept());
-            });
-
-            let stream = t!(TcpStream::connect(&addr));
-            assert_eq!(addr, t!(stream.peer_addr()));
-        })
-    }
-
-    #[test]
-    fn partial_read() {
-        each_ip(&mut |addr| {
-            let (tx, rx) = channel();
-            let srv = t!(TcpListener::bind(&addr));
-            let _t = thread::spawn(move || {
-                let mut cl = t!(srv.accept()).0;
-                cl.write(&[10]).unwrap();
-                let mut b = [0];
-                t!(cl.read(&mut b));
-                tx.send(()).unwrap();
-            });
-
-            let mut c = t!(TcpStream::connect(&addr));
-            let mut b = [0; 10];
-            assert_eq!(c.read(&mut b).unwrap(), 1);
-            t!(c.write(&[1]));
-            rx.recv().unwrap();
-        })
-    }
-
-    #[test]
-    fn read_vectored() {
-        each_ip(&mut |addr| {
-            let srv = t!(TcpListener::bind(&addr));
-            let mut s1 = t!(TcpStream::connect(&addr));
-            let mut s2 = t!(srv.accept()).0;
-
-            let len = s1.write(&[10, 11, 12]).unwrap();
-            assert_eq!(len, 3);
-
-            let mut a = [];
-            let mut b = [0];
-            let mut c = [0; 3];
-            let len = t!(s2.read_vectored(&mut [
-                IoSliceMut::new(&mut a),
-                IoSliceMut::new(&mut b),
-                IoSliceMut::new(&mut c)
-            ],));
-            assert!(len > 0);
-            assert_eq!(b, [10]);
-            // some implementations don't support readv, so we may only fill the first buffer
-            assert!(len == 1 || c == [11, 12, 0]);
-        })
-    }
-
-    #[test]
-    fn write_vectored() {
-        each_ip(&mut |addr| {
-            let srv = t!(TcpListener::bind(&addr));
-            let mut s1 = t!(TcpStream::connect(&addr));
-            let mut s2 = t!(srv.accept()).0;
-
-            let a = [];
-            let b = [10];
-            let c = [11, 12];
-            t!(s1.write_vectored(&[IoSlice::new(&a), IoSlice::new(&b), IoSlice::new(&c)]));
-
-            let mut buf = [0; 4];
-            let len = t!(s2.read(&mut buf));
-            // some implementations don't support writev, so we may only write the first buffer
-            if len == 1 {
-                assert_eq!(buf, [10, 0, 0, 0]);
-            } else {
-                assert_eq!(len, 3);
-                assert_eq!(buf, [10, 11, 12, 0]);
-            }
-        })
-    }
-
-    #[test]
-    fn double_bind() {
-        each_ip(&mut |addr| {
-            let listener1 = t!(TcpListener::bind(&addr));
-            match TcpListener::bind(&addr) {
-                Ok(listener2) => panic!(
-                    "This system (perhaps due to options set by TcpListener::bind) \
-                     permits double binding: {:?} and {:?}",
-                    listener1, listener2
-                ),
-                Err(e) => {
-                    assert!(
-                        e.kind() == ErrorKind::ConnectionRefused
-                            || e.kind() == ErrorKind::Other
-                            || e.kind() == ErrorKind::AddrInUse,
-                        "unknown error: {} {:?}",
-                        e,
-                        e.kind()
-                    );
-                }
-            }
-        })
-    }
-
-    #[test]
-    fn tcp_clone_smoke() {
-        each_ip(&mut |addr| {
-            let acceptor = t!(TcpListener::bind(&addr));
-
-            let _t = thread::spawn(move || {
-                let mut s = t!(TcpStream::connect(&addr));
-                let mut buf = [0, 0];
-                assert_eq!(s.read(&mut buf).unwrap(), 1);
-                assert_eq!(buf[0], 1);
-                t!(s.write(&[2]));
-            });
-
-            let mut s1 = t!(acceptor.accept()).0;
-            let s2 = t!(s1.try_clone());
-
-            let (tx1, rx1) = channel();
-            let (tx2, rx2) = channel();
-            let _t = thread::spawn(move || {
-                let mut s2 = s2;
-                rx1.recv().unwrap();
-                t!(s2.write(&[1]));
-                tx2.send(()).unwrap();
-            });
-            tx1.send(()).unwrap();
-            let mut buf = [0, 0];
-            assert_eq!(s1.read(&mut buf).unwrap(), 1);
-            rx2.recv().unwrap();
-        })
-    }
-
-    #[test]
-    fn tcp_clone_two_read() {
-        each_ip(&mut |addr| {
-            let acceptor = t!(TcpListener::bind(&addr));
-            let (tx1, rx) = channel();
-            let tx2 = tx1.clone();
-
-            let _t = thread::spawn(move || {
-                let mut s = t!(TcpStream::connect(&addr));
-                t!(s.write(&[1]));
-                rx.recv().unwrap();
-                t!(s.write(&[2]));
-                rx.recv().unwrap();
-            });
-
-            let mut s1 = t!(acceptor.accept()).0;
-            let s2 = t!(s1.try_clone());
-
-            let (done, rx) = channel();
-            let _t = thread::spawn(move || {
-                let mut s2 = s2;
-                let mut buf = [0, 0];
-                t!(s2.read(&mut buf));
-                tx2.send(()).unwrap();
-                done.send(()).unwrap();
-            });
-            let mut buf = [0, 0];
-            t!(s1.read(&mut buf));
-            tx1.send(()).unwrap();
-
-            rx.recv().unwrap();
-        })
-    }
-
-    #[test]
-    fn tcp_clone_two_write() {
-        each_ip(&mut |addr| {
-            let acceptor = t!(TcpListener::bind(&addr));
-
-            let _t = thread::spawn(move || {
-                let mut s = t!(TcpStream::connect(&addr));
-                let mut buf = [0, 1];
-                t!(s.read(&mut buf));
-                t!(s.read(&mut buf));
-            });
-
-            let mut s1 = t!(acceptor.accept()).0;
-            let s2 = t!(s1.try_clone());
-
-            let (done, rx) = channel();
-            let _t = thread::spawn(move || {
-                let mut s2 = s2;
-                t!(s2.write(&[1]));
-                done.send(()).unwrap();
-            });
-            t!(s1.write(&[2]));
-
-            rx.recv().unwrap();
-        })
-    }
-
-    #[test]
-    // FIXME: https://github.com/fortanix/rust-sgx/issues/110
-    #[cfg_attr(target_env = "sgx", ignore)]
-    fn shutdown_smoke() {
-        each_ip(&mut |addr| {
-            let a = t!(TcpListener::bind(&addr));
-            let _t = thread::spawn(move || {
-                let mut c = t!(a.accept()).0;
-                let mut b = [0];
-                assert_eq!(c.read(&mut b).unwrap(), 0);
-                t!(c.write(&[1]));
-            });
-
-            let mut s = t!(TcpStream::connect(&addr));
-            t!(s.shutdown(Shutdown::Write));
-            assert!(s.write(&[1]).is_err());
-            let mut b = [0, 0];
-            assert_eq!(t!(s.read(&mut b)), 1);
-            assert_eq!(b[0], 1);
-        })
-    }
-
-    #[test]
-    // FIXME: https://github.com/fortanix/rust-sgx/issues/110
-    #[cfg_attr(target_env = "sgx", ignore)]
-    fn close_readwrite_smoke() {
-        each_ip(&mut |addr| {
-            let a = t!(TcpListener::bind(&addr));
-            let (tx, rx) = channel::<()>();
-            let _t = thread::spawn(move || {
-                let _s = t!(a.accept());
-                let _ = rx.recv();
-            });
-
-            let mut b = [0];
-            let mut s = t!(TcpStream::connect(&addr));
-            let mut s2 = t!(s.try_clone());
-
-            // closing should prevent reads/writes
-            t!(s.shutdown(Shutdown::Write));
-            assert!(s.write(&[0]).is_err());
-            t!(s.shutdown(Shutdown::Read));
-            assert_eq!(s.read(&mut b).unwrap(), 0);
-
-            // closing should affect previous handles
-            assert!(s2.write(&[0]).is_err());
-            assert_eq!(s2.read(&mut b).unwrap(), 0);
-
-            // closing should affect new handles
-            let mut s3 = t!(s.try_clone());
-            assert!(s3.write(&[0]).is_err());
-            assert_eq!(s3.read(&mut b).unwrap(), 0);
-
-            // make sure these don't die
-            let _ = s2.shutdown(Shutdown::Read);
-            let _ = s2.shutdown(Shutdown::Write);
-            let _ = s3.shutdown(Shutdown::Read);
-            let _ = s3.shutdown(Shutdown::Write);
-            drop(tx);
-        })
-    }
-
-    #[test]
-    #[cfg(unix)] // test doesn't work on Windows, see #31657
-    fn close_read_wakes_up() {
-        each_ip(&mut |addr| {
-            let a = t!(TcpListener::bind(&addr));
-            let (tx1, rx) = channel::<()>();
-            let _t = thread::spawn(move || {
-                let _s = t!(a.accept());
-                let _ = rx.recv();
-            });
-
-            let s = t!(TcpStream::connect(&addr));
-            let s2 = t!(s.try_clone());
-            let (tx, rx) = channel();
-            let _t = thread::spawn(move || {
-                let mut s2 = s2;
-                assert_eq!(t!(s2.read(&mut [0])), 0);
-                tx.send(()).unwrap();
-            });
-            // this should wake up the child thread
-            t!(s.shutdown(Shutdown::Read));
-
-            // this test will never finish if the child doesn't wake up
-            rx.recv().unwrap();
-            drop(tx1);
-        })
-    }
-
-    #[test]
-    fn clone_while_reading() {
-        each_ip(&mut |addr| {
-            let accept = t!(TcpListener::bind(&addr));
-
-            // Enqueue a thread to write to a socket
-            let (tx, rx) = channel();
-            let (txdone, rxdone) = channel();
-            let txdone2 = txdone.clone();
-            let _t = thread::spawn(move || {
-                let mut tcp = t!(TcpStream::connect(&addr));
-                rx.recv().unwrap();
-                t!(tcp.write(&[0]));
-                txdone2.send(()).unwrap();
-            });
-
-            // Spawn off a reading clone
-            let tcp = t!(accept.accept()).0;
-            let tcp2 = t!(tcp.try_clone());
-            let txdone3 = txdone.clone();
-            let _t = thread::spawn(move || {
-                let mut tcp2 = tcp2;
-                t!(tcp2.read(&mut [0]));
-                txdone3.send(()).unwrap();
-            });
-
-            // Try to ensure that the reading clone is indeed reading
-            for _ in 0..50 {
-                thread::yield_now();
-            }
-
-            // clone the handle again while it's reading, then let it finish the
-            // read.
-            let _ = t!(tcp.try_clone());
-            tx.send(()).unwrap();
-            rxdone.recv().unwrap();
-            rxdone.recv().unwrap();
-        })
-    }
-
-    #[test]
-    fn clone_accept_smoke() {
-        each_ip(&mut |addr| {
-            let a = t!(TcpListener::bind(&addr));
-            let a2 = t!(a.try_clone());
-
-            let _t = thread::spawn(move || {
-                let _ = TcpStream::connect(&addr);
-            });
-            let _t = thread::spawn(move || {
-                let _ = TcpStream::connect(&addr);
-            });
-
-            t!(a.accept());
-            t!(a2.accept());
-        })
-    }
-
-    #[test]
-    fn clone_accept_concurrent() {
-        each_ip(&mut |addr| {
-            let a = t!(TcpListener::bind(&addr));
-            let a2 = t!(a.try_clone());
-
-            let (tx, rx) = channel();
-            let tx2 = tx.clone();
-
-            let _t = thread::spawn(move || {
-                tx.send(t!(a.accept())).unwrap();
-            });
-            let _t = thread::spawn(move || {
-                tx2.send(t!(a2.accept())).unwrap();
-            });
-
-            let _t = thread::spawn(move || {
-                let _ = TcpStream::connect(&addr);
-            });
-            let _t = thread::spawn(move || {
-                let _ = TcpStream::connect(&addr);
-            });
-
-            rx.recv().unwrap();
-            rx.recv().unwrap();
-        })
-    }
-
-    #[test]
-    fn debug() {
-        #[cfg(not(target_env = "sgx"))]
-        fn render_socket_addr<'a>(addr: &'a SocketAddr) -> impl fmt::Debug + 'a {
-            addr
-        }
-        #[cfg(target_env = "sgx")]
-        fn render_socket_addr<'a>(addr: &'a SocketAddr) -> impl fmt::Debug + 'a {
-            addr.to_string()
-        }
-
-        #[cfg(target_env = "sgx")]
-        use crate::os::fortanix_sgx::io::AsRawFd;
-        #[cfg(unix)]
-        use crate::os::unix::io::AsRawFd;
-        #[cfg(not(windows))]
-        fn render_inner(addr: &dyn AsRawFd) -> impl fmt::Debug {
-            addr.as_raw_fd()
-        }
-        #[cfg(windows)]
-        fn render_inner(addr: &dyn crate::os::windows::io::AsRawSocket) -> impl fmt::Debug {
-            addr.as_raw_socket()
-        }
-
-        let inner_name = if cfg!(windows) { "socket" } else { "fd" };
-        let socket_addr = next_test_ip4();
-
-        let listener = t!(TcpListener::bind(&socket_addr));
-        let compare = format!(
-            "TcpListener {{ addr: {:?}, {}: {:?} }}",
-            render_socket_addr(&socket_addr),
-            inner_name,
-            render_inner(&listener)
-        );
-        assert_eq!(format!("{:?}", listener), compare);
-
-        let stream = t!(TcpStream::connect(&("localhost", socket_addr.port())));
-        let compare = format!(
-            "TcpStream {{ addr: {:?}, peer: {:?}, {}: {:?} }}",
-            render_socket_addr(&stream.local_addr().unwrap()),
-            render_socket_addr(&stream.peer_addr().unwrap()),
-            inner_name,
-            render_inner(&stream)
-        );
-        assert_eq!(format!("{:?}", stream), compare);
-    }
-
-    // FIXME: re-enabled openbsd tests once their socket timeout code
-    //        no longer has rounding errors.
-    // VxWorks ignores SO_SNDTIMEO.
-    #[cfg_attr(any(target_os = "netbsd", target_os = "openbsd", target_os = "vxworks"), ignore)]
-    #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
-    #[test]
-    fn timeouts() {
-        let addr = next_test_ip4();
-        let listener = t!(TcpListener::bind(&addr));
-
-        let stream = t!(TcpStream::connect(&("localhost", addr.port())));
-        let dur = Duration::new(15410, 0);
-
-        assert_eq!(None, t!(stream.read_timeout()));
-
-        t!(stream.set_read_timeout(Some(dur)));
-        assert_eq!(Some(dur), t!(stream.read_timeout()));
-
-        assert_eq!(None, t!(stream.write_timeout()));
-
-        t!(stream.set_write_timeout(Some(dur)));
-        assert_eq!(Some(dur), t!(stream.write_timeout()));
-
-        t!(stream.set_read_timeout(None));
-        assert_eq!(None, t!(stream.read_timeout()));
-
-        t!(stream.set_write_timeout(None));
-        assert_eq!(None, t!(stream.write_timeout()));
-        drop(listener);
-    }
-
-    #[test]
-    #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
-    fn test_read_timeout() {
-        let addr = next_test_ip4();
-        let listener = t!(TcpListener::bind(&addr));
-
-        let mut stream = t!(TcpStream::connect(&("localhost", addr.port())));
-        t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
-
-        let mut buf = [0; 10];
-        let start = Instant::now();
-        let kind = stream.read_exact(&mut buf).err().expect("expected error").kind();
-        assert!(
-            kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
-            "unexpected_error: {:?}",
-            kind
-        );
-        assert!(start.elapsed() > Duration::from_millis(400));
-        drop(listener);
-    }
-
-    #[test]
-    #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
-    fn test_read_with_timeout() {
-        let addr = next_test_ip4();
-        let listener = t!(TcpListener::bind(&addr));
-
-        let mut stream = t!(TcpStream::connect(&("localhost", addr.port())));
-        t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
-
-        let mut other_end = t!(listener.accept()).0;
-        t!(other_end.write_all(b"hello world"));
-
-        let mut buf = [0; 11];
-        t!(stream.read(&mut buf));
-        assert_eq!(b"hello world", &buf[..]);
-
-        let start = Instant::now();
-        let kind = stream.read_exact(&mut buf).err().expect("expected error").kind();
-        assert!(
-            kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
-            "unexpected_error: {:?}",
-            kind
-        );
-        assert!(start.elapsed() > Duration::from_millis(400));
-        drop(listener);
-    }
-
-    // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
-    // when passed zero Durations
-    #[test]
-    fn test_timeout_zero_duration() {
-        let addr = next_test_ip4();
-
-        let listener = t!(TcpListener::bind(&addr));
-        let stream = t!(TcpStream::connect(&addr));
-
-        let result = stream.set_write_timeout(Some(Duration::new(0, 0)));
-        let err = result.unwrap_err();
-        assert_eq!(err.kind(), ErrorKind::InvalidInput);
-
-        let result = stream.set_read_timeout(Some(Duration::new(0, 0)));
-        let err = result.unwrap_err();
-        assert_eq!(err.kind(), ErrorKind::InvalidInput);
-
-        drop(listener);
-    }
-
-    #[test]
-    #[cfg_attr(target_env = "sgx", ignore)]
-    fn nodelay() {
-        let addr = next_test_ip4();
-        let _listener = t!(TcpListener::bind(&addr));
-
-        let stream = t!(TcpStream::connect(&("localhost", addr.port())));
-
-        assert_eq!(false, t!(stream.nodelay()));
-        t!(stream.set_nodelay(true));
-        assert_eq!(true, t!(stream.nodelay()));
-        t!(stream.set_nodelay(false));
-        assert_eq!(false, t!(stream.nodelay()));
-    }
-
-    #[test]
-    #[cfg_attr(target_env = "sgx", ignore)]
-    fn ttl() {
-        let ttl = 100;
-
-        let addr = next_test_ip4();
-        let listener = t!(TcpListener::bind(&addr));
-
-        t!(listener.set_ttl(ttl));
-        assert_eq!(ttl, t!(listener.ttl()));
-
-        let stream = t!(TcpStream::connect(&("localhost", addr.port())));
-
-        t!(stream.set_ttl(ttl));
-        assert_eq!(ttl, t!(stream.ttl()));
-    }
-
-    #[test]
-    #[cfg_attr(target_env = "sgx", ignore)]
-    fn set_nonblocking() {
-        let addr = next_test_ip4();
-        let listener = t!(TcpListener::bind(&addr));
-
-        t!(listener.set_nonblocking(true));
-        t!(listener.set_nonblocking(false));
-
-        let mut stream = t!(TcpStream::connect(&("localhost", addr.port())));
-
-        t!(stream.set_nonblocking(false));
-        t!(stream.set_nonblocking(true));
-
-        let mut buf = [0];
-        match stream.read(&mut buf) {
-            Ok(_) => panic!("expected error"),
-            Err(ref e) if e.kind() == ErrorKind::WouldBlock => {}
-            Err(e) => panic!("unexpected error {}", e),
-        }
-    }
-
-    #[test]
-    #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
-    fn peek() {
-        each_ip(&mut |addr| {
-            let (txdone, rxdone) = channel();
-
-            let srv = t!(TcpListener::bind(&addr));
-            let _t = thread::spawn(move || {
-                let mut cl = t!(srv.accept()).0;
-                cl.write(&[1, 3, 3, 7]).unwrap();
-                t!(rxdone.recv());
-            });
-
-            let mut c = t!(TcpStream::connect(&addr));
-            let mut b = [0; 10];
-            for _ in 1..3 {
-                let len = c.peek(&mut b).unwrap();
-                assert_eq!(len, 4);
-            }
-            let len = c.read(&mut b).unwrap();
-            assert_eq!(len, 4);
-
-            t!(c.set_nonblocking(true));
-            match c.peek(&mut b) {
-                Ok(_) => panic!("expected error"),
-                Err(ref e) if e.kind() == ErrorKind::WouldBlock => {}
-                Err(e) => panic!("unexpected error {}", e),
-            }
-            t!(txdone.send(()));
-        })
-    }
-
-    #[test]
-    #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
-    fn connect_timeout_valid() {
-        let listener = TcpListener::bind("127.0.0.1:0").unwrap();
-        let addr = listener.local_addr().unwrap();
-        TcpStream::connect_timeout(&addr, Duration::from_secs(2)).unwrap();
-    }
-}
diff --git a/library/std/src/net/tcp/tests.rs b/library/std/src/net/tcp/tests.rs
new file mode 100644
index 00000000000..abe9bc24cec
--- /dev/null
+++ b/library/std/src/net/tcp/tests.rs
@@ -0,0 +1,862 @@
+use crate::fmt;
+use crate::io::prelude::*;
+use crate::io::{ErrorKind, IoSlice, IoSliceMut};
+use crate::net::test::{next_test_ip4, next_test_ip6};
+use crate::net::*;
+use crate::sync::mpsc::channel;
+use crate::thread;
+use crate::time::{Duration, Instant};
+
+fn each_ip(f: &mut dyn FnMut(SocketAddr)) {
+    f(next_test_ip4());
+    f(next_test_ip6());
+}
+
+macro_rules! t {
+    ($e:expr) => {
+        match $e {
+            Ok(t) => t,
+            Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
+        }
+    };
+}
+
+#[test]
+fn bind_error() {
+    match TcpListener::bind("1.1.1.1:9999") {
+        Ok(..) => panic!(),
+        Err(e) => assert_eq!(e.kind(), ErrorKind::AddrNotAvailable),
+    }
+}
+
+#[test]
+fn connect_error() {
+    match TcpStream::connect("0.0.0.0:1") {
+        Ok(..) => panic!(),
+        Err(e) => assert!(
+            e.kind() == ErrorKind::ConnectionRefused
+                || e.kind() == ErrorKind::InvalidInput
+                || e.kind() == ErrorKind::AddrInUse
+                || e.kind() == ErrorKind::AddrNotAvailable,
+            "bad error: {} {:?}",
+            e,
+            e.kind()
+        ),
+    }
+}
+
+#[test]
+fn listen_localhost() {
+    let socket_addr = next_test_ip4();
+    let listener = t!(TcpListener::bind(&socket_addr));
+
+    let _t = thread::spawn(move || {
+        let mut stream = t!(TcpStream::connect(&("localhost", socket_addr.port())));
+        t!(stream.write(&[144]));
+    });
+
+    let mut stream = t!(listener.accept()).0;
+    let mut buf = [0];
+    t!(stream.read(&mut buf));
+    assert!(buf[0] == 144);
+}
+
+#[test]
+fn connect_loopback() {
+    each_ip(&mut |addr| {
+        let acceptor = t!(TcpListener::bind(&addr));
+
+        let _t = thread::spawn(move || {
+            let host = match addr {
+                SocketAddr::V4(..) => "127.0.0.1",
+                SocketAddr::V6(..) => "::1",
+            };
+            let mut stream = t!(TcpStream::connect(&(host, addr.port())));
+            t!(stream.write(&[66]));
+        });
+
+        let mut stream = t!(acceptor.accept()).0;
+        let mut buf = [0];
+        t!(stream.read(&mut buf));
+        assert!(buf[0] == 66);
+    })
+}
+
+#[test]
+fn smoke_test() {
+    each_ip(&mut |addr| {
+        let acceptor = t!(TcpListener::bind(&addr));
+
+        let (tx, rx) = channel();
+        let _t = thread::spawn(move || {
+            let mut stream = t!(TcpStream::connect(&addr));
+            t!(stream.write(&[99]));
+            tx.send(t!(stream.local_addr())).unwrap();
+        });
+
+        let (mut stream, addr) = t!(acceptor.accept());
+        let mut buf = [0];
+        t!(stream.read(&mut buf));
+        assert!(buf[0] == 99);
+        assert_eq!(addr, t!(rx.recv()));
+    })
+}
+
+#[test]
+fn read_eof() {
+    each_ip(&mut |addr| {
+        let acceptor = t!(TcpListener::bind(&addr));
+
+        let _t = thread::spawn(move || {
+            let _stream = t!(TcpStream::connect(&addr));
+            // Close
+        });
+
+        let mut stream = t!(acceptor.accept()).0;
+        let mut buf = [0];
+        let nread = t!(stream.read(&mut buf));
+        assert_eq!(nread, 0);
+        let nread = t!(stream.read(&mut buf));
+        assert_eq!(nread, 0);
+    })
+}
+
+#[test]
+fn write_close() {
+    each_ip(&mut |addr| {
+        let acceptor = t!(TcpListener::bind(&addr));
+
+        let (tx, rx) = channel();
+        let _t = thread::spawn(move || {
+            drop(t!(TcpStream::connect(&addr)));
+            tx.send(()).unwrap();
+        });
+
+        let mut stream = t!(acceptor.accept()).0;
+        rx.recv().unwrap();
+        let buf = [0];
+        match stream.write(&buf) {
+            Ok(..) => {}
+            Err(e) => {
+                assert!(
+                    e.kind() == ErrorKind::ConnectionReset
+                        || e.kind() == ErrorKind::BrokenPipe
+                        || e.kind() == ErrorKind::ConnectionAborted,
+                    "unknown error: {}",
+                    e
+                );
+            }
+        }
+    })
+}
+
+#[test]
+fn multiple_connect_serial() {
+    each_ip(&mut |addr| {
+        let max = 10;
+        let acceptor = t!(TcpListener::bind(&addr));
+
+        let _t = thread::spawn(move || {
+            for _ in 0..max {
+                let mut stream = t!(TcpStream::connect(&addr));
+                t!(stream.write(&[99]));
+            }
+        });
+
+        for stream in acceptor.incoming().take(max) {
+            let mut stream = t!(stream);
+            let mut buf = [0];
+            t!(stream.read(&mut buf));
+            assert_eq!(buf[0], 99);
+        }
+    })
+}
+
+#[test]
+fn multiple_connect_interleaved_greedy_schedule() {
+    const MAX: usize = 10;
+    each_ip(&mut |addr| {
+        let acceptor = t!(TcpListener::bind(&addr));
+
+        let _t = thread::spawn(move || {
+            let acceptor = acceptor;
+            for (i, stream) in acceptor.incoming().enumerate().take(MAX) {
+                // Start another thread to handle the connection
+                let _t = thread::spawn(move || {
+                    let mut stream = t!(stream);
+                    let mut buf = [0];
+                    t!(stream.read(&mut buf));
+                    assert!(buf[0] == i as u8);
+                });
+            }
+        });
+
+        connect(0, addr);
+    });
+
+    fn connect(i: usize, addr: SocketAddr) {
+        if i == MAX {
+            return;
+        }
+
+        let t = thread::spawn(move || {
+            let mut stream = t!(TcpStream::connect(&addr));
+            // Connect again before writing
+            connect(i + 1, addr);
+            t!(stream.write(&[i as u8]));
+        });
+        t.join().ok().expect("thread panicked");
+    }
+}
+
+#[test]
+fn multiple_connect_interleaved_lazy_schedule() {
+    const MAX: usize = 10;
+    each_ip(&mut |addr| {
+        let acceptor = t!(TcpListener::bind(&addr));
+
+        let _t = thread::spawn(move || {
+            for stream in acceptor.incoming().take(MAX) {
+                // Start another thread to handle the connection
+                let _t = thread::spawn(move || {
+                    let mut stream = t!(stream);
+                    let mut buf = [0];
+                    t!(stream.read(&mut buf));
+                    assert!(buf[0] == 99);
+                });
+            }
+        });
+
+        connect(0, addr);
+    });
+
+    fn connect(i: usize, addr: SocketAddr) {
+        if i == MAX {
+            return;
+        }
+
+        let t = thread::spawn(move || {
+            let mut stream = t!(TcpStream::connect(&addr));
+            connect(i + 1, addr);
+            t!(stream.write(&[99]));
+        });
+        t.join().ok().expect("thread panicked");
+    }
+}
+
+#[test]
+fn socket_and_peer_name() {
+    each_ip(&mut |addr| {
+        let listener = t!(TcpListener::bind(&addr));
+        let so_name = t!(listener.local_addr());
+        assert_eq!(addr, so_name);
+        let _t = thread::spawn(move || {
+            t!(listener.accept());
+        });
+
+        let stream = t!(TcpStream::connect(&addr));
+        assert_eq!(addr, t!(stream.peer_addr()));
+    })
+}
+
+#[test]
+fn partial_read() {
+    each_ip(&mut |addr| {
+        let (tx, rx) = channel();
+        let srv = t!(TcpListener::bind(&addr));
+        let _t = thread::spawn(move || {
+            let mut cl = t!(srv.accept()).0;
+            cl.write(&[10]).unwrap();
+            let mut b = [0];
+            t!(cl.read(&mut b));
+            tx.send(()).unwrap();
+        });
+
+        let mut c = t!(TcpStream::connect(&addr));
+        let mut b = [0; 10];
+        assert_eq!(c.read(&mut b).unwrap(), 1);
+        t!(c.write(&[1]));
+        rx.recv().unwrap();
+    })
+}
+
+#[test]
+fn read_vectored() {
+    each_ip(&mut |addr| {
+        let srv = t!(TcpListener::bind(&addr));
+        let mut s1 = t!(TcpStream::connect(&addr));
+        let mut s2 = t!(srv.accept()).0;
+
+        let len = s1.write(&[10, 11, 12]).unwrap();
+        assert_eq!(len, 3);
+
+        let mut a = [];
+        let mut b = [0];
+        let mut c = [0; 3];
+        let len = t!(s2.read_vectored(&mut [
+            IoSliceMut::new(&mut a),
+            IoSliceMut::new(&mut b),
+            IoSliceMut::new(&mut c)
+        ],));
+        assert!(len > 0);
+        assert_eq!(b, [10]);
+        // some implementations don't support readv, so we may only fill the first buffer
+        assert!(len == 1 || c == [11, 12, 0]);
+    })
+}
+
+#[test]
+fn write_vectored() {
+    each_ip(&mut |addr| {
+        let srv = t!(TcpListener::bind(&addr));
+        let mut s1 = t!(TcpStream::connect(&addr));
+        let mut s2 = t!(srv.accept()).0;
+
+        let a = [];
+        let b = [10];
+        let c = [11, 12];
+        t!(s1.write_vectored(&[IoSlice::new(&a), IoSlice::new(&b), IoSlice::new(&c)]));
+
+        let mut buf = [0; 4];
+        let len = t!(s2.read(&mut buf));
+        // some implementations don't support writev, so we may only write the first buffer
+        if len == 1 {
+            assert_eq!(buf, [10, 0, 0, 0]);
+        } else {
+            assert_eq!(len, 3);
+            assert_eq!(buf, [10, 11, 12, 0]);
+        }
+    })
+}
+
+#[test]
+fn double_bind() {
+    each_ip(&mut |addr| {
+        let listener1 = t!(TcpListener::bind(&addr));
+        match TcpListener::bind(&addr) {
+            Ok(listener2) => panic!(
+                "This system (perhaps due to options set by TcpListener::bind) \
+                 permits double binding: {:?} and {:?}",
+                listener1, listener2
+            ),
+            Err(e) => {
+                assert!(
+                    e.kind() == ErrorKind::ConnectionRefused
+                        || e.kind() == ErrorKind::Other
+                        || e.kind() == ErrorKind::AddrInUse,
+                    "unknown error: {} {:?}",
+                    e,
+                    e.kind()
+                );
+            }
+        }
+    })
+}
+
+#[test]
+fn tcp_clone_smoke() {
+    each_ip(&mut |addr| {
+        let acceptor = t!(TcpListener::bind(&addr));
+
+        let _t = thread::spawn(move || {
+            let mut s = t!(TcpStream::connect(&addr));
+            let mut buf = [0, 0];
+            assert_eq!(s.read(&mut buf).unwrap(), 1);
+            assert_eq!(buf[0], 1);
+            t!(s.write(&[2]));
+        });
+
+        let mut s1 = t!(acceptor.accept()).0;
+        let s2 = t!(s1.try_clone());
+
+        let (tx1, rx1) = channel();
+        let (tx2, rx2) = channel();
+        let _t = thread::spawn(move || {
+            let mut s2 = s2;
+            rx1.recv().unwrap();
+            t!(s2.write(&[1]));
+            tx2.send(()).unwrap();
+        });
+        tx1.send(()).unwrap();
+        let mut buf = [0, 0];
+        assert_eq!(s1.read(&mut buf).unwrap(), 1);
+        rx2.recv().unwrap();
+    })
+}
+
+#[test]
+fn tcp_clone_two_read() {
+    each_ip(&mut |addr| {
+        let acceptor = t!(TcpListener::bind(&addr));
+        let (tx1, rx) = channel();
+        let tx2 = tx1.clone();
+
+        let _t = thread::spawn(move || {
+            let mut s = t!(TcpStream::connect(&addr));
+            t!(s.write(&[1]));
+            rx.recv().unwrap();
+            t!(s.write(&[2]));
+            rx.recv().unwrap();
+        });
+
+        let mut s1 = t!(acceptor.accept()).0;
+        let s2 = t!(s1.try_clone());
+
+        let (done, rx) = channel();
+        let _t = thread::spawn(move || {
+            let mut s2 = s2;
+            let mut buf = [0, 0];
+            t!(s2.read(&mut buf));
+            tx2.send(()).unwrap();
+            done.send(()).unwrap();
+        });
+        let mut buf = [0, 0];
+        t!(s1.read(&mut buf));
+        tx1.send(()).unwrap();
+
+        rx.recv().unwrap();
+    })
+}
+
+#[test]
+fn tcp_clone_two_write() {
+    each_ip(&mut |addr| {
+        let acceptor = t!(TcpListener::bind(&addr));
+
+        let _t = thread::spawn(move || {
+            let mut s = t!(TcpStream::connect(&addr));
+            let mut buf = [0, 1];
+            t!(s.read(&mut buf));
+            t!(s.read(&mut buf));
+        });
+
+        let mut s1 = t!(acceptor.accept()).0;
+        let s2 = t!(s1.try_clone());
+
+        let (done, rx) = channel();
+        let _t = thread::spawn(move || {
+            let mut s2 = s2;
+            t!(s2.write(&[1]));
+            done.send(()).unwrap();
+        });
+        t!(s1.write(&[2]));
+
+        rx.recv().unwrap();
+    })
+}
+
+#[test]
+// FIXME: https://github.com/fortanix/rust-sgx/issues/110
+#[cfg_attr(target_env = "sgx", ignore)]
+fn shutdown_smoke() {
+    each_ip(&mut |addr| {
+        let a = t!(TcpListener::bind(&addr));
+        let _t = thread::spawn(move || {
+            let mut c = t!(a.accept()).0;
+            let mut b = [0];
+            assert_eq!(c.read(&mut b).unwrap(), 0);
+            t!(c.write(&[1]));
+        });
+
+        let mut s = t!(TcpStream::connect(&addr));
+        t!(s.shutdown(Shutdown::Write));
+        assert!(s.write(&[1]).is_err());
+        let mut b = [0, 0];
+        assert_eq!(t!(s.read(&mut b)), 1);
+        assert_eq!(b[0], 1);
+    })
+}
+
+#[test]
+// FIXME: https://github.com/fortanix/rust-sgx/issues/110
+#[cfg_attr(target_env = "sgx", ignore)]
+fn close_readwrite_smoke() {
+    each_ip(&mut |addr| {
+        let a = t!(TcpListener::bind(&addr));
+        let (tx, rx) = channel::<()>();
+        let _t = thread::spawn(move || {
+            let _s = t!(a.accept());
+            let _ = rx.recv();
+        });
+
+        let mut b = [0];
+        let mut s = t!(TcpStream::connect(&addr));
+        let mut s2 = t!(s.try_clone());
+
+        // closing should prevent reads/writes
+        t!(s.shutdown(Shutdown::Write));
+        assert!(s.write(&[0]).is_err());
+        t!(s.shutdown(Shutdown::Read));
+        assert_eq!(s.read(&mut b).unwrap(), 0);
+
+        // closing should affect previous handles
+        assert!(s2.write(&[0]).is_err());
+        assert_eq!(s2.read(&mut b).unwrap(), 0);
+
+        // closing should affect new handles
+        let mut s3 = t!(s.try_clone());
+        assert!(s3.write(&[0]).is_err());
+        assert_eq!(s3.read(&mut b).unwrap(), 0);
+
+        // make sure these don't die
+        let _ = s2.shutdown(Shutdown::Read);
+        let _ = s2.shutdown(Shutdown::Write);
+        let _ = s3.shutdown(Shutdown::Read);
+        let _ = s3.shutdown(Shutdown::Write);
+        drop(tx);
+    })
+}
+
+#[test]
+#[cfg(unix)] // test doesn't work on Windows, see #31657
+fn close_read_wakes_up() {
+    each_ip(&mut |addr| {
+        let a = t!(TcpListener::bind(&addr));
+        let (tx1, rx) = channel::<()>();
+        let _t = thread::spawn(move || {
+            let _s = t!(a.accept());
+            let _ = rx.recv();
+        });
+
+        let s = t!(TcpStream::connect(&addr));
+        let s2 = t!(s.try_clone());
+        let (tx, rx) = channel();
+        let _t = thread::spawn(move || {
+            let mut s2 = s2;
+            assert_eq!(t!(s2.read(&mut [0])), 0);
+            tx.send(()).unwrap();
+        });
+        // this should wake up the child thread
+        t!(s.shutdown(Shutdown::Read));
+
+        // this test will never finish if the child doesn't wake up
+        rx.recv().unwrap();
+        drop(tx1);
+    })
+}
+
+#[test]
+fn clone_while_reading() {
+    each_ip(&mut |addr| {
+        let accept = t!(TcpListener::bind(&addr));
+
+        // Enqueue a thread to write to a socket
+        let (tx, rx) = channel();
+        let (txdone, rxdone) = channel();
+        let txdone2 = txdone.clone();
+        let _t = thread::spawn(move || {
+            let mut tcp = t!(TcpStream::connect(&addr));
+            rx.recv().unwrap();
+            t!(tcp.write(&[0]));
+            txdone2.send(()).unwrap();
+        });
+
+        // Spawn off a reading clone
+        let tcp = t!(accept.accept()).0;
+        let tcp2 = t!(tcp.try_clone());
+        let txdone3 = txdone.clone();
+        let _t = thread::spawn(move || {
+            let mut tcp2 = tcp2;
+            t!(tcp2.read(&mut [0]));
+            txdone3.send(()).unwrap();
+        });
+
+        // Try to ensure that the reading clone is indeed reading
+        for _ in 0..50 {
+            thread::yield_now();
+        }
+
+        // clone the handle again while it's reading, then let it finish the
+        // read.
+        let _ = t!(tcp.try_clone());
+        tx.send(()).unwrap();
+        rxdone.recv().unwrap();
+        rxdone.recv().unwrap();
+    })
+}
+
+#[test]
+fn clone_accept_smoke() {
+    each_ip(&mut |addr| {
+        let a = t!(TcpListener::bind(&addr));
+        let a2 = t!(a.try_clone());
+
+        let _t = thread::spawn(move || {
+            let _ = TcpStream::connect(&addr);
+        });
+        let _t = thread::spawn(move || {
+            let _ = TcpStream::connect(&addr);
+        });
+
+        t!(a.accept());
+        t!(a2.accept());
+    })
+}
+
+#[test]
+fn clone_accept_concurrent() {
+    each_ip(&mut |addr| {
+        let a = t!(TcpListener::bind(&addr));
+        let a2 = t!(a.try_clone());
+
+        let (tx, rx) = channel();
+        let tx2 = tx.clone();
+
+        let _t = thread::spawn(move || {
+            tx.send(t!(a.accept())).unwrap();
+        });
+        let _t = thread::spawn(move || {
+            tx2.send(t!(a2.accept())).unwrap();
+        });
+
+        let _t = thread::spawn(move || {
+            let _ = TcpStream::connect(&addr);
+        });
+        let _t = thread::spawn(move || {
+            let _ = TcpStream::connect(&addr);
+        });
+
+        rx.recv().unwrap();
+        rx.recv().unwrap();
+    })
+}
+
+#[test]
+fn debug() {
+    #[cfg(not(target_env = "sgx"))]
+    fn render_socket_addr<'a>(addr: &'a SocketAddr) -> impl fmt::Debug + 'a {
+        addr
+    }
+    #[cfg(target_env = "sgx")]
+    fn render_socket_addr<'a>(addr: &'a SocketAddr) -> impl fmt::Debug + 'a {
+        addr.to_string()
+    }
+
+    #[cfg(target_env = "sgx")]
+    use crate::os::fortanix_sgx::io::AsRawFd;
+    #[cfg(unix)]
+    use crate::os::unix::io::AsRawFd;
+    #[cfg(not(windows))]
+    fn render_inner(addr: &dyn AsRawFd) -> impl fmt::Debug {
+        addr.as_raw_fd()
+    }
+    #[cfg(windows)]
+    fn render_inner(addr: &dyn crate::os::windows::io::AsRawSocket) -> impl fmt::Debug {
+        addr.as_raw_socket()
+    }
+
+    let inner_name = if cfg!(windows) { "socket" } else { "fd" };
+    let socket_addr = next_test_ip4();
+
+    let listener = t!(TcpListener::bind(&socket_addr));
+    let compare = format!(
+        "TcpListener {{ addr: {:?}, {}: {:?} }}",
+        render_socket_addr(&socket_addr),
+        inner_name,
+        render_inner(&listener)
+    );
+    assert_eq!(format!("{:?}", listener), compare);
+
+    let stream = t!(TcpStream::connect(&("localhost", socket_addr.port())));
+    let compare = format!(
+        "TcpStream {{ addr: {:?}, peer: {:?}, {}: {:?} }}",
+        render_socket_addr(&stream.local_addr().unwrap()),
+        render_socket_addr(&stream.peer_addr().unwrap()),
+        inner_name,
+        render_inner(&stream)
+    );
+    assert_eq!(format!("{:?}", stream), compare);
+}
+
+// FIXME: re-enabled openbsd tests once their socket timeout code
+//        no longer has rounding errors.
+// VxWorks ignores SO_SNDTIMEO.
+#[cfg_attr(any(target_os = "netbsd", target_os = "openbsd", target_os = "vxworks"), ignore)]
+#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
+#[test]
+fn timeouts() {
+    let addr = next_test_ip4();
+    let listener = t!(TcpListener::bind(&addr));
+
+    let stream = t!(TcpStream::connect(&("localhost", addr.port())));
+    let dur = Duration::new(15410, 0);
+
+    assert_eq!(None, t!(stream.read_timeout()));
+
+    t!(stream.set_read_timeout(Some(dur)));
+    assert_eq!(Some(dur), t!(stream.read_timeout()));
+
+    assert_eq!(None, t!(stream.write_timeout()));
+
+    t!(stream.set_write_timeout(Some(dur)));
+    assert_eq!(Some(dur), t!(stream.write_timeout()));
+
+    t!(stream.set_read_timeout(None));
+    assert_eq!(None, t!(stream.read_timeout()));
+
+    t!(stream.set_write_timeout(None));
+    assert_eq!(None, t!(stream.write_timeout()));
+    drop(listener);
+}
+
+#[test]
+#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
+fn test_read_timeout() {
+    let addr = next_test_ip4();
+    let listener = t!(TcpListener::bind(&addr));
+
+    let mut stream = t!(TcpStream::connect(&("localhost", addr.port())));
+    t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
+
+    let mut buf = [0; 10];
+    let start = Instant::now();
+    let kind = stream.read_exact(&mut buf).err().expect("expected error").kind();
+    assert!(
+        kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
+        "unexpected_error: {:?}",
+        kind
+    );
+    assert!(start.elapsed() > Duration::from_millis(400));
+    drop(listener);
+}
+
+#[test]
+#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
+fn test_read_with_timeout() {
+    let addr = next_test_ip4();
+    let listener = t!(TcpListener::bind(&addr));
+
+    let mut stream = t!(TcpStream::connect(&("localhost", addr.port())));
+    t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
+
+    let mut other_end = t!(listener.accept()).0;
+    t!(other_end.write_all(b"hello world"));
+
+    let mut buf = [0; 11];
+    t!(stream.read(&mut buf));
+    assert_eq!(b"hello world", &buf[..]);
+
+    let start = Instant::now();
+    let kind = stream.read_exact(&mut buf).err().expect("expected error").kind();
+    assert!(
+        kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
+        "unexpected_error: {:?}",
+        kind
+    );
+    assert!(start.elapsed() > Duration::from_millis(400));
+    drop(listener);
+}
+
+// Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
+// when passed zero Durations
+#[test]
+fn test_timeout_zero_duration() {
+    let addr = next_test_ip4();
+
+    let listener = t!(TcpListener::bind(&addr));
+    let stream = t!(TcpStream::connect(&addr));
+
+    let result = stream.set_write_timeout(Some(Duration::new(0, 0)));
+    let err = result.unwrap_err();
+    assert_eq!(err.kind(), ErrorKind::InvalidInput);
+
+    let result = stream.set_read_timeout(Some(Duration::new(0, 0)));
+    let err = result.unwrap_err();
+    assert_eq!(err.kind(), ErrorKind::InvalidInput);
+
+    drop(listener);
+}
+
+#[test]
+#[cfg_attr(target_env = "sgx", ignore)]
+fn nodelay() {
+    let addr = next_test_ip4();
+    let _listener = t!(TcpListener::bind(&addr));
+
+    let stream = t!(TcpStream::connect(&("localhost", addr.port())));
+
+    assert_eq!(false, t!(stream.nodelay()));
+    t!(stream.set_nodelay(true));
+    assert_eq!(true, t!(stream.nodelay()));
+    t!(stream.set_nodelay(false));
+    assert_eq!(false, t!(stream.nodelay()));
+}
+
+#[test]
+#[cfg_attr(target_env = "sgx", ignore)]
+fn ttl() {
+    let ttl = 100;
+
+    let addr = next_test_ip4();
+    let listener = t!(TcpListener::bind(&addr));
+
+    t!(listener.set_ttl(ttl));
+    assert_eq!(ttl, t!(listener.ttl()));
+
+    let stream = t!(TcpStream::connect(&("localhost", addr.port())));
+
+    t!(stream.set_ttl(ttl));
+    assert_eq!(ttl, t!(stream.ttl()));
+}
+
+#[test]
+#[cfg_attr(target_env = "sgx", ignore)]
+fn set_nonblocking() {
+    let addr = next_test_ip4();
+    let listener = t!(TcpListener::bind(&addr));
+
+    t!(listener.set_nonblocking(true));
+    t!(listener.set_nonblocking(false));
+
+    let mut stream = t!(TcpStream::connect(&("localhost", addr.port())));
+
+    t!(stream.set_nonblocking(false));
+    t!(stream.set_nonblocking(true));
+
+    let mut buf = [0];
+    match stream.read(&mut buf) {
+        Ok(_) => panic!("expected error"),
+        Err(ref e) if e.kind() == ErrorKind::WouldBlock => {}
+        Err(e) => panic!("unexpected error {}", e),
+    }
+}
+
+#[test]
+#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
+fn peek() {
+    each_ip(&mut |addr| {
+        let (txdone, rxdone) = channel();
+
+        let srv = t!(TcpListener::bind(&addr));
+        let _t = thread::spawn(move || {
+            let mut cl = t!(srv.accept()).0;
+            cl.write(&[1, 3, 3, 7]).unwrap();
+            t!(rxdone.recv());
+        });
+
+        let mut c = t!(TcpStream::connect(&addr));
+        let mut b = [0; 10];
+        for _ in 1..3 {
+            let len = c.peek(&mut b).unwrap();
+            assert_eq!(len, 4);
+        }
+        let len = c.read(&mut b).unwrap();
+        assert_eq!(len, 4);
+
+        t!(c.set_nonblocking(true));
+        match c.peek(&mut b) {
+            Ok(_) => panic!("expected error"),
+            Err(ref e) if e.kind() == ErrorKind::WouldBlock => {}
+            Err(e) => panic!("unexpected error {}", e),
+        }
+        t!(txdone.send(()));
+    })
+}
+
+#[test]
+#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
+fn connect_timeout_valid() {
+    let listener = TcpListener::bind("127.0.0.1:0").unwrap();
+    let addr = listener.local_addr().unwrap();
+    TcpStream::connect_timeout(&addr, Duration::from_secs(2)).unwrap();
+}
diff --git a/library/std/src/net/udp.rs b/library/std/src/net/udp.rs
index d730b2b87ac..17e3e4497c4 100644
--- a/library/std/src/net/udp.rs
+++ b/library/std/src/net/udp.rs
@@ -1,3 +1,6 @@
+#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))]
+mod tests;
+
 use crate::fmt;
 use crate::io::{self, Error, ErrorKind};
 use crate::net::{Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs};
@@ -798,380 +801,3 @@ impl fmt::Debug for UdpSocket {
         self.0.fmt(f)
     }
 }
-
-#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))]
-mod tests {
-    use crate::io::ErrorKind;
-    use crate::net::test::{next_test_ip4, next_test_ip6};
-    use crate::net::*;
-    use crate::sync::mpsc::channel;
-    use crate::sys_common::AsInner;
-    use crate::thread;
-    use crate::time::{Duration, Instant};
-
-    fn each_ip(f: &mut dyn FnMut(SocketAddr, SocketAddr)) {
-        f(next_test_ip4(), next_test_ip4());
-        f(next_test_ip6(), next_test_ip6());
-    }
-
-    macro_rules! t {
-        ($e:expr) => {
-            match $e {
-                Ok(t) => t,
-                Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
-            }
-        };
-    }
-
-    #[test]
-    fn bind_error() {
-        match UdpSocket::bind("1.1.1.1:9999") {
-            Ok(..) => panic!(),
-            Err(e) => assert_eq!(e.kind(), ErrorKind::AddrNotAvailable),
-        }
-    }
-
-    #[test]
-    fn socket_smoke_test_ip4() {
-        each_ip(&mut |server_ip, client_ip| {
-            let (tx1, rx1) = channel();
-            let (tx2, rx2) = channel();
-
-            let _t = thread::spawn(move || {
-                let client = t!(UdpSocket::bind(&client_ip));
-                rx1.recv().unwrap();
-                t!(client.send_to(&[99], &server_ip));
-                tx2.send(()).unwrap();
-            });
-
-            let server = t!(UdpSocket::bind(&server_ip));
-            tx1.send(()).unwrap();
-            let mut buf = [0];
-            let (nread, src) = t!(server.recv_from(&mut buf));
-            assert_eq!(nread, 1);
-            assert_eq!(buf[0], 99);
-            assert_eq!(src, client_ip);
-            rx2.recv().unwrap();
-        })
-    }
-
-    #[test]
-    fn socket_name() {
-        each_ip(&mut |addr, _| {
-            let server = t!(UdpSocket::bind(&addr));
-            assert_eq!(addr, t!(server.local_addr()));
-        })
-    }
-
-    #[test]
-    fn socket_peer() {
-        each_ip(&mut |addr1, addr2| {
-            let server = t!(UdpSocket::bind(&addr1));
-            assert_eq!(server.peer_addr().unwrap_err().kind(), ErrorKind::NotConnected);
-            t!(server.connect(&addr2));
-            assert_eq!(addr2, t!(server.peer_addr()));
-        })
-    }
-
-    #[test]
-    fn udp_clone_smoke() {
-        each_ip(&mut |addr1, addr2| {
-            let sock1 = t!(UdpSocket::bind(&addr1));
-            let sock2 = t!(UdpSocket::bind(&addr2));
-
-            let _t = thread::spawn(move || {
-                let mut buf = [0, 0];
-                assert_eq!(sock2.recv_from(&mut buf).unwrap(), (1, addr1));
-                assert_eq!(buf[0], 1);
-                t!(sock2.send_to(&[2], &addr1));
-            });
-
-            let sock3 = t!(sock1.try_clone());
-
-            let (tx1, rx1) = channel();
-            let (tx2, rx2) = channel();
-            let _t = thread::spawn(move || {
-                rx1.recv().unwrap();
-                t!(sock3.send_to(&[1], &addr2));
-                tx2.send(()).unwrap();
-            });
-            tx1.send(()).unwrap();
-            let mut buf = [0, 0];
-            assert_eq!(sock1.recv_from(&mut buf).unwrap(), (1, addr2));
-            rx2.recv().unwrap();
-        })
-    }
-
-    #[test]
-    fn udp_clone_two_read() {
-        each_ip(&mut |addr1, addr2| {
-            let sock1 = t!(UdpSocket::bind(&addr1));
-            let sock2 = t!(UdpSocket::bind(&addr2));
-            let (tx1, rx) = channel();
-            let tx2 = tx1.clone();
-
-            let _t = thread::spawn(move || {
-                t!(sock2.send_to(&[1], &addr1));
-                rx.recv().unwrap();
-                t!(sock2.send_to(&[2], &addr1));
-                rx.recv().unwrap();
-            });
-
-            let sock3 = t!(sock1.try_clone());
-
-            let (done, rx) = channel();
-            let _t = thread::spawn(move || {
-                let mut buf = [0, 0];
-                t!(sock3.recv_from(&mut buf));
-                tx2.send(()).unwrap();
-                done.send(()).unwrap();
-            });
-            let mut buf = [0, 0];
-            t!(sock1.recv_from(&mut buf));
-            tx1.send(()).unwrap();
-
-            rx.recv().unwrap();
-        })
-    }
-
-    #[test]
-    fn udp_clone_two_write() {
-        each_ip(&mut |addr1, addr2| {
-            let sock1 = t!(UdpSocket::bind(&addr1));
-            let sock2 = t!(UdpSocket::bind(&addr2));
-
-            let (tx, rx) = channel();
-            let (serv_tx, serv_rx) = channel();
-
-            let _t = thread::spawn(move || {
-                let mut buf = [0, 1];
-                rx.recv().unwrap();
-                t!(sock2.recv_from(&mut buf));
-                serv_tx.send(()).unwrap();
-            });
-
-            let sock3 = t!(sock1.try_clone());
-
-            let (done, rx) = channel();
-            let tx2 = tx.clone();
-            let _t = thread::spawn(move || {
-                match sock3.send_to(&[1], &addr2) {
-                    Ok(..) => {
-                        let _ = tx2.send(());
-                    }
-                    Err(..) => {}
-                }
-                done.send(()).unwrap();
-            });
-            match sock1.send_to(&[2], &addr2) {
-                Ok(..) => {
-                    let _ = tx.send(());
-                }
-                Err(..) => {}
-            }
-            drop(tx);
-
-            rx.recv().unwrap();
-            serv_rx.recv().unwrap();
-        })
-    }
-
-    #[test]
-    fn debug() {
-        let name = if cfg!(windows) { "socket" } else { "fd" };
-        let socket_addr = next_test_ip4();
-
-        let udpsock = t!(UdpSocket::bind(&socket_addr));
-        let udpsock_inner = udpsock.0.socket().as_inner();
-        let compare =
-            format!("UdpSocket {{ addr: {:?}, {}: {:?} }}", socket_addr, name, udpsock_inner);
-        assert_eq!(format!("{:?}", udpsock), compare);
-    }
-
-    // FIXME: re-enabled openbsd/netbsd tests once their socket timeout code
-    //        no longer has rounding errors.
-    // VxWorks ignores SO_SNDTIMEO.
-    #[cfg_attr(any(target_os = "netbsd", target_os = "openbsd", target_os = "vxworks"), ignore)]
-    #[test]
-    fn timeouts() {
-        let addr = next_test_ip4();
-
-        let stream = t!(UdpSocket::bind(&addr));
-        let dur = Duration::new(15410, 0);
-
-        assert_eq!(None, t!(stream.read_timeout()));
-
-        t!(stream.set_read_timeout(Some(dur)));
-        assert_eq!(Some(dur), t!(stream.read_timeout()));
-
-        assert_eq!(None, t!(stream.write_timeout()));
-
-        t!(stream.set_write_timeout(Some(dur)));
-        assert_eq!(Some(dur), t!(stream.write_timeout()));
-
-        t!(stream.set_read_timeout(None));
-        assert_eq!(None, t!(stream.read_timeout()));
-
-        t!(stream.set_write_timeout(None));
-        assert_eq!(None, t!(stream.write_timeout()));
-    }
-
-    #[test]
-    fn test_read_timeout() {
-        let addr = next_test_ip4();
-
-        let stream = t!(UdpSocket::bind(&addr));
-        t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
-
-        let mut buf = [0; 10];
-
-        let start = Instant::now();
-        loop {
-            let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
-            if kind != ErrorKind::Interrupted {
-                assert!(
-                    kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
-                    "unexpected_error: {:?}",
-                    kind
-                );
-                break;
-            }
-        }
-        assert!(start.elapsed() > Duration::from_millis(400));
-    }
-
-    #[test]
-    fn test_read_with_timeout() {
-        let addr = next_test_ip4();
-
-        let stream = t!(UdpSocket::bind(&addr));
-        t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
-
-        t!(stream.send_to(b"hello world", &addr));
-
-        let mut buf = [0; 11];
-        t!(stream.recv_from(&mut buf));
-        assert_eq!(b"hello world", &buf[..]);
-
-        let start = Instant::now();
-        loop {
-            let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
-            if kind != ErrorKind::Interrupted {
-                assert!(
-                    kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
-                    "unexpected_error: {:?}",
-                    kind
-                );
-                break;
-            }
-        }
-        assert!(start.elapsed() > Duration::from_millis(400));
-    }
-
-    // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
-    // when passed zero Durations
-    #[test]
-    fn test_timeout_zero_duration() {
-        let addr = next_test_ip4();
-
-        let socket = t!(UdpSocket::bind(&addr));
-
-        let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
-        let err = result.unwrap_err();
-        assert_eq!(err.kind(), ErrorKind::InvalidInput);
-
-        let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
-        let err = result.unwrap_err();
-        assert_eq!(err.kind(), ErrorKind::InvalidInput);
-    }
-
-    #[test]
-    fn connect_send_recv() {
-        let addr = next_test_ip4();
-
-        let socket = t!(UdpSocket::bind(&addr));
-        t!(socket.connect(addr));
-
-        t!(socket.send(b"hello world"));
-
-        let mut buf = [0; 11];
-        t!(socket.recv(&mut buf));
-        assert_eq!(b"hello world", &buf[..]);
-    }
-
-    #[test]
-    fn connect_send_peek_recv() {
-        each_ip(&mut |addr, _| {
-            let socket = t!(UdpSocket::bind(&addr));
-            t!(socket.connect(addr));
-
-            t!(socket.send(b"hello world"));
-
-            for _ in 1..3 {
-                let mut buf = [0; 11];
-                let size = t!(socket.peek(&mut buf));
-                assert_eq!(b"hello world", &buf[..]);
-                assert_eq!(size, 11);
-            }
-
-            let mut buf = [0; 11];
-            let size = t!(socket.recv(&mut buf));
-            assert_eq!(b"hello world", &buf[..]);
-            assert_eq!(size, 11);
-        })
-    }
-
-    #[test]
-    fn peek_from() {
-        each_ip(&mut |addr, _| {
-            let socket = t!(UdpSocket::bind(&addr));
-            t!(socket.send_to(b"hello world", &addr));
-
-            for _ in 1..3 {
-                let mut buf = [0; 11];
-                let (size, _) = t!(socket.peek_from(&mut buf));
-                assert_eq!(b"hello world", &buf[..]);
-                assert_eq!(size, 11);
-            }
-
-            let mut buf = [0; 11];
-            let (size, _) = t!(socket.recv_from(&mut buf));
-            assert_eq!(b"hello world", &buf[..]);
-            assert_eq!(size, 11);
-        })
-    }
-
-    #[test]
-    fn ttl() {
-        let ttl = 100;
-
-        let addr = next_test_ip4();
-
-        let stream = t!(UdpSocket::bind(&addr));
-
-        t!(stream.set_ttl(ttl));
-        assert_eq!(ttl, t!(stream.ttl()));
-    }
-
-    #[test]
-    fn set_nonblocking() {
-        each_ip(&mut |addr, _| {
-            let socket = t!(UdpSocket::bind(&addr));
-
-            t!(socket.set_nonblocking(true));
-            t!(socket.set_nonblocking(false));
-
-            t!(socket.connect(addr));
-
-            t!(socket.set_nonblocking(false));
-            t!(socket.set_nonblocking(true));
-
-            let mut buf = [0];
-            match socket.recv(&mut buf) {
-                Ok(_) => panic!("expected error"),
-                Err(ref e) if e.kind() == ErrorKind::WouldBlock => {}
-                Err(e) => panic!("unexpected error {}", e),
-            }
-        })
-    }
-}
diff --git a/library/std/src/net/udp/tests.rs b/library/std/src/net/udp/tests.rs
new file mode 100644
index 00000000000..658369f79aa
--- /dev/null
+++ b/library/std/src/net/udp/tests.rs
@@ -0,0 +1,372 @@
+use crate::io::ErrorKind;
+use crate::net::test::{next_test_ip4, next_test_ip6};
+use crate::net::*;
+use crate::sync::mpsc::channel;
+use crate::sys_common::AsInner;
+use crate::thread;
+use crate::time::{Duration, Instant};
+
+fn each_ip(f: &mut dyn FnMut(SocketAddr, SocketAddr)) {
+    f(next_test_ip4(), next_test_ip4());
+    f(next_test_ip6(), next_test_ip6());
+}
+
+macro_rules! t {
+    ($e:expr) => {
+        match $e {
+            Ok(t) => t,
+            Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
+        }
+    };
+}
+
+#[test]
+fn bind_error() {
+    match UdpSocket::bind("1.1.1.1:9999") {
+        Ok(..) => panic!(),
+        Err(e) => assert_eq!(e.kind(), ErrorKind::AddrNotAvailable),
+    }
+}
+
+#[test]
+fn socket_smoke_test_ip4() {
+    each_ip(&mut |server_ip, client_ip| {
+        let (tx1, rx1) = channel();
+        let (tx2, rx2) = channel();
+
+        let _t = thread::spawn(move || {
+            let client = t!(UdpSocket::bind(&client_ip));
+            rx1.recv().unwrap();
+            t!(client.send_to(&[99], &server_ip));
+            tx2.send(()).unwrap();
+        });
+
+        let server = t!(UdpSocket::bind(&server_ip));
+        tx1.send(()).unwrap();
+        let mut buf = [0];
+        let (nread, src) = t!(server.recv_from(&mut buf));
+        assert_eq!(nread, 1);
+        assert_eq!(buf[0], 99);
+        assert_eq!(src, client_ip);
+        rx2.recv().unwrap();
+    })
+}
+
+#[test]
+fn socket_name() {
+    each_ip(&mut |addr, _| {
+        let server = t!(UdpSocket::bind(&addr));
+        assert_eq!(addr, t!(server.local_addr()));
+    })
+}
+
+#[test]
+fn socket_peer() {
+    each_ip(&mut |addr1, addr2| {
+        let server = t!(UdpSocket::bind(&addr1));
+        assert_eq!(server.peer_addr().unwrap_err().kind(), ErrorKind::NotConnected);
+        t!(server.connect(&addr2));
+        assert_eq!(addr2, t!(server.peer_addr()));
+    })
+}
+
+#[test]
+fn udp_clone_smoke() {
+    each_ip(&mut |addr1, addr2| {
+        let sock1 = t!(UdpSocket::bind(&addr1));
+        let sock2 = t!(UdpSocket::bind(&addr2));
+
+        let _t = thread::spawn(move || {
+            let mut buf = [0, 0];
+            assert_eq!(sock2.recv_from(&mut buf).unwrap(), (1, addr1));
+            assert_eq!(buf[0], 1);
+            t!(sock2.send_to(&[2], &addr1));
+        });
+
+        let sock3 = t!(sock1.try_clone());
+
+        let (tx1, rx1) = channel();
+        let (tx2, rx2) = channel();
+        let _t = thread::spawn(move || {
+            rx1.recv().unwrap();
+            t!(sock3.send_to(&[1], &addr2));
+            tx2.send(()).unwrap();
+        });
+        tx1.send(()).unwrap();
+        let mut buf = [0, 0];
+        assert_eq!(sock1.recv_from(&mut buf).unwrap(), (1, addr2));
+        rx2.recv().unwrap();
+    })
+}
+
+#[test]
+fn udp_clone_two_read() {
+    each_ip(&mut |addr1, addr2| {
+        let sock1 = t!(UdpSocket::bind(&addr1));
+        let sock2 = t!(UdpSocket::bind(&addr2));
+        let (tx1, rx) = channel();
+        let tx2 = tx1.clone();
+
+        let _t = thread::spawn(move || {
+            t!(sock2.send_to(&[1], &addr1));
+            rx.recv().unwrap();
+            t!(sock2.send_to(&[2], &addr1));
+            rx.recv().unwrap();
+        });
+
+        let sock3 = t!(sock1.try_clone());
+
+        let (done, rx) = channel();
+        let _t = thread::spawn(move || {
+            let mut buf = [0, 0];
+            t!(sock3.recv_from(&mut buf));
+            tx2.send(()).unwrap();
+            done.send(()).unwrap();
+        });
+        let mut buf = [0, 0];
+        t!(sock1.recv_from(&mut buf));
+        tx1.send(()).unwrap();
+
+        rx.recv().unwrap();
+    })
+}
+
+#[test]
+fn udp_clone_two_write() {
+    each_ip(&mut |addr1, addr2| {
+        let sock1 = t!(UdpSocket::bind(&addr1));
+        let sock2 = t!(UdpSocket::bind(&addr2));
+
+        let (tx, rx) = channel();
+        let (serv_tx, serv_rx) = channel();
+
+        let _t = thread::spawn(move || {
+            let mut buf = [0, 1];
+            rx.recv().unwrap();
+            t!(sock2.recv_from(&mut buf));
+            serv_tx.send(()).unwrap();
+        });
+
+        let sock3 = t!(sock1.try_clone());
+
+        let (done, rx) = channel();
+        let tx2 = tx.clone();
+        let _t = thread::spawn(move || {
+            match sock3.send_to(&[1], &addr2) {
+                Ok(..) => {
+                    let _ = tx2.send(());
+                }
+                Err(..) => {}
+            }
+            done.send(()).unwrap();
+        });
+        match sock1.send_to(&[2], &addr2) {
+            Ok(..) => {
+                let _ = tx.send(());
+            }
+            Err(..) => {}
+        }
+        drop(tx);
+
+        rx.recv().unwrap();
+        serv_rx.recv().unwrap();
+    })
+}
+
+#[test]
+fn debug() {
+    let name = if cfg!(windows) { "socket" } else { "fd" };
+    let socket_addr = next_test_ip4();
+
+    let udpsock = t!(UdpSocket::bind(&socket_addr));
+    let udpsock_inner = udpsock.0.socket().as_inner();
+    let compare = format!("UdpSocket {{ addr: {:?}, {}: {:?} }}", socket_addr, name, udpsock_inner);
+    assert_eq!(format!("{:?}", udpsock), compare);
+}
+
+// FIXME: re-enabled openbsd/netbsd tests once their socket timeout code
+//        no longer has rounding errors.
+// VxWorks ignores SO_SNDTIMEO.
+#[cfg_attr(any(target_os = "netbsd", target_os = "openbsd", target_os = "vxworks"), ignore)]
+#[test]
+fn timeouts() {
+    let addr = next_test_ip4();
+
+    let stream = t!(UdpSocket::bind(&addr));
+    let dur = Duration::new(15410, 0);
+
+    assert_eq!(None, t!(stream.read_timeout()));
+
+    t!(stream.set_read_timeout(Some(dur)));
+    assert_eq!(Some(dur), t!(stream.read_timeout()));
+
+    assert_eq!(None, t!(stream.write_timeout()));
+
+    t!(stream.set_write_timeout(Some(dur)));
+    assert_eq!(Some(dur), t!(stream.write_timeout()));
+
+    t!(stream.set_read_timeout(None));
+    assert_eq!(None, t!(stream.read_timeout()));
+
+    t!(stream.set_write_timeout(None));
+    assert_eq!(None, t!(stream.write_timeout()));
+}
+
+#[test]
+fn test_read_timeout() {
+    let addr = next_test_ip4();
+
+    let stream = t!(UdpSocket::bind(&addr));
+    t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
+
+    let mut buf = [0; 10];
+
+    let start = Instant::now();
+    loop {
+        let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
+        if kind != ErrorKind::Interrupted {
+            assert!(
+                kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
+                "unexpected_error: {:?}",
+                kind
+            );
+            break;
+        }
+    }
+    assert!(start.elapsed() > Duration::from_millis(400));
+}
+
+#[test]
+fn test_read_with_timeout() {
+    let addr = next_test_ip4();
+
+    let stream = t!(UdpSocket::bind(&addr));
+    t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
+
+    t!(stream.send_to(b"hello world", &addr));
+
+    let mut buf = [0; 11];
+    t!(stream.recv_from(&mut buf));
+    assert_eq!(b"hello world", &buf[..]);
+
+    let start = Instant::now();
+    loop {
+        let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
+        if kind != ErrorKind::Interrupted {
+            assert!(
+                kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
+                "unexpected_error: {:?}",
+                kind
+            );
+            break;
+        }
+    }
+    assert!(start.elapsed() > Duration::from_millis(400));
+}
+
+// Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
+// when passed zero Durations
+#[test]
+fn test_timeout_zero_duration() {
+    let addr = next_test_ip4();
+
+    let socket = t!(UdpSocket::bind(&addr));
+
+    let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
+    let err = result.unwrap_err();
+    assert_eq!(err.kind(), ErrorKind::InvalidInput);
+
+    let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
+    let err = result.unwrap_err();
+    assert_eq!(err.kind(), ErrorKind::InvalidInput);
+}
+
+#[test]
+fn connect_send_recv() {
+    let addr = next_test_ip4();
+
+    let socket = t!(UdpSocket::bind(&addr));
+    t!(socket.connect(addr));
+
+    t!(socket.send(b"hello world"));
+
+    let mut buf = [0; 11];
+    t!(socket.recv(&mut buf));
+    assert_eq!(b"hello world", &buf[..]);
+}
+
+#[test]
+fn connect_send_peek_recv() {
+    each_ip(&mut |addr, _| {
+        let socket = t!(UdpSocket::bind(&addr));
+        t!(socket.connect(addr));
+
+        t!(socket.send(b"hello world"));
+
+        for _ in 1..3 {
+            let mut buf = [0; 11];
+            let size = t!(socket.peek(&mut buf));
+            assert_eq!(b"hello world", &buf[..]);
+            assert_eq!(size, 11);
+        }
+
+        let mut buf = [0; 11];
+        let size = t!(socket.recv(&mut buf));
+        assert_eq!(b"hello world", &buf[..]);
+        assert_eq!(size, 11);
+    })
+}
+
+#[test]
+fn peek_from() {
+    each_ip(&mut |addr, _| {
+        let socket = t!(UdpSocket::bind(&addr));
+        t!(socket.send_to(b"hello world", &addr));
+
+        for _ in 1..3 {
+            let mut buf = [0; 11];
+            let (size, _) = t!(socket.peek_from(&mut buf));
+            assert_eq!(b"hello world", &buf[..]);
+            assert_eq!(size, 11);
+        }
+
+        let mut buf = [0; 11];
+        let (size, _) = t!(socket.recv_from(&mut buf));
+        assert_eq!(b"hello world", &buf[..]);
+        assert_eq!(size, 11);
+    })
+}
+
+#[test]
+fn ttl() {
+    let ttl = 100;
+
+    let addr = next_test_ip4();
+
+    let stream = t!(UdpSocket::bind(&addr));
+
+    t!(stream.set_ttl(ttl));
+    assert_eq!(ttl, t!(stream.ttl()));
+}
+
+#[test]
+fn set_nonblocking() {
+    each_ip(&mut |addr, _| {
+        let socket = t!(UdpSocket::bind(&addr));
+
+        t!(socket.set_nonblocking(true));
+        t!(socket.set_nonblocking(false));
+
+        t!(socket.connect(addr));
+
+        t!(socket.set_nonblocking(false));
+        t!(socket.set_nonblocking(true));
+
+        let mut buf = [0];
+        match socket.recv(&mut buf) {
+            Ok(_) => panic!("expected error"),
+            Err(ref e) if e.kind() == ErrorKind::WouldBlock => {}
+            Err(e) => panic!("unexpected error {}", e),
+        }
+    })
+}
diff --git a/library/std/src/num.rs b/library/std/src/num.rs
index b496c16a749..0f1c5962685 100644
--- a/library/std/src/num.rs
+++ b/library/std/src/num.rs
@@ -6,6 +6,12 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 #![allow(missing_docs)]
 
+#[cfg(test)]
+mod tests;
+
+#[cfg(test)]
+mod benches;
+
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::num::Wrapping;
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -48,250 +54,3 @@ where
     assert_eq!(ten.div(two), ten / two);
     assert_eq!(ten.rem(two), ten % two);
 }
-
-#[cfg(test)]
-mod tests {
-    use crate::ops::Mul;
-
-    #[test]
-    fn test_saturating_add_uint() {
-        assert_eq!(3_usize.saturating_add(5_usize), 8_usize);
-        assert_eq!(3_usize.saturating_add(usize::MAX - 1), usize::MAX);
-        assert_eq!(usize::MAX.saturating_add(usize::MAX), usize::MAX);
-        assert_eq!((usize::MAX - 2).saturating_add(1), usize::MAX - 1);
-    }
-
-    #[test]
-    fn test_saturating_sub_uint() {
-        assert_eq!(5_usize.saturating_sub(3_usize), 2_usize);
-        assert_eq!(3_usize.saturating_sub(5_usize), 0_usize);
-        assert_eq!(0_usize.saturating_sub(1_usize), 0_usize);
-        assert_eq!((usize::MAX - 1).saturating_sub(usize::MAX), 0);
-    }
-
-    #[test]
-    fn test_saturating_add_int() {
-        assert_eq!(3i32.saturating_add(5), 8);
-        assert_eq!(3isize.saturating_add(isize::MAX - 1), isize::MAX);
-        assert_eq!(isize::MAX.saturating_add(isize::MAX), isize::MAX);
-        assert_eq!((isize::MAX - 2).saturating_add(1), isize::MAX - 1);
-        assert_eq!(3i32.saturating_add(-5), -2);
-        assert_eq!(isize::MIN.saturating_add(-1), isize::MIN);
-        assert_eq!((-2isize).saturating_add(-isize::MAX), isize::MIN);
-    }
-
-    #[test]
-    fn test_saturating_sub_int() {
-        assert_eq!(3i32.saturating_sub(5), -2);
-        assert_eq!(isize::MIN.saturating_sub(1), isize::MIN);
-        assert_eq!((-2isize).saturating_sub(isize::MAX), isize::MIN);
-        assert_eq!(3i32.saturating_sub(-5), 8);
-        assert_eq!(3isize.saturating_sub(-(isize::MAX - 1)), isize::MAX);
-        assert_eq!(isize::MAX.saturating_sub(-isize::MAX), isize::MAX);
-        assert_eq!((isize::MAX - 2).saturating_sub(-1), isize::MAX - 1);
-    }
-
-    #[test]
-    fn test_checked_add() {
-        let five_less = usize::MAX - 5;
-        assert_eq!(five_less.checked_add(0), Some(usize::MAX - 5));
-        assert_eq!(five_less.checked_add(1), Some(usize::MAX - 4));
-        assert_eq!(five_less.checked_add(2), Some(usize::MAX - 3));
-        assert_eq!(five_less.checked_add(3), Some(usize::MAX - 2));
-        assert_eq!(five_less.checked_add(4), Some(usize::MAX - 1));
-        assert_eq!(five_less.checked_add(5), Some(usize::MAX));
-        assert_eq!(five_less.checked_add(6), None);
-        assert_eq!(five_less.checked_add(7), None);
-    }
-
-    #[test]
-    fn test_checked_sub() {
-        assert_eq!(5_usize.checked_sub(0), Some(5));
-        assert_eq!(5_usize.checked_sub(1), Some(4));
-        assert_eq!(5_usize.checked_sub(2), Some(3));
-        assert_eq!(5_usize.checked_sub(3), Some(2));
-        assert_eq!(5_usize.checked_sub(4), Some(1));
-        assert_eq!(5_usize.checked_sub(5), Some(0));
-        assert_eq!(5_usize.checked_sub(6), None);
-        assert_eq!(5_usize.checked_sub(7), None);
-    }
-
-    #[test]
-    fn test_checked_mul() {
-        let third = usize::MAX / 3;
-        assert_eq!(third.checked_mul(0), Some(0));
-        assert_eq!(third.checked_mul(1), Some(third));
-        assert_eq!(third.checked_mul(2), Some(third * 2));
-        assert_eq!(third.checked_mul(3), Some(third * 3));
-        assert_eq!(third.checked_mul(4), None);
-    }
-
-    macro_rules! test_is_power_of_two {
-        ($test_name:ident, $T:ident) => {
-            fn $test_name() {
-                #![test]
-                assert_eq!((0 as $T).is_power_of_two(), false);
-                assert_eq!((1 as $T).is_power_of_two(), true);
-                assert_eq!((2 as $T).is_power_of_two(), true);
-                assert_eq!((3 as $T).is_power_of_two(), false);
-                assert_eq!((4 as $T).is_power_of_two(), true);
-                assert_eq!((5 as $T).is_power_of_two(), false);
-                assert_eq!(($T::MAX / 2 + 1).is_power_of_two(), true);
-            }
-        };
-    }
-
-    test_is_power_of_two! { test_is_power_of_two_u8, u8 }
-    test_is_power_of_two! { test_is_power_of_two_u16, u16 }
-    test_is_power_of_two! { test_is_power_of_two_u32, u32 }
-    test_is_power_of_two! { test_is_power_of_two_u64, u64 }
-    test_is_power_of_two! { test_is_power_of_two_uint, usize }
-
-    macro_rules! test_next_power_of_two {
-        ($test_name:ident, $T:ident) => {
-            fn $test_name() {
-                #![test]
-                assert_eq!((0 as $T).next_power_of_two(), 1);
-                let mut next_power = 1;
-                for i in 1 as $T..40 {
-                    assert_eq!(i.next_power_of_two(), next_power);
-                    if i == next_power {
-                        next_power *= 2
-                    }
-                }
-            }
-        };
-    }
-
-    test_next_power_of_two! { test_next_power_of_two_u8, u8 }
-    test_next_power_of_two! { test_next_power_of_two_u16, u16 }
-    test_next_power_of_two! { test_next_power_of_two_u32, u32 }
-    test_next_power_of_two! { test_next_power_of_two_u64, u64 }
-    test_next_power_of_two! { test_next_power_of_two_uint, usize }
-
-    macro_rules! test_checked_next_power_of_two {
-        ($test_name:ident, $T:ident) => {
-            fn $test_name() {
-                #![test]
-                assert_eq!((0 as $T).checked_next_power_of_two(), Some(1));
-                let smax = $T::MAX >> 1;
-                assert_eq!(smax.checked_next_power_of_two(), Some(smax + 1));
-                assert_eq!((smax + 1).checked_next_power_of_two(), Some(smax + 1));
-                assert_eq!((smax + 2).checked_next_power_of_two(), None);
-                assert_eq!(($T::MAX - 1).checked_next_power_of_two(), None);
-                assert_eq!($T::MAX.checked_next_power_of_two(), None);
-                let mut next_power = 1;
-                for i in 1 as $T..40 {
-                    assert_eq!(i.checked_next_power_of_two(), Some(next_power));
-                    if i == next_power {
-                        next_power *= 2
-                    }
-                }
-            }
-        };
-    }
-
-    test_checked_next_power_of_two! { test_checked_next_power_of_two_u8, u8 }
-    test_checked_next_power_of_two! { test_checked_next_power_of_two_u16, u16 }
-    test_checked_next_power_of_two! { test_checked_next_power_of_two_u32, u32 }
-    test_checked_next_power_of_two! { test_checked_next_power_of_two_u64, u64 }
-    test_checked_next_power_of_two! { test_checked_next_power_of_two_uint, usize }
-
-    #[test]
-    fn test_pow() {
-        fn naive_pow<T: Mul<Output = T> + Copy>(one: T, base: T, exp: usize) -> T {
-            (0..exp).fold(one, |acc, _| acc * base)
-        }
-        macro_rules! assert_pow {
-            (($num:expr, $exp:expr) => $expected:expr) => {{
-                let result = $num.pow($exp);
-                assert_eq!(result, $expected);
-                assert_eq!(result, naive_pow(1, $num, $exp));
-            }};
-        }
-        assert_pow!((3u32,     0 ) => 1);
-        assert_pow!((5u32,     1 ) => 5);
-        assert_pow!((-4i32,    2 ) => 16);
-        assert_pow!((8u32,     3 ) => 512);
-        assert_pow!((2u64,     50) => 1125899906842624);
-    }
-
-    #[test]
-    fn test_uint_to_str_overflow() {
-        let mut u8_val: u8 = 255;
-        assert_eq!(u8_val.to_string(), "255");
-
-        u8_val = u8_val.wrapping_add(1);
-        assert_eq!(u8_val.to_string(), "0");
-
-        let mut u16_val: u16 = 65_535;
-        assert_eq!(u16_val.to_string(), "65535");
-
-        u16_val = u16_val.wrapping_add(1);
-        assert_eq!(u16_val.to_string(), "0");
-
-        let mut u32_val: u32 = 4_294_967_295;
-        assert_eq!(u32_val.to_string(), "4294967295");
-
-        u32_val = u32_val.wrapping_add(1);
-        assert_eq!(u32_val.to_string(), "0");
-
-        let mut u64_val: u64 = 18_446_744_073_709_551_615;
-        assert_eq!(u64_val.to_string(), "18446744073709551615");
-
-        u64_val = u64_val.wrapping_add(1);
-        assert_eq!(u64_val.to_string(), "0");
-    }
-
-    fn from_str<T: crate::str::FromStr>(t: &str) -> Option<T> {
-        crate::str::FromStr::from_str(t).ok()
-    }
-
-    #[test]
-    fn test_uint_from_str_overflow() {
-        let mut u8_val: u8 = 255;
-        assert_eq!(from_str::<u8>("255"), Some(u8_val));
-        assert_eq!(from_str::<u8>("256"), None);
-
-        u8_val = u8_val.wrapping_add(1);
-        assert_eq!(from_str::<u8>("0"), Some(u8_val));
-        assert_eq!(from_str::<u8>("-1"), None);
-
-        let mut u16_val: u16 = 65_535;
-        assert_eq!(from_str::<u16>("65535"), Some(u16_val));
-        assert_eq!(from_str::<u16>("65536"), None);
-
-        u16_val = u16_val.wrapping_add(1);
-        assert_eq!(from_str::<u16>("0"), Some(u16_val));
-        assert_eq!(from_str::<u16>("-1"), None);
-
-        let mut u32_val: u32 = 4_294_967_295;
-        assert_eq!(from_str::<u32>("4294967295"), Some(u32_val));
-        assert_eq!(from_str::<u32>("4294967296"), None);
-
-        u32_val = u32_val.wrapping_add(1);
-        assert_eq!(from_str::<u32>("0"), Some(u32_val));
-        assert_eq!(from_str::<u32>("-1"), None);
-
-        let mut u64_val: u64 = 18_446_744_073_709_551_615;
-        assert_eq!(from_str::<u64>("18446744073709551615"), Some(u64_val));
-        assert_eq!(from_str::<u64>("18446744073709551616"), None);
-
-        u64_val = u64_val.wrapping_add(1);
-        assert_eq!(from_str::<u64>("0"), Some(u64_val));
-        assert_eq!(from_str::<u64>("-1"), None);
-    }
-}
-
-#[cfg(test)]
-mod bench {
-    use test::Bencher;
-
-    #[bench]
-    fn bench_pow_function(b: &mut Bencher) {
-        let v = (0..1024).collect::<Vec<u32>>();
-        b.iter(|| {
-            v.iter().fold(0u32, |old, new| old.pow(*new as u32));
-        });
-    }
-}
diff --git a/library/std/src/num/benches.rs b/library/std/src/num/benches.rs
new file mode 100644
index 00000000000..233ea0506c0
--- /dev/null
+++ b/library/std/src/num/benches.rs
@@ -0,0 +1,9 @@
+use test::Bencher;
+
+#[bench]
+fn bench_pow_function(b: &mut Bencher) {
+    let v = (0..1024).collect::<Vec<u32>>();
+    b.iter(|| {
+        v.iter().fold(0u32, |old, new| old.pow(*new as u32));
+    });
+}
diff --git a/library/std/src/num/tests.rs b/library/std/src/num/tests.rs
new file mode 100644
index 00000000000..2f50b73f490
--- /dev/null
+++ b/library/std/src/num/tests.rs
@@ -0,0 +1,230 @@
+use crate::ops::Mul;
+
+#[test]
+fn test_saturating_add_uint() {
+    assert_eq!(3_usize.saturating_add(5_usize), 8_usize);
+    assert_eq!(3_usize.saturating_add(usize::MAX - 1), usize::MAX);
+    assert_eq!(usize::MAX.saturating_add(usize::MAX), usize::MAX);
+    assert_eq!((usize::MAX - 2).saturating_add(1), usize::MAX - 1);
+}
+
+#[test]
+fn test_saturating_sub_uint() {
+    assert_eq!(5_usize.saturating_sub(3_usize), 2_usize);
+    assert_eq!(3_usize.saturating_sub(5_usize), 0_usize);
+    assert_eq!(0_usize.saturating_sub(1_usize), 0_usize);
+    assert_eq!((usize::MAX - 1).saturating_sub(usize::MAX), 0);
+}
+
+#[test]
+fn test_saturating_add_int() {
+    assert_eq!(3i32.saturating_add(5), 8);
+    assert_eq!(3isize.saturating_add(isize::MAX - 1), isize::MAX);
+    assert_eq!(isize::MAX.saturating_add(isize::MAX), isize::MAX);
+    assert_eq!((isize::MAX - 2).saturating_add(1), isize::MAX - 1);
+    assert_eq!(3i32.saturating_add(-5), -2);
+    assert_eq!(isize::MIN.saturating_add(-1), isize::MIN);
+    assert_eq!((-2isize).saturating_add(-isize::MAX), isize::MIN);
+}
+
+#[test]
+fn test_saturating_sub_int() {
+    assert_eq!(3i32.saturating_sub(5), -2);
+    assert_eq!(isize::MIN.saturating_sub(1), isize::MIN);
+    assert_eq!((-2isize).saturating_sub(isize::MAX), isize::MIN);
+    assert_eq!(3i32.saturating_sub(-5), 8);
+    assert_eq!(3isize.saturating_sub(-(isize::MAX - 1)), isize::MAX);
+    assert_eq!(isize::MAX.saturating_sub(-isize::MAX), isize::MAX);
+    assert_eq!((isize::MAX - 2).saturating_sub(-1), isize::MAX - 1);
+}
+
+#[test]
+fn test_checked_add() {
+    let five_less = usize::MAX - 5;
+    assert_eq!(five_less.checked_add(0), Some(usize::MAX - 5));
+    assert_eq!(five_less.checked_add(1), Some(usize::MAX - 4));
+    assert_eq!(five_less.checked_add(2), Some(usize::MAX - 3));
+    assert_eq!(five_less.checked_add(3), Some(usize::MAX - 2));
+    assert_eq!(five_less.checked_add(4), Some(usize::MAX - 1));
+    assert_eq!(five_less.checked_add(5), Some(usize::MAX));
+    assert_eq!(five_less.checked_add(6), None);
+    assert_eq!(five_less.checked_add(7), None);
+}
+
+#[test]
+fn test_checked_sub() {
+    assert_eq!(5_usize.checked_sub(0), Some(5));
+    assert_eq!(5_usize.checked_sub(1), Some(4));
+    assert_eq!(5_usize.checked_sub(2), Some(3));
+    assert_eq!(5_usize.checked_sub(3), Some(2));
+    assert_eq!(5_usize.checked_sub(4), Some(1));
+    assert_eq!(5_usize.checked_sub(5), Some(0));
+    assert_eq!(5_usize.checked_sub(6), None);
+    assert_eq!(5_usize.checked_sub(7), None);
+}
+
+#[test]
+fn test_checked_mul() {
+    let third = usize::MAX / 3;
+    assert_eq!(third.checked_mul(0), Some(0));
+    assert_eq!(third.checked_mul(1), Some(third));
+    assert_eq!(third.checked_mul(2), Some(third * 2));
+    assert_eq!(third.checked_mul(3), Some(third * 3));
+    assert_eq!(third.checked_mul(4), None);
+}
+
+macro_rules! test_is_power_of_two {
+    ($test_name:ident, $T:ident) => {
+        fn $test_name() {
+            #![test]
+            assert_eq!((0 as $T).is_power_of_two(), false);
+            assert_eq!((1 as $T).is_power_of_two(), true);
+            assert_eq!((2 as $T).is_power_of_two(), true);
+            assert_eq!((3 as $T).is_power_of_two(), false);
+            assert_eq!((4 as $T).is_power_of_two(), true);
+            assert_eq!((5 as $T).is_power_of_two(), false);
+            assert_eq!(($T::MAX / 2 + 1).is_power_of_two(), true);
+        }
+    };
+}
+
+test_is_power_of_two! { test_is_power_of_two_u8, u8 }
+test_is_power_of_two! { test_is_power_of_two_u16, u16 }
+test_is_power_of_two! { test_is_power_of_two_u32, u32 }
+test_is_power_of_two! { test_is_power_of_two_u64, u64 }
+test_is_power_of_two! { test_is_power_of_two_uint, usize }
+
+macro_rules! test_next_power_of_two {
+    ($test_name:ident, $T:ident) => {
+        fn $test_name() {
+            #![test]
+            assert_eq!((0 as $T).next_power_of_two(), 1);
+            let mut next_power = 1;
+            for i in 1 as $T..40 {
+                assert_eq!(i.next_power_of_two(), next_power);
+                if i == next_power {
+                    next_power *= 2
+                }
+            }
+        }
+    };
+}
+
+test_next_power_of_two! { test_next_power_of_two_u8, u8 }
+test_next_power_of_two! { test_next_power_of_two_u16, u16 }
+test_next_power_of_two! { test_next_power_of_two_u32, u32 }
+test_next_power_of_two! { test_next_power_of_two_u64, u64 }
+test_next_power_of_two! { test_next_power_of_two_uint, usize }
+
+macro_rules! test_checked_next_power_of_two {
+    ($test_name:ident, $T:ident) => {
+        fn $test_name() {
+            #![test]
+            assert_eq!((0 as $T).checked_next_power_of_two(), Some(1));
+            let smax = $T::MAX >> 1;
+            assert_eq!(smax.checked_next_power_of_two(), Some(smax + 1));
+            assert_eq!((smax + 1).checked_next_power_of_two(), Some(smax + 1));
+            assert_eq!((smax + 2).checked_next_power_of_two(), None);
+            assert_eq!(($T::MAX - 1).checked_next_power_of_two(), None);
+            assert_eq!($T::MAX.checked_next_power_of_two(), None);
+            let mut next_power = 1;
+            for i in 1 as $T..40 {
+                assert_eq!(i.checked_next_power_of_two(), Some(next_power));
+                if i == next_power {
+                    next_power *= 2
+                }
+            }
+        }
+    };
+}
+
+test_checked_next_power_of_two! { test_checked_next_power_of_two_u8, u8 }
+test_checked_next_power_of_two! { test_checked_next_power_of_two_u16, u16 }
+test_checked_next_power_of_two! { test_checked_next_power_of_two_u32, u32 }
+test_checked_next_power_of_two! { test_checked_next_power_of_two_u64, u64 }
+test_checked_next_power_of_two! { test_checked_next_power_of_two_uint, usize }
+
+#[test]
+fn test_pow() {
+    fn naive_pow<T: Mul<Output = T> + Copy>(one: T, base: T, exp: usize) -> T {
+        (0..exp).fold(one, |acc, _| acc * base)
+    }
+    macro_rules! assert_pow {
+        (($num:expr, $exp:expr) => $expected:expr) => {{
+            let result = $num.pow($exp);
+            assert_eq!(result, $expected);
+            assert_eq!(result, naive_pow(1, $num, $exp));
+        }};
+    }
+    assert_pow!((3u32,     0 ) => 1);
+    assert_pow!((5u32,     1 ) => 5);
+    assert_pow!((-4i32,    2 ) => 16);
+    assert_pow!((8u32,     3 ) => 512);
+    assert_pow!((2u64,     50) => 1125899906842624);
+}
+
+#[test]
+fn test_uint_to_str_overflow() {
+    let mut u8_val: u8 = 255;
+    assert_eq!(u8_val.to_string(), "255");
+
+    u8_val = u8_val.wrapping_add(1);
+    assert_eq!(u8_val.to_string(), "0");
+
+    let mut u16_val: u16 = 65_535;
+    assert_eq!(u16_val.to_string(), "65535");
+
+    u16_val = u16_val.wrapping_add(1);
+    assert_eq!(u16_val.to_string(), "0");
+
+    let mut u32_val: u32 = 4_294_967_295;
+    assert_eq!(u32_val.to_string(), "4294967295");
+
+    u32_val = u32_val.wrapping_add(1);
+    assert_eq!(u32_val.to_string(), "0");
+
+    let mut u64_val: u64 = 18_446_744_073_709_551_615;
+    assert_eq!(u64_val.to_string(), "18446744073709551615");
+
+    u64_val = u64_val.wrapping_add(1);
+    assert_eq!(u64_val.to_string(), "0");
+}
+
+fn from_str<T: crate::str::FromStr>(t: &str) -> Option<T> {
+    crate::str::FromStr::from_str(t).ok()
+}
+
+#[test]
+fn test_uint_from_str_overflow() {
+    let mut u8_val: u8 = 255;
+    assert_eq!(from_str::<u8>("255"), Some(u8_val));
+    assert_eq!(from_str::<u8>("256"), None);
+
+    u8_val = u8_val.wrapping_add(1);
+    assert_eq!(from_str::<u8>("0"), Some(u8_val));
+    assert_eq!(from_str::<u8>("-1"), None);
+
+    let mut u16_val: u16 = 65_535;
+    assert_eq!(from_str::<u16>("65535"), Some(u16_val));
+    assert_eq!(from_str::<u16>("65536"), None);
+
+    u16_val = u16_val.wrapping_add(1);
+    assert_eq!(from_str::<u16>("0"), Some(u16_val));
+    assert_eq!(from_str::<u16>("-1"), None);
+
+    let mut u32_val: u32 = 4_294_967_295;
+    assert_eq!(from_str::<u32>("4294967295"), Some(u32_val));
+    assert_eq!(from_str::<u32>("4294967296"), None);
+
+    u32_val = u32_val.wrapping_add(1);
+    assert_eq!(from_str::<u32>("0"), Some(u32_val));
+    assert_eq!(from_str::<u32>("-1"), None);
+
+    let mut u64_val: u64 = 18_446_744_073_709_551_615;
+    assert_eq!(from_str::<u64>("18446744073709551615"), Some(u64_val));
+    assert_eq!(from_str::<u64>("18446744073709551616"), None);
+
+    u64_val = u64_val.wrapping_add(1);
+    assert_eq!(from_str::<u64>("0"), Some(u64_val));
+    assert_eq!(from_str::<u64>("-1"), None);
+}
diff --git a/library/std/src/os/raw/mod.rs b/library/std/src/os/raw/mod.rs
index 47daf0cce1b..1fe27a34600 100644
--- a/library/std/src/os/raw/mod.rs
+++ b/library/std/src/os/raw/mod.rs
@@ -8,6 +8,10 @@
 
 #![stable(feature = "raw_os", since = "1.1.0")]
 
+#[cfg(test)]
+#[allow(unused_imports)]
+mod tests;
+
 #[doc(include = "char.md")]
 #[cfg(any(
     all(
@@ -144,24 +148,3 @@ pub type c_double = f64;
 #[stable(feature = "raw_os", since = "1.1.0")]
 #[doc(no_inline)]
 pub use core::ffi::c_void;
-
-#[cfg(test)]
-#[allow(unused_imports)]
-mod tests {
-    use crate::any::TypeId;
-    use crate::mem;
-
-    macro_rules! ok {
-        ($($t:ident)*) => {$(
-            assert!(TypeId::of::<libc::$t>() == TypeId::of::<raw::$t>(),
-                    "{} is wrong", stringify!($t));
-        )*}
-    }
-
-    #[test]
-    fn same() {
-        use crate::os::raw;
-        ok!(c_char c_schar c_uchar c_short c_ushort c_int c_uint c_long c_ulong
-            c_longlong c_ulonglong c_float c_double);
-    }
-}
diff --git a/library/std/src/os/raw/tests.rs b/library/std/src/os/raw/tests.rs
new file mode 100644
index 00000000000..e808faf81d6
--- /dev/null
+++ b/library/std/src/os/raw/tests.rs
@@ -0,0 +1,16 @@
+use crate::any::TypeId;
+use crate::mem;
+
+macro_rules! ok {
+    ($($t:ident)*) => {$(
+        assert!(TypeId::of::<libc::$t>() == TypeId::of::<raw::$t>(),
+                "{} is wrong", stringify!($t));
+    )*}
+}
+
+#[test]
+fn same() {
+    use crate::os::raw;
+    ok!(c_char c_schar c_uchar c_short c_ushort c_int c_uint c_long c_ulong
+        c_longlong c_ulonglong c_float c_double);
+}
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index afdbdbeac3e..d71e89d0eee 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-filelength
-
 //! Cross-platform path manipulation.
 //!
 //! This module provides two types, [`PathBuf`] and [`Path`] (akin to [`String`]
@@ -61,6 +59,9 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+#[cfg(test)]
+mod tests;
+
 use crate::borrow::{Borrow, Cow};
 use crate::cmp;
 use crate::error::Error;
@@ -2741,1401 +2742,3 @@ impl Error for StripPrefixError {
         "prefix not found"
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    use crate::rc::Rc;
-    use crate::sync::Arc;
-
-    macro_rules! t(
-        ($path:expr, iter: $iter:expr) => (
-            {
-                let path = Path::new($path);
-
-                // Forward iteration
-                let comps = path.iter()
-                    .map(|p| p.to_string_lossy().into_owned())
-                    .collect::<Vec<String>>();
-                let exp: &[&str] = &$iter;
-                let exps = exp.iter().map(|s| s.to_string()).collect::<Vec<String>>();
-                assert!(comps == exps, "iter: Expected {:?}, found {:?}",
-                        exps, comps);
-
-                // Reverse iteration
-                let comps = Path::new($path).iter().rev()
-                    .map(|p| p.to_string_lossy().into_owned())
-                    .collect::<Vec<String>>();
-                let exps = exps.into_iter().rev().collect::<Vec<String>>();
-                assert!(comps == exps, "iter().rev(): Expected {:?}, found {:?}",
-                        exps, comps);
-            }
-        );
-
-        ($path:expr, has_root: $has_root:expr, is_absolute: $is_absolute:expr) => (
-            {
-                let path = Path::new($path);
-
-                let act_root = path.has_root();
-                assert!(act_root == $has_root, "has_root: Expected {:?}, found {:?}",
-                        $has_root, act_root);
-
-                let act_abs = path.is_absolute();
-                assert!(act_abs == $is_absolute, "is_absolute: Expected {:?}, found {:?}",
-                        $is_absolute, act_abs);
-            }
-        );
-
-        ($path:expr, parent: $parent:expr, file_name: $file:expr) => (
-            {
-                let path = Path::new($path);
-
-                let parent = path.parent().map(|p| p.to_str().unwrap());
-                let exp_parent: Option<&str> = $parent;
-                assert!(parent == exp_parent, "parent: Expected {:?}, found {:?}",
-                        exp_parent, parent);
-
-                let file = path.file_name().map(|p| p.to_str().unwrap());
-                let exp_file: Option<&str> = $file;
-                assert!(file == exp_file, "file_name: Expected {:?}, found {:?}",
-                        exp_file, file);
-            }
-        );
-
-        ($path:expr, file_stem: $file_stem:expr, extension: $extension:expr) => (
-            {
-                let path = Path::new($path);
-
-                let stem = path.file_stem().map(|p| p.to_str().unwrap());
-                let exp_stem: Option<&str> = $file_stem;
-                assert!(stem == exp_stem, "file_stem: Expected {:?}, found {:?}",
-                        exp_stem, stem);
-
-                let ext = path.extension().map(|p| p.to_str().unwrap());
-                let exp_ext: Option<&str> = $extension;
-                assert!(ext == exp_ext, "extension: Expected {:?}, found {:?}",
-                        exp_ext, ext);
-            }
-        );
-
-        ($path:expr, iter: $iter:expr,
-                     has_root: $has_root:expr, is_absolute: $is_absolute:expr,
-                     parent: $parent:expr, file_name: $file:expr,
-                     file_stem: $file_stem:expr, extension: $extension:expr) => (
-            {
-                t!($path, iter: $iter);
-                t!($path, has_root: $has_root, is_absolute: $is_absolute);
-                t!($path, parent: $parent, file_name: $file);
-                t!($path, file_stem: $file_stem, extension: $extension);
-            }
-        );
-    );
-
-    #[test]
-    fn into() {
-        use crate::borrow::Cow;
-
-        let static_path = Path::new("/home/foo");
-        let static_cow_path: Cow<'static, Path> = static_path.into();
-        let pathbuf = PathBuf::from("/home/foo");
-
-        {
-            let path: &Path = &pathbuf;
-            let borrowed_cow_path: Cow<'_, Path> = path.into();
-
-            assert_eq!(static_cow_path, borrowed_cow_path);
-        }
-
-        let owned_cow_path: Cow<'static, Path> = pathbuf.into();
-
-        assert_eq!(static_cow_path, owned_cow_path);
-    }
-
-    #[test]
-    #[cfg(unix)]
-    pub fn test_decompositions_unix() {
-        t!("",
-        iter: [],
-        has_root: false,
-        is_absolute: false,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("foo",
-        iter: ["foo"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some(""),
-        file_name: Some("foo"),
-        file_stem: Some("foo"),
-        extension: None
-        );
-
-        t!("/",
-        iter: ["/"],
-        has_root: true,
-        is_absolute: true,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("/foo",
-        iter: ["/", "foo"],
-        has_root: true,
-        is_absolute: true,
-        parent: Some("/"),
-        file_name: Some("foo"),
-        file_stem: Some("foo"),
-        extension: None
-        );
-
-        t!("foo/",
-        iter: ["foo"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some(""),
-        file_name: Some("foo"),
-        file_stem: Some("foo"),
-        extension: None
-        );
-
-        t!("/foo/",
-        iter: ["/", "foo"],
-        has_root: true,
-        is_absolute: true,
-        parent: Some("/"),
-        file_name: Some("foo"),
-        file_stem: Some("foo"),
-        extension: None
-        );
-
-        t!("foo/bar",
-        iter: ["foo", "bar"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("foo"),
-        file_name: Some("bar"),
-        file_stem: Some("bar"),
-        extension: None
-        );
-
-        t!("/foo/bar",
-        iter: ["/", "foo", "bar"],
-        has_root: true,
-        is_absolute: true,
-        parent: Some("/foo"),
-        file_name: Some("bar"),
-        file_stem: Some("bar"),
-        extension: None
-        );
-
-        t!("///foo///",
-        iter: ["/", "foo"],
-        has_root: true,
-        is_absolute: true,
-        parent: Some("/"),
-        file_name: Some("foo"),
-        file_stem: Some("foo"),
-        extension: None
-        );
-
-        t!("///foo///bar",
-        iter: ["/", "foo", "bar"],
-        has_root: true,
-        is_absolute: true,
-        parent: Some("///foo"),
-        file_name: Some("bar"),
-        file_stem: Some("bar"),
-        extension: None
-        );
-
-        t!("./.",
-        iter: ["."],
-        has_root: false,
-        is_absolute: false,
-        parent: Some(""),
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("/..",
-        iter: ["/", ".."],
-        has_root: true,
-        is_absolute: true,
-        parent: Some("/"),
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("../",
-        iter: [".."],
-        has_root: false,
-        is_absolute: false,
-        parent: Some(""),
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("foo/.",
-        iter: ["foo"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some(""),
-        file_name: Some("foo"),
-        file_stem: Some("foo"),
-        extension: None
-        );
-
-        t!("foo/..",
-        iter: ["foo", ".."],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("foo"),
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("foo/./",
-        iter: ["foo"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some(""),
-        file_name: Some("foo"),
-        file_stem: Some("foo"),
-        extension: None
-        );
-
-        t!("foo/./bar",
-        iter: ["foo", "bar"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("foo"),
-        file_name: Some("bar"),
-        file_stem: Some("bar"),
-        extension: None
-        );
-
-        t!("foo/../",
-        iter: ["foo", ".."],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("foo"),
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("foo/../bar",
-        iter: ["foo", "..", "bar"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("foo/.."),
-        file_name: Some("bar"),
-        file_stem: Some("bar"),
-        extension: None
-        );
-
-        t!("./a",
-        iter: [".", "a"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("."),
-        file_name: Some("a"),
-        file_stem: Some("a"),
-        extension: None
-        );
-
-        t!(".",
-        iter: ["."],
-        has_root: false,
-        is_absolute: false,
-        parent: Some(""),
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("./",
-        iter: ["."],
-        has_root: false,
-        is_absolute: false,
-        parent: Some(""),
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("a/b",
-        iter: ["a", "b"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("a"),
-        file_name: Some("b"),
-        file_stem: Some("b"),
-        extension: None
-        );
-
-        t!("a//b",
-        iter: ["a", "b"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("a"),
-        file_name: Some("b"),
-        file_stem: Some("b"),
-        extension: None
-        );
-
-        t!("a/./b",
-        iter: ["a", "b"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("a"),
-        file_name: Some("b"),
-        file_stem: Some("b"),
-        extension: None
-        );
-
-        t!("a/b/c",
-        iter: ["a", "b", "c"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("a/b"),
-        file_name: Some("c"),
-        file_stem: Some("c"),
-        extension: None
-        );
-
-        t!(".foo",
-        iter: [".foo"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some(""),
-        file_name: Some(".foo"),
-        file_stem: Some(".foo"),
-        extension: None
-        );
-    }
-
-    #[test]
-    #[cfg(windows)]
-    pub fn test_decompositions_windows() {
-        t!("",
-        iter: [],
-        has_root: false,
-        is_absolute: false,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("foo",
-        iter: ["foo"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some(""),
-        file_name: Some("foo"),
-        file_stem: Some("foo"),
-        extension: None
-        );
-
-        t!("/",
-        iter: ["\\"],
-        has_root: true,
-        is_absolute: false,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("\\",
-        iter: ["\\"],
-        has_root: true,
-        is_absolute: false,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("c:",
-        iter: ["c:"],
-        has_root: false,
-        is_absolute: false,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("c:\\",
-        iter: ["c:", "\\"],
-        has_root: true,
-        is_absolute: true,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("c:/",
-        iter: ["c:", "\\"],
-        has_root: true,
-        is_absolute: true,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("/foo",
-        iter: ["\\", "foo"],
-        has_root: true,
-        is_absolute: false,
-        parent: Some("/"),
-        file_name: Some("foo"),
-        file_stem: Some("foo"),
-        extension: None
-        );
-
-        t!("foo/",
-        iter: ["foo"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some(""),
-        file_name: Some("foo"),
-        file_stem: Some("foo"),
-        extension: None
-        );
-
-        t!("/foo/",
-        iter: ["\\", "foo"],
-        has_root: true,
-        is_absolute: false,
-        parent: Some("/"),
-        file_name: Some("foo"),
-        file_stem: Some("foo"),
-        extension: None
-        );
-
-        t!("foo/bar",
-        iter: ["foo", "bar"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("foo"),
-        file_name: Some("bar"),
-        file_stem: Some("bar"),
-        extension: None
-        );
-
-        t!("/foo/bar",
-        iter: ["\\", "foo", "bar"],
-        has_root: true,
-        is_absolute: false,
-        parent: Some("/foo"),
-        file_name: Some("bar"),
-        file_stem: Some("bar"),
-        extension: None
-        );
-
-        t!("///foo///",
-        iter: ["\\", "foo"],
-        has_root: true,
-        is_absolute: false,
-        parent: Some("/"),
-        file_name: Some("foo"),
-        file_stem: Some("foo"),
-        extension: None
-        );
-
-        t!("///foo///bar",
-        iter: ["\\", "foo", "bar"],
-        has_root: true,
-        is_absolute: false,
-        parent: Some("///foo"),
-        file_name: Some("bar"),
-        file_stem: Some("bar"),
-        extension: None
-        );
-
-        t!("./.",
-        iter: ["."],
-        has_root: false,
-        is_absolute: false,
-        parent: Some(""),
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("/..",
-        iter: ["\\", ".."],
-        has_root: true,
-        is_absolute: false,
-        parent: Some("/"),
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("../",
-        iter: [".."],
-        has_root: false,
-        is_absolute: false,
-        parent: Some(""),
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("foo/.",
-        iter: ["foo"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some(""),
-        file_name: Some("foo"),
-        file_stem: Some("foo"),
-        extension: None
-        );
-
-        t!("foo/..",
-        iter: ["foo", ".."],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("foo"),
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("foo/./",
-        iter: ["foo"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some(""),
-        file_name: Some("foo"),
-        file_stem: Some("foo"),
-        extension: None
-        );
-
-        t!("foo/./bar",
-        iter: ["foo", "bar"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("foo"),
-        file_name: Some("bar"),
-        file_stem: Some("bar"),
-        extension: None
-        );
-
-        t!("foo/../",
-        iter: ["foo", ".."],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("foo"),
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("foo/../bar",
-        iter: ["foo", "..", "bar"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("foo/.."),
-        file_name: Some("bar"),
-        file_stem: Some("bar"),
-        extension: None
-        );
-
-        t!("./a",
-        iter: [".", "a"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("."),
-        file_name: Some("a"),
-        file_stem: Some("a"),
-        extension: None
-        );
-
-        t!(".",
-        iter: ["."],
-        has_root: false,
-        is_absolute: false,
-        parent: Some(""),
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("./",
-        iter: ["."],
-        has_root: false,
-        is_absolute: false,
-        parent: Some(""),
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("a/b",
-        iter: ["a", "b"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("a"),
-        file_name: Some("b"),
-        file_stem: Some("b"),
-        extension: None
-        );
-
-        t!("a//b",
-        iter: ["a", "b"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("a"),
-        file_name: Some("b"),
-        file_stem: Some("b"),
-        extension: None
-        );
-
-        t!("a/./b",
-        iter: ["a", "b"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("a"),
-        file_name: Some("b"),
-        file_stem: Some("b"),
-        extension: None
-        );
-
-        t!("a/b/c",
-           iter: ["a", "b", "c"],
-           has_root: false,
-           is_absolute: false,
-           parent: Some("a/b"),
-           file_name: Some("c"),
-           file_stem: Some("c"),
-           extension: None);
-
-        t!("a\\b\\c",
-        iter: ["a", "b", "c"],
-        has_root: false,
-        is_absolute: false,
-        parent: Some("a\\b"),
-        file_name: Some("c"),
-        file_stem: Some("c"),
-        extension: None
-        );
-
-        t!("\\a",
-        iter: ["\\", "a"],
-        has_root: true,
-        is_absolute: false,
-        parent: Some("\\"),
-        file_name: Some("a"),
-        file_stem: Some("a"),
-        extension: None
-        );
-
-        t!("c:\\foo.txt",
-        iter: ["c:", "\\", "foo.txt"],
-        has_root: true,
-        is_absolute: true,
-        parent: Some("c:\\"),
-        file_name: Some("foo.txt"),
-        file_stem: Some("foo"),
-        extension: Some("txt")
-        );
-
-        t!("\\\\server\\share\\foo.txt",
-        iter: ["\\\\server\\share", "\\", "foo.txt"],
-        has_root: true,
-        is_absolute: true,
-        parent: Some("\\\\server\\share\\"),
-        file_name: Some("foo.txt"),
-        file_stem: Some("foo"),
-        extension: Some("txt")
-        );
-
-        t!("\\\\server\\share",
-        iter: ["\\\\server\\share", "\\"],
-        has_root: true,
-        is_absolute: true,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("\\\\server",
-        iter: ["\\", "server"],
-        has_root: true,
-        is_absolute: false,
-        parent: Some("\\"),
-        file_name: Some("server"),
-        file_stem: Some("server"),
-        extension: None
-        );
-
-        t!("\\\\?\\bar\\foo.txt",
-        iter: ["\\\\?\\bar", "\\", "foo.txt"],
-        has_root: true,
-        is_absolute: true,
-        parent: Some("\\\\?\\bar\\"),
-        file_name: Some("foo.txt"),
-        file_stem: Some("foo"),
-        extension: Some("txt")
-        );
-
-        t!("\\\\?\\bar",
-        iter: ["\\\\?\\bar"],
-        has_root: true,
-        is_absolute: true,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("\\\\?\\",
-        iter: ["\\\\?\\"],
-        has_root: true,
-        is_absolute: true,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("\\\\?\\UNC\\server\\share\\foo.txt",
-        iter: ["\\\\?\\UNC\\server\\share", "\\", "foo.txt"],
-        has_root: true,
-        is_absolute: true,
-        parent: Some("\\\\?\\UNC\\server\\share\\"),
-        file_name: Some("foo.txt"),
-        file_stem: Some("foo"),
-        extension: Some("txt")
-        );
-
-        t!("\\\\?\\UNC\\server",
-        iter: ["\\\\?\\UNC\\server"],
-        has_root: true,
-        is_absolute: true,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("\\\\?\\UNC\\",
-        iter: ["\\\\?\\UNC\\"],
-        has_root: true,
-        is_absolute: true,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("\\\\?\\C:\\foo.txt",
-        iter: ["\\\\?\\C:", "\\", "foo.txt"],
-        has_root: true,
-        is_absolute: true,
-        parent: Some("\\\\?\\C:\\"),
-        file_name: Some("foo.txt"),
-        file_stem: Some("foo"),
-        extension: Some("txt")
-        );
-
-        t!("\\\\?\\C:\\",
-        iter: ["\\\\?\\C:", "\\"],
-        has_root: true,
-        is_absolute: true,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("\\\\?\\C:",
-        iter: ["\\\\?\\C:"],
-        has_root: true,
-        is_absolute: true,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("\\\\?\\foo/bar",
-        iter: ["\\\\?\\foo/bar"],
-        has_root: true,
-        is_absolute: true,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("\\\\?\\C:/foo",
-        iter: ["\\\\?\\C:/foo"],
-        has_root: true,
-        is_absolute: true,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("\\\\.\\foo\\bar",
-        iter: ["\\\\.\\foo", "\\", "bar"],
-        has_root: true,
-        is_absolute: true,
-        parent: Some("\\\\.\\foo\\"),
-        file_name: Some("bar"),
-        file_stem: Some("bar"),
-        extension: None
-        );
-
-        t!("\\\\.\\foo",
-        iter: ["\\\\.\\foo", "\\"],
-        has_root: true,
-        is_absolute: true,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("\\\\.\\foo/bar",
-        iter: ["\\\\.\\foo/bar", "\\"],
-        has_root: true,
-        is_absolute: true,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("\\\\.\\foo\\bar/baz",
-        iter: ["\\\\.\\foo", "\\", "bar", "baz"],
-        has_root: true,
-        is_absolute: true,
-        parent: Some("\\\\.\\foo\\bar"),
-        file_name: Some("baz"),
-        file_stem: Some("baz"),
-        extension: None
-        );
-
-        t!("\\\\.\\",
-        iter: ["\\\\.\\", "\\"],
-        has_root: true,
-        is_absolute: true,
-        parent: None,
-        file_name: None,
-        file_stem: None,
-        extension: None
-        );
-
-        t!("\\\\?\\a\\b\\",
-        iter: ["\\\\?\\a", "\\", "b"],
-        has_root: true,
-        is_absolute: true,
-        parent: Some("\\\\?\\a\\"),
-        file_name: Some("b"),
-        file_stem: Some("b"),
-        extension: None
-        );
-    }
-
-    #[test]
-    pub fn test_stem_ext() {
-        t!("foo",
-        file_stem: Some("foo"),
-        extension: None
-        );
-
-        t!("foo.",
-        file_stem: Some("foo"),
-        extension: Some("")
-        );
-
-        t!(".foo",
-        file_stem: Some(".foo"),
-        extension: None
-        );
-
-        t!("foo.txt",
-        file_stem: Some("foo"),
-        extension: Some("txt")
-        );
-
-        t!("foo.bar.txt",
-        file_stem: Some("foo.bar"),
-        extension: Some("txt")
-        );
-
-        t!("foo.bar.",
-        file_stem: Some("foo.bar"),
-        extension: Some("")
-        );
-
-        t!(".", file_stem: None, extension: None);
-
-        t!("..", file_stem: None, extension: None);
-
-        t!("", file_stem: None, extension: None);
-    }
-
-    #[test]
-    pub fn test_push() {
-        macro_rules! tp(
-            ($path:expr, $push:expr, $expected:expr) => ( {
-                let mut actual = PathBuf::from($path);
-                actual.push($push);
-                assert!(actual.to_str() == Some($expected),
-                        "pushing {:?} onto {:?}: Expected {:?}, got {:?}",
-                        $push, $path, $expected, actual.to_str().unwrap());
-            });
-        );
-
-        if cfg!(unix) || cfg!(all(target_env = "sgx", target_vendor = "fortanix")) {
-            tp!("", "foo", "foo");
-            tp!("foo", "bar", "foo/bar");
-            tp!("foo/", "bar", "foo/bar");
-            tp!("foo//", "bar", "foo//bar");
-            tp!("foo/.", "bar", "foo/./bar");
-            tp!("foo./.", "bar", "foo././bar");
-            tp!("foo", "", "foo/");
-            tp!("foo", ".", "foo/.");
-            tp!("foo", "..", "foo/..");
-            tp!("foo", "/", "/");
-            tp!("/foo/bar", "/", "/");
-            tp!("/foo/bar", "/baz", "/baz");
-            tp!("/foo/bar", "./baz", "/foo/bar/./baz");
-        } else {
-            tp!("", "foo", "foo");
-            tp!("foo", "bar", r"foo\bar");
-            tp!("foo/", "bar", r"foo/bar");
-            tp!(r"foo\", "bar", r"foo\bar");
-            tp!("foo//", "bar", r"foo//bar");
-            tp!(r"foo\\", "bar", r"foo\\bar");
-            tp!("foo/.", "bar", r"foo/.\bar");
-            tp!("foo./.", "bar", r"foo./.\bar");
-            tp!(r"foo\.", "bar", r"foo\.\bar");
-            tp!(r"foo.\.", "bar", r"foo.\.\bar");
-            tp!("foo", "", "foo\\");
-            tp!("foo", ".", r"foo\.");
-            tp!("foo", "..", r"foo\..");
-            tp!("foo", "/", "/");
-            tp!("foo", r"\", r"\");
-            tp!("/foo/bar", "/", "/");
-            tp!(r"\foo\bar", r"\", r"\");
-            tp!("/foo/bar", "/baz", "/baz");
-            tp!("/foo/bar", r"\baz", r"\baz");
-            tp!("/foo/bar", "./baz", r"/foo/bar\./baz");
-            tp!("/foo/bar", r".\baz", r"/foo/bar\.\baz");
-
-            tp!("c:\\", "windows", "c:\\windows");
-            tp!("c:", "windows", "c:windows");
-
-            tp!("a\\b\\c", "d", "a\\b\\c\\d");
-            tp!("\\a\\b\\c", "d", "\\a\\b\\c\\d");
-            tp!("a\\b", "c\\d", "a\\b\\c\\d");
-            tp!("a\\b", "\\c\\d", "\\c\\d");
-            tp!("a\\b", ".", "a\\b\\.");
-            tp!("a\\b", "..\\c", "a\\b\\..\\c");
-            tp!("a\\b", "C:a.txt", "C:a.txt");
-            tp!("a\\b", "C:\\a.txt", "C:\\a.txt");
-            tp!("C:\\a", "C:\\b.txt", "C:\\b.txt");
-            tp!("C:\\a\\b\\c", "C:d", "C:d");
-            tp!("C:a\\b\\c", "C:d", "C:d");
-            tp!("C:", r"a\b\c", r"C:a\b\c");
-            tp!("C:", r"..\a", r"C:..\a");
-            tp!("\\\\server\\share\\foo", "bar", "\\\\server\\share\\foo\\bar");
-            tp!("\\\\server\\share\\foo", "C:baz", "C:baz");
-            tp!("\\\\?\\C:\\a\\b", "C:c\\d", "C:c\\d");
-            tp!("\\\\?\\C:a\\b", "C:c\\d", "C:c\\d");
-            tp!("\\\\?\\C:\\a\\b", "C:\\c\\d", "C:\\c\\d");
-            tp!("\\\\?\\foo\\bar", "baz", "\\\\?\\foo\\bar\\baz");
-            tp!("\\\\?\\UNC\\server\\share\\foo", "bar", "\\\\?\\UNC\\server\\share\\foo\\bar");
-            tp!("\\\\?\\UNC\\server\\share", "C:\\a", "C:\\a");
-            tp!("\\\\?\\UNC\\server\\share", "C:a", "C:a");
-
-            // Note: modified from old path API
-            tp!("\\\\?\\UNC\\server", "foo", "\\\\?\\UNC\\server\\foo");
-
-            tp!("C:\\a", "\\\\?\\UNC\\server\\share", "\\\\?\\UNC\\server\\share");
-            tp!("\\\\.\\foo\\bar", "baz", "\\\\.\\foo\\bar\\baz");
-            tp!("\\\\.\\foo\\bar", "C:a", "C:a");
-            // again, not sure about the following, but I'm assuming \\.\ should be verbatim
-            tp!("\\\\.\\foo", "..\\bar", "\\\\.\\foo\\..\\bar");
-
-            tp!("\\\\?\\C:", "foo", "\\\\?\\C:\\foo"); // this is a weird one
-        }
-    }
-
-    #[test]
-    pub fn test_pop() {
-        macro_rules! tp(
-            ($path:expr, $expected:expr, $output:expr) => ( {
-                let mut actual = PathBuf::from($path);
-                let output = actual.pop();
-                assert!(actual.to_str() == Some($expected) && output == $output,
-                        "popping from {:?}: Expected {:?}/{:?}, got {:?}/{:?}",
-                        $path, $expected, $output,
-                        actual.to_str().unwrap(), output);
-            });
-        );
-
-        tp!("", "", false);
-        tp!("/", "/", false);
-        tp!("foo", "", true);
-        tp!(".", "", true);
-        tp!("/foo", "/", true);
-        tp!("/foo/bar", "/foo", true);
-        tp!("foo/bar", "foo", true);
-        tp!("foo/.", "", true);
-        tp!("foo//bar", "foo", true);
-
-        if cfg!(windows) {
-            tp!("a\\b\\c", "a\\b", true);
-            tp!("\\a", "\\", true);
-            tp!("\\", "\\", false);
-
-            tp!("C:\\a\\b", "C:\\a", true);
-            tp!("C:\\a", "C:\\", true);
-            tp!("C:\\", "C:\\", false);
-            tp!("C:a\\b", "C:a", true);
-            tp!("C:a", "C:", true);
-            tp!("C:", "C:", false);
-            tp!("\\\\server\\share\\a\\b", "\\\\server\\share\\a", true);
-            tp!("\\\\server\\share\\a", "\\\\server\\share\\", true);
-            tp!("\\\\server\\share", "\\\\server\\share", false);
-            tp!("\\\\?\\a\\b\\c", "\\\\?\\a\\b", true);
-            tp!("\\\\?\\a\\b", "\\\\?\\a\\", true);
-            tp!("\\\\?\\a", "\\\\?\\a", false);
-            tp!("\\\\?\\C:\\a\\b", "\\\\?\\C:\\a", true);
-            tp!("\\\\?\\C:\\a", "\\\\?\\C:\\", true);
-            tp!("\\\\?\\C:\\", "\\\\?\\C:\\", false);
-            tp!("\\\\?\\UNC\\server\\share\\a\\b", "\\\\?\\UNC\\server\\share\\a", true);
-            tp!("\\\\?\\UNC\\server\\share\\a", "\\\\?\\UNC\\server\\share\\", true);
-            tp!("\\\\?\\UNC\\server\\share", "\\\\?\\UNC\\server\\share", false);
-            tp!("\\\\.\\a\\b\\c", "\\\\.\\a\\b", true);
-            tp!("\\\\.\\a\\b", "\\\\.\\a\\", true);
-            tp!("\\\\.\\a", "\\\\.\\a", false);
-
-            tp!("\\\\?\\a\\b\\", "\\\\?\\a\\", true);
-        }
-    }
-
-    #[test]
-    pub fn test_set_file_name() {
-        macro_rules! tfn(
-                ($path:expr, $file:expr, $expected:expr) => ( {
-                let mut p = PathBuf::from($path);
-                p.set_file_name($file);
-                assert!(p.to_str() == Some($expected),
-                        "setting file name of {:?} to {:?}: Expected {:?}, got {:?}",
-                        $path, $file, $expected,
-                        p.to_str().unwrap());
-            });
-        );
-
-        tfn!("foo", "foo", "foo");
-        tfn!("foo", "bar", "bar");
-        tfn!("foo", "", "");
-        tfn!("", "foo", "foo");
-        if cfg!(unix) || cfg!(all(target_env = "sgx", target_vendor = "fortanix")) {
-            tfn!(".", "foo", "./foo");
-            tfn!("foo/", "bar", "bar");
-            tfn!("foo/.", "bar", "bar");
-            tfn!("..", "foo", "../foo");
-            tfn!("foo/..", "bar", "foo/../bar");
-            tfn!("/", "foo", "/foo");
-        } else {
-            tfn!(".", "foo", r".\foo");
-            tfn!(r"foo\", "bar", r"bar");
-            tfn!(r"foo\.", "bar", r"bar");
-            tfn!("..", "foo", r"..\foo");
-            tfn!(r"foo\..", "bar", r"foo\..\bar");
-            tfn!(r"\", "foo", r"\foo");
-        }
-    }
-
-    #[test]
-    pub fn test_set_extension() {
-        macro_rules! tfe(
-                ($path:expr, $ext:expr, $expected:expr, $output:expr) => ( {
-                let mut p = PathBuf::from($path);
-                let output = p.set_extension($ext);
-                assert!(p.to_str() == Some($expected) && output == $output,
-                        "setting extension of {:?} to {:?}: Expected {:?}/{:?}, got {:?}/{:?}",
-                        $path, $ext, $expected, $output,
-                        p.to_str().unwrap(), output);
-            });
-        );
-
-        tfe!("foo", "txt", "foo.txt", true);
-        tfe!("foo.bar", "txt", "foo.txt", true);
-        tfe!("foo.bar.baz", "txt", "foo.bar.txt", true);
-        tfe!(".test", "txt", ".test.txt", true);
-        tfe!("foo.txt", "", "foo", true);
-        tfe!("foo", "", "foo", true);
-        tfe!("", "foo", "", false);
-        tfe!(".", "foo", ".", false);
-        tfe!("foo/", "bar", "foo.bar", true);
-        tfe!("foo/.", "bar", "foo.bar", true);
-        tfe!("..", "foo", "..", false);
-        tfe!("foo/..", "bar", "foo/..", false);
-        tfe!("/", "foo", "/", false);
-    }
-
-    #[test]
-    fn test_eq_receivers() {
-        use crate::borrow::Cow;
-
-        let borrowed: &Path = Path::new("foo/bar");
-        let mut owned: PathBuf = PathBuf::new();
-        owned.push("foo");
-        owned.push("bar");
-        let borrowed_cow: Cow<'_, Path> = borrowed.into();
-        let owned_cow: Cow<'_, Path> = owned.clone().into();
-
-        macro_rules! t {
-            ($($current:expr),+) => {
-                $(
-                    assert_eq!($current, borrowed);
-                    assert_eq!($current, owned);
-                    assert_eq!($current, borrowed_cow);
-                    assert_eq!($current, owned_cow);
-                )+
-            }
-        }
-
-        t!(borrowed, owned, borrowed_cow, owned_cow);
-    }
-
-    #[test]
-    pub fn test_compare() {
-        use crate::collections::hash_map::DefaultHasher;
-        use crate::hash::{Hash, Hasher};
-
-        fn hash<T: Hash>(t: T) -> u64 {
-            let mut s = DefaultHasher::new();
-            t.hash(&mut s);
-            s.finish()
-        }
-
-        macro_rules! tc(
-            ($path1:expr, $path2:expr, eq: $eq:expr,
-             starts_with: $starts_with:expr, ends_with: $ends_with:expr,
-             relative_from: $relative_from:expr) => ({
-                 let path1 = Path::new($path1);
-                 let path2 = Path::new($path2);
-
-                 let eq = path1 == path2;
-                 assert!(eq == $eq, "{:?} == {:?}, expected {:?}, got {:?}",
-                         $path1, $path2, $eq, eq);
-                 assert!($eq == (hash(path1) == hash(path2)),
-                         "{:?} == {:?}, expected {:?}, got {} and {}",
-                         $path1, $path2, $eq, hash(path1), hash(path2));
-
-                 let starts_with = path1.starts_with(path2);
-                 assert!(starts_with == $starts_with,
-                         "{:?}.starts_with({:?}), expected {:?}, got {:?}", $path1, $path2,
-                         $starts_with, starts_with);
-
-                 let ends_with = path1.ends_with(path2);
-                 assert!(ends_with == $ends_with,
-                         "{:?}.ends_with({:?}), expected {:?}, got {:?}", $path1, $path2,
-                         $ends_with, ends_with);
-
-                 let relative_from = path1.strip_prefix(path2)
-                                          .map(|p| p.to_str().unwrap())
-                                          .ok();
-                 let exp: Option<&str> = $relative_from;
-                 assert!(relative_from == exp,
-                         "{:?}.strip_prefix({:?}), expected {:?}, got {:?}",
-                         $path1, $path2, exp, relative_from);
-            });
-        );
-
-        tc!("", "",
-        eq: true,
-        starts_with: true,
-        ends_with: true,
-        relative_from: Some("")
-        );
-
-        tc!("foo", "",
-        eq: false,
-        starts_with: true,
-        ends_with: true,
-        relative_from: Some("foo")
-        );
-
-        tc!("", "foo",
-        eq: false,
-        starts_with: false,
-        ends_with: false,
-        relative_from: None
-        );
-
-        tc!("foo", "foo",
-        eq: true,
-        starts_with: true,
-        ends_with: true,
-        relative_from: Some("")
-        );
-
-        tc!("foo/", "foo",
-        eq: true,
-        starts_with: true,
-        ends_with: true,
-        relative_from: Some("")
-        );
-
-        tc!("foo/bar", "foo",
-        eq: false,
-        starts_with: true,
-        ends_with: false,
-        relative_from: Some("bar")
-        );
-
-        tc!("foo/bar/baz", "foo/bar",
-        eq: false,
-        starts_with: true,
-        ends_with: false,
-        relative_from: Some("baz")
-        );
-
-        tc!("foo/bar", "foo/bar/baz",
-        eq: false,
-        starts_with: false,
-        ends_with: false,
-        relative_from: None
-        );
-
-        tc!("./foo/bar/", ".",
-        eq: false,
-        starts_with: true,
-        ends_with: false,
-        relative_from: Some("foo/bar")
-        );
-
-        if cfg!(windows) {
-            tc!(r"C:\src\rust\cargo-test\test\Cargo.toml",
-            r"c:\src\rust\cargo-test\test",
-            eq: false,
-            starts_with: true,
-            ends_with: false,
-            relative_from: Some("Cargo.toml")
-            );
-
-            tc!(r"c:\foo", r"C:\foo",
-            eq: true,
-            starts_with: true,
-            ends_with: true,
-            relative_from: Some("")
-            );
-        }
-    }
-
-    #[test]
-    fn test_components_debug() {
-        let path = Path::new("/tmp");
-
-        let mut components = path.components();
-
-        let expected = "Components([RootDir, Normal(\"tmp\")])";
-        let actual = format!("{:?}", components);
-        assert_eq!(expected, actual);
-
-        let _ = components.next().unwrap();
-        let expected = "Components([Normal(\"tmp\")])";
-        let actual = format!("{:?}", components);
-        assert_eq!(expected, actual);
-
-        let _ = components.next().unwrap();
-        let expected = "Components([])";
-        let actual = format!("{:?}", components);
-        assert_eq!(expected, actual);
-    }
-
-    #[cfg(unix)]
-    #[test]
-    fn test_iter_debug() {
-        let path = Path::new("/tmp");
-
-        let mut iter = path.iter();
-
-        let expected = "Iter([\"/\", \"tmp\"])";
-        let actual = format!("{:?}", iter);
-        assert_eq!(expected, actual);
-
-        let _ = iter.next().unwrap();
-        let expected = "Iter([\"tmp\"])";
-        let actual = format!("{:?}", iter);
-        assert_eq!(expected, actual);
-
-        let _ = iter.next().unwrap();
-        let expected = "Iter([])";
-        let actual = format!("{:?}", iter);
-        assert_eq!(expected, actual);
-    }
-
-    #[test]
-    fn into_boxed() {
-        let orig: &str = "some/sort/of/path";
-        let path = Path::new(orig);
-        let boxed: Box<Path> = Box::from(path);
-        let path_buf = path.to_owned().into_boxed_path().into_path_buf();
-        assert_eq!(path, &*boxed);
-        assert_eq!(&*boxed, &*path_buf);
-        assert_eq!(&*path_buf, path);
-    }
-
-    #[test]
-    fn test_clone_into() {
-        let mut path_buf = PathBuf::from("supercalifragilisticexpialidocious");
-        let path = Path::new("short");
-        path.clone_into(&mut path_buf);
-        assert_eq!(path, path_buf);
-        assert!(path_buf.into_os_string().capacity() >= 15);
-    }
-
-    #[test]
-    fn display_format_flags() {
-        assert_eq!(format!("a{:#<5}b", Path::new("").display()), "a#####b");
-        assert_eq!(format!("a{:#<5}b", Path::new("a").display()), "aa####b");
-    }
-
-    #[test]
-    fn into_rc() {
-        let orig = "hello/world";
-        let path = Path::new(orig);
-        let rc: Rc<Path> = Rc::from(path);
-        let arc: Arc<Path> = Arc::from(path);
-
-        assert_eq!(&*rc, path);
-        assert_eq!(&*arc, path);
-
-        let rc2: Rc<Path> = Rc::from(path.to_owned());
-        let arc2: Arc<Path> = Arc::from(path.to_owned());
-
-        assert_eq!(&*rc2, path);
-        assert_eq!(&*arc2, path);
-    }
-}
diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs
new file mode 100644
index 00000000000..ff94fda5a22
--- /dev/null
+++ b/library/std/src/path/tests.rs
@@ -0,0 +1,1394 @@
+use super::*;
+
+use crate::rc::Rc;
+use crate::sync::Arc;
+
+macro_rules! t(
+    ($path:expr, iter: $iter:expr) => (
+        {
+            let path = Path::new($path);
+
+            // Forward iteration
+            let comps = path.iter()
+                .map(|p| p.to_string_lossy().into_owned())
+                .collect::<Vec<String>>();
+            let exp: &[&str] = &$iter;
+            let exps = exp.iter().map(|s| s.to_string()).collect::<Vec<String>>();
+            assert!(comps == exps, "iter: Expected {:?}, found {:?}",
+                    exps, comps);
+
+            // Reverse iteration
+            let comps = Path::new($path).iter().rev()
+                .map(|p| p.to_string_lossy().into_owned())
+                .collect::<Vec<String>>();
+            let exps = exps.into_iter().rev().collect::<Vec<String>>();
+            assert!(comps == exps, "iter().rev(): Expected {:?}, found {:?}",
+                    exps, comps);
+        }
+    );
+
+    ($path:expr, has_root: $has_root:expr, is_absolute: $is_absolute:expr) => (
+        {
+            let path = Path::new($path);
+
+            let act_root = path.has_root();
+            assert!(act_root == $has_root, "has_root: Expected {:?}, found {:?}",
+                    $has_root, act_root);
+
+            let act_abs = path.is_absolute();
+            assert!(act_abs == $is_absolute, "is_absolute: Expected {:?}, found {:?}",
+                    $is_absolute, act_abs);
+        }
+    );
+
+    ($path:expr, parent: $parent:expr, file_name: $file:expr) => (
+        {
+            let path = Path::new($path);
+
+            let parent = path.parent().map(|p| p.to_str().unwrap());
+            let exp_parent: Option<&str> = $parent;
+            assert!(parent == exp_parent, "parent: Expected {:?}, found {:?}",
+                    exp_parent, parent);
+
+            let file = path.file_name().map(|p| p.to_str().unwrap());
+            let exp_file: Option<&str> = $file;
+            assert!(file == exp_file, "file_name: Expected {:?}, found {:?}",
+                    exp_file, file);
+        }
+    );
+
+    ($path:expr, file_stem: $file_stem:expr, extension: $extension:expr) => (
+        {
+            let path = Path::new($path);
+
+            let stem = path.file_stem().map(|p| p.to_str().unwrap());
+            let exp_stem: Option<&str> = $file_stem;
+            assert!(stem == exp_stem, "file_stem: Expected {:?}, found {:?}",
+                    exp_stem, stem);
+
+            let ext = path.extension().map(|p| p.to_str().unwrap());
+            let exp_ext: Option<&str> = $extension;
+            assert!(ext == exp_ext, "extension: Expected {:?}, found {:?}",
+                    exp_ext, ext);
+        }
+    );
+
+    ($path:expr, iter: $iter:expr,
+                 has_root: $has_root:expr, is_absolute: $is_absolute:expr,
+                 parent: $parent:expr, file_name: $file:expr,
+                 file_stem: $file_stem:expr, extension: $extension:expr) => (
+        {
+            t!($path, iter: $iter);
+            t!($path, has_root: $has_root, is_absolute: $is_absolute);
+            t!($path, parent: $parent, file_name: $file);
+            t!($path, file_stem: $file_stem, extension: $extension);
+        }
+    );
+);
+
+#[test]
+fn into() {
+    use crate::borrow::Cow;
+
+    let static_path = Path::new("/home/foo");
+    let static_cow_path: Cow<'static, Path> = static_path.into();
+    let pathbuf = PathBuf::from("/home/foo");
+
+    {
+        let path: &Path = &pathbuf;
+        let borrowed_cow_path: Cow<'_, Path> = path.into();
+
+        assert_eq!(static_cow_path, borrowed_cow_path);
+    }
+
+    let owned_cow_path: Cow<'static, Path> = pathbuf.into();
+
+    assert_eq!(static_cow_path, owned_cow_path);
+}
+
+#[test]
+#[cfg(unix)]
+pub fn test_decompositions_unix() {
+    t!("",
+    iter: [],
+    has_root: false,
+    is_absolute: false,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("foo",
+    iter: ["foo"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some(""),
+    file_name: Some("foo"),
+    file_stem: Some("foo"),
+    extension: None
+    );
+
+    t!("/",
+    iter: ["/"],
+    has_root: true,
+    is_absolute: true,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("/foo",
+    iter: ["/", "foo"],
+    has_root: true,
+    is_absolute: true,
+    parent: Some("/"),
+    file_name: Some("foo"),
+    file_stem: Some("foo"),
+    extension: None
+    );
+
+    t!("foo/",
+    iter: ["foo"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some(""),
+    file_name: Some("foo"),
+    file_stem: Some("foo"),
+    extension: None
+    );
+
+    t!("/foo/",
+    iter: ["/", "foo"],
+    has_root: true,
+    is_absolute: true,
+    parent: Some("/"),
+    file_name: Some("foo"),
+    file_stem: Some("foo"),
+    extension: None
+    );
+
+    t!("foo/bar",
+    iter: ["foo", "bar"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("foo"),
+    file_name: Some("bar"),
+    file_stem: Some("bar"),
+    extension: None
+    );
+
+    t!("/foo/bar",
+    iter: ["/", "foo", "bar"],
+    has_root: true,
+    is_absolute: true,
+    parent: Some("/foo"),
+    file_name: Some("bar"),
+    file_stem: Some("bar"),
+    extension: None
+    );
+
+    t!("///foo///",
+    iter: ["/", "foo"],
+    has_root: true,
+    is_absolute: true,
+    parent: Some("/"),
+    file_name: Some("foo"),
+    file_stem: Some("foo"),
+    extension: None
+    );
+
+    t!("///foo///bar",
+    iter: ["/", "foo", "bar"],
+    has_root: true,
+    is_absolute: true,
+    parent: Some("///foo"),
+    file_name: Some("bar"),
+    file_stem: Some("bar"),
+    extension: None
+    );
+
+    t!("./.",
+    iter: ["."],
+    has_root: false,
+    is_absolute: false,
+    parent: Some(""),
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("/..",
+    iter: ["/", ".."],
+    has_root: true,
+    is_absolute: true,
+    parent: Some("/"),
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("../",
+    iter: [".."],
+    has_root: false,
+    is_absolute: false,
+    parent: Some(""),
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("foo/.",
+    iter: ["foo"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some(""),
+    file_name: Some("foo"),
+    file_stem: Some("foo"),
+    extension: None
+    );
+
+    t!("foo/..",
+    iter: ["foo", ".."],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("foo"),
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("foo/./",
+    iter: ["foo"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some(""),
+    file_name: Some("foo"),
+    file_stem: Some("foo"),
+    extension: None
+    );
+
+    t!("foo/./bar",
+    iter: ["foo", "bar"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("foo"),
+    file_name: Some("bar"),
+    file_stem: Some("bar"),
+    extension: None
+    );
+
+    t!("foo/../",
+    iter: ["foo", ".."],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("foo"),
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("foo/../bar",
+    iter: ["foo", "..", "bar"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("foo/.."),
+    file_name: Some("bar"),
+    file_stem: Some("bar"),
+    extension: None
+    );
+
+    t!("./a",
+    iter: [".", "a"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("."),
+    file_name: Some("a"),
+    file_stem: Some("a"),
+    extension: None
+    );
+
+    t!(".",
+    iter: ["."],
+    has_root: false,
+    is_absolute: false,
+    parent: Some(""),
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("./",
+    iter: ["."],
+    has_root: false,
+    is_absolute: false,
+    parent: Some(""),
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("a/b",
+    iter: ["a", "b"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("a"),
+    file_name: Some("b"),
+    file_stem: Some("b"),
+    extension: None
+    );
+
+    t!("a//b",
+    iter: ["a", "b"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("a"),
+    file_name: Some("b"),
+    file_stem: Some("b"),
+    extension: None
+    );
+
+    t!("a/./b",
+    iter: ["a", "b"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("a"),
+    file_name: Some("b"),
+    file_stem: Some("b"),
+    extension: None
+    );
+
+    t!("a/b/c",
+    iter: ["a", "b", "c"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("a/b"),
+    file_name: Some("c"),
+    file_stem: Some("c"),
+    extension: None
+    );
+
+    t!(".foo",
+    iter: [".foo"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some(""),
+    file_name: Some(".foo"),
+    file_stem: Some(".foo"),
+    extension: None
+    );
+}
+
+#[test]
+#[cfg(windows)]
+pub fn test_decompositions_windows() {
+    t!("",
+    iter: [],
+    has_root: false,
+    is_absolute: false,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("foo",
+    iter: ["foo"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some(""),
+    file_name: Some("foo"),
+    file_stem: Some("foo"),
+    extension: None
+    );
+
+    t!("/",
+    iter: ["\\"],
+    has_root: true,
+    is_absolute: false,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("\\",
+    iter: ["\\"],
+    has_root: true,
+    is_absolute: false,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("c:",
+    iter: ["c:"],
+    has_root: false,
+    is_absolute: false,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("c:\\",
+    iter: ["c:", "\\"],
+    has_root: true,
+    is_absolute: true,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("c:/",
+    iter: ["c:", "\\"],
+    has_root: true,
+    is_absolute: true,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("/foo",
+    iter: ["\\", "foo"],
+    has_root: true,
+    is_absolute: false,
+    parent: Some("/"),
+    file_name: Some("foo"),
+    file_stem: Some("foo"),
+    extension: None
+    );
+
+    t!("foo/",
+    iter: ["foo"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some(""),
+    file_name: Some("foo"),
+    file_stem: Some("foo"),
+    extension: None
+    );
+
+    t!("/foo/",
+    iter: ["\\", "foo"],
+    has_root: true,
+    is_absolute: false,
+    parent: Some("/"),
+    file_name: Some("foo"),
+    file_stem: Some("foo"),
+    extension: None
+    );
+
+    t!("foo/bar",
+    iter: ["foo", "bar"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("foo"),
+    file_name: Some("bar"),
+    file_stem: Some("bar"),
+    extension: None
+    );
+
+    t!("/foo/bar",
+    iter: ["\\", "foo", "bar"],
+    has_root: true,
+    is_absolute: false,
+    parent: Some("/foo"),
+    file_name: Some("bar"),
+    file_stem: Some("bar"),
+    extension: None
+    );
+
+    t!("///foo///",
+    iter: ["\\", "foo"],
+    has_root: true,
+    is_absolute: false,
+    parent: Some("/"),
+    file_name: Some("foo"),
+    file_stem: Some("foo"),
+    extension: None
+    );
+
+    t!("///foo///bar",
+    iter: ["\\", "foo", "bar"],
+    has_root: true,
+    is_absolute: false,
+    parent: Some("///foo"),
+    file_name: Some("bar"),
+    file_stem: Some("bar"),
+    extension: None
+    );
+
+    t!("./.",
+    iter: ["."],
+    has_root: false,
+    is_absolute: false,
+    parent: Some(""),
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("/..",
+    iter: ["\\", ".."],
+    has_root: true,
+    is_absolute: false,
+    parent: Some("/"),
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("../",
+    iter: [".."],
+    has_root: false,
+    is_absolute: false,
+    parent: Some(""),
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("foo/.",
+    iter: ["foo"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some(""),
+    file_name: Some("foo"),
+    file_stem: Some("foo"),
+    extension: None
+    );
+
+    t!("foo/..",
+    iter: ["foo", ".."],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("foo"),
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("foo/./",
+    iter: ["foo"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some(""),
+    file_name: Some("foo"),
+    file_stem: Some("foo"),
+    extension: None
+    );
+
+    t!("foo/./bar",
+    iter: ["foo", "bar"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("foo"),
+    file_name: Some("bar"),
+    file_stem: Some("bar"),
+    extension: None
+    );
+
+    t!("foo/../",
+    iter: ["foo", ".."],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("foo"),
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("foo/../bar",
+    iter: ["foo", "..", "bar"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("foo/.."),
+    file_name: Some("bar"),
+    file_stem: Some("bar"),
+    extension: None
+    );
+
+    t!("./a",
+    iter: [".", "a"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("."),
+    file_name: Some("a"),
+    file_stem: Some("a"),
+    extension: None
+    );
+
+    t!(".",
+    iter: ["."],
+    has_root: false,
+    is_absolute: false,
+    parent: Some(""),
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("./",
+    iter: ["."],
+    has_root: false,
+    is_absolute: false,
+    parent: Some(""),
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("a/b",
+    iter: ["a", "b"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("a"),
+    file_name: Some("b"),
+    file_stem: Some("b"),
+    extension: None
+    );
+
+    t!("a//b",
+    iter: ["a", "b"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("a"),
+    file_name: Some("b"),
+    file_stem: Some("b"),
+    extension: None
+    );
+
+    t!("a/./b",
+    iter: ["a", "b"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("a"),
+    file_name: Some("b"),
+    file_stem: Some("b"),
+    extension: None
+    );
+
+    t!("a/b/c",
+       iter: ["a", "b", "c"],
+       has_root: false,
+       is_absolute: false,
+       parent: Some("a/b"),
+       file_name: Some("c"),
+       file_stem: Some("c"),
+       extension: None);
+
+    t!("a\\b\\c",
+    iter: ["a", "b", "c"],
+    has_root: false,
+    is_absolute: false,
+    parent: Some("a\\b"),
+    file_name: Some("c"),
+    file_stem: Some("c"),
+    extension: None
+    );
+
+    t!("\\a",
+    iter: ["\\", "a"],
+    has_root: true,
+    is_absolute: false,
+    parent: Some("\\"),
+    file_name: Some("a"),
+    file_stem: Some("a"),
+    extension: None
+    );
+
+    t!("c:\\foo.txt",
+    iter: ["c:", "\\", "foo.txt"],
+    has_root: true,
+    is_absolute: true,
+    parent: Some("c:\\"),
+    file_name: Some("foo.txt"),
+    file_stem: Some("foo"),
+    extension: Some("txt")
+    );
+
+    t!("\\\\server\\share\\foo.txt",
+    iter: ["\\\\server\\share", "\\", "foo.txt"],
+    has_root: true,
+    is_absolute: true,
+    parent: Some("\\\\server\\share\\"),
+    file_name: Some("foo.txt"),
+    file_stem: Some("foo"),
+    extension: Some("txt")
+    );
+
+    t!("\\\\server\\share",
+    iter: ["\\\\server\\share", "\\"],
+    has_root: true,
+    is_absolute: true,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("\\\\server",
+    iter: ["\\", "server"],
+    has_root: true,
+    is_absolute: false,
+    parent: Some("\\"),
+    file_name: Some("server"),
+    file_stem: Some("server"),
+    extension: None
+    );
+
+    t!("\\\\?\\bar\\foo.txt",
+    iter: ["\\\\?\\bar", "\\", "foo.txt"],
+    has_root: true,
+    is_absolute: true,
+    parent: Some("\\\\?\\bar\\"),
+    file_name: Some("foo.txt"),
+    file_stem: Some("foo"),
+    extension: Some("txt")
+    );
+
+    t!("\\\\?\\bar",
+    iter: ["\\\\?\\bar"],
+    has_root: true,
+    is_absolute: true,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("\\\\?\\",
+    iter: ["\\\\?\\"],
+    has_root: true,
+    is_absolute: true,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("\\\\?\\UNC\\server\\share\\foo.txt",
+    iter: ["\\\\?\\UNC\\server\\share", "\\", "foo.txt"],
+    has_root: true,
+    is_absolute: true,
+    parent: Some("\\\\?\\UNC\\server\\share\\"),
+    file_name: Some("foo.txt"),
+    file_stem: Some("foo"),
+    extension: Some("txt")
+    );
+
+    t!("\\\\?\\UNC\\server",
+    iter: ["\\\\?\\UNC\\server"],
+    has_root: true,
+    is_absolute: true,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("\\\\?\\UNC\\",
+    iter: ["\\\\?\\UNC\\"],
+    has_root: true,
+    is_absolute: true,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("\\\\?\\C:\\foo.txt",
+    iter: ["\\\\?\\C:", "\\", "foo.txt"],
+    has_root: true,
+    is_absolute: true,
+    parent: Some("\\\\?\\C:\\"),
+    file_name: Some("foo.txt"),
+    file_stem: Some("foo"),
+    extension: Some("txt")
+    );
+
+    t!("\\\\?\\C:\\",
+    iter: ["\\\\?\\C:", "\\"],
+    has_root: true,
+    is_absolute: true,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("\\\\?\\C:",
+    iter: ["\\\\?\\C:"],
+    has_root: true,
+    is_absolute: true,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("\\\\?\\foo/bar",
+    iter: ["\\\\?\\foo/bar"],
+    has_root: true,
+    is_absolute: true,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("\\\\?\\C:/foo",
+    iter: ["\\\\?\\C:/foo"],
+    has_root: true,
+    is_absolute: true,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("\\\\.\\foo\\bar",
+    iter: ["\\\\.\\foo", "\\", "bar"],
+    has_root: true,
+    is_absolute: true,
+    parent: Some("\\\\.\\foo\\"),
+    file_name: Some("bar"),
+    file_stem: Some("bar"),
+    extension: None
+    );
+
+    t!("\\\\.\\foo",
+    iter: ["\\\\.\\foo", "\\"],
+    has_root: true,
+    is_absolute: true,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("\\\\.\\foo/bar",
+    iter: ["\\\\.\\foo/bar", "\\"],
+    has_root: true,
+    is_absolute: true,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("\\\\.\\foo\\bar/baz",
+    iter: ["\\\\.\\foo", "\\", "bar", "baz"],
+    has_root: true,
+    is_absolute: true,
+    parent: Some("\\\\.\\foo\\bar"),
+    file_name: Some("baz"),
+    file_stem: Some("baz"),
+    extension: None
+    );
+
+    t!("\\\\.\\",
+    iter: ["\\\\.\\", "\\"],
+    has_root: true,
+    is_absolute: true,
+    parent: None,
+    file_name: None,
+    file_stem: None,
+    extension: None
+    );
+
+    t!("\\\\?\\a\\b\\",
+    iter: ["\\\\?\\a", "\\", "b"],
+    has_root: true,
+    is_absolute: true,
+    parent: Some("\\\\?\\a\\"),
+    file_name: Some("b"),
+    file_stem: Some("b"),
+    extension: None
+    );
+}
+
+#[test]
+pub fn test_stem_ext() {
+    t!("foo",
+    file_stem: Some("foo"),
+    extension: None
+    );
+
+    t!("foo.",
+    file_stem: Some("foo"),
+    extension: Some("")
+    );
+
+    t!(".foo",
+    file_stem: Some(".foo"),
+    extension: None
+    );
+
+    t!("foo.txt",
+    file_stem: Some("foo"),
+    extension: Some("txt")
+    );
+
+    t!("foo.bar.txt",
+    file_stem: Some("foo.bar"),
+    extension: Some("txt")
+    );
+
+    t!("foo.bar.",
+    file_stem: Some("foo.bar"),
+    extension: Some("")
+    );
+
+    t!(".", file_stem: None, extension: None);
+
+    t!("..", file_stem: None, extension: None);
+
+    t!("", file_stem: None, extension: None);
+}
+
+#[test]
+pub fn test_push() {
+    macro_rules! tp(
+        ($path:expr, $push:expr, $expected:expr) => ( {
+            let mut actual = PathBuf::from($path);
+            actual.push($push);
+            assert!(actual.to_str() == Some($expected),
+                    "pushing {:?} onto {:?}: Expected {:?}, got {:?}",
+                    $push, $path, $expected, actual.to_str().unwrap());
+        });
+    );
+
+    if cfg!(unix) || cfg!(all(target_env = "sgx", target_vendor = "fortanix")) {
+        tp!("", "foo", "foo");
+        tp!("foo", "bar", "foo/bar");
+        tp!("foo/", "bar", "foo/bar");
+        tp!("foo//", "bar", "foo//bar");
+        tp!("foo/.", "bar", "foo/./bar");
+        tp!("foo./.", "bar", "foo././bar");
+        tp!("foo", "", "foo/");
+        tp!("foo", ".", "foo/.");
+        tp!("foo", "..", "foo/..");
+        tp!("foo", "/", "/");
+        tp!("/foo/bar", "/", "/");
+        tp!("/foo/bar", "/baz", "/baz");
+        tp!("/foo/bar", "./baz", "/foo/bar/./baz");
+    } else {
+        tp!("", "foo", "foo");
+        tp!("foo", "bar", r"foo\bar");
+        tp!("foo/", "bar", r"foo/bar");
+        tp!(r"foo\", "bar", r"foo\bar");
+        tp!("foo//", "bar", r"foo//bar");
+        tp!(r"foo\\", "bar", r"foo\\bar");
+        tp!("foo/.", "bar", r"foo/.\bar");
+        tp!("foo./.", "bar", r"foo./.\bar");
+        tp!(r"foo\.", "bar", r"foo\.\bar");
+        tp!(r"foo.\.", "bar", r"foo.\.\bar");
+        tp!("foo", "", "foo\\");
+        tp!("foo", ".", r"foo\.");
+        tp!("foo", "..", r"foo\..");
+        tp!("foo", "/", "/");
+        tp!("foo", r"\", r"\");
+        tp!("/foo/bar", "/", "/");
+        tp!(r"\foo\bar", r"\", r"\");
+        tp!("/foo/bar", "/baz", "/baz");
+        tp!("/foo/bar", r"\baz", r"\baz");
+        tp!("/foo/bar", "./baz", r"/foo/bar\./baz");
+        tp!("/foo/bar", r".\baz", r"/foo/bar\.\baz");
+
+        tp!("c:\\", "windows", "c:\\windows");
+        tp!("c:", "windows", "c:windows");
+
+        tp!("a\\b\\c", "d", "a\\b\\c\\d");
+        tp!("\\a\\b\\c", "d", "\\a\\b\\c\\d");
+        tp!("a\\b", "c\\d", "a\\b\\c\\d");
+        tp!("a\\b", "\\c\\d", "\\c\\d");
+        tp!("a\\b", ".", "a\\b\\.");
+        tp!("a\\b", "..\\c", "a\\b\\..\\c");
+        tp!("a\\b", "C:a.txt", "C:a.txt");
+        tp!("a\\b", "C:\\a.txt", "C:\\a.txt");
+        tp!("C:\\a", "C:\\b.txt", "C:\\b.txt");
+        tp!("C:\\a\\b\\c", "C:d", "C:d");
+        tp!("C:a\\b\\c", "C:d", "C:d");
+        tp!("C:", r"a\b\c", r"C:a\b\c");
+        tp!("C:", r"..\a", r"C:..\a");
+        tp!("\\\\server\\share\\foo", "bar", "\\\\server\\share\\foo\\bar");
+        tp!("\\\\server\\share\\foo", "C:baz", "C:baz");
+        tp!("\\\\?\\C:\\a\\b", "C:c\\d", "C:c\\d");
+        tp!("\\\\?\\C:a\\b", "C:c\\d", "C:c\\d");
+        tp!("\\\\?\\C:\\a\\b", "C:\\c\\d", "C:\\c\\d");
+        tp!("\\\\?\\foo\\bar", "baz", "\\\\?\\foo\\bar\\baz");
+        tp!("\\\\?\\UNC\\server\\share\\foo", "bar", "\\\\?\\UNC\\server\\share\\foo\\bar");
+        tp!("\\\\?\\UNC\\server\\share", "C:\\a", "C:\\a");
+        tp!("\\\\?\\UNC\\server\\share", "C:a", "C:a");
+
+        // Note: modified from old path API
+        tp!("\\\\?\\UNC\\server", "foo", "\\\\?\\UNC\\server\\foo");
+
+        tp!("C:\\a", "\\\\?\\UNC\\server\\share", "\\\\?\\UNC\\server\\share");
+        tp!("\\\\.\\foo\\bar", "baz", "\\\\.\\foo\\bar\\baz");
+        tp!("\\\\.\\foo\\bar", "C:a", "C:a");
+        // again, not sure about the following, but I'm assuming \\.\ should be verbatim
+        tp!("\\\\.\\foo", "..\\bar", "\\\\.\\foo\\..\\bar");
+
+        tp!("\\\\?\\C:", "foo", "\\\\?\\C:\\foo"); // this is a weird one
+    }
+}
+
+#[test]
+pub fn test_pop() {
+    macro_rules! tp(
+        ($path:expr, $expected:expr, $output:expr) => ( {
+            let mut actual = PathBuf::from($path);
+            let output = actual.pop();
+            assert!(actual.to_str() == Some($expected) && output == $output,
+                    "popping from {:?}: Expected {:?}/{:?}, got {:?}/{:?}",
+                    $path, $expected, $output,
+                    actual.to_str().unwrap(), output);
+        });
+    );
+
+    tp!("", "", false);
+    tp!("/", "/", false);
+    tp!("foo", "", true);
+    tp!(".", "", true);
+    tp!("/foo", "/", true);
+    tp!("/foo/bar", "/foo", true);
+    tp!("foo/bar", "foo", true);
+    tp!("foo/.", "", true);
+    tp!("foo//bar", "foo", true);
+
+    if cfg!(windows) {
+        tp!("a\\b\\c", "a\\b", true);
+        tp!("\\a", "\\", true);
+        tp!("\\", "\\", false);
+
+        tp!("C:\\a\\b", "C:\\a", true);
+        tp!("C:\\a", "C:\\", true);
+        tp!("C:\\", "C:\\", false);
+        tp!("C:a\\b", "C:a", true);
+        tp!("C:a", "C:", true);
+        tp!("C:", "C:", false);
+        tp!("\\\\server\\share\\a\\b", "\\\\server\\share\\a", true);
+        tp!("\\\\server\\share\\a", "\\\\server\\share\\", true);
+        tp!("\\\\server\\share", "\\\\server\\share", false);
+        tp!("\\\\?\\a\\b\\c", "\\\\?\\a\\b", true);
+        tp!("\\\\?\\a\\b", "\\\\?\\a\\", true);
+        tp!("\\\\?\\a", "\\\\?\\a", false);
+        tp!("\\\\?\\C:\\a\\b", "\\\\?\\C:\\a", true);
+        tp!("\\\\?\\C:\\a", "\\\\?\\C:\\", true);
+        tp!("\\\\?\\C:\\", "\\\\?\\C:\\", false);
+        tp!("\\\\?\\UNC\\server\\share\\a\\b", "\\\\?\\UNC\\server\\share\\a", true);
+        tp!("\\\\?\\UNC\\server\\share\\a", "\\\\?\\UNC\\server\\share\\", true);
+        tp!("\\\\?\\UNC\\server\\share", "\\\\?\\UNC\\server\\share", false);
+        tp!("\\\\.\\a\\b\\c", "\\\\.\\a\\b", true);
+        tp!("\\\\.\\a\\b", "\\\\.\\a\\", true);
+        tp!("\\\\.\\a", "\\\\.\\a", false);
+
+        tp!("\\\\?\\a\\b\\", "\\\\?\\a\\", true);
+    }
+}
+
+#[test]
+pub fn test_set_file_name() {
+    macro_rules! tfn(
+            ($path:expr, $file:expr, $expected:expr) => ( {
+            let mut p = PathBuf::from($path);
+            p.set_file_name($file);
+            assert!(p.to_str() == Some($expected),
+                    "setting file name of {:?} to {:?}: Expected {:?}, got {:?}",
+                    $path, $file, $expected,
+                    p.to_str().unwrap());
+        });
+    );
+
+    tfn!("foo", "foo", "foo");
+    tfn!("foo", "bar", "bar");
+    tfn!("foo", "", "");
+    tfn!("", "foo", "foo");
+    if cfg!(unix) || cfg!(all(target_env = "sgx", target_vendor = "fortanix")) {
+        tfn!(".", "foo", "./foo");
+        tfn!("foo/", "bar", "bar");
+        tfn!("foo/.", "bar", "bar");
+        tfn!("..", "foo", "../foo");
+        tfn!("foo/..", "bar", "foo/../bar");
+        tfn!("/", "foo", "/foo");
+    } else {
+        tfn!(".", "foo", r".\foo");
+        tfn!(r"foo\", "bar", r"bar");
+        tfn!(r"foo\.", "bar", r"bar");
+        tfn!("..", "foo", r"..\foo");
+        tfn!(r"foo\..", "bar", r"foo\..\bar");
+        tfn!(r"\", "foo", r"\foo");
+    }
+}
+
+#[test]
+pub fn test_set_extension() {
+    macro_rules! tfe(
+            ($path:expr, $ext:expr, $expected:expr, $output:expr) => ( {
+            let mut p = PathBuf::from($path);
+            let output = p.set_extension($ext);
+            assert!(p.to_str() == Some($expected) && output == $output,
+                    "setting extension of {:?} to {:?}: Expected {:?}/{:?}, got {:?}/{:?}",
+                    $path, $ext, $expected, $output,
+                    p.to_str().unwrap(), output);
+        });
+    );
+
+    tfe!("foo", "txt", "foo.txt", true);
+    tfe!("foo.bar", "txt", "foo.txt", true);
+    tfe!("foo.bar.baz", "txt", "foo.bar.txt", true);
+    tfe!(".test", "txt", ".test.txt", true);
+    tfe!("foo.txt", "", "foo", true);
+    tfe!("foo", "", "foo", true);
+    tfe!("", "foo", "", false);
+    tfe!(".", "foo", ".", false);
+    tfe!("foo/", "bar", "foo.bar", true);
+    tfe!("foo/.", "bar", "foo.bar", true);
+    tfe!("..", "foo", "..", false);
+    tfe!("foo/..", "bar", "foo/..", false);
+    tfe!("/", "foo", "/", false);
+}
+
+#[test]
+fn test_eq_receivers() {
+    use crate::borrow::Cow;
+
+    let borrowed: &Path = Path::new("foo/bar");
+    let mut owned: PathBuf = PathBuf::new();
+    owned.push("foo");
+    owned.push("bar");
+    let borrowed_cow: Cow<'_, Path> = borrowed.into();
+    let owned_cow: Cow<'_, Path> = owned.clone().into();
+
+    macro_rules! t {
+        ($($current:expr),+) => {
+            $(
+                assert_eq!($current, borrowed);
+                assert_eq!($current, owned);
+                assert_eq!($current, borrowed_cow);
+                assert_eq!($current, owned_cow);
+            )+
+        }
+    }
+
+    t!(borrowed, owned, borrowed_cow, owned_cow);
+}
+
+#[test]
+pub fn test_compare() {
+    use crate::collections::hash_map::DefaultHasher;
+    use crate::hash::{Hash, Hasher};
+
+    fn hash<T: Hash>(t: T) -> u64 {
+        let mut s = DefaultHasher::new();
+        t.hash(&mut s);
+        s.finish()
+    }
+
+    macro_rules! tc(
+        ($path1:expr, $path2:expr, eq: $eq:expr,
+         starts_with: $starts_with:expr, ends_with: $ends_with:expr,
+         relative_from: $relative_from:expr) => ({
+             let path1 = Path::new($path1);
+             let path2 = Path::new($path2);
+
+             let eq = path1 == path2;
+             assert!(eq == $eq, "{:?} == {:?}, expected {:?}, got {:?}",
+                     $path1, $path2, $eq, eq);
+             assert!($eq == (hash(path1) == hash(path2)),
+                     "{:?} == {:?}, expected {:?}, got {} and {}",
+                     $path1, $path2, $eq, hash(path1), hash(path2));
+
+             let starts_with = path1.starts_with(path2);
+             assert!(starts_with == $starts_with,
+                     "{:?}.starts_with({:?}), expected {:?}, got {:?}", $path1, $path2,
+                     $starts_with, starts_with);
+
+             let ends_with = path1.ends_with(path2);
+             assert!(ends_with == $ends_with,
+                     "{:?}.ends_with({:?}), expected {:?}, got {:?}", $path1, $path2,
+                     $ends_with, ends_with);
+
+             let relative_from = path1.strip_prefix(path2)
+                                      .map(|p| p.to_str().unwrap())
+                                      .ok();
+             let exp: Option<&str> = $relative_from;
+             assert!(relative_from == exp,
+                     "{:?}.strip_prefix({:?}), expected {:?}, got {:?}",
+                     $path1, $path2, exp, relative_from);
+        });
+    );
+
+    tc!("", "",
+    eq: true,
+    starts_with: true,
+    ends_with: true,
+    relative_from: Some("")
+    );
+
+    tc!("foo", "",
+    eq: false,
+    starts_with: true,
+    ends_with: true,
+    relative_from: Some("foo")
+    );
+
+    tc!("", "foo",
+    eq: false,
+    starts_with: false,
+    ends_with: false,
+    relative_from: None
+    );
+
+    tc!("foo", "foo",
+    eq: true,
+    starts_with: true,
+    ends_with: true,
+    relative_from: Some("")
+    );
+
+    tc!("foo/", "foo",
+    eq: true,
+    starts_with: true,
+    ends_with: true,
+    relative_from: Some("")
+    );
+
+    tc!("foo/bar", "foo",
+    eq: false,
+    starts_with: true,
+    ends_with: false,
+    relative_from: Some("bar")
+    );
+
+    tc!("foo/bar/baz", "foo/bar",
+    eq: false,
+    starts_with: true,
+    ends_with: false,
+    relative_from: Some("baz")
+    );
+
+    tc!("foo/bar", "foo/bar/baz",
+    eq: false,
+    starts_with: false,
+    ends_with: false,
+    relative_from: None
+    );
+
+    tc!("./foo/bar/", ".",
+    eq: false,
+    starts_with: true,
+    ends_with: false,
+    relative_from: Some("foo/bar")
+    );
+
+    if cfg!(windows) {
+        tc!(r"C:\src\rust\cargo-test\test\Cargo.toml",
+        r"c:\src\rust\cargo-test\test",
+        eq: false,
+        starts_with: true,
+        ends_with: false,
+        relative_from: Some("Cargo.toml")
+        );
+
+        tc!(r"c:\foo", r"C:\foo",
+        eq: true,
+        starts_with: true,
+        ends_with: true,
+        relative_from: Some("")
+        );
+    }
+}
+
+#[test]
+fn test_components_debug() {
+    let path = Path::new("/tmp");
+
+    let mut components = path.components();
+
+    let expected = "Components([RootDir, Normal(\"tmp\")])";
+    let actual = format!("{:?}", components);
+    assert_eq!(expected, actual);
+
+    let _ = components.next().unwrap();
+    let expected = "Components([Normal(\"tmp\")])";
+    let actual = format!("{:?}", components);
+    assert_eq!(expected, actual);
+
+    let _ = components.next().unwrap();
+    let expected = "Components([])";
+    let actual = format!("{:?}", components);
+    assert_eq!(expected, actual);
+}
+
+#[cfg(unix)]
+#[test]
+fn test_iter_debug() {
+    let path = Path::new("/tmp");
+
+    let mut iter = path.iter();
+
+    let expected = "Iter([\"/\", \"tmp\"])";
+    let actual = format!("{:?}", iter);
+    assert_eq!(expected, actual);
+
+    let _ = iter.next().unwrap();
+    let expected = "Iter([\"tmp\"])";
+    let actual = format!("{:?}", iter);
+    assert_eq!(expected, actual);
+
+    let _ = iter.next().unwrap();
+    let expected = "Iter([])";
+    let actual = format!("{:?}", iter);
+    assert_eq!(expected, actual);
+}
+
+#[test]
+fn into_boxed() {
+    let orig: &str = "some/sort/of/path";
+    let path = Path::new(orig);
+    let boxed: Box<Path> = Box::from(path);
+    let path_buf = path.to_owned().into_boxed_path().into_path_buf();
+    assert_eq!(path, &*boxed);
+    assert_eq!(&*boxed, &*path_buf);
+    assert_eq!(&*path_buf, path);
+}
+
+#[test]
+fn test_clone_into() {
+    let mut path_buf = PathBuf::from("supercalifragilisticexpialidocious");
+    let path = Path::new("short");
+    path.clone_into(&mut path_buf);
+    assert_eq!(path, path_buf);
+    assert!(path_buf.into_os_string().capacity() >= 15);
+}
+
+#[test]
+fn display_format_flags() {
+    assert_eq!(format!("a{:#<5}b", Path::new("").display()), "a#####b");
+    assert_eq!(format!("a{:#<5}b", Path::new("a").display()), "aa####b");
+}
+
+#[test]
+fn into_rc() {
+    let orig = "hello/world";
+    let path = Path::new(orig);
+    let rc: Rc<Path> = Rc::from(path);
+    let arc: Arc<Path> = Arc::from(path);
+
+    assert_eq!(&*rc, path);
+    assert_eq!(&*arc, path);
+
+    let rc2: Rc<Path> = Rc::from(path.to_owned());
+    let arc2: Arc<Path> = Arc::from(path.to_owned());
+
+    assert_eq!(&*rc2, path);
+    assert_eq!(&*arc2, path);
+}
diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs
index 710c616be73..c7a7c779d3c 100644
--- a/library/std/src/prelude/mod.rs
+++ b/library/std/src/prelude/mod.rs
@@ -75,7 +75,7 @@
 //! [`std::result`]: crate::result
 //! [`std::slice`]: crate::slice
 //! [`std::string`]: crate::string
-//! [`std::vec`]: ../vec/index.html
+//! [`std::vec`]: mod@crate::vec
 //! [`to_owned`]: crate::borrow::ToOwned::to_owned
 //! [book-closures]: ../../book/ch13-01-closures.html
 //! [book-dtor]: ../../book/ch15-03-drop.html
diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs
index 2339ca527bd..2a4cb22cc52 100644
--- a/library/std/src/primitive_docs.rs
+++ b/library/std/src/primitive_docs.rs
@@ -1,7 +1,6 @@
 #[doc(primitive = "bool")]
 #[doc(alias = "true")]
 #[doc(alias = "false")]
-//
 /// The boolean type.
 ///
 /// The `bool` represents a value, which could only be either `true` or `false`. If you cast
@@ -12,8 +11,8 @@
 /// `bool` implements various traits, such as [`BitAnd`], [`BitOr`], [`Not`], etc.,
 /// which allow us to perform boolean operations using `&`, `|` and `!`.
 ///
-/// `if` always demands a `bool` value. [`assert!`], being an important macro in testing,
-/// checks whether an expression returns `true`.
+/// `if` always demands a `bool` value. [`assert!`], which is an important macro in testing,
+/// checks whether an expression returns `true` and panics if it isn't.
 ///
 /// ```
 /// let bool_val = true & false | false;
@@ -194,14 +193,48 @@ mod prim_bool {}
 /// # `!` and traits
 ///
 /// When writing your own traits, `!` should have an `impl` whenever there is an obvious `impl`
-/// which doesn't `panic!`. As it turns out, most traits can have an `impl` for `!`. Take [`Debug`]
+/// which doesn't `panic!`. The reason is that functions returning an `impl Trait` where `!`
+/// does not have an `impl` of `Trait` cannot diverge as their only possible code path. In other
+/// words, they can't return `!` from every code path. As an example, this code doesn't compile:
+///
+/// ```compile_fail
+/// use core::ops::Add;
+///
+/// fn foo() -> impl Add<u32> {
+///     unimplemented!()
+/// }
+/// ```
+///
+/// But this code does:
+///
+/// ```
+/// use core::ops::Add;
+///
+/// fn foo() -> impl Add<u32> {
+///     if true {
+///         unimplemented!()
+///     } else {
+///         0
+///     }
+/// }
+/// ```
+///
+/// The reason is that, in the first example, there are many possible types that `!` could coerce
+/// to, because many types implement `Add<u32>`. However, in the second example,
+/// the `else` branch returns a `0`, which the compiler infers from the return type to be of type
+/// `u32`. Since `u32` is a concrete type, `!` can and will be coerced to it. See issue [#36375]
+/// for more information on this quirk of `!`.
+///
+/// [#36375]: https://github.com/rust-lang/rust/issues/36375
+///
+/// As it turns out, though, most traits can have an `impl` for `!`. Take [`Debug`]
 /// for example:
 ///
 /// ```
 /// #![feature(never_type)]
 /// # use std::fmt;
 /// # trait Debug {
-/// # fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result;
+/// #     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result;
 /// # }
 /// impl Debug for ! {
 ///     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -477,7 +510,7 @@ mod prim_pointer {}
 /// an array. Indeed, this provides most of the API for working with arrays.
 /// Slices have a dynamic size and do not coerce to arrays.
 ///
-/// You can move elements out of an array with a slice pattern. If you want
+/// You can move elements out of an array with a [slice pattern]. If you want
 /// one element, see [`mem::replace`].
 ///
 /// # Examples
@@ -519,7 +552,7 @@ mod prim_pointer {}
 /// for x in &array { }
 /// ```
 ///
-/// You can use a slice pattern to move elements out of an array:
+/// You can use a [slice pattern] to move elements out of an array:
 ///
 /// ```
 /// fn move_away(_: String) { /* Do interesting things. */ }
@@ -534,7 +567,7 @@ mod prim_pointer {}
 /// [`Hash`]: hash::Hash
 /// [`Borrow`]: borrow::Borrow
 /// [`BorrowMut`]: borrow::BorrowMut
-///
+/// [slice pattern]: ../reference/patterns.html#slice-patterns
 #[stable(feature = "rust1", since = "1.0.0")]
 mod prim_array {}
 
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index c42bc109652..d1960a049d9 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -96,6 +96,9 @@
 
 #![stable(feature = "process", since = "1.0.0")]
 
+#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))]
+mod tests;
+
 use crate::io::prelude::*;
 
 use crate::ffi::OsStr;
@@ -1702,411 +1705,3 @@ impl Termination for ExitCode {
         self.0.as_i32()
     }
 }
-
-#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))]
-mod tests {
-    use crate::io::prelude::*;
-
-    use super::{Command, Output, Stdio};
-    use crate::io::ErrorKind;
-    use crate::str;
-
-    // FIXME(#10380) these tests should not all be ignored on android.
-
-    #[test]
-    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
-    fn smoke() {
-        let p = if cfg!(target_os = "windows") {
-            Command::new("cmd").args(&["/C", "exit 0"]).spawn()
-        } else {
-            Command::new("true").spawn()
-        };
-        assert!(p.is_ok());
-        let mut p = p.unwrap();
-        assert!(p.wait().unwrap().success());
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "android", ignore)]
-    fn smoke_failure() {
-        match Command::new("if-this-is-a-binary-then-the-world-has-ended").spawn() {
-            Ok(..) => panic!(),
-            Err(..) => {}
-        }
-    }
-
-    #[test]
-    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
-    fn exit_reported_right() {
-        let p = if cfg!(target_os = "windows") {
-            Command::new("cmd").args(&["/C", "exit 1"]).spawn()
-        } else {
-            Command::new("false").spawn()
-        };
-        assert!(p.is_ok());
-        let mut p = p.unwrap();
-        assert!(p.wait().unwrap().code() == Some(1));
-        drop(p.wait());
-    }
-
-    #[test]
-    #[cfg(unix)]
-    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
-    fn signal_reported_right() {
-        use crate::os::unix::process::ExitStatusExt;
-
-        let mut p =
-            Command::new("/bin/sh").arg("-c").arg("read a").stdin(Stdio::piped()).spawn().unwrap();
-        p.kill().unwrap();
-        match p.wait().unwrap().signal() {
-            Some(9) => {}
-            result => panic!("not terminated by signal 9 (instead, {:?})", result),
-        }
-    }
-
-    pub fn run_output(mut cmd: Command) -> String {
-        let p = cmd.spawn();
-        assert!(p.is_ok());
-        let mut p = p.unwrap();
-        assert!(p.stdout.is_some());
-        let mut ret = String::new();
-        p.stdout.as_mut().unwrap().read_to_string(&mut ret).unwrap();
-        assert!(p.wait().unwrap().success());
-        return ret;
-    }
-
-    #[test]
-    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
-    fn stdout_works() {
-        if cfg!(target_os = "windows") {
-            let mut cmd = Command::new("cmd");
-            cmd.args(&["/C", "echo foobar"]).stdout(Stdio::piped());
-            assert_eq!(run_output(cmd), "foobar\r\n");
-        } else {
-            let mut cmd = Command::new("echo");
-            cmd.arg("foobar").stdout(Stdio::piped());
-            assert_eq!(run_output(cmd), "foobar\n");
-        }
-    }
-
-    #[test]
-    #[cfg_attr(any(windows, target_os = "android", target_os = "vxworks"), ignore)]
-    fn set_current_dir_works() {
-        let mut cmd = Command::new("/bin/sh");
-        cmd.arg("-c").arg("pwd").current_dir("/").stdout(Stdio::piped());
-        assert_eq!(run_output(cmd), "/\n");
-    }
-
-    #[test]
-    #[cfg_attr(any(windows, target_os = "android", target_os = "vxworks"), ignore)]
-    fn stdin_works() {
-        let mut p = Command::new("/bin/sh")
-            .arg("-c")
-            .arg("read line; echo $line")
-            .stdin(Stdio::piped())
-            .stdout(Stdio::piped())
-            .spawn()
-            .unwrap();
-        p.stdin.as_mut().unwrap().write("foobar".as_bytes()).unwrap();
-        drop(p.stdin.take());
-        let mut out = String::new();
-        p.stdout.as_mut().unwrap().read_to_string(&mut out).unwrap();
-        assert!(p.wait().unwrap().success());
-        assert_eq!(out, "foobar\n");
-    }
-
-    #[test]
-    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
-    fn test_process_status() {
-        let mut status = if cfg!(target_os = "windows") {
-            Command::new("cmd").args(&["/C", "exit 1"]).status().unwrap()
-        } else {
-            Command::new("false").status().unwrap()
-        };
-        assert!(status.code() == Some(1));
-
-        status = if cfg!(target_os = "windows") {
-            Command::new("cmd").args(&["/C", "exit 0"]).status().unwrap()
-        } else {
-            Command::new("true").status().unwrap()
-        };
-        assert!(status.success());
-    }
-
-    #[test]
-    fn test_process_output_fail_to_start() {
-        match Command::new("/no-binary-by-this-name-should-exist").output() {
-            Err(e) => assert_eq!(e.kind(), ErrorKind::NotFound),
-            Ok(..) => panic!(),
-        }
-    }
-
-    #[test]
-    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
-    fn test_process_output_output() {
-        let Output { status, stdout, stderr } = if cfg!(target_os = "windows") {
-            Command::new("cmd").args(&["/C", "echo hello"]).output().unwrap()
-        } else {
-            Command::new("echo").arg("hello").output().unwrap()
-        };
-        let output_str = str::from_utf8(&stdout).unwrap();
-
-        assert!(status.success());
-        assert_eq!(output_str.trim().to_string(), "hello");
-        assert_eq!(stderr, Vec::new());
-    }
-
-    #[test]
-    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
-    fn test_process_output_error() {
-        let Output { status, stdout, stderr } = if cfg!(target_os = "windows") {
-            Command::new("cmd").args(&["/C", "mkdir ."]).output().unwrap()
-        } else {
-            Command::new("mkdir").arg("./").output().unwrap()
-        };
-
-        assert!(status.code() == Some(1));
-        assert_eq!(stdout, Vec::new());
-        assert!(!stderr.is_empty());
-    }
-
-    #[test]
-    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
-    fn test_finish_once() {
-        let mut prog = if cfg!(target_os = "windows") {
-            Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
-        } else {
-            Command::new("false").spawn().unwrap()
-        };
-        assert!(prog.wait().unwrap().code() == Some(1));
-    }
-
-    #[test]
-    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
-    fn test_finish_twice() {
-        let mut prog = if cfg!(target_os = "windows") {
-            Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
-        } else {
-            Command::new("false").spawn().unwrap()
-        };
-        assert!(prog.wait().unwrap().code() == Some(1));
-        assert!(prog.wait().unwrap().code() == Some(1));
-    }
-
-    #[test]
-    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
-    fn test_wait_with_output_once() {
-        let prog = if cfg!(target_os = "windows") {
-            Command::new("cmd").args(&["/C", "echo hello"]).stdout(Stdio::piped()).spawn().unwrap()
-        } else {
-            Command::new("echo").arg("hello").stdout(Stdio::piped()).spawn().unwrap()
-        };
-
-        let Output { status, stdout, stderr } = prog.wait_with_output().unwrap();
-        let output_str = str::from_utf8(&stdout).unwrap();
-
-        assert!(status.success());
-        assert_eq!(output_str.trim().to_string(), "hello");
-        assert_eq!(stderr, Vec::new());
-    }
-
-    #[cfg(all(unix, not(target_os = "android")))]
-    pub fn env_cmd() -> Command {
-        Command::new("env")
-    }
-    #[cfg(target_os = "android")]
-    pub fn env_cmd() -> Command {
-        let mut cmd = Command::new("/system/bin/sh");
-        cmd.arg("-c").arg("set");
-        cmd
-    }
-
-    #[cfg(windows)]
-    pub fn env_cmd() -> Command {
-        let mut cmd = Command::new("cmd");
-        cmd.arg("/c").arg("set");
-        cmd
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "vxworks", ignore)]
-    fn test_override_env() {
-        use crate::env;
-
-        // In some build environments (such as chrooted Nix builds), `env` can
-        // only be found in the explicitly-provided PATH env variable, not in
-        // default places such as /bin or /usr/bin. So we need to pass through
-        // PATH to our sub-process.
-        let mut cmd = env_cmd();
-        cmd.env_clear().env("RUN_TEST_NEW_ENV", "123");
-        if let Some(p) = env::var_os("PATH") {
-            cmd.env("PATH", &p);
-        }
-        let result = cmd.output().unwrap();
-        let output = String::from_utf8_lossy(&result.stdout).to_string();
-
-        assert!(
-            output.contains("RUN_TEST_NEW_ENV=123"),
-            "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}",
-            output
-        );
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "vxworks", ignore)]
-    fn test_add_to_env() {
-        let result = env_cmd().env("RUN_TEST_NEW_ENV", "123").output().unwrap();
-        let output = String::from_utf8_lossy(&result.stdout).to_string();
-
-        assert!(
-            output.contains("RUN_TEST_NEW_ENV=123"),
-            "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}",
-            output
-        );
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "vxworks", ignore)]
-    fn test_capture_env_at_spawn() {
-        use crate::env;
-
-        let mut cmd = env_cmd();
-        cmd.env("RUN_TEST_NEW_ENV1", "123");
-
-        // This variable will not be present if the environment has already
-        // been captured above.
-        env::set_var("RUN_TEST_NEW_ENV2", "456");
-        let result = cmd.output().unwrap();
-        env::remove_var("RUN_TEST_NEW_ENV2");
-
-        let output = String::from_utf8_lossy(&result.stdout).to_string();
-
-        assert!(
-            output.contains("RUN_TEST_NEW_ENV1=123"),
-            "didn't find RUN_TEST_NEW_ENV1 inside of:\n\n{}",
-            output
-        );
-        assert!(
-            output.contains("RUN_TEST_NEW_ENV2=456"),
-            "didn't find RUN_TEST_NEW_ENV2 inside of:\n\n{}",
-            output
-        );
-    }
-
-    // Regression tests for #30858.
-    #[test]
-    fn test_interior_nul_in_progname_is_error() {
-        match Command::new("has-some-\0\0s-inside").spawn() {
-            Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
-            Ok(_) => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_interior_nul_in_arg_is_error() {
-        match Command::new("echo").arg("has-some-\0\0s-inside").spawn() {
-            Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
-            Ok(_) => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_interior_nul_in_args_is_error() {
-        match Command::new("echo").args(&["has-some-\0\0s-inside"]).spawn() {
-            Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
-            Ok(_) => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_interior_nul_in_current_dir_is_error() {
-        match Command::new("echo").current_dir("has-some-\0\0s-inside").spawn() {
-            Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
-            Ok(_) => panic!(),
-        }
-    }
-
-    // Regression tests for #30862.
-    #[test]
-    #[cfg_attr(target_os = "vxworks", ignore)]
-    fn test_interior_nul_in_env_key_is_error() {
-        match env_cmd().env("has-some-\0\0s-inside", "value").spawn() {
-            Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
-            Ok(_) => panic!(),
-        }
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "vxworks", ignore)]
-    fn test_interior_nul_in_env_value_is_error() {
-        match env_cmd().env("key", "has-some-\0\0s-inside").spawn() {
-            Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
-            Ok(_) => panic!(),
-        }
-    }
-
-    /// Tests that process creation flags work by debugging a process.
-    /// Other creation flags make it hard or impossible to detect
-    /// behavioral changes in the process.
-    #[test]
-    #[cfg(windows)]
-    fn test_creation_flags() {
-        use crate::os::windows::process::CommandExt;
-        use crate::sys::c::{BOOL, DWORD, INFINITE};
-        #[repr(C, packed)]
-        struct DEBUG_EVENT {
-            pub event_code: DWORD,
-            pub process_id: DWORD,
-            pub thread_id: DWORD,
-            // This is a union in the real struct, but we don't
-            // need this data for the purposes of this test.
-            pub _junk: [u8; 164],
-        }
-
-        extern "system" {
-            fn WaitForDebugEvent(lpDebugEvent: *mut DEBUG_EVENT, dwMilliseconds: DWORD) -> BOOL;
-            fn ContinueDebugEvent(
-                dwProcessId: DWORD,
-                dwThreadId: DWORD,
-                dwContinueStatus: DWORD,
-            ) -> BOOL;
-        }
-
-        const DEBUG_PROCESS: DWORD = 1;
-        const EXIT_PROCESS_DEBUG_EVENT: DWORD = 5;
-        const DBG_EXCEPTION_NOT_HANDLED: DWORD = 0x80010001;
-
-        let mut child = Command::new("cmd")
-            .creation_flags(DEBUG_PROCESS)
-            .stdin(Stdio::piped())
-            .spawn()
-            .unwrap();
-        child.stdin.take().unwrap().write_all(b"exit\r\n").unwrap();
-        let mut events = 0;
-        let mut event = DEBUG_EVENT { event_code: 0, process_id: 0, thread_id: 0, _junk: [0; 164] };
-        loop {
-            if unsafe { WaitForDebugEvent(&mut event as *mut DEBUG_EVENT, INFINITE) } == 0 {
-                panic!("WaitForDebugEvent failed!");
-            }
-            events += 1;
-
-            if event.event_code == EXIT_PROCESS_DEBUG_EVENT {
-                break;
-            }
-
-            if unsafe {
-                ContinueDebugEvent(event.process_id, event.thread_id, DBG_EXCEPTION_NOT_HANDLED)
-            } == 0
-            {
-                panic!("ContinueDebugEvent failed!");
-            }
-        }
-        assert!(events > 0);
-    }
-
-    #[test]
-    fn test_command_implements_send_sync() {
-        fn take_send_sync_type<T: Send + Sync>(_: T) {}
-        take_send_sync_type(Command::new(""))
-    }
-}
diff --git a/library/std/src/process/tests.rs b/library/std/src/process/tests.rs
new file mode 100644
index 00000000000..05e093434be
--- /dev/null
+++ b/library/std/src/process/tests.rs
@@ -0,0 +1,401 @@
+use crate::io::prelude::*;
+
+use super::{Command, Output, Stdio};
+use crate::io::ErrorKind;
+use crate::str;
+
+// FIXME(#10380) these tests should not all be ignored on android.
+
+#[test]
+#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
+fn smoke() {
+    let p = if cfg!(target_os = "windows") {
+        Command::new("cmd").args(&["/C", "exit 0"]).spawn()
+    } else {
+        Command::new("true").spawn()
+    };
+    assert!(p.is_ok());
+    let mut p = p.unwrap();
+    assert!(p.wait().unwrap().success());
+}
+
+#[test]
+#[cfg_attr(target_os = "android", ignore)]
+fn smoke_failure() {
+    match Command::new("if-this-is-a-binary-then-the-world-has-ended").spawn() {
+        Ok(..) => panic!(),
+        Err(..) => {}
+    }
+}
+
+#[test]
+#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
+fn exit_reported_right() {
+    let p = if cfg!(target_os = "windows") {
+        Command::new("cmd").args(&["/C", "exit 1"]).spawn()
+    } else {
+        Command::new("false").spawn()
+    };
+    assert!(p.is_ok());
+    let mut p = p.unwrap();
+    assert!(p.wait().unwrap().code() == Some(1));
+    drop(p.wait());
+}
+
+#[test]
+#[cfg(unix)]
+#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
+fn signal_reported_right() {
+    use crate::os::unix::process::ExitStatusExt;
+
+    let mut p =
+        Command::new("/bin/sh").arg("-c").arg("read a").stdin(Stdio::piped()).spawn().unwrap();
+    p.kill().unwrap();
+    match p.wait().unwrap().signal() {
+        Some(9) => {}
+        result => panic!("not terminated by signal 9 (instead, {:?})", result),
+    }
+}
+
+pub fn run_output(mut cmd: Command) -> String {
+    let p = cmd.spawn();
+    assert!(p.is_ok());
+    let mut p = p.unwrap();
+    assert!(p.stdout.is_some());
+    let mut ret = String::new();
+    p.stdout.as_mut().unwrap().read_to_string(&mut ret).unwrap();
+    assert!(p.wait().unwrap().success());
+    return ret;
+}
+
+#[test]
+#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
+fn stdout_works() {
+    if cfg!(target_os = "windows") {
+        let mut cmd = Command::new("cmd");
+        cmd.args(&["/C", "echo foobar"]).stdout(Stdio::piped());
+        assert_eq!(run_output(cmd), "foobar\r\n");
+    } else {
+        let mut cmd = Command::new("echo");
+        cmd.arg("foobar").stdout(Stdio::piped());
+        assert_eq!(run_output(cmd), "foobar\n");
+    }
+}
+
+#[test]
+#[cfg_attr(any(windows, target_os = "android", target_os = "vxworks"), ignore)]
+fn set_current_dir_works() {
+    let mut cmd = Command::new("/bin/sh");
+    cmd.arg("-c").arg("pwd").current_dir("/").stdout(Stdio::piped());
+    assert_eq!(run_output(cmd), "/\n");
+}
+
+#[test]
+#[cfg_attr(any(windows, target_os = "android", target_os = "vxworks"), ignore)]
+fn stdin_works() {
+    let mut p = Command::new("/bin/sh")
+        .arg("-c")
+        .arg("read line; echo $line")
+        .stdin(Stdio::piped())
+        .stdout(Stdio::piped())
+        .spawn()
+        .unwrap();
+    p.stdin.as_mut().unwrap().write("foobar".as_bytes()).unwrap();
+    drop(p.stdin.take());
+    let mut out = String::new();
+    p.stdout.as_mut().unwrap().read_to_string(&mut out).unwrap();
+    assert!(p.wait().unwrap().success());
+    assert_eq!(out, "foobar\n");
+}
+
+#[test]
+#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
+fn test_process_status() {
+    let mut status = if cfg!(target_os = "windows") {
+        Command::new("cmd").args(&["/C", "exit 1"]).status().unwrap()
+    } else {
+        Command::new("false").status().unwrap()
+    };
+    assert!(status.code() == Some(1));
+
+    status = if cfg!(target_os = "windows") {
+        Command::new("cmd").args(&["/C", "exit 0"]).status().unwrap()
+    } else {
+        Command::new("true").status().unwrap()
+    };
+    assert!(status.success());
+}
+
+#[test]
+fn test_process_output_fail_to_start() {
+    match Command::new("/no-binary-by-this-name-should-exist").output() {
+        Err(e) => assert_eq!(e.kind(), ErrorKind::NotFound),
+        Ok(..) => panic!(),
+    }
+}
+
+#[test]
+#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
+fn test_process_output_output() {
+    let Output { status, stdout, stderr } = if cfg!(target_os = "windows") {
+        Command::new("cmd").args(&["/C", "echo hello"]).output().unwrap()
+    } else {
+        Command::new("echo").arg("hello").output().unwrap()
+    };
+    let output_str = str::from_utf8(&stdout).unwrap();
+
+    assert!(status.success());
+    assert_eq!(output_str.trim().to_string(), "hello");
+    assert_eq!(stderr, Vec::new());
+}
+
+#[test]
+#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
+fn test_process_output_error() {
+    let Output { status, stdout, stderr } = if cfg!(target_os = "windows") {
+        Command::new("cmd").args(&["/C", "mkdir ."]).output().unwrap()
+    } else {
+        Command::new("mkdir").arg("./").output().unwrap()
+    };
+
+    assert!(status.code() == Some(1));
+    assert_eq!(stdout, Vec::new());
+    assert!(!stderr.is_empty());
+}
+
+#[test]
+#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
+fn test_finish_once() {
+    let mut prog = if cfg!(target_os = "windows") {
+        Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
+    } else {
+        Command::new("false").spawn().unwrap()
+    };
+    assert!(prog.wait().unwrap().code() == Some(1));
+}
+
+#[test]
+#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
+fn test_finish_twice() {
+    let mut prog = if cfg!(target_os = "windows") {
+        Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
+    } else {
+        Command::new("false").spawn().unwrap()
+    };
+    assert!(prog.wait().unwrap().code() == Some(1));
+    assert!(prog.wait().unwrap().code() == Some(1));
+}
+
+#[test]
+#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
+fn test_wait_with_output_once() {
+    let prog = if cfg!(target_os = "windows") {
+        Command::new("cmd").args(&["/C", "echo hello"]).stdout(Stdio::piped()).spawn().unwrap()
+    } else {
+        Command::new("echo").arg("hello").stdout(Stdio::piped()).spawn().unwrap()
+    };
+
+    let Output { status, stdout, stderr } = prog.wait_with_output().unwrap();
+    let output_str = str::from_utf8(&stdout).unwrap();
+
+    assert!(status.success());
+    assert_eq!(output_str.trim().to_string(), "hello");
+    assert_eq!(stderr, Vec::new());
+}
+
+#[cfg(all(unix, not(target_os = "android")))]
+pub fn env_cmd() -> Command {
+    Command::new("env")
+}
+#[cfg(target_os = "android")]
+pub fn env_cmd() -> Command {
+    let mut cmd = Command::new("/system/bin/sh");
+    cmd.arg("-c").arg("set");
+    cmd
+}
+
+#[cfg(windows)]
+pub fn env_cmd() -> Command {
+    let mut cmd = Command::new("cmd");
+    cmd.arg("/c").arg("set");
+    cmd
+}
+
+#[test]
+#[cfg_attr(target_os = "vxworks", ignore)]
+fn test_override_env() {
+    use crate::env;
+
+    // In some build environments (such as chrooted Nix builds), `env` can
+    // only be found in the explicitly-provided PATH env variable, not in
+    // default places such as /bin or /usr/bin. So we need to pass through
+    // PATH to our sub-process.
+    let mut cmd = env_cmd();
+    cmd.env_clear().env("RUN_TEST_NEW_ENV", "123");
+    if let Some(p) = env::var_os("PATH") {
+        cmd.env("PATH", &p);
+    }
+    let result = cmd.output().unwrap();
+    let output = String::from_utf8_lossy(&result.stdout).to_string();
+
+    assert!(
+        output.contains("RUN_TEST_NEW_ENV=123"),
+        "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}",
+        output
+    );
+}
+
+#[test]
+#[cfg_attr(target_os = "vxworks", ignore)]
+fn test_add_to_env() {
+    let result = env_cmd().env("RUN_TEST_NEW_ENV", "123").output().unwrap();
+    let output = String::from_utf8_lossy(&result.stdout).to_string();
+
+    assert!(
+        output.contains("RUN_TEST_NEW_ENV=123"),
+        "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}",
+        output
+    );
+}
+
+#[test]
+#[cfg_attr(target_os = "vxworks", ignore)]
+fn test_capture_env_at_spawn() {
+    use crate::env;
+
+    let mut cmd = env_cmd();
+    cmd.env("RUN_TEST_NEW_ENV1", "123");
+
+    // This variable will not be present if the environment has already
+    // been captured above.
+    env::set_var("RUN_TEST_NEW_ENV2", "456");
+    let result = cmd.output().unwrap();
+    env::remove_var("RUN_TEST_NEW_ENV2");
+
+    let output = String::from_utf8_lossy(&result.stdout).to_string();
+
+    assert!(
+        output.contains("RUN_TEST_NEW_ENV1=123"),
+        "didn't find RUN_TEST_NEW_ENV1 inside of:\n\n{}",
+        output
+    );
+    assert!(
+        output.contains("RUN_TEST_NEW_ENV2=456"),
+        "didn't find RUN_TEST_NEW_ENV2 inside of:\n\n{}",
+        output
+    );
+}
+
+// Regression tests for #30858.
+#[test]
+fn test_interior_nul_in_progname_is_error() {
+    match Command::new("has-some-\0\0s-inside").spawn() {
+        Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
+        Ok(_) => panic!(),
+    }
+}
+
+#[test]
+fn test_interior_nul_in_arg_is_error() {
+    match Command::new("echo").arg("has-some-\0\0s-inside").spawn() {
+        Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
+        Ok(_) => panic!(),
+    }
+}
+
+#[test]
+fn test_interior_nul_in_args_is_error() {
+    match Command::new("echo").args(&["has-some-\0\0s-inside"]).spawn() {
+        Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
+        Ok(_) => panic!(),
+    }
+}
+
+#[test]
+fn test_interior_nul_in_current_dir_is_error() {
+    match Command::new("echo").current_dir("has-some-\0\0s-inside").spawn() {
+        Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
+        Ok(_) => panic!(),
+    }
+}
+
+// Regression tests for #30862.
+#[test]
+#[cfg_attr(target_os = "vxworks", ignore)]
+fn test_interior_nul_in_env_key_is_error() {
+    match env_cmd().env("has-some-\0\0s-inside", "value").spawn() {
+        Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
+        Ok(_) => panic!(),
+    }
+}
+
+#[test]
+#[cfg_attr(target_os = "vxworks", ignore)]
+fn test_interior_nul_in_env_value_is_error() {
+    match env_cmd().env("key", "has-some-\0\0s-inside").spawn() {
+        Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
+        Ok(_) => panic!(),
+    }
+}
+
+/// Tests that process creation flags work by debugging a process.
+/// Other creation flags make it hard or impossible to detect
+/// behavioral changes in the process.
+#[test]
+#[cfg(windows)]
+fn test_creation_flags() {
+    use crate::os::windows::process::CommandExt;
+    use crate::sys::c::{BOOL, DWORD, INFINITE};
+    #[repr(C, packed)]
+    struct DEBUG_EVENT {
+        pub event_code: DWORD,
+        pub process_id: DWORD,
+        pub thread_id: DWORD,
+        // This is a union in the real struct, but we don't
+        // need this data for the purposes of this test.
+        pub _junk: [u8; 164],
+    }
+
+    extern "system" {
+        fn WaitForDebugEvent(lpDebugEvent: *mut DEBUG_EVENT, dwMilliseconds: DWORD) -> BOOL;
+        fn ContinueDebugEvent(
+            dwProcessId: DWORD,
+            dwThreadId: DWORD,
+            dwContinueStatus: DWORD,
+        ) -> BOOL;
+    }
+
+    const DEBUG_PROCESS: DWORD = 1;
+    const EXIT_PROCESS_DEBUG_EVENT: DWORD = 5;
+    const DBG_EXCEPTION_NOT_HANDLED: DWORD = 0x80010001;
+
+    let mut child =
+        Command::new("cmd").creation_flags(DEBUG_PROCESS).stdin(Stdio::piped()).spawn().unwrap();
+    child.stdin.take().unwrap().write_all(b"exit\r\n").unwrap();
+    let mut events = 0;
+    let mut event = DEBUG_EVENT { event_code: 0, process_id: 0, thread_id: 0, _junk: [0; 164] };
+    loop {
+        if unsafe { WaitForDebugEvent(&mut event as *mut DEBUG_EVENT, INFINITE) } == 0 {
+            panic!("WaitForDebugEvent failed!");
+        }
+        events += 1;
+
+        if event.event_code == EXIT_PROCESS_DEBUG_EVENT {
+            break;
+        }
+
+        if unsafe {
+            ContinueDebugEvent(event.process_id, event.thread_id, DBG_EXCEPTION_NOT_HANDLED)
+        } == 0
+        {
+            panic!("ContinueDebugEvent failed!");
+        }
+    }
+    assert!(events > 0);
+}
+
+#[test]
+fn test_command_implements_send_sync() {
+    fn take_send_sync_type<T: Send + Sync>(_: T) {}
+    take_send_sync_type(Command::new(""))
+}
diff --git a/library/std/src/sync/barrier.rs b/library/std/src/sync/barrier.rs
index 23c989fd2fd..5d434791e9a 100644
--- a/library/std/src/sync/barrier.rs
+++ b/library/std/src/sync/barrier.rs
@@ -1,3 +1,6 @@
+#[cfg(test)]
+mod tests;
+
 use crate::fmt;
 use crate::sync::{Condvar, Mutex};
 
@@ -174,42 +177,3 @@ impl BarrierWaitResult {
         self.0
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use crate::sync::mpsc::{channel, TryRecvError};
-    use crate::sync::{Arc, Barrier};
-    use crate::thread;
-
-    #[test]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    fn test_barrier() {
-        const N: usize = 10;
-
-        let barrier = Arc::new(Barrier::new(N));
-        let (tx, rx) = channel();
-
-        for _ in 0..N - 1 {
-            let c = barrier.clone();
-            let tx = tx.clone();
-            thread::spawn(move || {
-                tx.send(c.wait().is_leader()).unwrap();
-            });
-        }
-
-        // At this point, all spawned threads should be blocked,
-        // so we shouldn't get anything from the port
-        assert!(matches!(rx.try_recv(), Err(TryRecvError::Empty)));
-
-        let mut leader_found = barrier.wait().is_leader();
-
-        // Now, the barrier is cleared and we should get data.
-        for _ in 0..N - 1 {
-            if rx.recv().unwrap() {
-                assert!(!leader_found);
-                leader_found = true;
-            }
-        }
-        assert!(leader_found);
-    }
-}
diff --git a/library/std/src/sync/barrier/tests.rs b/library/std/src/sync/barrier/tests.rs
new file mode 100644
index 00000000000..834a3e75158
--- /dev/null
+++ b/library/std/src/sync/barrier/tests.rs
@@ -0,0 +1,35 @@
+use crate::sync::mpsc::{channel, TryRecvError};
+use crate::sync::{Arc, Barrier};
+use crate::thread;
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn test_barrier() {
+    const N: usize = 10;
+
+    let barrier = Arc::new(Barrier::new(N));
+    let (tx, rx) = channel();
+
+    for _ in 0..N - 1 {
+        let c = barrier.clone();
+        let tx = tx.clone();
+        thread::spawn(move || {
+            tx.send(c.wait().is_leader()).unwrap();
+        });
+    }
+
+    // At this point, all spawned threads should be blocked,
+    // so we shouldn't get anything from the port
+    assert!(matches!(rx.try_recv(), Err(TryRecvError::Empty)));
+
+    let mut leader_found = barrier.wait().is_leader();
+
+    // Now, the barrier is cleared and we should get data.
+    for _ in 0..N - 1 {
+        if rx.recv().unwrap() {
+            assert!(!leader_found);
+            leader_found = true;
+        }
+    }
+    assert!(leader_found);
+}
diff --git a/library/std/src/sync/condvar.rs b/library/std/src/sync/condvar.rs
index 4efd86aa3ed..651f813b3e2 100644
--- a/library/std/src/sync/condvar.rs
+++ b/library/std/src/sync/condvar.rs
@@ -1,3 +1,6 @@
+#[cfg(test)]
+mod tests;
+
 use crate::fmt;
 use crate::sync::atomic::{AtomicUsize, Ordering};
 use crate::sync::{mutex, MutexGuard, PoisonError};
@@ -598,218 +601,3 @@ impl Drop for Condvar {
         unsafe { self.inner.destroy() }
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use crate::sync::atomic::{AtomicBool, Ordering};
-    use crate::sync::mpsc::channel;
-    use crate::sync::{Arc, Condvar, Mutex};
-    use crate::thread;
-    use crate::time::Duration;
-
-    #[test]
-    fn smoke() {
-        let c = Condvar::new();
-        c.notify_one();
-        c.notify_all();
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    fn notify_one() {
-        let m = Arc::new(Mutex::new(()));
-        let m2 = m.clone();
-        let c = Arc::new(Condvar::new());
-        let c2 = c.clone();
-
-        let g = m.lock().unwrap();
-        let _t = thread::spawn(move || {
-            let _g = m2.lock().unwrap();
-            c2.notify_one();
-        });
-        let g = c.wait(g).unwrap();
-        drop(g);
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    fn notify_all() {
-        const N: usize = 10;
-
-        let data = Arc::new((Mutex::new(0), Condvar::new()));
-        let (tx, rx) = channel();
-        for _ in 0..N {
-            let data = data.clone();
-            let tx = tx.clone();
-            thread::spawn(move || {
-                let &(ref lock, ref cond) = &*data;
-                let mut cnt = lock.lock().unwrap();
-                *cnt += 1;
-                if *cnt == N {
-                    tx.send(()).unwrap();
-                }
-                while *cnt != 0 {
-                    cnt = cond.wait(cnt).unwrap();
-                }
-                tx.send(()).unwrap();
-            });
-        }
-        drop(tx);
-
-        let &(ref lock, ref cond) = &*data;
-        rx.recv().unwrap();
-        let mut cnt = lock.lock().unwrap();
-        *cnt = 0;
-        cond.notify_all();
-        drop(cnt);
-
-        for _ in 0..N {
-            rx.recv().unwrap();
-        }
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    fn wait_while() {
-        let pair = Arc::new((Mutex::new(false), Condvar::new()));
-        let pair2 = pair.clone();
-
-        // Inside of our lock, spawn a new thread, and then wait for it to start.
-        thread::spawn(move || {
-            let &(ref lock, ref cvar) = &*pair2;
-            let mut started = lock.lock().unwrap();
-            *started = true;
-            // We notify the condvar that the value has changed.
-            cvar.notify_one();
-        });
-
-        // Wait for the thread to start up.
-        let &(ref lock, ref cvar) = &*pair;
-        let guard = cvar.wait_while(lock.lock().unwrap(), |started| !*started);
-        assert!(*guard.unwrap());
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    fn wait_timeout_wait() {
-        let m = Arc::new(Mutex::new(()));
-        let c = Arc::new(Condvar::new());
-
-        loop {
-            let g = m.lock().unwrap();
-            let (_g, no_timeout) = c.wait_timeout(g, Duration::from_millis(1)).unwrap();
-            // spurious wakeups mean this isn't necessarily true
-            // so execute test again, if not timeout
-            if !no_timeout.timed_out() {
-                continue;
-            }
-
-            break;
-        }
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    fn wait_timeout_while_wait() {
-        let m = Arc::new(Mutex::new(()));
-        let c = Arc::new(Condvar::new());
-
-        let g = m.lock().unwrap();
-        let (_g, wait) = c.wait_timeout_while(g, Duration::from_millis(1), |_| true).unwrap();
-        // no spurious wakeups. ensure it timed-out
-        assert!(wait.timed_out());
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    fn wait_timeout_while_instant_satisfy() {
-        let m = Arc::new(Mutex::new(()));
-        let c = Arc::new(Condvar::new());
-
-        let g = m.lock().unwrap();
-        let (_g, wait) = c.wait_timeout_while(g, Duration::from_millis(0), |_| false).unwrap();
-        // ensure it didn't time-out even if we were not given any time.
-        assert!(!wait.timed_out());
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    fn wait_timeout_while_wake() {
-        let pair = Arc::new((Mutex::new(false), Condvar::new()));
-        let pair_copy = pair.clone();
-
-        let &(ref m, ref c) = &*pair;
-        let g = m.lock().unwrap();
-        let _t = thread::spawn(move || {
-            let &(ref lock, ref cvar) = &*pair_copy;
-            let mut started = lock.lock().unwrap();
-            thread::sleep(Duration::from_millis(1));
-            *started = true;
-            cvar.notify_one();
-        });
-        let (g2, wait) = c
-            .wait_timeout_while(g, Duration::from_millis(u64::MAX), |&mut notified| !notified)
-            .unwrap();
-        // ensure it didn't time-out even if we were not given any time.
-        assert!(!wait.timed_out());
-        assert!(*g2);
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    fn wait_timeout_wake() {
-        let m = Arc::new(Mutex::new(()));
-        let c = Arc::new(Condvar::new());
-
-        loop {
-            let g = m.lock().unwrap();
-
-            let c2 = c.clone();
-            let m2 = m.clone();
-
-            let notified = Arc::new(AtomicBool::new(false));
-            let notified_copy = notified.clone();
-
-            let t = thread::spawn(move || {
-                let _g = m2.lock().unwrap();
-                thread::sleep(Duration::from_millis(1));
-                notified_copy.store(true, Ordering::SeqCst);
-                c2.notify_one();
-            });
-            let (g, timeout_res) = c.wait_timeout(g, Duration::from_millis(u64::MAX)).unwrap();
-            assert!(!timeout_res.timed_out());
-            // spurious wakeups mean this isn't necessarily true
-            // so execute test again, if not notified
-            if !notified.load(Ordering::SeqCst) {
-                t.join().unwrap();
-                continue;
-            }
-            drop(g);
-
-            t.join().unwrap();
-
-            break;
-        }
-    }
-
-    #[test]
-    #[should_panic]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    fn two_mutexes() {
-        let m = Arc::new(Mutex::new(()));
-        let m2 = m.clone();
-        let c = Arc::new(Condvar::new());
-        let c2 = c.clone();
-
-        let mut g = m.lock().unwrap();
-        let _t = thread::spawn(move || {
-            let _g = m2.lock().unwrap();
-            c2.notify_one();
-        });
-        g = c.wait(g).unwrap();
-        drop(g);
-
-        let m = Mutex::new(());
-        let _ = c.wait(m.lock().unwrap()).unwrap();
-    }
-}
diff --git a/library/std/src/sync/condvar/tests.rs b/library/std/src/sync/condvar/tests.rs
new file mode 100644
index 00000000000..86d099ee3a1
--- /dev/null
+++ b/library/std/src/sync/condvar/tests.rs
@@ -0,0 +1,211 @@
+use crate::sync::atomic::{AtomicBool, Ordering};
+use crate::sync::mpsc::channel;
+use crate::sync::{Arc, Condvar, Mutex};
+use crate::thread;
+use crate::time::Duration;
+
+#[test]
+fn smoke() {
+    let c = Condvar::new();
+    c.notify_one();
+    c.notify_all();
+}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn notify_one() {
+    let m = Arc::new(Mutex::new(()));
+    let m2 = m.clone();
+    let c = Arc::new(Condvar::new());
+    let c2 = c.clone();
+
+    let g = m.lock().unwrap();
+    let _t = thread::spawn(move || {
+        let _g = m2.lock().unwrap();
+        c2.notify_one();
+    });
+    let g = c.wait(g).unwrap();
+    drop(g);
+}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn notify_all() {
+    const N: usize = 10;
+
+    let data = Arc::new((Mutex::new(0), Condvar::new()));
+    let (tx, rx) = channel();
+    for _ in 0..N {
+        let data = data.clone();
+        let tx = tx.clone();
+        thread::spawn(move || {
+            let &(ref lock, ref cond) = &*data;
+            let mut cnt = lock.lock().unwrap();
+            *cnt += 1;
+            if *cnt == N {
+                tx.send(()).unwrap();
+            }
+            while *cnt != 0 {
+                cnt = cond.wait(cnt).unwrap();
+            }
+            tx.send(()).unwrap();
+        });
+    }
+    drop(tx);
+
+    let &(ref lock, ref cond) = &*data;
+    rx.recv().unwrap();
+    let mut cnt = lock.lock().unwrap();
+    *cnt = 0;
+    cond.notify_all();
+    drop(cnt);
+
+    for _ in 0..N {
+        rx.recv().unwrap();
+    }
+}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn wait_while() {
+    let pair = Arc::new((Mutex::new(false), Condvar::new()));
+    let pair2 = pair.clone();
+
+    // Inside of our lock, spawn a new thread, and then wait for it to start.
+    thread::spawn(move || {
+        let &(ref lock, ref cvar) = &*pair2;
+        let mut started = lock.lock().unwrap();
+        *started = true;
+        // We notify the condvar that the value has changed.
+        cvar.notify_one();
+    });
+
+    // Wait for the thread to start up.
+    let &(ref lock, ref cvar) = &*pair;
+    let guard = cvar.wait_while(lock.lock().unwrap(), |started| !*started);
+    assert!(*guard.unwrap());
+}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn wait_timeout_wait() {
+    let m = Arc::new(Mutex::new(()));
+    let c = Arc::new(Condvar::new());
+
+    loop {
+        let g = m.lock().unwrap();
+        let (_g, no_timeout) = c.wait_timeout(g, Duration::from_millis(1)).unwrap();
+        // spurious wakeups mean this isn't necessarily true
+        // so execute test again, if not timeout
+        if !no_timeout.timed_out() {
+            continue;
+        }
+
+        break;
+    }
+}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn wait_timeout_while_wait() {
+    let m = Arc::new(Mutex::new(()));
+    let c = Arc::new(Condvar::new());
+
+    let g = m.lock().unwrap();
+    let (_g, wait) = c.wait_timeout_while(g, Duration::from_millis(1), |_| true).unwrap();
+    // no spurious wakeups. ensure it timed-out
+    assert!(wait.timed_out());
+}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn wait_timeout_while_instant_satisfy() {
+    let m = Arc::new(Mutex::new(()));
+    let c = Arc::new(Condvar::new());
+
+    let g = m.lock().unwrap();
+    let (_g, wait) = c.wait_timeout_while(g, Duration::from_millis(0), |_| false).unwrap();
+    // ensure it didn't time-out even if we were not given any time.
+    assert!(!wait.timed_out());
+}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn wait_timeout_while_wake() {
+    let pair = Arc::new((Mutex::new(false), Condvar::new()));
+    let pair_copy = pair.clone();
+
+    let &(ref m, ref c) = &*pair;
+    let g = m.lock().unwrap();
+    let _t = thread::spawn(move || {
+        let &(ref lock, ref cvar) = &*pair_copy;
+        let mut started = lock.lock().unwrap();
+        thread::sleep(Duration::from_millis(1));
+        *started = true;
+        cvar.notify_one();
+    });
+    let (g2, wait) = c
+        .wait_timeout_while(g, Duration::from_millis(u64::MAX), |&mut notified| !notified)
+        .unwrap();
+    // ensure it didn't time-out even if we were not given any time.
+    assert!(!wait.timed_out());
+    assert!(*g2);
+}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn wait_timeout_wake() {
+    let m = Arc::new(Mutex::new(()));
+    let c = Arc::new(Condvar::new());
+
+    loop {
+        let g = m.lock().unwrap();
+
+        let c2 = c.clone();
+        let m2 = m.clone();
+
+        let notified = Arc::new(AtomicBool::new(false));
+        let notified_copy = notified.clone();
+
+        let t = thread::spawn(move || {
+            let _g = m2.lock().unwrap();
+            thread::sleep(Duration::from_millis(1));
+            notified_copy.store(true, Ordering::SeqCst);
+            c2.notify_one();
+        });
+        let (g, timeout_res) = c.wait_timeout(g, Duration::from_millis(u64::MAX)).unwrap();
+        assert!(!timeout_res.timed_out());
+        // spurious wakeups mean this isn't necessarily true
+        // so execute test again, if not notified
+        if !notified.load(Ordering::SeqCst) {
+            t.join().unwrap();
+            continue;
+        }
+        drop(g);
+
+        t.join().unwrap();
+
+        break;
+    }
+}
+
+#[test]
+#[should_panic]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn two_mutexes() {
+    let m = Arc::new(Mutex::new(()));
+    let m2 = m.clone();
+    let c = Arc::new(Condvar::new());
+    let c2 = c.clone();
+
+    let mut g = m.lock().unwrap();
+    let _t = thread::spawn(move || {
+        let _g = m2.lock().unwrap();
+        c2.notify_one();
+    });
+    g = c.wait(g).unwrap();
+    drop(g);
+
+    let m = Mutex::new(());
+    let _ = c.wait(m.lock().unwrap()).unwrap();
+}
diff --git a/library/std/src/sync/mpsc/mod.rs b/library/std/src/sync/mpsc/mod.rs
index ac83017d9e1..073f969bbe2 100644
--- a/library/std/src/sync/mpsc/mod.rs
+++ b/library/std/src/sync/mpsc/mod.rs
@@ -108,6 +108,12 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+#[cfg(all(test, not(target_os = "emscripten")))]
+mod tests;
+
+#[cfg(all(test, not(target_os = "emscripten")))]
+mod sync_tests;
+
 // A description of how Rust's channel implementation works
 //
 // Channels are supposed to be the basic building block for all other
@@ -1606,1364 +1612,3 @@ impl From<RecvError> for RecvTimeoutError {
         }
     }
 }
-
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod tests {
-    use super::*;
-    use crate::env;
-    use crate::thread;
-    use crate::time::{Duration, Instant};
-
-    pub fn stress_factor() -> usize {
-        match env::var("RUST_TEST_STRESS") {
-            Ok(val) => val.parse().unwrap(),
-            Err(..) => 1,
-        }
-    }
-
-    #[test]
-    fn smoke() {
-        let (tx, rx) = channel::<i32>();
-        tx.send(1).unwrap();
-        assert_eq!(rx.recv().unwrap(), 1);
-    }
-
-    #[test]
-    fn drop_full() {
-        let (tx, _rx) = channel::<Box<isize>>();
-        tx.send(box 1).unwrap();
-    }
-
-    #[test]
-    fn drop_full_shared() {
-        let (tx, _rx) = channel::<Box<isize>>();
-        drop(tx.clone());
-        drop(tx.clone());
-        tx.send(box 1).unwrap();
-    }
-
-    #[test]
-    fn smoke_shared() {
-        let (tx, rx) = channel::<i32>();
-        tx.send(1).unwrap();
-        assert_eq!(rx.recv().unwrap(), 1);
-        let tx = tx.clone();
-        tx.send(1).unwrap();
-        assert_eq!(rx.recv().unwrap(), 1);
-    }
-
-    #[test]
-    fn smoke_threads() {
-        let (tx, rx) = channel::<i32>();
-        let _t = thread::spawn(move || {
-            tx.send(1).unwrap();
-        });
-        assert_eq!(rx.recv().unwrap(), 1);
-    }
-
-    #[test]
-    fn smoke_port_gone() {
-        let (tx, rx) = channel::<i32>();
-        drop(rx);
-        assert!(tx.send(1).is_err());
-    }
-
-    #[test]
-    fn smoke_shared_port_gone() {
-        let (tx, rx) = channel::<i32>();
-        drop(rx);
-        assert!(tx.send(1).is_err())
-    }
-
-    #[test]
-    fn smoke_shared_port_gone2() {
-        let (tx, rx) = channel::<i32>();
-        drop(rx);
-        let tx2 = tx.clone();
-        drop(tx);
-        assert!(tx2.send(1).is_err());
-    }
-
-    #[test]
-    fn port_gone_concurrent() {
-        let (tx, rx) = channel::<i32>();
-        let _t = thread::spawn(move || {
-            rx.recv().unwrap();
-        });
-        while tx.send(1).is_ok() {}
-    }
-
-    #[test]
-    fn port_gone_concurrent_shared() {
-        let (tx, rx) = channel::<i32>();
-        let tx2 = tx.clone();
-        let _t = thread::spawn(move || {
-            rx.recv().unwrap();
-        });
-        while tx.send(1).is_ok() && tx2.send(1).is_ok() {}
-    }
-
-    #[test]
-    fn smoke_chan_gone() {
-        let (tx, rx) = channel::<i32>();
-        drop(tx);
-        assert!(rx.recv().is_err());
-    }
-
-    #[test]
-    fn smoke_chan_gone_shared() {
-        let (tx, rx) = channel::<()>();
-        let tx2 = tx.clone();
-        drop(tx);
-        drop(tx2);
-        assert!(rx.recv().is_err());
-    }
-
-    #[test]
-    fn chan_gone_concurrent() {
-        let (tx, rx) = channel::<i32>();
-        let _t = thread::spawn(move || {
-            tx.send(1).unwrap();
-            tx.send(1).unwrap();
-        });
-        while rx.recv().is_ok() {}
-    }
-
-    #[test]
-    fn stress() {
-        let (tx, rx) = channel::<i32>();
-        let t = thread::spawn(move || {
-            for _ in 0..10000 {
-                tx.send(1).unwrap();
-            }
-        });
-        for _ in 0..10000 {
-            assert_eq!(rx.recv().unwrap(), 1);
-        }
-        t.join().ok().expect("thread panicked");
-    }
-
-    #[test]
-    fn stress_shared() {
-        const AMT: u32 = 10000;
-        const NTHREADS: u32 = 8;
-        let (tx, rx) = channel::<i32>();
-
-        let t = thread::spawn(move || {
-            for _ in 0..AMT * NTHREADS {
-                assert_eq!(rx.recv().unwrap(), 1);
-            }
-            match rx.try_recv() {
-                Ok(..) => panic!(),
-                _ => {}
-            }
-        });
-
-        for _ in 0..NTHREADS {
-            let tx = tx.clone();
-            thread::spawn(move || {
-                for _ in 0..AMT {
-                    tx.send(1).unwrap();
-                }
-            });
-        }
-        drop(tx);
-        t.join().ok().expect("thread panicked");
-    }
-
-    #[test]
-    fn send_from_outside_runtime() {
-        let (tx1, rx1) = channel::<()>();
-        let (tx2, rx2) = channel::<i32>();
-        let t1 = thread::spawn(move || {
-            tx1.send(()).unwrap();
-            for _ in 0..40 {
-                assert_eq!(rx2.recv().unwrap(), 1);
-            }
-        });
-        rx1.recv().unwrap();
-        let t2 = thread::spawn(move || {
-            for _ in 0..40 {
-                tx2.send(1).unwrap();
-            }
-        });
-        t1.join().ok().expect("thread panicked");
-        t2.join().ok().expect("thread panicked");
-    }
-
-    #[test]
-    fn recv_from_outside_runtime() {
-        let (tx, rx) = channel::<i32>();
-        let t = thread::spawn(move || {
-            for _ in 0..40 {
-                assert_eq!(rx.recv().unwrap(), 1);
-            }
-        });
-        for _ in 0..40 {
-            tx.send(1).unwrap();
-        }
-        t.join().ok().expect("thread panicked");
-    }
-
-    #[test]
-    fn no_runtime() {
-        let (tx1, rx1) = channel::<i32>();
-        let (tx2, rx2) = channel::<i32>();
-        let t1 = thread::spawn(move || {
-            assert_eq!(rx1.recv().unwrap(), 1);
-            tx2.send(2).unwrap();
-        });
-        let t2 = thread::spawn(move || {
-            tx1.send(1).unwrap();
-            assert_eq!(rx2.recv().unwrap(), 2);
-        });
-        t1.join().ok().expect("thread panicked");
-        t2.join().ok().expect("thread panicked");
-    }
-
-    #[test]
-    fn oneshot_single_thread_close_port_first() {
-        // Simple test of closing without sending
-        let (_tx, rx) = channel::<i32>();
-        drop(rx);
-    }
-
-    #[test]
-    fn oneshot_single_thread_close_chan_first() {
-        // Simple test of closing without sending
-        let (tx, _rx) = channel::<i32>();
-        drop(tx);
-    }
-
-    #[test]
-    fn oneshot_single_thread_send_port_close() {
-        // Testing that the sender cleans up the payload if receiver is closed
-        let (tx, rx) = channel::<Box<i32>>();
-        drop(rx);
-        assert!(tx.send(box 0).is_err());
-    }
-
-    #[test]
-    fn oneshot_single_thread_recv_chan_close() {
-        // Receiving on a closed chan will panic
-        let res = thread::spawn(move || {
-            let (tx, rx) = channel::<i32>();
-            drop(tx);
-            rx.recv().unwrap();
-        })
-        .join();
-        // What is our res?
-        assert!(res.is_err());
-    }
-
-    #[test]
-    fn oneshot_single_thread_send_then_recv() {
-        let (tx, rx) = channel::<Box<i32>>();
-        tx.send(box 10).unwrap();
-        assert!(*rx.recv().unwrap() == 10);
-    }
-
-    #[test]
-    fn oneshot_single_thread_try_send_open() {
-        let (tx, rx) = channel::<i32>();
-        assert!(tx.send(10).is_ok());
-        assert!(rx.recv().unwrap() == 10);
-    }
-
-    #[test]
-    fn oneshot_single_thread_try_send_closed() {
-        let (tx, rx) = channel::<i32>();
-        drop(rx);
-        assert!(tx.send(10).is_err());
-    }
-
-    #[test]
-    fn oneshot_single_thread_try_recv_open() {
-        let (tx, rx) = channel::<i32>();
-        tx.send(10).unwrap();
-        assert!(rx.recv() == Ok(10));
-    }
-
-    #[test]
-    fn oneshot_single_thread_try_recv_closed() {
-        let (tx, rx) = channel::<i32>();
-        drop(tx);
-        assert!(rx.recv().is_err());
-    }
-
-    #[test]
-    fn oneshot_single_thread_peek_data() {
-        let (tx, rx) = channel::<i32>();
-        assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
-        tx.send(10).unwrap();
-        assert_eq!(rx.try_recv(), Ok(10));
-    }
-
-    #[test]
-    fn oneshot_single_thread_peek_close() {
-        let (tx, rx) = channel::<i32>();
-        drop(tx);
-        assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
-        assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
-    }
-
-    #[test]
-    fn oneshot_single_thread_peek_open() {
-        let (_tx, rx) = channel::<i32>();
-        assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
-    }
-
-    #[test]
-    fn oneshot_multi_task_recv_then_send() {
-        let (tx, rx) = channel::<Box<i32>>();
-        let _t = thread::spawn(move || {
-            assert!(*rx.recv().unwrap() == 10);
-        });
-
-        tx.send(box 10).unwrap();
-    }
-
-    #[test]
-    fn oneshot_multi_task_recv_then_close() {
-        let (tx, rx) = channel::<Box<i32>>();
-        let _t = thread::spawn(move || {
-            drop(tx);
-        });
-        let res = thread::spawn(move || {
-            assert!(*rx.recv().unwrap() == 10);
-        })
-        .join();
-        assert!(res.is_err());
-    }
-
-    #[test]
-    fn oneshot_multi_thread_close_stress() {
-        for _ in 0..stress_factor() {
-            let (tx, rx) = channel::<i32>();
-            let _t = thread::spawn(move || {
-                drop(rx);
-            });
-            drop(tx);
-        }
-    }
-
-    #[test]
-    fn oneshot_multi_thread_send_close_stress() {
-        for _ in 0..stress_factor() {
-            let (tx, rx) = channel::<i32>();
-            let _t = thread::spawn(move || {
-                drop(rx);
-            });
-            let _ = thread::spawn(move || {
-                tx.send(1).unwrap();
-            })
-            .join();
-        }
-    }
-
-    #[test]
-    fn oneshot_multi_thread_recv_close_stress() {
-        for _ in 0..stress_factor() {
-            let (tx, rx) = channel::<i32>();
-            thread::spawn(move || {
-                let res = thread::spawn(move || {
-                    rx.recv().unwrap();
-                })
-                .join();
-                assert!(res.is_err());
-            });
-            let _t = thread::spawn(move || {
-                thread::spawn(move || {
-                    drop(tx);
-                });
-            });
-        }
-    }
-
-    #[test]
-    fn oneshot_multi_thread_send_recv_stress() {
-        for _ in 0..stress_factor() {
-            let (tx, rx) = channel::<Box<isize>>();
-            let _t = thread::spawn(move || {
-                tx.send(box 10).unwrap();
-            });
-            assert!(*rx.recv().unwrap() == 10);
-        }
-    }
-
-    #[test]
-    fn stream_send_recv_stress() {
-        for _ in 0..stress_factor() {
-            let (tx, rx) = channel();
-
-            send(tx, 0);
-            recv(rx, 0);
-
-            fn send(tx: Sender<Box<i32>>, i: i32) {
-                if i == 10 {
-                    return;
-                }
-
-                thread::spawn(move || {
-                    tx.send(box i).unwrap();
-                    send(tx, i + 1);
-                });
-            }
-
-            fn recv(rx: Receiver<Box<i32>>, i: i32) {
-                if i == 10 {
-                    return;
-                }
-
-                thread::spawn(move || {
-                    assert!(*rx.recv().unwrap() == i);
-                    recv(rx, i + 1);
-                });
-            }
-        }
-    }
-
-    #[test]
-    fn oneshot_single_thread_recv_timeout() {
-        let (tx, rx) = channel();
-        tx.send(()).unwrap();
-        assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(()));
-        assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Err(RecvTimeoutError::Timeout));
-        tx.send(()).unwrap();
-        assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(()));
-    }
-
-    #[test]
-    fn stress_recv_timeout_two_threads() {
-        let (tx, rx) = channel();
-        let stress = stress_factor() + 100;
-        let timeout = Duration::from_millis(100);
-
-        thread::spawn(move || {
-            for i in 0..stress {
-                if i % 2 == 0 {
-                    thread::sleep(timeout * 2);
-                }
-                tx.send(1usize).unwrap();
-            }
-        });
-
-        let mut recv_count = 0;
-        loop {
-            match rx.recv_timeout(timeout) {
-                Ok(n) => {
-                    assert_eq!(n, 1usize);
-                    recv_count += 1;
-                }
-                Err(RecvTimeoutError::Timeout) => continue,
-                Err(RecvTimeoutError::Disconnected) => break,
-            }
-        }
-
-        assert_eq!(recv_count, stress);
-    }
-
-    #[test]
-    fn recv_timeout_upgrade() {
-        let (tx, rx) = channel::<()>();
-        let timeout = Duration::from_millis(1);
-        let _tx_clone = tx.clone();
-
-        let start = Instant::now();
-        assert_eq!(rx.recv_timeout(timeout), Err(RecvTimeoutError::Timeout));
-        assert!(Instant::now() >= start + timeout);
-    }
-
-    #[test]
-    fn stress_recv_timeout_shared() {
-        let (tx, rx) = channel();
-        let stress = stress_factor() + 100;
-
-        for i in 0..stress {
-            let tx = tx.clone();
-            thread::spawn(move || {
-                thread::sleep(Duration::from_millis(i as u64 * 10));
-                tx.send(1usize).unwrap();
-            });
-        }
-
-        drop(tx);
-
-        let mut recv_count = 0;
-        loop {
-            match rx.recv_timeout(Duration::from_millis(10)) {
-                Ok(n) => {
-                    assert_eq!(n, 1usize);
-                    recv_count += 1;
-                }
-                Err(RecvTimeoutError::Timeout) => continue,
-                Err(RecvTimeoutError::Disconnected) => break,
-            }
-        }
-
-        assert_eq!(recv_count, stress);
-    }
-
-    #[test]
-    fn very_long_recv_timeout_wont_panic() {
-        let (tx, rx) = channel::<()>();
-        let join_handle = thread::spawn(move || rx.recv_timeout(Duration::from_secs(u64::MAX)));
-        thread::sleep(Duration::from_secs(1));
-        assert!(tx.send(()).is_ok());
-        assert_eq!(join_handle.join().unwrap(), Ok(()));
-    }
-
-    #[test]
-    fn recv_a_lot() {
-        // Regression test that we don't run out of stack in scheduler context
-        let (tx, rx) = channel();
-        for _ in 0..10000 {
-            tx.send(()).unwrap();
-        }
-        for _ in 0..10000 {
-            rx.recv().unwrap();
-        }
-    }
-
-    #[test]
-    fn shared_recv_timeout() {
-        let (tx, rx) = channel();
-        let total = 5;
-        for _ in 0..total {
-            let tx = tx.clone();
-            thread::spawn(move || {
-                tx.send(()).unwrap();
-            });
-        }
-
-        for _ in 0..total {
-            rx.recv().unwrap();
-        }
-
-        assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Err(RecvTimeoutError::Timeout));
-        tx.send(()).unwrap();
-        assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(()));
-    }
-
-    #[test]
-    fn shared_chan_stress() {
-        let (tx, rx) = channel();
-        let total = stress_factor() + 100;
-        for _ in 0..total {
-            let tx = tx.clone();
-            thread::spawn(move || {
-                tx.send(()).unwrap();
-            });
-        }
-
-        for _ in 0..total {
-            rx.recv().unwrap();
-        }
-    }
-
-    #[test]
-    fn test_nested_recv_iter() {
-        let (tx, rx) = channel::<i32>();
-        let (total_tx, total_rx) = channel::<i32>();
-
-        let _t = thread::spawn(move || {
-            let mut acc = 0;
-            for x in rx.iter() {
-                acc += x;
-            }
-            total_tx.send(acc).unwrap();
-        });
-
-        tx.send(3).unwrap();
-        tx.send(1).unwrap();
-        tx.send(2).unwrap();
-        drop(tx);
-        assert_eq!(total_rx.recv().unwrap(), 6);
-    }
-
-    #[test]
-    fn test_recv_iter_break() {
-        let (tx, rx) = channel::<i32>();
-        let (count_tx, count_rx) = channel();
-
-        let _t = thread::spawn(move || {
-            let mut count = 0;
-            for x in rx.iter() {
-                if count >= 3 {
-                    break;
-                } else {
-                    count += x;
-                }
-            }
-            count_tx.send(count).unwrap();
-        });
-
-        tx.send(2).unwrap();
-        tx.send(2).unwrap();
-        tx.send(2).unwrap();
-        let _ = tx.send(2);
-        drop(tx);
-        assert_eq!(count_rx.recv().unwrap(), 4);
-    }
-
-    #[test]
-    fn test_recv_try_iter() {
-        let (request_tx, request_rx) = channel();
-        let (response_tx, response_rx) = channel();
-
-        // Request `x`s until we have `6`.
-        let t = thread::spawn(move || {
-            let mut count = 0;
-            loop {
-                for x in response_rx.try_iter() {
-                    count += x;
-                    if count == 6 {
-                        return count;
-                    }
-                }
-                request_tx.send(()).unwrap();
-            }
-        });
-
-        for _ in request_rx.iter() {
-            if response_tx.send(2).is_err() {
-                break;
-            }
-        }
-
-        assert_eq!(t.join().unwrap(), 6);
-    }
-
-    #[test]
-    fn test_recv_into_iter_owned() {
-        let mut iter = {
-            let (tx, rx) = channel::<i32>();
-            tx.send(1).unwrap();
-            tx.send(2).unwrap();
-
-            rx.into_iter()
-        };
-        assert_eq!(iter.next().unwrap(), 1);
-        assert_eq!(iter.next().unwrap(), 2);
-        assert_eq!(iter.next().is_none(), true);
-    }
-
-    #[test]
-    fn test_recv_into_iter_borrowed() {
-        let (tx, rx) = channel::<i32>();
-        tx.send(1).unwrap();
-        tx.send(2).unwrap();
-        drop(tx);
-        let mut iter = (&rx).into_iter();
-        assert_eq!(iter.next().unwrap(), 1);
-        assert_eq!(iter.next().unwrap(), 2);
-        assert_eq!(iter.next().is_none(), true);
-    }
-
-    #[test]
-    fn try_recv_states() {
-        let (tx1, rx1) = channel::<i32>();
-        let (tx2, rx2) = channel::<()>();
-        let (tx3, rx3) = channel::<()>();
-        let _t = thread::spawn(move || {
-            rx2.recv().unwrap();
-            tx1.send(1).unwrap();
-            tx3.send(()).unwrap();
-            rx2.recv().unwrap();
-            drop(tx1);
-            tx3.send(()).unwrap();
-        });
-
-        assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty));
-        tx2.send(()).unwrap();
-        rx3.recv().unwrap();
-        assert_eq!(rx1.try_recv(), Ok(1));
-        assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty));
-        tx2.send(()).unwrap();
-        rx3.recv().unwrap();
-        assert_eq!(rx1.try_recv(), Err(TryRecvError::Disconnected));
-    }
-
-    // This bug used to end up in a livelock inside of the Receiver destructor
-    // because the internal state of the Shared packet was corrupted
-    #[test]
-    fn destroy_upgraded_shared_port_when_sender_still_active() {
-        let (tx, rx) = channel();
-        let (tx2, rx2) = channel();
-        let _t = thread::spawn(move || {
-            rx.recv().unwrap(); // wait on a oneshot
-            drop(rx); // destroy a shared
-            tx2.send(()).unwrap();
-        });
-        // make sure the other thread has gone to sleep
-        for _ in 0..5000 {
-            thread::yield_now();
-        }
-
-        // upgrade to a shared chan and send a message
-        let t = tx.clone();
-        drop(tx);
-        t.send(()).unwrap();
-
-        // wait for the child thread to exit before we exit
-        rx2.recv().unwrap();
-    }
-
-    #[test]
-    fn issue_32114() {
-        let (tx, _) = channel();
-        let _ = tx.send(123);
-        assert_eq!(tx.send(123), Err(SendError(123)));
-    }
-}
-
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod sync_tests {
-    use super::*;
-    use crate::env;
-    use crate::thread;
-    use crate::time::Duration;
-
-    pub fn stress_factor() -> usize {
-        match env::var("RUST_TEST_STRESS") {
-            Ok(val) => val.parse().unwrap(),
-            Err(..) => 1,
-        }
-    }
-
-    #[test]
-    fn smoke() {
-        let (tx, rx) = sync_channel::<i32>(1);
-        tx.send(1).unwrap();
-        assert_eq!(rx.recv().unwrap(), 1);
-    }
-
-    #[test]
-    fn drop_full() {
-        let (tx, _rx) = sync_channel::<Box<isize>>(1);
-        tx.send(box 1).unwrap();
-    }
-
-    #[test]
-    fn smoke_shared() {
-        let (tx, rx) = sync_channel::<i32>(1);
-        tx.send(1).unwrap();
-        assert_eq!(rx.recv().unwrap(), 1);
-        let tx = tx.clone();
-        tx.send(1).unwrap();
-        assert_eq!(rx.recv().unwrap(), 1);
-    }
-
-    #[test]
-    fn recv_timeout() {
-        let (tx, rx) = sync_channel::<i32>(1);
-        assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Err(RecvTimeoutError::Timeout));
-        tx.send(1).unwrap();
-        assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(1));
-    }
-
-    #[test]
-    fn smoke_threads() {
-        let (tx, rx) = sync_channel::<i32>(0);
-        let _t = thread::spawn(move || {
-            tx.send(1).unwrap();
-        });
-        assert_eq!(rx.recv().unwrap(), 1);
-    }
-
-    #[test]
-    fn smoke_port_gone() {
-        let (tx, rx) = sync_channel::<i32>(0);
-        drop(rx);
-        assert!(tx.send(1).is_err());
-    }
-
-    #[test]
-    fn smoke_shared_port_gone2() {
-        let (tx, rx) = sync_channel::<i32>(0);
-        drop(rx);
-        let tx2 = tx.clone();
-        drop(tx);
-        assert!(tx2.send(1).is_err());
-    }
-
-    #[test]
-    fn port_gone_concurrent() {
-        let (tx, rx) = sync_channel::<i32>(0);
-        let _t = thread::spawn(move || {
-            rx.recv().unwrap();
-        });
-        while tx.send(1).is_ok() {}
-    }
-
-    #[test]
-    fn port_gone_concurrent_shared() {
-        let (tx, rx) = sync_channel::<i32>(0);
-        let tx2 = tx.clone();
-        let _t = thread::spawn(move || {
-            rx.recv().unwrap();
-        });
-        while tx.send(1).is_ok() && tx2.send(1).is_ok() {}
-    }
-
-    #[test]
-    fn smoke_chan_gone() {
-        let (tx, rx) = sync_channel::<i32>(0);
-        drop(tx);
-        assert!(rx.recv().is_err());
-    }
-
-    #[test]
-    fn smoke_chan_gone_shared() {
-        let (tx, rx) = sync_channel::<()>(0);
-        let tx2 = tx.clone();
-        drop(tx);
-        drop(tx2);
-        assert!(rx.recv().is_err());
-    }
-
-    #[test]
-    fn chan_gone_concurrent() {
-        let (tx, rx) = sync_channel::<i32>(0);
-        thread::spawn(move || {
-            tx.send(1).unwrap();
-            tx.send(1).unwrap();
-        });
-        while rx.recv().is_ok() {}
-    }
-
-    #[test]
-    fn stress() {
-        let (tx, rx) = sync_channel::<i32>(0);
-        thread::spawn(move || {
-            for _ in 0..10000 {
-                tx.send(1).unwrap();
-            }
-        });
-        for _ in 0..10000 {
-            assert_eq!(rx.recv().unwrap(), 1);
-        }
-    }
-
-    #[test]
-    fn stress_recv_timeout_two_threads() {
-        let (tx, rx) = sync_channel::<i32>(0);
-
-        thread::spawn(move || {
-            for _ in 0..10000 {
-                tx.send(1).unwrap();
-            }
-        });
-
-        let mut recv_count = 0;
-        loop {
-            match rx.recv_timeout(Duration::from_millis(1)) {
-                Ok(v) => {
-                    assert_eq!(v, 1);
-                    recv_count += 1;
-                }
-                Err(RecvTimeoutError::Timeout) => continue,
-                Err(RecvTimeoutError::Disconnected) => break,
-            }
-        }
-
-        assert_eq!(recv_count, 10000);
-    }
-
-    #[test]
-    fn stress_recv_timeout_shared() {
-        const AMT: u32 = 1000;
-        const NTHREADS: u32 = 8;
-        let (tx, rx) = sync_channel::<i32>(0);
-        let (dtx, drx) = sync_channel::<()>(0);
-
-        thread::spawn(move || {
-            let mut recv_count = 0;
-            loop {
-                match rx.recv_timeout(Duration::from_millis(10)) {
-                    Ok(v) => {
-                        assert_eq!(v, 1);
-                        recv_count += 1;
-                    }
-                    Err(RecvTimeoutError::Timeout) => continue,
-                    Err(RecvTimeoutError::Disconnected) => break,
-                }
-            }
-
-            assert_eq!(recv_count, AMT * NTHREADS);
-            assert!(rx.try_recv().is_err());
-
-            dtx.send(()).unwrap();
-        });
-
-        for _ in 0..NTHREADS {
-            let tx = tx.clone();
-            thread::spawn(move || {
-                for _ in 0..AMT {
-                    tx.send(1).unwrap();
-                }
-            });
-        }
-
-        drop(tx);
-
-        drx.recv().unwrap();
-    }
-
-    #[test]
-    fn stress_shared() {
-        const AMT: u32 = 1000;
-        const NTHREADS: u32 = 8;
-        let (tx, rx) = sync_channel::<i32>(0);
-        let (dtx, drx) = sync_channel::<()>(0);
-
-        thread::spawn(move || {
-            for _ in 0..AMT * NTHREADS {
-                assert_eq!(rx.recv().unwrap(), 1);
-            }
-            match rx.try_recv() {
-                Ok(..) => panic!(),
-                _ => {}
-            }
-            dtx.send(()).unwrap();
-        });
-
-        for _ in 0..NTHREADS {
-            let tx = tx.clone();
-            thread::spawn(move || {
-                for _ in 0..AMT {
-                    tx.send(1).unwrap();
-                }
-            });
-        }
-        drop(tx);
-        drx.recv().unwrap();
-    }
-
-    #[test]
-    fn oneshot_single_thread_close_port_first() {
-        // Simple test of closing without sending
-        let (_tx, rx) = sync_channel::<i32>(0);
-        drop(rx);
-    }
-
-    #[test]
-    fn oneshot_single_thread_close_chan_first() {
-        // Simple test of closing without sending
-        let (tx, _rx) = sync_channel::<i32>(0);
-        drop(tx);
-    }
-
-    #[test]
-    fn oneshot_single_thread_send_port_close() {
-        // Testing that the sender cleans up the payload if receiver is closed
-        let (tx, rx) = sync_channel::<Box<i32>>(0);
-        drop(rx);
-        assert!(tx.send(box 0).is_err());
-    }
-
-    #[test]
-    fn oneshot_single_thread_recv_chan_close() {
-        // Receiving on a closed chan will panic
-        let res = thread::spawn(move || {
-            let (tx, rx) = sync_channel::<i32>(0);
-            drop(tx);
-            rx.recv().unwrap();
-        })
-        .join();
-        // What is our res?
-        assert!(res.is_err());
-    }
-
-    #[test]
-    fn oneshot_single_thread_send_then_recv() {
-        let (tx, rx) = sync_channel::<Box<i32>>(1);
-        tx.send(box 10).unwrap();
-        assert!(*rx.recv().unwrap() == 10);
-    }
-
-    #[test]
-    fn oneshot_single_thread_try_send_open() {
-        let (tx, rx) = sync_channel::<i32>(1);
-        assert_eq!(tx.try_send(10), Ok(()));
-        assert!(rx.recv().unwrap() == 10);
-    }
-
-    #[test]
-    fn oneshot_single_thread_try_send_closed() {
-        let (tx, rx) = sync_channel::<i32>(0);
-        drop(rx);
-        assert_eq!(tx.try_send(10), Err(TrySendError::Disconnected(10)));
-    }
-
-    #[test]
-    fn oneshot_single_thread_try_send_closed2() {
-        let (tx, _rx) = sync_channel::<i32>(0);
-        assert_eq!(tx.try_send(10), Err(TrySendError::Full(10)));
-    }
-
-    #[test]
-    fn oneshot_single_thread_try_recv_open() {
-        let (tx, rx) = sync_channel::<i32>(1);
-        tx.send(10).unwrap();
-        assert!(rx.recv() == Ok(10));
-    }
-
-    #[test]
-    fn oneshot_single_thread_try_recv_closed() {
-        let (tx, rx) = sync_channel::<i32>(0);
-        drop(tx);
-        assert!(rx.recv().is_err());
-    }
-
-    #[test]
-    fn oneshot_single_thread_try_recv_closed_with_data() {
-        let (tx, rx) = sync_channel::<i32>(1);
-        tx.send(10).unwrap();
-        drop(tx);
-        assert_eq!(rx.try_recv(), Ok(10));
-        assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
-    }
-
-    #[test]
-    fn oneshot_single_thread_peek_data() {
-        let (tx, rx) = sync_channel::<i32>(1);
-        assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
-        tx.send(10).unwrap();
-        assert_eq!(rx.try_recv(), Ok(10));
-    }
-
-    #[test]
-    fn oneshot_single_thread_peek_close() {
-        let (tx, rx) = sync_channel::<i32>(0);
-        drop(tx);
-        assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
-        assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
-    }
-
-    #[test]
-    fn oneshot_single_thread_peek_open() {
-        let (_tx, rx) = sync_channel::<i32>(0);
-        assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
-    }
-
-    #[test]
-    fn oneshot_multi_task_recv_then_send() {
-        let (tx, rx) = sync_channel::<Box<i32>>(0);
-        let _t = thread::spawn(move || {
-            assert!(*rx.recv().unwrap() == 10);
-        });
-
-        tx.send(box 10).unwrap();
-    }
-
-    #[test]
-    fn oneshot_multi_task_recv_then_close() {
-        let (tx, rx) = sync_channel::<Box<i32>>(0);
-        let _t = thread::spawn(move || {
-            drop(tx);
-        });
-        let res = thread::spawn(move || {
-            assert!(*rx.recv().unwrap() == 10);
-        })
-        .join();
-        assert!(res.is_err());
-    }
-
-    #[test]
-    fn oneshot_multi_thread_close_stress() {
-        for _ in 0..stress_factor() {
-            let (tx, rx) = sync_channel::<i32>(0);
-            let _t = thread::spawn(move || {
-                drop(rx);
-            });
-            drop(tx);
-        }
-    }
-
-    #[test]
-    fn oneshot_multi_thread_send_close_stress() {
-        for _ in 0..stress_factor() {
-            let (tx, rx) = sync_channel::<i32>(0);
-            let _t = thread::spawn(move || {
-                drop(rx);
-            });
-            let _ = thread::spawn(move || {
-                tx.send(1).unwrap();
-            })
-            .join();
-        }
-    }
-
-    #[test]
-    fn oneshot_multi_thread_recv_close_stress() {
-        for _ in 0..stress_factor() {
-            let (tx, rx) = sync_channel::<i32>(0);
-            let _t = thread::spawn(move || {
-                let res = thread::spawn(move || {
-                    rx.recv().unwrap();
-                })
-                .join();
-                assert!(res.is_err());
-            });
-            let _t = thread::spawn(move || {
-                thread::spawn(move || {
-                    drop(tx);
-                });
-            });
-        }
-    }
-
-    #[test]
-    fn oneshot_multi_thread_send_recv_stress() {
-        for _ in 0..stress_factor() {
-            let (tx, rx) = sync_channel::<Box<i32>>(0);
-            let _t = thread::spawn(move || {
-                tx.send(box 10).unwrap();
-            });
-            assert!(*rx.recv().unwrap() == 10);
-        }
-    }
-
-    #[test]
-    fn stream_send_recv_stress() {
-        for _ in 0..stress_factor() {
-            let (tx, rx) = sync_channel::<Box<i32>>(0);
-
-            send(tx, 0);
-            recv(rx, 0);
-
-            fn send(tx: SyncSender<Box<i32>>, i: i32) {
-                if i == 10 {
-                    return;
-                }
-
-                thread::spawn(move || {
-                    tx.send(box i).unwrap();
-                    send(tx, i + 1);
-                });
-            }
-
-            fn recv(rx: Receiver<Box<i32>>, i: i32) {
-                if i == 10 {
-                    return;
-                }
-
-                thread::spawn(move || {
-                    assert!(*rx.recv().unwrap() == i);
-                    recv(rx, i + 1);
-                });
-            }
-        }
-    }
-
-    #[test]
-    fn recv_a_lot() {
-        // Regression test that we don't run out of stack in scheduler context
-        let (tx, rx) = sync_channel(10000);
-        for _ in 0..10000 {
-            tx.send(()).unwrap();
-        }
-        for _ in 0..10000 {
-            rx.recv().unwrap();
-        }
-    }
-
-    #[test]
-    fn shared_chan_stress() {
-        let (tx, rx) = sync_channel(0);
-        let total = stress_factor() + 100;
-        for _ in 0..total {
-            let tx = tx.clone();
-            thread::spawn(move || {
-                tx.send(()).unwrap();
-            });
-        }
-
-        for _ in 0..total {
-            rx.recv().unwrap();
-        }
-    }
-
-    #[test]
-    fn test_nested_recv_iter() {
-        let (tx, rx) = sync_channel::<i32>(0);
-        let (total_tx, total_rx) = sync_channel::<i32>(0);
-
-        let _t = thread::spawn(move || {
-            let mut acc = 0;
-            for x in rx.iter() {
-                acc += x;
-            }
-            total_tx.send(acc).unwrap();
-        });
-
-        tx.send(3).unwrap();
-        tx.send(1).unwrap();
-        tx.send(2).unwrap();
-        drop(tx);
-        assert_eq!(total_rx.recv().unwrap(), 6);
-    }
-
-    #[test]
-    fn test_recv_iter_break() {
-        let (tx, rx) = sync_channel::<i32>(0);
-        let (count_tx, count_rx) = sync_channel(0);
-
-        let _t = thread::spawn(move || {
-            let mut count = 0;
-            for x in rx.iter() {
-                if count >= 3 {
-                    break;
-                } else {
-                    count += x;
-                }
-            }
-            count_tx.send(count).unwrap();
-        });
-
-        tx.send(2).unwrap();
-        tx.send(2).unwrap();
-        tx.send(2).unwrap();
-        let _ = tx.try_send(2);
-        drop(tx);
-        assert_eq!(count_rx.recv().unwrap(), 4);
-    }
-
-    #[test]
-    fn try_recv_states() {
-        let (tx1, rx1) = sync_channel::<i32>(1);
-        let (tx2, rx2) = sync_channel::<()>(1);
-        let (tx3, rx3) = sync_channel::<()>(1);
-        let _t = thread::spawn(move || {
-            rx2.recv().unwrap();
-            tx1.send(1).unwrap();
-            tx3.send(()).unwrap();
-            rx2.recv().unwrap();
-            drop(tx1);
-            tx3.send(()).unwrap();
-        });
-
-        assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty));
-        tx2.send(()).unwrap();
-        rx3.recv().unwrap();
-        assert_eq!(rx1.try_recv(), Ok(1));
-        assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty));
-        tx2.send(()).unwrap();
-        rx3.recv().unwrap();
-        assert_eq!(rx1.try_recv(), Err(TryRecvError::Disconnected));
-    }
-
-    // This bug used to end up in a livelock inside of the Receiver destructor
-    // because the internal state of the Shared packet was corrupted
-    #[test]
-    fn destroy_upgraded_shared_port_when_sender_still_active() {
-        let (tx, rx) = sync_channel::<()>(0);
-        let (tx2, rx2) = sync_channel::<()>(0);
-        let _t = thread::spawn(move || {
-            rx.recv().unwrap(); // wait on a oneshot
-            drop(rx); // destroy a shared
-            tx2.send(()).unwrap();
-        });
-        // make sure the other thread has gone to sleep
-        for _ in 0..5000 {
-            thread::yield_now();
-        }
-
-        // upgrade to a shared chan and send a message
-        let t = tx.clone();
-        drop(tx);
-        t.send(()).unwrap();
-
-        // wait for the child thread to exit before we exit
-        rx2.recv().unwrap();
-    }
-
-    #[test]
-    fn send1() {
-        let (tx, rx) = sync_channel::<i32>(0);
-        let _t = thread::spawn(move || {
-            rx.recv().unwrap();
-        });
-        assert_eq!(tx.send(1), Ok(()));
-    }
-
-    #[test]
-    fn send2() {
-        let (tx, rx) = sync_channel::<i32>(0);
-        let _t = thread::spawn(move || {
-            drop(rx);
-        });
-        assert!(tx.send(1).is_err());
-    }
-
-    #[test]
-    fn send3() {
-        let (tx, rx) = sync_channel::<i32>(1);
-        assert_eq!(tx.send(1), Ok(()));
-        let _t = thread::spawn(move || {
-            drop(rx);
-        });
-        assert!(tx.send(1).is_err());
-    }
-
-    #[test]
-    fn send4() {
-        let (tx, rx) = sync_channel::<i32>(0);
-        let tx2 = tx.clone();
-        let (done, donerx) = channel();
-        let done2 = done.clone();
-        let _t = thread::spawn(move || {
-            assert!(tx.send(1).is_err());
-            done.send(()).unwrap();
-        });
-        let _t = thread::spawn(move || {
-            assert!(tx2.send(2).is_err());
-            done2.send(()).unwrap();
-        });
-        drop(rx);
-        donerx.recv().unwrap();
-        donerx.recv().unwrap();
-    }
-
-    #[test]
-    fn try_send1() {
-        let (tx, _rx) = sync_channel::<i32>(0);
-        assert_eq!(tx.try_send(1), Err(TrySendError::Full(1)));
-    }
-
-    #[test]
-    fn try_send2() {
-        let (tx, _rx) = sync_channel::<i32>(1);
-        assert_eq!(tx.try_send(1), Ok(()));
-        assert_eq!(tx.try_send(1), Err(TrySendError::Full(1)));
-    }
-
-    #[test]
-    fn try_send3() {
-        let (tx, rx) = sync_channel::<i32>(1);
-        assert_eq!(tx.try_send(1), Ok(()));
-        drop(rx);
-        assert_eq!(tx.try_send(1), Err(TrySendError::Disconnected(1)));
-    }
-
-    #[test]
-    fn issue_15761() {
-        fn repro() {
-            let (tx1, rx1) = sync_channel::<()>(3);
-            let (tx2, rx2) = sync_channel::<()>(3);
-
-            let _t = thread::spawn(move || {
-                rx1.recv().unwrap();
-                tx2.try_send(()).unwrap();
-            });
-
-            tx1.try_send(()).unwrap();
-            rx2.recv().unwrap();
-        }
-
-        for _ in 0..100 {
-            repro()
-        }
-    }
-}
diff --git a/library/std/src/sync/mpsc/mpsc_queue.rs b/library/std/src/sync/mpsc/mpsc_queue.rs
index 6e7a7be4430..42bc639dc25 100644
--- a/library/std/src/sync/mpsc/mpsc_queue.rs
+++ b/library/std/src/sync/mpsc/mpsc_queue.rs
@@ -11,6 +11,9 @@
 // http://www.1024cores.net/home/lock-free-algorithms
 //                         /queues/non-intrusive-mpsc-node-based-queue
 
+#[cfg(all(test, not(target_os = "emscripten")))]
+mod tests;
+
 pub use self::PopResult::*;
 
 use core::cell::UnsafeCell;
@@ -112,54 +115,3 @@ impl<T> Drop for Queue<T> {
         }
     }
 }
-
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod tests {
-    use super::{Data, Empty, Inconsistent, Queue};
-    use crate::sync::mpsc::channel;
-    use crate::sync::Arc;
-    use crate::thread;
-
-    #[test]
-    fn test_full() {
-        let q: Queue<Box<_>> = Queue::new();
-        q.push(box 1);
-        q.push(box 2);
-    }
-
-    #[test]
-    fn test() {
-        let nthreads = 8;
-        let nmsgs = 1000;
-        let q = Queue::new();
-        match q.pop() {
-            Empty => {}
-            Inconsistent | Data(..) => panic!(),
-        }
-        let (tx, rx) = channel();
-        let q = Arc::new(q);
-
-        for _ in 0..nthreads {
-            let tx = tx.clone();
-            let q = q.clone();
-            thread::spawn(move || {
-                for i in 0..nmsgs {
-                    q.push(i);
-                }
-                tx.send(()).unwrap();
-            });
-        }
-
-        let mut i = 0;
-        while i < nthreads * nmsgs {
-            match q.pop() {
-                Empty | Inconsistent => {}
-                Data(_) => i += 1,
-            }
-        }
-        drop(tx);
-        for _ in 0..nthreads {
-            rx.recv().unwrap();
-        }
-    }
-}
diff --git a/library/std/src/sync/mpsc/mpsc_queue/tests.rs b/library/std/src/sync/mpsc/mpsc_queue/tests.rs
new file mode 100644
index 00000000000..348b83424b0
--- /dev/null
+++ b/library/std/src/sync/mpsc/mpsc_queue/tests.rs
@@ -0,0 +1,47 @@
+use super::{Data, Empty, Inconsistent, Queue};
+use crate::sync::mpsc::channel;
+use crate::sync::Arc;
+use crate::thread;
+
+#[test]
+fn test_full() {
+    let q: Queue<Box<_>> = Queue::new();
+    q.push(box 1);
+    q.push(box 2);
+}
+
+#[test]
+fn test() {
+    let nthreads = 8;
+    let nmsgs = 1000;
+    let q = Queue::new();
+    match q.pop() {
+        Empty => {}
+        Inconsistent | Data(..) => panic!(),
+    }
+    let (tx, rx) = channel();
+    let q = Arc::new(q);
+
+    for _ in 0..nthreads {
+        let tx = tx.clone();
+        let q = q.clone();
+        thread::spawn(move || {
+            for i in 0..nmsgs {
+                q.push(i);
+            }
+            tx.send(()).unwrap();
+        });
+    }
+
+    let mut i = 0;
+    while i < nthreads * nmsgs {
+        match q.pop() {
+            Empty | Inconsistent => {}
+            Data(_) => i += 1,
+        }
+    }
+    drop(tx);
+    for _ in 0..nthreads {
+        rx.recv().unwrap();
+    }
+}
diff --git a/library/std/src/sync/mpsc/spsc_queue.rs b/library/std/src/sync/mpsc/spsc_queue.rs
index 0274268f69f..9bf99f193ca 100644
--- a/library/std/src/sync/mpsc/spsc_queue.rs
+++ b/library/std/src/sync/mpsc/spsc_queue.rs
@@ -6,6 +6,9 @@
 
 // http://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue
 
+#[cfg(all(test, not(target_os = "emscripten")))]
+mod tests;
+
 use core::cell::UnsafeCell;
 use core::ptr;
 
@@ -231,108 +234,3 @@ impl<T, ProducerAddition, ConsumerAddition> Drop for Queue<T, ProducerAddition,
         }
     }
 }
-
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod tests {
-    use super::Queue;
-    use crate::sync::mpsc::channel;
-    use crate::sync::Arc;
-    use crate::thread;
-
-    #[test]
-    fn smoke() {
-        unsafe {
-            let queue = Queue::with_additions(0, (), ());
-            queue.push(1);
-            queue.push(2);
-            assert_eq!(queue.pop(), Some(1));
-            assert_eq!(queue.pop(), Some(2));
-            assert_eq!(queue.pop(), None);
-            queue.push(3);
-            queue.push(4);
-            assert_eq!(queue.pop(), Some(3));
-            assert_eq!(queue.pop(), Some(4));
-            assert_eq!(queue.pop(), None);
-        }
-    }
-
-    #[test]
-    fn peek() {
-        unsafe {
-            let queue = Queue::with_additions(0, (), ());
-            queue.push(vec![1]);
-
-            // Ensure the borrowchecker works
-            match queue.peek() {
-                Some(vec) => {
-                    assert_eq!(&*vec, &[1]);
-                }
-                None => unreachable!(),
-            }
-
-            match queue.pop() {
-                Some(vec) => {
-                    assert_eq!(&*vec, &[1]);
-                }
-                None => unreachable!(),
-            }
-        }
-    }
-
-    #[test]
-    fn drop_full() {
-        unsafe {
-            let q: Queue<Box<_>> = Queue::with_additions(0, (), ());
-            q.push(box 1);
-            q.push(box 2);
-        }
-    }
-
-    #[test]
-    fn smoke_bound() {
-        unsafe {
-            let q = Queue::with_additions(0, (), ());
-            q.push(1);
-            q.push(2);
-            assert_eq!(q.pop(), Some(1));
-            assert_eq!(q.pop(), Some(2));
-            assert_eq!(q.pop(), None);
-            q.push(3);
-            q.push(4);
-            assert_eq!(q.pop(), Some(3));
-            assert_eq!(q.pop(), Some(4));
-            assert_eq!(q.pop(), None);
-        }
-    }
-
-    #[test]
-    fn stress() {
-        unsafe {
-            stress_bound(0);
-            stress_bound(1);
-        }
-
-        unsafe fn stress_bound(bound: usize) {
-            let q = Arc::new(Queue::with_additions(bound, (), ()));
-
-            let (tx, rx) = channel();
-            let q2 = q.clone();
-            let _t = thread::spawn(move || {
-                for _ in 0..100000 {
-                    loop {
-                        match q2.pop() {
-                            Some(1) => break,
-                            Some(_) => panic!(),
-                            None => {}
-                        }
-                    }
-                }
-                tx.send(()).unwrap();
-            });
-            for _ in 0..100000 {
-                q.push(1);
-            }
-            rx.recv().unwrap();
-        }
-    }
-}
diff --git a/library/std/src/sync/mpsc/spsc_queue/tests.rs b/library/std/src/sync/mpsc/spsc_queue/tests.rs
new file mode 100644
index 00000000000..e4fd15cbbde
--- /dev/null
+++ b/library/std/src/sync/mpsc/spsc_queue/tests.rs
@@ -0,0 +1,101 @@
+use super::Queue;
+use crate::sync::mpsc::channel;
+use crate::sync::Arc;
+use crate::thread;
+
+#[test]
+fn smoke() {
+    unsafe {
+        let queue = Queue::with_additions(0, (), ());
+        queue.push(1);
+        queue.push(2);
+        assert_eq!(queue.pop(), Some(1));
+        assert_eq!(queue.pop(), Some(2));
+        assert_eq!(queue.pop(), None);
+        queue.push(3);
+        queue.push(4);
+        assert_eq!(queue.pop(), Some(3));
+        assert_eq!(queue.pop(), Some(4));
+        assert_eq!(queue.pop(), None);
+    }
+}
+
+#[test]
+fn peek() {
+    unsafe {
+        let queue = Queue::with_additions(0, (), ());
+        queue.push(vec![1]);
+
+        // Ensure the borrowchecker works
+        match queue.peek() {
+            Some(vec) => {
+                assert_eq!(&*vec, &[1]);
+            }
+            None => unreachable!(),
+        }
+
+        match queue.pop() {
+            Some(vec) => {
+                assert_eq!(&*vec, &[1]);
+            }
+            None => unreachable!(),
+        }
+    }
+}
+
+#[test]
+fn drop_full() {
+    unsafe {
+        let q: Queue<Box<_>> = Queue::with_additions(0, (), ());
+        q.push(box 1);
+        q.push(box 2);
+    }
+}
+
+#[test]
+fn smoke_bound() {
+    unsafe {
+        let q = Queue::with_additions(0, (), ());
+        q.push(1);
+        q.push(2);
+        assert_eq!(q.pop(), Some(1));
+        assert_eq!(q.pop(), Some(2));
+        assert_eq!(q.pop(), None);
+        q.push(3);
+        q.push(4);
+        assert_eq!(q.pop(), Some(3));
+        assert_eq!(q.pop(), Some(4));
+        assert_eq!(q.pop(), None);
+    }
+}
+
+#[test]
+fn stress() {
+    unsafe {
+        stress_bound(0);
+        stress_bound(1);
+    }
+
+    unsafe fn stress_bound(bound: usize) {
+        let q = Arc::new(Queue::with_additions(bound, (), ()));
+
+        let (tx, rx) = channel();
+        let q2 = q.clone();
+        let _t = thread::spawn(move || {
+            for _ in 0..100000 {
+                loop {
+                    match q2.pop() {
+                        Some(1) => break,
+                        Some(_) => panic!(),
+                        None => {}
+                    }
+                }
+            }
+            tx.send(()).unwrap();
+        });
+        for _ in 0..100000 {
+            q.push(1);
+        }
+        rx.recv().unwrap();
+    }
+}
diff --git a/library/std/src/sync/mpsc/sync_tests.rs b/library/std/src/sync/mpsc/sync_tests.rs
new file mode 100644
index 00000000000..0052a38f7bb
--- /dev/null
+++ b/library/std/src/sync/mpsc/sync_tests.rs
@@ -0,0 +1,647 @@
+use super::*;
+use crate::env;
+use crate::thread;
+use crate::time::Duration;
+
+pub fn stress_factor() -> usize {
+    match env::var("RUST_TEST_STRESS") {
+        Ok(val) => val.parse().unwrap(),
+        Err(..) => 1,
+    }
+}
+
+#[test]
+fn smoke() {
+    let (tx, rx) = sync_channel::<i32>(1);
+    tx.send(1).unwrap();
+    assert_eq!(rx.recv().unwrap(), 1);
+}
+
+#[test]
+fn drop_full() {
+    let (tx, _rx) = sync_channel::<Box<isize>>(1);
+    tx.send(box 1).unwrap();
+}
+
+#[test]
+fn smoke_shared() {
+    let (tx, rx) = sync_channel::<i32>(1);
+    tx.send(1).unwrap();
+    assert_eq!(rx.recv().unwrap(), 1);
+    let tx = tx.clone();
+    tx.send(1).unwrap();
+    assert_eq!(rx.recv().unwrap(), 1);
+}
+
+#[test]
+fn recv_timeout() {
+    let (tx, rx) = sync_channel::<i32>(1);
+    assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Err(RecvTimeoutError::Timeout));
+    tx.send(1).unwrap();
+    assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(1));
+}
+
+#[test]
+fn smoke_threads() {
+    let (tx, rx) = sync_channel::<i32>(0);
+    let _t = thread::spawn(move || {
+        tx.send(1).unwrap();
+    });
+    assert_eq!(rx.recv().unwrap(), 1);
+}
+
+#[test]
+fn smoke_port_gone() {
+    let (tx, rx) = sync_channel::<i32>(0);
+    drop(rx);
+    assert!(tx.send(1).is_err());
+}
+
+#[test]
+fn smoke_shared_port_gone2() {
+    let (tx, rx) = sync_channel::<i32>(0);
+    drop(rx);
+    let tx2 = tx.clone();
+    drop(tx);
+    assert!(tx2.send(1).is_err());
+}
+
+#[test]
+fn port_gone_concurrent() {
+    let (tx, rx) = sync_channel::<i32>(0);
+    let _t = thread::spawn(move || {
+        rx.recv().unwrap();
+    });
+    while tx.send(1).is_ok() {}
+}
+
+#[test]
+fn port_gone_concurrent_shared() {
+    let (tx, rx) = sync_channel::<i32>(0);
+    let tx2 = tx.clone();
+    let _t = thread::spawn(move || {
+        rx.recv().unwrap();
+    });
+    while tx.send(1).is_ok() && tx2.send(1).is_ok() {}
+}
+
+#[test]
+fn smoke_chan_gone() {
+    let (tx, rx) = sync_channel::<i32>(0);
+    drop(tx);
+    assert!(rx.recv().is_err());
+}
+
+#[test]
+fn smoke_chan_gone_shared() {
+    let (tx, rx) = sync_channel::<()>(0);
+    let tx2 = tx.clone();
+    drop(tx);
+    drop(tx2);
+    assert!(rx.recv().is_err());
+}
+
+#[test]
+fn chan_gone_concurrent() {
+    let (tx, rx) = sync_channel::<i32>(0);
+    thread::spawn(move || {
+        tx.send(1).unwrap();
+        tx.send(1).unwrap();
+    });
+    while rx.recv().is_ok() {}
+}
+
+#[test]
+fn stress() {
+    let (tx, rx) = sync_channel::<i32>(0);
+    thread::spawn(move || {
+        for _ in 0..10000 {
+            tx.send(1).unwrap();
+        }
+    });
+    for _ in 0..10000 {
+        assert_eq!(rx.recv().unwrap(), 1);
+    }
+}
+
+#[test]
+fn stress_recv_timeout_two_threads() {
+    let (tx, rx) = sync_channel::<i32>(0);
+
+    thread::spawn(move || {
+        for _ in 0..10000 {
+            tx.send(1).unwrap();
+        }
+    });
+
+    let mut recv_count = 0;
+    loop {
+        match rx.recv_timeout(Duration::from_millis(1)) {
+            Ok(v) => {
+                assert_eq!(v, 1);
+                recv_count += 1;
+            }
+            Err(RecvTimeoutError::Timeout) => continue,
+            Err(RecvTimeoutError::Disconnected) => break,
+        }
+    }
+
+    assert_eq!(recv_count, 10000);
+}
+
+#[test]
+fn stress_recv_timeout_shared() {
+    const AMT: u32 = 1000;
+    const NTHREADS: u32 = 8;
+    let (tx, rx) = sync_channel::<i32>(0);
+    let (dtx, drx) = sync_channel::<()>(0);
+
+    thread::spawn(move || {
+        let mut recv_count = 0;
+        loop {
+            match rx.recv_timeout(Duration::from_millis(10)) {
+                Ok(v) => {
+                    assert_eq!(v, 1);
+                    recv_count += 1;
+                }
+                Err(RecvTimeoutError::Timeout) => continue,
+                Err(RecvTimeoutError::Disconnected) => break,
+            }
+        }
+
+        assert_eq!(recv_count, AMT * NTHREADS);
+        assert!(rx.try_recv().is_err());
+
+        dtx.send(()).unwrap();
+    });
+
+    for _ in 0..NTHREADS {
+        let tx = tx.clone();
+        thread::spawn(move || {
+            for _ in 0..AMT {
+                tx.send(1).unwrap();
+            }
+        });
+    }
+
+    drop(tx);
+
+    drx.recv().unwrap();
+}
+
+#[test]
+fn stress_shared() {
+    const AMT: u32 = 1000;
+    const NTHREADS: u32 = 8;
+    let (tx, rx) = sync_channel::<i32>(0);
+    let (dtx, drx) = sync_channel::<()>(0);
+
+    thread::spawn(move || {
+        for _ in 0..AMT * NTHREADS {
+            assert_eq!(rx.recv().unwrap(), 1);
+        }
+        match rx.try_recv() {
+            Ok(..) => panic!(),
+            _ => {}
+        }
+        dtx.send(()).unwrap();
+    });
+
+    for _ in 0..NTHREADS {
+        let tx = tx.clone();
+        thread::spawn(move || {
+            for _ in 0..AMT {
+                tx.send(1).unwrap();
+            }
+        });
+    }
+    drop(tx);
+    drx.recv().unwrap();
+}
+
+#[test]
+fn oneshot_single_thread_close_port_first() {
+    // Simple test of closing without sending
+    let (_tx, rx) = sync_channel::<i32>(0);
+    drop(rx);
+}
+
+#[test]
+fn oneshot_single_thread_close_chan_first() {
+    // Simple test of closing without sending
+    let (tx, _rx) = sync_channel::<i32>(0);
+    drop(tx);
+}
+
+#[test]
+fn oneshot_single_thread_send_port_close() {
+    // Testing that the sender cleans up the payload if receiver is closed
+    let (tx, rx) = sync_channel::<Box<i32>>(0);
+    drop(rx);
+    assert!(tx.send(box 0).is_err());
+}
+
+#[test]
+fn oneshot_single_thread_recv_chan_close() {
+    // Receiving on a closed chan will panic
+    let res = thread::spawn(move || {
+        let (tx, rx) = sync_channel::<i32>(0);
+        drop(tx);
+        rx.recv().unwrap();
+    })
+    .join();
+    // What is our res?
+    assert!(res.is_err());
+}
+
+#[test]
+fn oneshot_single_thread_send_then_recv() {
+    let (tx, rx) = sync_channel::<Box<i32>>(1);
+    tx.send(box 10).unwrap();
+    assert!(*rx.recv().unwrap() == 10);
+}
+
+#[test]
+fn oneshot_single_thread_try_send_open() {
+    let (tx, rx) = sync_channel::<i32>(1);
+    assert_eq!(tx.try_send(10), Ok(()));
+    assert!(rx.recv().unwrap() == 10);
+}
+
+#[test]
+fn oneshot_single_thread_try_send_closed() {
+    let (tx, rx) = sync_channel::<i32>(0);
+    drop(rx);
+    assert_eq!(tx.try_send(10), Err(TrySendError::Disconnected(10)));
+}
+
+#[test]
+fn oneshot_single_thread_try_send_closed2() {
+    let (tx, _rx) = sync_channel::<i32>(0);
+    assert_eq!(tx.try_send(10), Err(TrySendError::Full(10)));
+}
+
+#[test]
+fn oneshot_single_thread_try_recv_open() {
+    let (tx, rx) = sync_channel::<i32>(1);
+    tx.send(10).unwrap();
+    assert!(rx.recv() == Ok(10));
+}
+
+#[test]
+fn oneshot_single_thread_try_recv_closed() {
+    let (tx, rx) = sync_channel::<i32>(0);
+    drop(tx);
+    assert!(rx.recv().is_err());
+}
+
+#[test]
+fn oneshot_single_thread_try_recv_closed_with_data() {
+    let (tx, rx) = sync_channel::<i32>(1);
+    tx.send(10).unwrap();
+    drop(tx);
+    assert_eq!(rx.try_recv(), Ok(10));
+    assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
+}
+
+#[test]
+fn oneshot_single_thread_peek_data() {
+    let (tx, rx) = sync_channel::<i32>(1);
+    assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
+    tx.send(10).unwrap();
+    assert_eq!(rx.try_recv(), Ok(10));
+}
+
+#[test]
+fn oneshot_single_thread_peek_close() {
+    let (tx, rx) = sync_channel::<i32>(0);
+    drop(tx);
+    assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
+    assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
+}
+
+#[test]
+fn oneshot_single_thread_peek_open() {
+    let (_tx, rx) = sync_channel::<i32>(0);
+    assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
+}
+
+#[test]
+fn oneshot_multi_task_recv_then_send() {
+    let (tx, rx) = sync_channel::<Box<i32>>(0);
+    let _t = thread::spawn(move || {
+        assert!(*rx.recv().unwrap() == 10);
+    });
+
+    tx.send(box 10).unwrap();
+}
+
+#[test]
+fn oneshot_multi_task_recv_then_close() {
+    let (tx, rx) = sync_channel::<Box<i32>>(0);
+    let _t = thread::spawn(move || {
+        drop(tx);
+    });
+    let res = thread::spawn(move || {
+        assert!(*rx.recv().unwrap() == 10);
+    })
+    .join();
+    assert!(res.is_err());
+}
+
+#[test]
+fn oneshot_multi_thread_close_stress() {
+    for _ in 0..stress_factor() {
+        let (tx, rx) = sync_channel::<i32>(0);
+        let _t = thread::spawn(move || {
+            drop(rx);
+        });
+        drop(tx);
+    }
+}
+
+#[test]
+fn oneshot_multi_thread_send_close_stress() {
+    for _ in 0..stress_factor() {
+        let (tx, rx) = sync_channel::<i32>(0);
+        let _t = thread::spawn(move || {
+            drop(rx);
+        });
+        let _ = thread::spawn(move || {
+            tx.send(1).unwrap();
+        })
+        .join();
+    }
+}
+
+#[test]
+fn oneshot_multi_thread_recv_close_stress() {
+    for _ in 0..stress_factor() {
+        let (tx, rx) = sync_channel::<i32>(0);
+        let _t = thread::spawn(move || {
+            let res = thread::spawn(move || {
+                rx.recv().unwrap();
+            })
+            .join();
+            assert!(res.is_err());
+        });
+        let _t = thread::spawn(move || {
+            thread::spawn(move || {
+                drop(tx);
+            });
+        });
+    }
+}
+
+#[test]
+fn oneshot_multi_thread_send_recv_stress() {
+    for _ in 0..stress_factor() {
+        let (tx, rx) = sync_channel::<Box<i32>>(0);
+        let _t = thread::spawn(move || {
+            tx.send(box 10).unwrap();
+        });
+        assert!(*rx.recv().unwrap() == 10);
+    }
+}
+
+#[test]
+fn stream_send_recv_stress() {
+    for _ in 0..stress_factor() {
+        let (tx, rx) = sync_channel::<Box<i32>>(0);
+
+        send(tx, 0);
+        recv(rx, 0);
+
+        fn send(tx: SyncSender<Box<i32>>, i: i32) {
+            if i == 10 {
+                return;
+            }
+
+            thread::spawn(move || {
+                tx.send(box i).unwrap();
+                send(tx, i + 1);
+            });
+        }
+
+        fn recv(rx: Receiver<Box<i32>>, i: i32) {
+            if i == 10 {
+                return;
+            }
+
+            thread::spawn(move || {
+                assert!(*rx.recv().unwrap() == i);
+                recv(rx, i + 1);
+            });
+        }
+    }
+}
+
+#[test]
+fn recv_a_lot() {
+    // Regression test that we don't run out of stack in scheduler context
+    let (tx, rx) = sync_channel(10000);
+    for _ in 0..10000 {
+        tx.send(()).unwrap();
+    }
+    for _ in 0..10000 {
+        rx.recv().unwrap();
+    }
+}
+
+#[test]
+fn shared_chan_stress() {
+    let (tx, rx) = sync_channel(0);
+    let total = stress_factor() + 100;
+    for _ in 0..total {
+        let tx = tx.clone();
+        thread::spawn(move || {
+            tx.send(()).unwrap();
+        });
+    }
+
+    for _ in 0..total {
+        rx.recv().unwrap();
+    }
+}
+
+#[test]
+fn test_nested_recv_iter() {
+    let (tx, rx) = sync_channel::<i32>(0);
+    let (total_tx, total_rx) = sync_channel::<i32>(0);
+
+    let _t = thread::spawn(move || {
+        let mut acc = 0;
+        for x in rx.iter() {
+            acc += x;
+        }
+        total_tx.send(acc).unwrap();
+    });
+
+    tx.send(3).unwrap();
+    tx.send(1).unwrap();
+    tx.send(2).unwrap();
+    drop(tx);
+    assert_eq!(total_rx.recv().unwrap(), 6);
+}
+
+#[test]
+fn test_recv_iter_break() {
+    let (tx, rx) = sync_channel::<i32>(0);
+    let (count_tx, count_rx) = sync_channel(0);
+
+    let _t = thread::spawn(move || {
+        let mut count = 0;
+        for x in rx.iter() {
+            if count >= 3 {
+                break;
+            } else {
+                count += x;
+            }
+        }
+        count_tx.send(count).unwrap();
+    });
+
+    tx.send(2).unwrap();
+    tx.send(2).unwrap();
+    tx.send(2).unwrap();
+    let _ = tx.try_send(2);
+    drop(tx);
+    assert_eq!(count_rx.recv().unwrap(), 4);
+}
+
+#[test]
+fn try_recv_states() {
+    let (tx1, rx1) = sync_channel::<i32>(1);
+    let (tx2, rx2) = sync_channel::<()>(1);
+    let (tx3, rx3) = sync_channel::<()>(1);
+    let _t = thread::spawn(move || {
+        rx2.recv().unwrap();
+        tx1.send(1).unwrap();
+        tx3.send(()).unwrap();
+        rx2.recv().unwrap();
+        drop(tx1);
+        tx3.send(()).unwrap();
+    });
+
+    assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty));
+    tx2.send(()).unwrap();
+    rx3.recv().unwrap();
+    assert_eq!(rx1.try_recv(), Ok(1));
+    assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty));
+    tx2.send(()).unwrap();
+    rx3.recv().unwrap();
+    assert_eq!(rx1.try_recv(), Err(TryRecvError::Disconnected));
+}
+
+// This bug used to end up in a livelock inside of the Receiver destructor
+// because the internal state of the Shared packet was corrupted
+#[test]
+fn destroy_upgraded_shared_port_when_sender_still_active() {
+    let (tx, rx) = sync_channel::<()>(0);
+    let (tx2, rx2) = sync_channel::<()>(0);
+    let _t = thread::spawn(move || {
+        rx.recv().unwrap(); // wait on a oneshot
+        drop(rx); // destroy a shared
+        tx2.send(()).unwrap();
+    });
+    // make sure the other thread has gone to sleep
+    for _ in 0..5000 {
+        thread::yield_now();
+    }
+
+    // upgrade to a shared chan and send a message
+    let t = tx.clone();
+    drop(tx);
+    t.send(()).unwrap();
+
+    // wait for the child thread to exit before we exit
+    rx2.recv().unwrap();
+}
+
+#[test]
+fn send1() {
+    let (tx, rx) = sync_channel::<i32>(0);
+    let _t = thread::spawn(move || {
+        rx.recv().unwrap();
+    });
+    assert_eq!(tx.send(1), Ok(()));
+}
+
+#[test]
+fn send2() {
+    let (tx, rx) = sync_channel::<i32>(0);
+    let _t = thread::spawn(move || {
+        drop(rx);
+    });
+    assert!(tx.send(1).is_err());
+}
+
+#[test]
+fn send3() {
+    let (tx, rx) = sync_channel::<i32>(1);
+    assert_eq!(tx.send(1), Ok(()));
+    let _t = thread::spawn(move || {
+        drop(rx);
+    });
+    assert!(tx.send(1).is_err());
+}
+
+#[test]
+fn send4() {
+    let (tx, rx) = sync_channel::<i32>(0);
+    let tx2 = tx.clone();
+    let (done, donerx) = channel();
+    let done2 = done.clone();
+    let _t = thread::spawn(move || {
+        assert!(tx.send(1).is_err());
+        done.send(()).unwrap();
+    });
+    let _t = thread::spawn(move || {
+        assert!(tx2.send(2).is_err());
+        done2.send(()).unwrap();
+    });
+    drop(rx);
+    donerx.recv().unwrap();
+    donerx.recv().unwrap();
+}
+
+#[test]
+fn try_send1() {
+    let (tx, _rx) = sync_channel::<i32>(0);
+    assert_eq!(tx.try_send(1), Err(TrySendError::Full(1)));
+}
+
+#[test]
+fn try_send2() {
+    let (tx, _rx) = sync_channel::<i32>(1);
+    assert_eq!(tx.try_send(1), Ok(()));
+    assert_eq!(tx.try_send(1), Err(TrySendError::Full(1)));
+}
+
+#[test]
+fn try_send3() {
+    let (tx, rx) = sync_channel::<i32>(1);
+    assert_eq!(tx.try_send(1), Ok(()));
+    drop(rx);
+    assert_eq!(tx.try_send(1), Err(TrySendError::Disconnected(1)));
+}
+
+#[test]
+fn issue_15761() {
+    fn repro() {
+        let (tx1, rx1) = sync_channel::<()>(3);
+        let (tx2, rx2) = sync_channel::<()>(3);
+
+        let _t = thread::spawn(move || {
+            rx1.recv().unwrap();
+            tx2.try_send(()).unwrap();
+        });
+
+        tx1.try_send(()).unwrap();
+        rx2.recv().unwrap();
+    }
+
+    for _ in 0..100 {
+        repro()
+    }
+}
diff --git a/library/std/src/sync/mpsc/tests.rs b/library/std/src/sync/mpsc/tests.rs
new file mode 100644
index 00000000000..184ce193cbe
--- /dev/null
+++ b/library/std/src/sync/mpsc/tests.rs
@@ -0,0 +1,706 @@
+use super::*;
+use crate::env;
+use crate::thread;
+use crate::time::{Duration, Instant};
+
+pub fn stress_factor() -> usize {
+    match env::var("RUST_TEST_STRESS") {
+        Ok(val) => val.parse().unwrap(),
+        Err(..) => 1,
+    }
+}
+
+#[test]
+fn smoke() {
+    let (tx, rx) = channel::<i32>();
+    tx.send(1).unwrap();
+    assert_eq!(rx.recv().unwrap(), 1);
+}
+
+#[test]
+fn drop_full() {
+    let (tx, _rx) = channel::<Box<isize>>();
+    tx.send(box 1).unwrap();
+}
+
+#[test]
+fn drop_full_shared() {
+    let (tx, _rx) = channel::<Box<isize>>();
+    drop(tx.clone());
+    drop(tx.clone());
+    tx.send(box 1).unwrap();
+}
+
+#[test]
+fn smoke_shared() {
+    let (tx, rx) = channel::<i32>();
+    tx.send(1).unwrap();
+    assert_eq!(rx.recv().unwrap(), 1);
+    let tx = tx.clone();
+    tx.send(1).unwrap();
+    assert_eq!(rx.recv().unwrap(), 1);
+}
+
+#[test]
+fn smoke_threads() {
+    let (tx, rx) = channel::<i32>();
+    let _t = thread::spawn(move || {
+        tx.send(1).unwrap();
+    });
+    assert_eq!(rx.recv().unwrap(), 1);
+}
+
+#[test]
+fn smoke_port_gone() {
+    let (tx, rx) = channel::<i32>();
+    drop(rx);
+    assert!(tx.send(1).is_err());
+}
+
+#[test]
+fn smoke_shared_port_gone() {
+    let (tx, rx) = channel::<i32>();
+    drop(rx);
+    assert!(tx.send(1).is_err())
+}
+
+#[test]
+fn smoke_shared_port_gone2() {
+    let (tx, rx) = channel::<i32>();
+    drop(rx);
+    let tx2 = tx.clone();
+    drop(tx);
+    assert!(tx2.send(1).is_err());
+}
+
+#[test]
+fn port_gone_concurrent() {
+    let (tx, rx) = channel::<i32>();
+    let _t = thread::spawn(move || {
+        rx.recv().unwrap();
+    });
+    while tx.send(1).is_ok() {}
+}
+
+#[test]
+fn port_gone_concurrent_shared() {
+    let (tx, rx) = channel::<i32>();
+    let tx2 = tx.clone();
+    let _t = thread::spawn(move || {
+        rx.recv().unwrap();
+    });
+    while tx.send(1).is_ok() && tx2.send(1).is_ok() {}
+}
+
+#[test]
+fn smoke_chan_gone() {
+    let (tx, rx) = channel::<i32>();
+    drop(tx);
+    assert!(rx.recv().is_err());
+}
+
+#[test]
+fn smoke_chan_gone_shared() {
+    let (tx, rx) = channel::<()>();
+    let tx2 = tx.clone();
+    drop(tx);
+    drop(tx2);
+    assert!(rx.recv().is_err());
+}
+
+#[test]
+fn chan_gone_concurrent() {
+    let (tx, rx) = channel::<i32>();
+    let _t = thread::spawn(move || {
+        tx.send(1).unwrap();
+        tx.send(1).unwrap();
+    });
+    while rx.recv().is_ok() {}
+}
+
+#[test]
+fn stress() {
+    let (tx, rx) = channel::<i32>();
+    let t = thread::spawn(move || {
+        for _ in 0..10000 {
+            tx.send(1).unwrap();
+        }
+    });
+    for _ in 0..10000 {
+        assert_eq!(rx.recv().unwrap(), 1);
+    }
+    t.join().ok().expect("thread panicked");
+}
+
+#[test]
+fn stress_shared() {
+    const AMT: u32 = 10000;
+    const NTHREADS: u32 = 8;
+    let (tx, rx) = channel::<i32>();
+
+    let t = thread::spawn(move || {
+        for _ in 0..AMT * NTHREADS {
+            assert_eq!(rx.recv().unwrap(), 1);
+        }
+        match rx.try_recv() {
+            Ok(..) => panic!(),
+            _ => {}
+        }
+    });
+
+    for _ in 0..NTHREADS {
+        let tx = tx.clone();
+        thread::spawn(move || {
+            for _ in 0..AMT {
+                tx.send(1).unwrap();
+            }
+        });
+    }
+    drop(tx);
+    t.join().ok().expect("thread panicked");
+}
+
+#[test]
+fn send_from_outside_runtime() {
+    let (tx1, rx1) = channel::<()>();
+    let (tx2, rx2) = channel::<i32>();
+    let t1 = thread::spawn(move || {
+        tx1.send(()).unwrap();
+        for _ in 0..40 {
+            assert_eq!(rx2.recv().unwrap(), 1);
+        }
+    });
+    rx1.recv().unwrap();
+    let t2 = thread::spawn(move || {
+        for _ in 0..40 {
+            tx2.send(1).unwrap();
+        }
+    });
+    t1.join().ok().expect("thread panicked");
+    t2.join().ok().expect("thread panicked");
+}
+
+#[test]
+fn recv_from_outside_runtime() {
+    let (tx, rx) = channel::<i32>();
+    let t = thread::spawn(move || {
+        for _ in 0..40 {
+            assert_eq!(rx.recv().unwrap(), 1);
+        }
+    });
+    for _ in 0..40 {
+        tx.send(1).unwrap();
+    }
+    t.join().ok().expect("thread panicked");
+}
+
+#[test]
+fn no_runtime() {
+    let (tx1, rx1) = channel::<i32>();
+    let (tx2, rx2) = channel::<i32>();
+    let t1 = thread::spawn(move || {
+        assert_eq!(rx1.recv().unwrap(), 1);
+        tx2.send(2).unwrap();
+    });
+    let t2 = thread::spawn(move || {
+        tx1.send(1).unwrap();
+        assert_eq!(rx2.recv().unwrap(), 2);
+    });
+    t1.join().ok().expect("thread panicked");
+    t2.join().ok().expect("thread panicked");
+}
+
+#[test]
+fn oneshot_single_thread_close_port_first() {
+    // Simple test of closing without sending
+    let (_tx, rx) = channel::<i32>();
+    drop(rx);
+}
+
+#[test]
+fn oneshot_single_thread_close_chan_first() {
+    // Simple test of closing without sending
+    let (tx, _rx) = channel::<i32>();
+    drop(tx);
+}
+
+#[test]
+fn oneshot_single_thread_send_port_close() {
+    // Testing that the sender cleans up the payload if receiver is closed
+    let (tx, rx) = channel::<Box<i32>>();
+    drop(rx);
+    assert!(tx.send(box 0).is_err());
+}
+
+#[test]
+fn oneshot_single_thread_recv_chan_close() {
+    // Receiving on a closed chan will panic
+    let res = thread::spawn(move || {
+        let (tx, rx) = channel::<i32>();
+        drop(tx);
+        rx.recv().unwrap();
+    })
+    .join();
+    // What is our res?
+    assert!(res.is_err());
+}
+
+#[test]
+fn oneshot_single_thread_send_then_recv() {
+    let (tx, rx) = channel::<Box<i32>>();
+    tx.send(box 10).unwrap();
+    assert!(*rx.recv().unwrap() == 10);
+}
+
+#[test]
+fn oneshot_single_thread_try_send_open() {
+    let (tx, rx) = channel::<i32>();
+    assert!(tx.send(10).is_ok());
+    assert!(rx.recv().unwrap() == 10);
+}
+
+#[test]
+fn oneshot_single_thread_try_send_closed() {
+    let (tx, rx) = channel::<i32>();
+    drop(rx);
+    assert!(tx.send(10).is_err());
+}
+
+#[test]
+fn oneshot_single_thread_try_recv_open() {
+    let (tx, rx) = channel::<i32>();
+    tx.send(10).unwrap();
+    assert!(rx.recv() == Ok(10));
+}
+
+#[test]
+fn oneshot_single_thread_try_recv_closed() {
+    let (tx, rx) = channel::<i32>();
+    drop(tx);
+    assert!(rx.recv().is_err());
+}
+
+#[test]
+fn oneshot_single_thread_peek_data() {
+    let (tx, rx) = channel::<i32>();
+    assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
+    tx.send(10).unwrap();
+    assert_eq!(rx.try_recv(), Ok(10));
+}
+
+#[test]
+fn oneshot_single_thread_peek_close() {
+    let (tx, rx) = channel::<i32>();
+    drop(tx);
+    assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
+    assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
+}
+
+#[test]
+fn oneshot_single_thread_peek_open() {
+    let (_tx, rx) = channel::<i32>();
+    assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
+}
+
+#[test]
+fn oneshot_multi_task_recv_then_send() {
+    let (tx, rx) = channel::<Box<i32>>();
+    let _t = thread::spawn(move || {
+        assert!(*rx.recv().unwrap() == 10);
+    });
+
+    tx.send(box 10).unwrap();
+}
+
+#[test]
+fn oneshot_multi_task_recv_then_close() {
+    let (tx, rx) = channel::<Box<i32>>();
+    let _t = thread::spawn(move || {
+        drop(tx);
+    });
+    let res = thread::spawn(move || {
+        assert!(*rx.recv().unwrap() == 10);
+    })
+    .join();
+    assert!(res.is_err());
+}
+
+#[test]
+fn oneshot_multi_thread_close_stress() {
+    for _ in 0..stress_factor() {
+        let (tx, rx) = channel::<i32>();
+        let _t = thread::spawn(move || {
+            drop(rx);
+        });
+        drop(tx);
+    }
+}
+
+#[test]
+fn oneshot_multi_thread_send_close_stress() {
+    for _ in 0..stress_factor() {
+        let (tx, rx) = channel::<i32>();
+        let _t = thread::spawn(move || {
+            drop(rx);
+        });
+        let _ = thread::spawn(move || {
+            tx.send(1).unwrap();
+        })
+        .join();
+    }
+}
+
+#[test]
+fn oneshot_multi_thread_recv_close_stress() {
+    for _ in 0..stress_factor() {
+        let (tx, rx) = channel::<i32>();
+        thread::spawn(move || {
+            let res = thread::spawn(move || {
+                rx.recv().unwrap();
+            })
+            .join();
+            assert!(res.is_err());
+        });
+        let _t = thread::spawn(move || {
+            thread::spawn(move || {
+                drop(tx);
+            });
+        });
+    }
+}
+
+#[test]
+fn oneshot_multi_thread_send_recv_stress() {
+    for _ in 0..stress_factor() {
+        let (tx, rx) = channel::<Box<isize>>();
+        let _t = thread::spawn(move || {
+            tx.send(box 10).unwrap();
+        });
+        assert!(*rx.recv().unwrap() == 10);
+    }
+}
+
+#[test]
+fn stream_send_recv_stress() {
+    for _ in 0..stress_factor() {
+        let (tx, rx) = channel();
+
+        send(tx, 0);
+        recv(rx, 0);
+
+        fn send(tx: Sender<Box<i32>>, i: i32) {
+            if i == 10 {
+                return;
+            }
+
+            thread::spawn(move || {
+                tx.send(box i).unwrap();
+                send(tx, i + 1);
+            });
+        }
+
+        fn recv(rx: Receiver<Box<i32>>, i: i32) {
+            if i == 10 {
+                return;
+            }
+
+            thread::spawn(move || {
+                assert!(*rx.recv().unwrap() == i);
+                recv(rx, i + 1);
+            });
+        }
+    }
+}
+
+#[test]
+fn oneshot_single_thread_recv_timeout() {
+    let (tx, rx) = channel();
+    tx.send(()).unwrap();
+    assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(()));
+    assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Err(RecvTimeoutError::Timeout));
+    tx.send(()).unwrap();
+    assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(()));
+}
+
+#[test]
+fn stress_recv_timeout_two_threads() {
+    let (tx, rx) = channel();
+    let stress = stress_factor() + 100;
+    let timeout = Duration::from_millis(100);
+
+    thread::spawn(move || {
+        for i in 0..stress {
+            if i % 2 == 0 {
+                thread::sleep(timeout * 2);
+            }
+            tx.send(1usize).unwrap();
+        }
+    });
+
+    let mut recv_count = 0;
+    loop {
+        match rx.recv_timeout(timeout) {
+            Ok(n) => {
+                assert_eq!(n, 1usize);
+                recv_count += 1;
+            }
+            Err(RecvTimeoutError::Timeout) => continue,
+            Err(RecvTimeoutError::Disconnected) => break,
+        }
+    }
+
+    assert_eq!(recv_count, stress);
+}
+
+#[test]
+fn recv_timeout_upgrade() {
+    let (tx, rx) = channel::<()>();
+    let timeout = Duration::from_millis(1);
+    let _tx_clone = tx.clone();
+
+    let start = Instant::now();
+    assert_eq!(rx.recv_timeout(timeout), Err(RecvTimeoutError::Timeout));
+    assert!(Instant::now() >= start + timeout);
+}
+
+#[test]
+fn stress_recv_timeout_shared() {
+    let (tx, rx) = channel();
+    let stress = stress_factor() + 100;
+
+    for i in 0..stress {
+        let tx = tx.clone();
+        thread::spawn(move || {
+            thread::sleep(Duration::from_millis(i as u64 * 10));
+            tx.send(1usize).unwrap();
+        });
+    }
+
+    drop(tx);
+
+    let mut recv_count = 0;
+    loop {
+        match rx.recv_timeout(Duration::from_millis(10)) {
+            Ok(n) => {
+                assert_eq!(n, 1usize);
+                recv_count += 1;
+            }
+            Err(RecvTimeoutError::Timeout) => continue,
+            Err(RecvTimeoutError::Disconnected) => break,
+        }
+    }
+
+    assert_eq!(recv_count, stress);
+}
+
+#[test]
+fn very_long_recv_timeout_wont_panic() {
+    let (tx, rx) = channel::<()>();
+    let join_handle = thread::spawn(move || rx.recv_timeout(Duration::from_secs(u64::MAX)));
+    thread::sleep(Duration::from_secs(1));
+    assert!(tx.send(()).is_ok());
+    assert_eq!(join_handle.join().unwrap(), Ok(()));
+}
+
+#[test]
+fn recv_a_lot() {
+    // Regression test that we don't run out of stack in scheduler context
+    let (tx, rx) = channel();
+    for _ in 0..10000 {
+        tx.send(()).unwrap();
+    }
+    for _ in 0..10000 {
+        rx.recv().unwrap();
+    }
+}
+
+#[test]
+fn shared_recv_timeout() {
+    let (tx, rx) = channel();
+    let total = 5;
+    for _ in 0..total {
+        let tx = tx.clone();
+        thread::spawn(move || {
+            tx.send(()).unwrap();
+        });
+    }
+
+    for _ in 0..total {
+        rx.recv().unwrap();
+    }
+
+    assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Err(RecvTimeoutError::Timeout));
+    tx.send(()).unwrap();
+    assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(()));
+}
+
+#[test]
+fn shared_chan_stress() {
+    let (tx, rx) = channel();
+    let total = stress_factor() + 100;
+    for _ in 0..total {
+        let tx = tx.clone();
+        thread::spawn(move || {
+            tx.send(()).unwrap();
+        });
+    }
+
+    for _ in 0..total {
+        rx.recv().unwrap();
+    }
+}
+
+#[test]
+fn test_nested_recv_iter() {
+    let (tx, rx) = channel::<i32>();
+    let (total_tx, total_rx) = channel::<i32>();
+
+    let _t = thread::spawn(move || {
+        let mut acc = 0;
+        for x in rx.iter() {
+            acc += x;
+        }
+        total_tx.send(acc).unwrap();
+    });
+
+    tx.send(3).unwrap();
+    tx.send(1).unwrap();
+    tx.send(2).unwrap();
+    drop(tx);
+    assert_eq!(total_rx.recv().unwrap(), 6);
+}
+
+#[test]
+fn test_recv_iter_break() {
+    let (tx, rx) = channel::<i32>();
+    let (count_tx, count_rx) = channel();
+
+    let _t = thread::spawn(move || {
+        let mut count = 0;
+        for x in rx.iter() {
+            if count >= 3 {
+                break;
+            } else {
+                count += x;
+            }
+        }
+        count_tx.send(count).unwrap();
+    });
+
+    tx.send(2).unwrap();
+    tx.send(2).unwrap();
+    tx.send(2).unwrap();
+    let _ = tx.send(2);
+    drop(tx);
+    assert_eq!(count_rx.recv().unwrap(), 4);
+}
+
+#[test]
+fn test_recv_try_iter() {
+    let (request_tx, request_rx) = channel();
+    let (response_tx, response_rx) = channel();
+
+    // Request `x`s until we have `6`.
+    let t = thread::spawn(move || {
+        let mut count = 0;
+        loop {
+            for x in response_rx.try_iter() {
+                count += x;
+                if count == 6 {
+                    return count;
+                }
+            }
+            request_tx.send(()).unwrap();
+        }
+    });
+
+    for _ in request_rx.iter() {
+        if response_tx.send(2).is_err() {
+            break;
+        }
+    }
+
+    assert_eq!(t.join().unwrap(), 6);
+}
+
+#[test]
+fn test_recv_into_iter_owned() {
+    let mut iter = {
+        let (tx, rx) = channel::<i32>();
+        tx.send(1).unwrap();
+        tx.send(2).unwrap();
+
+        rx.into_iter()
+    };
+    assert_eq!(iter.next().unwrap(), 1);
+    assert_eq!(iter.next().unwrap(), 2);
+    assert_eq!(iter.next().is_none(), true);
+}
+
+#[test]
+fn test_recv_into_iter_borrowed() {
+    let (tx, rx) = channel::<i32>();
+    tx.send(1).unwrap();
+    tx.send(2).unwrap();
+    drop(tx);
+    let mut iter = (&rx).into_iter();
+    assert_eq!(iter.next().unwrap(), 1);
+    assert_eq!(iter.next().unwrap(), 2);
+    assert_eq!(iter.next().is_none(), true);
+}
+
+#[test]
+fn try_recv_states() {
+    let (tx1, rx1) = channel::<i32>();
+    let (tx2, rx2) = channel::<()>();
+    let (tx3, rx3) = channel::<()>();
+    let _t = thread::spawn(move || {
+        rx2.recv().unwrap();
+        tx1.send(1).unwrap();
+        tx3.send(()).unwrap();
+        rx2.recv().unwrap();
+        drop(tx1);
+        tx3.send(()).unwrap();
+    });
+
+    assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty));
+    tx2.send(()).unwrap();
+    rx3.recv().unwrap();
+    assert_eq!(rx1.try_recv(), Ok(1));
+    assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty));
+    tx2.send(()).unwrap();
+    rx3.recv().unwrap();
+    assert_eq!(rx1.try_recv(), Err(TryRecvError::Disconnected));
+}
+
+// This bug used to end up in a livelock inside of the Receiver destructor
+// because the internal state of the Shared packet was corrupted
+#[test]
+fn destroy_upgraded_shared_port_when_sender_still_active() {
+    let (tx, rx) = channel();
+    let (tx2, rx2) = channel();
+    let _t = thread::spawn(move || {
+        rx.recv().unwrap(); // wait on a oneshot
+        drop(rx); // destroy a shared
+        tx2.send(()).unwrap();
+    });
+    // make sure the other thread has gone to sleep
+    for _ in 0..5000 {
+        thread::yield_now();
+    }
+
+    // upgrade to a shared chan and send a message
+    let t = tx.clone();
+    drop(tx);
+    t.send(()).unwrap();
+
+    // wait for the child thread to exit before we exit
+    rx2.recv().unwrap();
+}
+
+#[test]
+fn issue_32114() {
+    let (tx, _) = channel();
+    let _ = tx.send(123);
+    assert_eq!(tx.send(123), Err(SendError(123)));
+}
diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs
index d7a4f00305c..0de71793834 100644
--- a/library/std/src/sync/mutex.rs
+++ b/library/std/src/sync/mutex.rs
@@ -1,3 +1,6 @@
+#[cfg(all(test, not(target_os = "emscripten")))]
+mod tests;
+
 use crate::cell::UnsafeCell;
 use crate::fmt;
 use crate::mem;
@@ -515,245 +518,3 @@ pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex {
 pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
     &guard.lock.poison
 }
-
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod tests {
-    use crate::sync::atomic::{AtomicUsize, Ordering};
-    use crate::sync::mpsc::channel;
-    use crate::sync::{Arc, Condvar, Mutex};
-    use crate::thread;
-
-    struct Packet<T>(Arc<(Mutex<T>, Condvar)>);
-
-    #[derive(Eq, PartialEq, Debug)]
-    struct NonCopy(i32);
-
-    #[test]
-    fn smoke() {
-        let m = Mutex::new(());
-        drop(m.lock().unwrap());
-        drop(m.lock().unwrap());
-    }
-
-    #[test]
-    fn lots_and_lots() {
-        const J: u32 = 1000;
-        const K: u32 = 3;
-
-        let m = Arc::new(Mutex::new(0));
-
-        fn inc(m: &Mutex<u32>) {
-            for _ in 0..J {
-                *m.lock().unwrap() += 1;
-            }
-        }
-
-        let (tx, rx) = channel();
-        for _ in 0..K {
-            let tx2 = tx.clone();
-            let m2 = m.clone();
-            thread::spawn(move || {
-                inc(&m2);
-                tx2.send(()).unwrap();
-            });
-            let tx2 = tx.clone();
-            let m2 = m.clone();
-            thread::spawn(move || {
-                inc(&m2);
-                tx2.send(()).unwrap();
-            });
-        }
-
-        drop(tx);
-        for _ in 0..2 * K {
-            rx.recv().unwrap();
-        }
-        assert_eq!(*m.lock().unwrap(), J * K * 2);
-    }
-
-    #[test]
-    fn try_lock() {
-        let m = Mutex::new(());
-        *m.try_lock().unwrap() = ();
-    }
-
-    #[test]
-    fn test_into_inner() {
-        let m = Mutex::new(NonCopy(10));
-        assert_eq!(m.into_inner().unwrap(), NonCopy(10));
-    }
-
-    #[test]
-    fn test_into_inner_drop() {
-        struct Foo(Arc<AtomicUsize>);
-        impl Drop for Foo {
-            fn drop(&mut self) {
-                self.0.fetch_add(1, Ordering::SeqCst);
-            }
-        }
-        let num_drops = Arc::new(AtomicUsize::new(0));
-        let m = Mutex::new(Foo(num_drops.clone()));
-        assert_eq!(num_drops.load(Ordering::SeqCst), 0);
-        {
-            let _inner = m.into_inner().unwrap();
-            assert_eq!(num_drops.load(Ordering::SeqCst), 0);
-        }
-        assert_eq!(num_drops.load(Ordering::SeqCst), 1);
-    }
-
-    #[test]
-    fn test_into_inner_poison() {
-        let m = Arc::new(Mutex::new(NonCopy(10)));
-        let m2 = m.clone();
-        let _ = thread::spawn(move || {
-            let _lock = m2.lock().unwrap();
-            panic!("test panic in inner thread to poison mutex");
-        })
-        .join();
-
-        assert!(m.is_poisoned());
-        match Arc::try_unwrap(m).unwrap().into_inner() {
-            Err(e) => assert_eq!(e.into_inner(), NonCopy(10)),
-            Ok(x) => panic!("into_inner of poisoned Mutex is Ok: {:?}", x),
-        }
-    }
-
-    #[test]
-    fn test_get_mut() {
-        let mut m = Mutex::new(NonCopy(10));
-        *m.get_mut().unwrap() = NonCopy(20);
-        assert_eq!(m.into_inner().unwrap(), NonCopy(20));
-    }
-
-    #[test]
-    fn test_get_mut_poison() {
-        let m = Arc::new(Mutex::new(NonCopy(10)));
-        let m2 = m.clone();
-        let _ = thread::spawn(move || {
-            let _lock = m2.lock().unwrap();
-            panic!("test panic in inner thread to poison mutex");
-        })
-        .join();
-
-        assert!(m.is_poisoned());
-        match Arc::try_unwrap(m).unwrap().get_mut() {
-            Err(e) => assert_eq!(*e.into_inner(), NonCopy(10)),
-            Ok(x) => panic!("get_mut of poisoned Mutex is Ok: {:?}", x),
-        }
-    }
-
-    #[test]
-    fn test_mutex_arc_condvar() {
-        let packet = Packet(Arc::new((Mutex::new(false), Condvar::new())));
-        let packet2 = Packet(packet.0.clone());
-        let (tx, rx) = channel();
-        let _t = thread::spawn(move || {
-            // wait until parent gets in
-            rx.recv().unwrap();
-            let &(ref lock, ref cvar) = &*packet2.0;
-            let mut lock = lock.lock().unwrap();
-            *lock = true;
-            cvar.notify_one();
-        });
-
-        let &(ref lock, ref cvar) = &*packet.0;
-        let mut lock = lock.lock().unwrap();
-        tx.send(()).unwrap();
-        assert!(!*lock);
-        while !*lock {
-            lock = cvar.wait(lock).unwrap();
-        }
-    }
-
-    #[test]
-    fn test_arc_condvar_poison() {
-        let packet = Packet(Arc::new((Mutex::new(1), Condvar::new())));
-        let packet2 = Packet(packet.0.clone());
-        let (tx, rx) = channel();
-
-        let _t = thread::spawn(move || -> () {
-            rx.recv().unwrap();
-            let &(ref lock, ref cvar) = &*packet2.0;
-            let _g = lock.lock().unwrap();
-            cvar.notify_one();
-            // Parent should fail when it wakes up.
-            panic!();
-        });
-
-        let &(ref lock, ref cvar) = &*packet.0;
-        let mut lock = lock.lock().unwrap();
-        tx.send(()).unwrap();
-        while *lock == 1 {
-            match cvar.wait(lock) {
-                Ok(l) => {
-                    lock = l;
-                    assert_eq!(*lock, 1);
-                }
-                Err(..) => break,
-            }
-        }
-    }
-
-    #[test]
-    fn test_mutex_arc_poison() {
-        let arc = Arc::new(Mutex::new(1));
-        assert!(!arc.is_poisoned());
-        let arc2 = arc.clone();
-        let _ = thread::spawn(move || {
-            let lock = arc2.lock().unwrap();
-            assert_eq!(*lock, 2);
-        })
-        .join();
-        assert!(arc.lock().is_err());
-        assert!(arc.is_poisoned());
-    }
-
-    #[test]
-    fn test_mutex_arc_nested() {
-        // Tests nested mutexes and access
-        // to underlying data.
-        let arc = Arc::new(Mutex::new(1));
-        let arc2 = Arc::new(Mutex::new(arc));
-        let (tx, rx) = channel();
-        let _t = thread::spawn(move || {
-            let lock = arc2.lock().unwrap();
-            let lock2 = lock.lock().unwrap();
-            assert_eq!(*lock2, 1);
-            tx.send(()).unwrap();
-        });
-        rx.recv().unwrap();
-    }
-
-    #[test]
-    fn test_mutex_arc_access_in_unwind() {
-        let arc = Arc::new(Mutex::new(1));
-        let arc2 = arc.clone();
-        let _ = thread::spawn(move || -> () {
-            struct Unwinder {
-                i: Arc<Mutex<i32>>,
-            }
-            impl Drop for Unwinder {
-                fn drop(&mut self) {
-                    *self.i.lock().unwrap() += 1;
-                }
-            }
-            let _u = Unwinder { i: arc2 };
-            panic!();
-        })
-        .join();
-        let lock = arc.lock().unwrap();
-        assert_eq!(*lock, 2);
-    }
-
-    #[test]
-    fn test_mutex_unsized() {
-        let mutex: &Mutex<[i32]> = &Mutex::new([1, 2, 3]);
-        {
-            let b = &mut *mutex.lock().unwrap();
-            b[0] = 4;
-            b[2] = 5;
-        }
-        let comp: &[i32] = &[4, 2, 5];
-        assert_eq!(&*mutex.lock().unwrap(), comp);
-    }
-}
diff --git a/library/std/src/sync/mutex/tests.rs b/library/std/src/sync/mutex/tests.rs
new file mode 100644
index 00000000000..a1b5aeddcb6
--- /dev/null
+++ b/library/std/src/sync/mutex/tests.rs
@@ -0,0 +1,238 @@
+use crate::sync::atomic::{AtomicUsize, Ordering};
+use crate::sync::mpsc::channel;
+use crate::sync::{Arc, Condvar, Mutex};
+use crate::thread;
+
+struct Packet<T>(Arc<(Mutex<T>, Condvar)>);
+
+#[derive(Eq, PartialEq, Debug)]
+struct NonCopy(i32);
+
+#[test]
+fn smoke() {
+    let m = Mutex::new(());
+    drop(m.lock().unwrap());
+    drop(m.lock().unwrap());
+}
+
+#[test]
+fn lots_and_lots() {
+    const J: u32 = 1000;
+    const K: u32 = 3;
+
+    let m = Arc::new(Mutex::new(0));
+
+    fn inc(m: &Mutex<u32>) {
+        for _ in 0..J {
+            *m.lock().unwrap() += 1;
+        }
+    }
+
+    let (tx, rx) = channel();
+    for _ in 0..K {
+        let tx2 = tx.clone();
+        let m2 = m.clone();
+        thread::spawn(move || {
+            inc(&m2);
+            tx2.send(()).unwrap();
+        });
+        let tx2 = tx.clone();
+        let m2 = m.clone();
+        thread::spawn(move || {
+            inc(&m2);
+            tx2.send(()).unwrap();
+        });
+    }
+
+    drop(tx);
+    for _ in 0..2 * K {
+        rx.recv().unwrap();
+    }
+    assert_eq!(*m.lock().unwrap(), J * K * 2);
+}
+
+#[test]
+fn try_lock() {
+    let m = Mutex::new(());
+    *m.try_lock().unwrap() = ();
+}
+
+#[test]
+fn test_into_inner() {
+    let m = Mutex::new(NonCopy(10));
+    assert_eq!(m.into_inner().unwrap(), NonCopy(10));
+}
+
+#[test]
+fn test_into_inner_drop() {
+    struct Foo(Arc<AtomicUsize>);
+    impl Drop for Foo {
+        fn drop(&mut self) {
+            self.0.fetch_add(1, Ordering::SeqCst);
+        }
+    }
+    let num_drops = Arc::new(AtomicUsize::new(0));
+    let m = Mutex::new(Foo(num_drops.clone()));
+    assert_eq!(num_drops.load(Ordering::SeqCst), 0);
+    {
+        let _inner = m.into_inner().unwrap();
+        assert_eq!(num_drops.load(Ordering::SeqCst), 0);
+    }
+    assert_eq!(num_drops.load(Ordering::SeqCst), 1);
+}
+
+#[test]
+fn test_into_inner_poison() {
+    let m = Arc::new(Mutex::new(NonCopy(10)));
+    let m2 = m.clone();
+    let _ = thread::spawn(move || {
+        let _lock = m2.lock().unwrap();
+        panic!("test panic in inner thread to poison mutex");
+    })
+    .join();
+
+    assert!(m.is_poisoned());
+    match Arc::try_unwrap(m).unwrap().into_inner() {
+        Err(e) => assert_eq!(e.into_inner(), NonCopy(10)),
+        Ok(x) => panic!("into_inner of poisoned Mutex is Ok: {:?}", x),
+    }
+}
+
+#[test]
+fn test_get_mut() {
+    let mut m = Mutex::new(NonCopy(10));
+    *m.get_mut().unwrap() = NonCopy(20);
+    assert_eq!(m.into_inner().unwrap(), NonCopy(20));
+}
+
+#[test]
+fn test_get_mut_poison() {
+    let m = Arc::new(Mutex::new(NonCopy(10)));
+    let m2 = m.clone();
+    let _ = thread::spawn(move || {
+        let _lock = m2.lock().unwrap();
+        panic!("test panic in inner thread to poison mutex");
+    })
+    .join();
+
+    assert!(m.is_poisoned());
+    match Arc::try_unwrap(m).unwrap().get_mut() {
+        Err(e) => assert_eq!(*e.into_inner(), NonCopy(10)),
+        Ok(x) => panic!("get_mut of poisoned Mutex is Ok: {:?}", x),
+    }
+}
+
+#[test]
+fn test_mutex_arc_condvar() {
+    let packet = Packet(Arc::new((Mutex::new(false), Condvar::new())));
+    let packet2 = Packet(packet.0.clone());
+    let (tx, rx) = channel();
+    let _t = thread::spawn(move || {
+        // wait until parent gets in
+        rx.recv().unwrap();
+        let &(ref lock, ref cvar) = &*packet2.0;
+        let mut lock = lock.lock().unwrap();
+        *lock = true;
+        cvar.notify_one();
+    });
+
+    let &(ref lock, ref cvar) = &*packet.0;
+    let mut lock = lock.lock().unwrap();
+    tx.send(()).unwrap();
+    assert!(!*lock);
+    while !*lock {
+        lock = cvar.wait(lock).unwrap();
+    }
+}
+
+#[test]
+fn test_arc_condvar_poison() {
+    let packet = Packet(Arc::new((Mutex::new(1), Condvar::new())));
+    let packet2 = Packet(packet.0.clone());
+    let (tx, rx) = channel();
+
+    let _t = thread::spawn(move || -> () {
+        rx.recv().unwrap();
+        let &(ref lock, ref cvar) = &*packet2.0;
+        let _g = lock.lock().unwrap();
+        cvar.notify_one();
+        // Parent should fail when it wakes up.
+        panic!();
+    });
+
+    let &(ref lock, ref cvar) = &*packet.0;
+    let mut lock = lock.lock().unwrap();
+    tx.send(()).unwrap();
+    while *lock == 1 {
+        match cvar.wait(lock) {
+            Ok(l) => {
+                lock = l;
+                assert_eq!(*lock, 1);
+            }
+            Err(..) => break,
+        }
+    }
+}
+
+#[test]
+fn test_mutex_arc_poison() {
+    let arc = Arc::new(Mutex::new(1));
+    assert!(!arc.is_poisoned());
+    let arc2 = arc.clone();
+    let _ = thread::spawn(move || {
+        let lock = arc2.lock().unwrap();
+        assert_eq!(*lock, 2);
+    })
+    .join();
+    assert!(arc.lock().is_err());
+    assert!(arc.is_poisoned());
+}
+
+#[test]
+fn test_mutex_arc_nested() {
+    // Tests nested mutexes and access
+    // to underlying data.
+    let arc = Arc::new(Mutex::new(1));
+    let arc2 = Arc::new(Mutex::new(arc));
+    let (tx, rx) = channel();
+    let _t = thread::spawn(move || {
+        let lock = arc2.lock().unwrap();
+        let lock2 = lock.lock().unwrap();
+        assert_eq!(*lock2, 1);
+        tx.send(()).unwrap();
+    });
+    rx.recv().unwrap();
+}
+
+#[test]
+fn test_mutex_arc_access_in_unwind() {
+    let arc = Arc::new(Mutex::new(1));
+    let arc2 = arc.clone();
+    let _ = thread::spawn(move || -> () {
+        struct Unwinder {
+            i: Arc<Mutex<i32>>,
+        }
+        impl Drop for Unwinder {
+            fn drop(&mut self) {
+                *self.i.lock().unwrap() += 1;
+            }
+        }
+        let _u = Unwinder { i: arc2 };
+        panic!();
+    })
+    .join();
+    let lock = arc.lock().unwrap();
+    assert_eq!(*lock, 2);
+}
+
+#[test]
+fn test_mutex_unsized() {
+    let mutex: &Mutex<[i32]> = &Mutex::new([1, 2, 3]);
+    {
+        let b = &mut *mutex.lock().unwrap();
+        b[0] = 4;
+        b[2] = 5;
+    }
+    let comp: &[i32] = &[4, 2, 5];
+    assert_eq!(&*mutex.lock().unwrap(), comp);
+}
diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs
index 714ec3e8786..8fed369bffc 100644
--- a/library/std/src/sync/once.rs
+++ b/library/std/src/sync/once.rs
@@ -84,6 +84,9 @@
 //   processor. Because both use Acquire ordering such a reordering is not
 //   allowed, so no need for SeqCst.
 
+#[cfg(all(test, not(target_os = "emscripten")))]
+mod tests;
+
 use crate::cell::Cell;
 use crate::fmt;
 use crate::marker;
@@ -568,123 +571,3 @@ impl OnceState {
         self.set_state_on_drop_to.set(POISONED);
     }
 }
-
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod tests {
-    use super::Once;
-    use crate::panic;
-    use crate::sync::mpsc::channel;
-    use crate::thread;
-
-    #[test]
-    fn smoke_once() {
-        static O: Once = Once::new();
-        let mut a = 0;
-        O.call_once(|| a += 1);
-        assert_eq!(a, 1);
-        O.call_once(|| a += 1);
-        assert_eq!(a, 1);
-    }
-
-    #[test]
-    fn stampede_once() {
-        static O: Once = Once::new();
-        static mut RUN: bool = false;
-
-        let (tx, rx) = channel();
-        for _ in 0..10 {
-            let tx = tx.clone();
-            thread::spawn(move || {
-                for _ in 0..4 {
-                    thread::yield_now()
-                }
-                unsafe {
-                    O.call_once(|| {
-                        assert!(!RUN);
-                        RUN = true;
-                    });
-                    assert!(RUN);
-                }
-                tx.send(()).unwrap();
-            });
-        }
-
-        unsafe {
-            O.call_once(|| {
-                assert!(!RUN);
-                RUN = true;
-            });
-            assert!(RUN);
-        }
-
-        for _ in 0..10 {
-            rx.recv().unwrap();
-        }
-    }
-
-    #[test]
-    fn poison_bad() {
-        static O: Once = Once::new();
-
-        // poison the once
-        let t = panic::catch_unwind(|| {
-            O.call_once(|| panic!());
-        });
-        assert!(t.is_err());
-
-        // poisoning propagates
-        let t = panic::catch_unwind(|| {
-            O.call_once(|| {});
-        });
-        assert!(t.is_err());
-
-        // we can subvert poisoning, however
-        let mut called = false;
-        O.call_once_force(|p| {
-            called = true;
-            assert!(p.poisoned())
-        });
-        assert!(called);
-
-        // once any success happens, we stop propagating the poison
-        O.call_once(|| {});
-    }
-
-    #[test]
-    fn wait_for_force_to_finish() {
-        static O: Once = Once::new();
-
-        // poison the once
-        let t = panic::catch_unwind(|| {
-            O.call_once(|| panic!());
-        });
-        assert!(t.is_err());
-
-        // make sure someone's waiting inside the once via a force
-        let (tx1, rx1) = channel();
-        let (tx2, rx2) = channel();
-        let t1 = thread::spawn(move || {
-            O.call_once_force(|p| {
-                assert!(p.poisoned());
-                tx1.send(()).unwrap();
-                rx2.recv().unwrap();
-            });
-        });
-
-        rx1.recv().unwrap();
-
-        // put another waiter on the once
-        let t2 = thread::spawn(|| {
-            let mut called = false;
-            O.call_once(|| {
-                called = true;
-            });
-            assert!(!called);
-        });
-
-        tx2.send(()).unwrap();
-
-        assert!(t1.join().is_ok());
-        assert!(t2.join().is_ok());
-    }
-}
diff --git a/library/std/src/sync/once/tests.rs b/library/std/src/sync/once/tests.rs
new file mode 100644
index 00000000000..fae2752526e
--- /dev/null
+++ b/library/std/src/sync/once/tests.rs
@@ -0,0 +1,116 @@
+use super::Once;
+use crate::panic;
+use crate::sync::mpsc::channel;
+use crate::thread;
+
+#[test]
+fn smoke_once() {
+    static O: Once = Once::new();
+    let mut a = 0;
+    O.call_once(|| a += 1);
+    assert_eq!(a, 1);
+    O.call_once(|| a += 1);
+    assert_eq!(a, 1);
+}
+
+#[test]
+fn stampede_once() {
+    static O: Once = Once::new();
+    static mut RUN: bool = false;
+
+    let (tx, rx) = channel();
+    for _ in 0..10 {
+        let tx = tx.clone();
+        thread::spawn(move || {
+            for _ in 0..4 {
+                thread::yield_now()
+            }
+            unsafe {
+                O.call_once(|| {
+                    assert!(!RUN);
+                    RUN = true;
+                });
+                assert!(RUN);
+            }
+            tx.send(()).unwrap();
+        });
+    }
+
+    unsafe {
+        O.call_once(|| {
+            assert!(!RUN);
+            RUN = true;
+        });
+        assert!(RUN);
+    }
+
+    for _ in 0..10 {
+        rx.recv().unwrap();
+    }
+}
+
+#[test]
+fn poison_bad() {
+    static O: Once = Once::new();
+
+    // poison the once
+    let t = panic::catch_unwind(|| {
+        O.call_once(|| panic!());
+    });
+    assert!(t.is_err());
+
+    // poisoning propagates
+    let t = panic::catch_unwind(|| {
+        O.call_once(|| {});
+    });
+    assert!(t.is_err());
+
+    // we can subvert poisoning, however
+    let mut called = false;
+    O.call_once_force(|p| {
+        called = true;
+        assert!(p.poisoned())
+    });
+    assert!(called);
+
+    // once any success happens, we stop propagating the poison
+    O.call_once(|| {});
+}
+
+#[test]
+fn wait_for_force_to_finish() {
+    static O: Once = Once::new();
+
+    // poison the once
+    let t = panic::catch_unwind(|| {
+        O.call_once(|| panic!());
+    });
+    assert!(t.is_err());
+
+    // make sure someone's waiting inside the once via a force
+    let (tx1, rx1) = channel();
+    let (tx2, rx2) = channel();
+    let t1 = thread::spawn(move || {
+        O.call_once_force(|p| {
+            assert!(p.poisoned());
+            tx1.send(()).unwrap();
+            rx2.recv().unwrap();
+        });
+    });
+
+    rx1.recv().unwrap();
+
+    // put another waiter on the once
+    let t2 = thread::spawn(|| {
+        let mut called = false;
+        O.call_once(|| {
+            called = true;
+        });
+        assert!(!called);
+    });
+
+    tx2.send(()).unwrap();
+
+    assert!(t1.join().is_ok());
+    assert!(t2.join().is_ok());
+}
diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs
index 586093c916d..2d219c2c7dd 100644
--- a/library/std/src/sync/rwlock.rs
+++ b/library/std/src/sync/rwlock.rs
@@ -1,3 +1,6 @@
+#[cfg(all(test, not(target_os = "emscripten")))]
+mod tests;
+
 use crate::cell::UnsafeCell;
 use crate::fmt;
 use crate::mem;
@@ -538,254 +541,3 @@ impl<T: ?Sized> Drop for RwLockWriteGuard<'_, T> {
         }
     }
 }
-
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod tests {
-    use crate::sync::atomic::{AtomicUsize, Ordering};
-    use crate::sync::mpsc::channel;
-    use crate::sync::{Arc, RwLock, TryLockError};
-    use crate::thread;
-    use rand::{self, Rng};
-
-    #[derive(Eq, PartialEq, Debug)]
-    struct NonCopy(i32);
-
-    #[test]
-    fn smoke() {
-        let l = RwLock::new(());
-        drop(l.read().unwrap());
-        drop(l.write().unwrap());
-        drop((l.read().unwrap(), l.read().unwrap()));
-        drop(l.write().unwrap());
-    }
-
-    #[test]
-    fn frob() {
-        const N: u32 = 10;
-        const M: usize = 1000;
-
-        let r = Arc::new(RwLock::new(()));
-
-        let (tx, rx) = channel::<()>();
-        for _ in 0..N {
-            let tx = tx.clone();
-            let r = r.clone();
-            thread::spawn(move || {
-                let mut rng = rand::thread_rng();
-                for _ in 0..M {
-                    if rng.gen_bool(1.0 / (N as f64)) {
-                        drop(r.write().unwrap());
-                    } else {
-                        drop(r.read().unwrap());
-                    }
-                }
-                drop(tx);
-            });
-        }
-        drop(tx);
-        let _ = rx.recv();
-    }
-
-    #[test]
-    fn test_rw_arc_poison_wr() {
-        let arc = Arc::new(RwLock::new(1));
-        let arc2 = arc.clone();
-        let _: Result<(), _> = thread::spawn(move || {
-            let _lock = arc2.write().unwrap();
-            panic!();
-        })
-        .join();
-        assert!(arc.read().is_err());
-    }
-
-    #[test]
-    fn test_rw_arc_poison_ww() {
-        let arc = Arc::new(RwLock::new(1));
-        assert!(!arc.is_poisoned());
-        let arc2 = arc.clone();
-        let _: Result<(), _> = thread::spawn(move || {
-            let _lock = arc2.write().unwrap();
-            panic!();
-        })
-        .join();
-        assert!(arc.write().is_err());
-        assert!(arc.is_poisoned());
-    }
-
-    #[test]
-    fn test_rw_arc_no_poison_rr() {
-        let arc = Arc::new(RwLock::new(1));
-        let arc2 = arc.clone();
-        let _: Result<(), _> = thread::spawn(move || {
-            let _lock = arc2.read().unwrap();
-            panic!();
-        })
-        .join();
-        let lock = arc.read().unwrap();
-        assert_eq!(*lock, 1);
-    }
-    #[test]
-    fn test_rw_arc_no_poison_rw() {
-        let arc = Arc::new(RwLock::new(1));
-        let arc2 = arc.clone();
-        let _: Result<(), _> = thread::spawn(move || {
-            let _lock = arc2.read().unwrap();
-            panic!()
-        })
-        .join();
-        let lock = arc.write().unwrap();
-        assert_eq!(*lock, 1);
-    }
-
-    #[test]
-    fn test_rw_arc() {
-        let arc = Arc::new(RwLock::new(0));
-        let arc2 = arc.clone();
-        let (tx, rx) = channel();
-
-        thread::spawn(move || {
-            let mut lock = arc2.write().unwrap();
-            for _ in 0..10 {
-                let tmp = *lock;
-                *lock = -1;
-                thread::yield_now();
-                *lock = tmp + 1;
-            }
-            tx.send(()).unwrap();
-        });
-
-        // Readers try to catch the writer in the act
-        let mut children = Vec::new();
-        for _ in 0..5 {
-            let arc3 = arc.clone();
-            children.push(thread::spawn(move || {
-                let lock = arc3.read().unwrap();
-                assert!(*lock >= 0);
-            }));
-        }
-
-        // Wait for children to pass their asserts
-        for r in children {
-            assert!(r.join().is_ok());
-        }
-
-        // Wait for writer to finish
-        rx.recv().unwrap();
-        let lock = arc.read().unwrap();
-        assert_eq!(*lock, 10);
-    }
-
-    #[test]
-    fn test_rw_arc_access_in_unwind() {
-        let arc = Arc::new(RwLock::new(1));
-        let arc2 = arc.clone();
-        let _ = thread::spawn(move || -> () {
-            struct Unwinder {
-                i: Arc<RwLock<isize>>,
-            }
-            impl Drop for Unwinder {
-                fn drop(&mut self) {
-                    let mut lock = self.i.write().unwrap();
-                    *lock += 1;
-                }
-            }
-            let _u = Unwinder { i: arc2 };
-            panic!();
-        })
-        .join();
-        let lock = arc.read().unwrap();
-        assert_eq!(*lock, 2);
-    }
-
-    #[test]
-    fn test_rwlock_unsized() {
-        let rw: &RwLock<[i32]> = &RwLock::new([1, 2, 3]);
-        {
-            let b = &mut *rw.write().unwrap();
-            b[0] = 4;
-            b[2] = 5;
-        }
-        let comp: &[i32] = &[4, 2, 5];
-        assert_eq!(&*rw.read().unwrap(), comp);
-    }
-
-    #[test]
-    fn test_rwlock_try_write() {
-        let lock = RwLock::new(0isize);
-        let read_guard = lock.read().unwrap();
-
-        let write_result = lock.try_write();
-        match write_result {
-            Err(TryLockError::WouldBlock) => (),
-            Ok(_) => assert!(false, "try_write should not succeed while read_guard is in scope"),
-            Err(_) => assert!(false, "unexpected error"),
-        }
-
-        drop(read_guard);
-    }
-
-    #[test]
-    fn test_into_inner() {
-        let m = RwLock::new(NonCopy(10));
-        assert_eq!(m.into_inner().unwrap(), NonCopy(10));
-    }
-
-    #[test]
-    fn test_into_inner_drop() {
-        struct Foo(Arc<AtomicUsize>);
-        impl Drop for Foo {
-            fn drop(&mut self) {
-                self.0.fetch_add(1, Ordering::SeqCst);
-            }
-        }
-        let num_drops = Arc::new(AtomicUsize::new(0));
-        let m = RwLock::new(Foo(num_drops.clone()));
-        assert_eq!(num_drops.load(Ordering::SeqCst), 0);
-        {
-            let _inner = m.into_inner().unwrap();
-            assert_eq!(num_drops.load(Ordering::SeqCst), 0);
-        }
-        assert_eq!(num_drops.load(Ordering::SeqCst), 1);
-    }
-
-    #[test]
-    fn test_into_inner_poison() {
-        let m = Arc::new(RwLock::new(NonCopy(10)));
-        let m2 = m.clone();
-        let _ = thread::spawn(move || {
-            let _lock = m2.write().unwrap();
-            panic!("test panic in inner thread to poison RwLock");
-        })
-        .join();
-
-        assert!(m.is_poisoned());
-        match Arc::try_unwrap(m).unwrap().into_inner() {
-            Err(e) => assert_eq!(e.into_inner(), NonCopy(10)),
-            Ok(x) => panic!("into_inner of poisoned RwLock is Ok: {:?}", x),
-        }
-    }
-
-    #[test]
-    fn test_get_mut() {
-        let mut m = RwLock::new(NonCopy(10));
-        *m.get_mut().unwrap() = NonCopy(20);
-        assert_eq!(m.into_inner().unwrap(), NonCopy(20));
-    }
-
-    #[test]
-    fn test_get_mut_poison() {
-        let m = Arc::new(RwLock::new(NonCopy(10)));
-        let m2 = m.clone();
-        let _ = thread::spawn(move || {
-            let _lock = m2.write().unwrap();
-            panic!("test panic in inner thread to poison RwLock");
-        })
-        .join();
-
-        assert!(m.is_poisoned());
-        match Arc::try_unwrap(m).unwrap().get_mut() {
-            Err(e) => assert_eq!(*e.into_inner(), NonCopy(10)),
-            Ok(x) => panic!("get_mut of poisoned RwLock is Ok: {:?}", x),
-        }
-    }
-}
diff --git a/library/std/src/sync/rwlock/tests.rs b/library/std/src/sync/rwlock/tests.rs
new file mode 100644
index 00000000000..e9b74fb3ecc
--- /dev/null
+++ b/library/std/src/sync/rwlock/tests.rs
@@ -0,0 +1,247 @@
+use crate::sync::atomic::{AtomicUsize, Ordering};
+use crate::sync::mpsc::channel;
+use crate::sync::{Arc, RwLock, TryLockError};
+use crate::thread;
+use rand::{self, Rng};
+
+#[derive(Eq, PartialEq, Debug)]
+struct NonCopy(i32);
+
+#[test]
+fn smoke() {
+    let l = RwLock::new(());
+    drop(l.read().unwrap());
+    drop(l.write().unwrap());
+    drop((l.read().unwrap(), l.read().unwrap()));
+    drop(l.write().unwrap());
+}
+
+#[test]
+fn frob() {
+    const N: u32 = 10;
+    const M: usize = 1000;
+
+    let r = Arc::new(RwLock::new(()));
+
+    let (tx, rx) = channel::<()>();
+    for _ in 0..N {
+        let tx = tx.clone();
+        let r = r.clone();
+        thread::spawn(move || {
+            let mut rng = rand::thread_rng();
+            for _ in 0..M {
+                if rng.gen_bool(1.0 / (N as f64)) {
+                    drop(r.write().unwrap());
+                } else {
+                    drop(r.read().unwrap());
+                }
+            }
+            drop(tx);
+        });
+    }
+    drop(tx);
+    let _ = rx.recv();
+}
+
+#[test]
+fn test_rw_arc_poison_wr() {
+    let arc = Arc::new(RwLock::new(1));
+    let arc2 = arc.clone();
+    let _: Result<(), _> = thread::spawn(move || {
+        let _lock = arc2.write().unwrap();
+        panic!();
+    })
+    .join();
+    assert!(arc.read().is_err());
+}
+
+#[test]
+fn test_rw_arc_poison_ww() {
+    let arc = Arc::new(RwLock::new(1));
+    assert!(!arc.is_poisoned());
+    let arc2 = arc.clone();
+    let _: Result<(), _> = thread::spawn(move || {
+        let _lock = arc2.write().unwrap();
+        panic!();
+    })
+    .join();
+    assert!(arc.write().is_err());
+    assert!(arc.is_poisoned());
+}
+
+#[test]
+fn test_rw_arc_no_poison_rr() {
+    let arc = Arc::new(RwLock::new(1));
+    let arc2 = arc.clone();
+    let _: Result<(), _> = thread::spawn(move || {
+        let _lock = arc2.read().unwrap();
+        panic!();
+    })
+    .join();
+    let lock = arc.read().unwrap();
+    assert_eq!(*lock, 1);
+}
+#[test]
+fn test_rw_arc_no_poison_rw() {
+    let arc = Arc::new(RwLock::new(1));
+    let arc2 = arc.clone();
+    let _: Result<(), _> = thread::spawn(move || {
+        let _lock = arc2.read().unwrap();
+        panic!()
+    })
+    .join();
+    let lock = arc.write().unwrap();
+    assert_eq!(*lock, 1);
+}
+
+#[test]
+fn test_rw_arc() {
+    let arc = Arc::new(RwLock::new(0));
+    let arc2 = arc.clone();
+    let (tx, rx) = channel();
+
+    thread::spawn(move || {
+        let mut lock = arc2.write().unwrap();
+        for _ in 0..10 {
+            let tmp = *lock;
+            *lock = -1;
+            thread::yield_now();
+            *lock = tmp + 1;
+        }
+        tx.send(()).unwrap();
+    });
+
+    // Readers try to catch the writer in the act
+    let mut children = Vec::new();
+    for _ in 0..5 {
+        let arc3 = arc.clone();
+        children.push(thread::spawn(move || {
+            let lock = arc3.read().unwrap();
+            assert!(*lock >= 0);
+        }));
+    }
+
+    // Wait for children to pass their asserts
+    for r in children {
+        assert!(r.join().is_ok());
+    }
+
+    // Wait for writer to finish
+    rx.recv().unwrap();
+    let lock = arc.read().unwrap();
+    assert_eq!(*lock, 10);
+}
+
+#[test]
+fn test_rw_arc_access_in_unwind() {
+    let arc = Arc::new(RwLock::new(1));
+    let arc2 = arc.clone();
+    let _ = thread::spawn(move || -> () {
+        struct Unwinder {
+            i: Arc<RwLock<isize>>,
+        }
+        impl Drop for Unwinder {
+            fn drop(&mut self) {
+                let mut lock = self.i.write().unwrap();
+                *lock += 1;
+            }
+        }
+        let _u = Unwinder { i: arc2 };
+        panic!();
+    })
+    .join();
+    let lock = arc.read().unwrap();
+    assert_eq!(*lock, 2);
+}
+
+#[test]
+fn test_rwlock_unsized() {
+    let rw: &RwLock<[i32]> = &RwLock::new([1, 2, 3]);
+    {
+        let b = &mut *rw.write().unwrap();
+        b[0] = 4;
+        b[2] = 5;
+    }
+    let comp: &[i32] = &[4, 2, 5];
+    assert_eq!(&*rw.read().unwrap(), comp);
+}
+
+#[test]
+fn test_rwlock_try_write() {
+    let lock = RwLock::new(0isize);
+    let read_guard = lock.read().unwrap();
+
+    let write_result = lock.try_write();
+    match write_result {
+        Err(TryLockError::WouldBlock) => (),
+        Ok(_) => assert!(false, "try_write should not succeed while read_guard is in scope"),
+        Err(_) => assert!(false, "unexpected error"),
+    }
+
+    drop(read_guard);
+}
+
+#[test]
+fn test_into_inner() {
+    let m = RwLock::new(NonCopy(10));
+    assert_eq!(m.into_inner().unwrap(), NonCopy(10));
+}
+
+#[test]
+fn test_into_inner_drop() {
+    struct Foo(Arc<AtomicUsize>);
+    impl Drop for Foo {
+        fn drop(&mut self) {
+            self.0.fetch_add(1, Ordering::SeqCst);
+        }
+    }
+    let num_drops = Arc::new(AtomicUsize::new(0));
+    let m = RwLock::new(Foo(num_drops.clone()));
+    assert_eq!(num_drops.load(Ordering::SeqCst), 0);
+    {
+        let _inner = m.into_inner().unwrap();
+        assert_eq!(num_drops.load(Ordering::SeqCst), 0);
+    }
+    assert_eq!(num_drops.load(Ordering::SeqCst), 1);
+}
+
+#[test]
+fn test_into_inner_poison() {
+    let m = Arc::new(RwLock::new(NonCopy(10)));
+    let m2 = m.clone();
+    let _ = thread::spawn(move || {
+        let _lock = m2.write().unwrap();
+        panic!("test panic in inner thread to poison RwLock");
+    })
+    .join();
+
+    assert!(m.is_poisoned());
+    match Arc::try_unwrap(m).unwrap().into_inner() {
+        Err(e) => assert_eq!(e.into_inner(), NonCopy(10)),
+        Ok(x) => panic!("into_inner of poisoned RwLock is Ok: {:?}", x),
+    }
+}
+
+#[test]
+fn test_get_mut() {
+    let mut m = RwLock::new(NonCopy(10));
+    *m.get_mut().unwrap() = NonCopy(20);
+    assert_eq!(m.into_inner().unwrap(), NonCopy(20));
+}
+
+#[test]
+fn test_get_mut_poison() {
+    let m = Arc::new(RwLock::new(NonCopy(10)));
+    let m2 = m.clone();
+    let _ = thread::spawn(move || {
+        let _lock = m2.write().unwrap();
+        panic!("test panic in inner thread to poison RwLock");
+    })
+    .join();
+
+    assert!(m.is_poisoned());
+    match Arc::try_unwrap(m).unwrap().get_mut() {
+        Err(e) => assert_eq!(*e.into_inner(), NonCopy(10)),
+        Ok(x) => panic!("get_mut of poisoned RwLock is Ok: {:?}", x),
+    }
+}
diff --git a/library/std/src/sys/sgx/abi/tls.rs b/library/std/src/sys/sgx/abi/tls.rs
index 2b0485c4f03..0d8952b2f27 100644
--- a/library/std/src/sys/sgx/abi/tls.rs
+++ b/library/std/src/sys/sgx/abi/tls.rs
@@ -1,3 +1,5 @@
+mod sync_bitset;
+
 use self::sync_bitset::*;
 use crate::cell::Cell;
 use crate::mem;
@@ -125,117 +127,3 @@ impl Tls {
         TLS_KEY_IN_USE.clear(key.to_index());
     }
 }
-
-mod sync_bitset {
-    use super::{TLS_KEYS_BITSET_SIZE, USIZE_BITS};
-    use crate::iter::{Enumerate, Peekable};
-    use crate::slice::Iter;
-    use crate::sync::atomic::{AtomicUsize, Ordering};
-
-    /// A bitset that can be used synchronously.
-    pub(super) struct SyncBitset([AtomicUsize; TLS_KEYS_BITSET_SIZE]);
-
-    pub(super) const SYNC_BITSET_INIT: SyncBitset =
-        SyncBitset([AtomicUsize::new(0), AtomicUsize::new(0)]);
-
-    impl SyncBitset {
-        pub fn get(&self, index: usize) -> bool {
-            let (hi, lo) = Self::split(index);
-            (self.0[hi].load(Ordering::Relaxed) & lo) != 0
-        }
-
-        /// Not atomic.
-        pub fn iter(&self) -> SyncBitsetIter<'_> {
-            SyncBitsetIter { iter: self.0.iter().enumerate().peekable(), elem_idx: 0 }
-        }
-
-        pub fn clear(&self, index: usize) {
-            let (hi, lo) = Self::split(index);
-            self.0[hi].fetch_and(!lo, Ordering::Relaxed);
-        }
-
-        /// Sets any unset bit. Not atomic. Returns `None` if all bits were
-        /// observed to be set.
-        pub fn set(&self) -> Option<usize> {
-            'elems: for (idx, elem) in self.0.iter().enumerate() {
-                let mut current = elem.load(Ordering::Relaxed);
-                loop {
-                    if 0 == !current {
-                        continue 'elems;
-                    }
-                    let trailing_ones = (!current).trailing_zeros() as usize;
-                    match elem.compare_exchange(
-                        current,
-                        current | (1 << trailing_ones),
-                        Ordering::AcqRel,
-                        Ordering::Relaxed,
-                    ) {
-                        Ok(_) => return Some(idx * USIZE_BITS + trailing_ones),
-                        Err(previous) => current = previous,
-                    }
-                }
-            }
-            None
-        }
-
-        fn split(index: usize) -> (usize, usize) {
-            (index / USIZE_BITS, 1 << (index % USIZE_BITS))
-        }
-    }
-
-    pub(super) struct SyncBitsetIter<'a> {
-        iter: Peekable<Enumerate<Iter<'a, AtomicUsize>>>,
-        elem_idx: usize,
-    }
-
-    impl<'a> Iterator for SyncBitsetIter<'a> {
-        type Item = usize;
-
-        fn next(&mut self) -> Option<usize> {
-            self.iter.peek().cloned().and_then(|(idx, elem)| {
-                let elem = elem.load(Ordering::Relaxed);
-                let low_mask = (1 << self.elem_idx) - 1;
-                let next = elem & !low_mask;
-                let next_idx = next.trailing_zeros() as usize;
-                self.elem_idx = next_idx + 1;
-                if self.elem_idx >= 64 {
-                    self.elem_idx = 0;
-                    self.iter.next();
-                }
-                match next_idx {
-                    64 => self.next(),
-                    _ => Some(idx * USIZE_BITS + next_idx),
-                }
-            })
-        }
-    }
-
-    #[cfg(test)]
-    mod tests {
-        use super::*;
-
-        fn test_data(bitset: [usize; 2], bit_indices: &[usize]) {
-            let set = SyncBitset([AtomicUsize::new(bitset[0]), AtomicUsize::new(bitset[1])]);
-            assert_eq!(set.iter().collect::<Vec<_>>(), bit_indices);
-            for &i in bit_indices {
-                assert!(set.get(i));
-            }
-        }
-
-        #[test]
-        fn iter() {
-            test_data([0b0110_1001, 0], &[0, 3, 5, 6]);
-            test_data([0x8000_0000_0000_0000, 0x8000_0000_0000_0001], &[63, 64, 127]);
-            test_data([0, 0], &[]);
-        }
-
-        #[test]
-        fn set_get_clear() {
-            let set = SYNC_BITSET_INIT;
-            let key = set.set().unwrap();
-            assert!(set.get(key));
-            set.clear(key);
-            assert!(!set.get(key));
-        }
-    }
-}
diff --git a/library/std/src/sys/sgx/abi/tls/sync_bitset.rs b/library/std/src/sys/sgx/abi/tls/sync_bitset.rs
new file mode 100644
index 00000000000..4eeff8f6ef7
--- /dev/null
+++ b/library/std/src/sys/sgx/abi/tls/sync_bitset.rs
@@ -0,0 +1,85 @@
+#[cfg(test)]
+mod tests;
+
+use super::{TLS_KEYS_BITSET_SIZE, USIZE_BITS};
+use crate::iter::{Enumerate, Peekable};
+use crate::slice::Iter;
+use crate::sync::atomic::{AtomicUsize, Ordering};
+
+/// A bitset that can be used synchronously.
+pub(super) struct SyncBitset([AtomicUsize; TLS_KEYS_BITSET_SIZE]);
+
+pub(super) const SYNC_BITSET_INIT: SyncBitset =
+    SyncBitset([AtomicUsize::new(0), AtomicUsize::new(0)]);
+
+impl SyncBitset {
+    pub fn get(&self, index: usize) -> bool {
+        let (hi, lo) = Self::split(index);
+        (self.0[hi].load(Ordering::Relaxed) & lo) != 0
+    }
+
+    /// Not atomic.
+    pub fn iter(&self) -> SyncBitsetIter<'_> {
+        SyncBitsetIter { iter: self.0.iter().enumerate().peekable(), elem_idx: 0 }
+    }
+
+    pub fn clear(&self, index: usize) {
+        let (hi, lo) = Self::split(index);
+        self.0[hi].fetch_and(!lo, Ordering::Relaxed);
+    }
+
+    /// Sets any unset bit. Not atomic. Returns `None` if all bits were
+    /// observed to be set.
+    pub fn set(&self) -> Option<usize> {
+        'elems: for (idx, elem) in self.0.iter().enumerate() {
+            let mut current = elem.load(Ordering::Relaxed);
+            loop {
+                if 0 == !current {
+                    continue 'elems;
+                }
+                let trailing_ones = (!current).trailing_zeros() as usize;
+                match elem.compare_exchange(
+                    current,
+                    current | (1 << trailing_ones),
+                    Ordering::AcqRel,
+                    Ordering::Relaxed,
+                ) {
+                    Ok(_) => return Some(idx * USIZE_BITS + trailing_ones),
+                    Err(previous) => current = previous,
+                }
+            }
+        }
+        None
+    }
+
+    fn split(index: usize) -> (usize, usize) {
+        (index / USIZE_BITS, 1 << (index % USIZE_BITS))
+    }
+}
+
+pub(super) struct SyncBitsetIter<'a> {
+    iter: Peekable<Enumerate<Iter<'a, AtomicUsize>>>,
+    elem_idx: usize,
+}
+
+impl<'a> Iterator for SyncBitsetIter<'a> {
+    type Item = usize;
+
+    fn next(&mut self) -> Option<usize> {
+        self.iter.peek().cloned().and_then(|(idx, elem)| {
+            let elem = elem.load(Ordering::Relaxed);
+            let low_mask = (1 << self.elem_idx) - 1;
+            let next = elem & !low_mask;
+            let next_idx = next.trailing_zeros() as usize;
+            self.elem_idx = next_idx + 1;
+            if self.elem_idx >= 64 {
+                self.elem_idx = 0;
+                self.iter.next();
+            }
+            match next_idx {
+                64 => self.next(),
+                _ => Some(idx * USIZE_BITS + next_idx),
+            }
+        })
+    }
+}
diff --git a/library/std/src/sys/sgx/abi/tls/sync_bitset/tests.rs b/library/std/src/sys/sgx/abi/tls/sync_bitset/tests.rs
new file mode 100644
index 00000000000..d7eb2e139d0
--- /dev/null
+++ b/library/std/src/sys/sgx/abi/tls/sync_bitset/tests.rs
@@ -0,0 +1,25 @@
+use super::*;
+
+fn test_data(bitset: [usize; 2], bit_indices: &[usize]) {
+    let set = SyncBitset([AtomicUsize::new(bitset[0]), AtomicUsize::new(bitset[1])]);
+    assert_eq!(set.iter().collect::<Vec<_>>(), bit_indices);
+    for &i in bit_indices {
+        assert!(set.get(i));
+    }
+}
+
+#[test]
+fn iter() {
+    test_data([0b0110_1001, 0], &[0, 3, 5, 6]);
+    test_data([0x8000_0000_0000_0000, 0x8000_0000_0000_0001], &[63, 64, 127]);
+    test_data([0, 0], &[]);
+}
+
+#[test]
+fn set_get_clear() {
+    let set = SYNC_BITSET_INIT;
+    let key = set.set().unwrap();
+    assert!(set.get(key));
+    set.clear(key);
+    assert!(!set.get(key));
+}
diff --git a/library/std/src/sys/sgx/rwlock.rs b/library/std/src/sys/sgx/rwlock.rs
index 722b4f5e0ba..3bf2a7d8fb4 100644
--- a/library/std/src/sys/sgx/rwlock.rs
+++ b/library/std/src/sys/sgx/rwlock.rs
@@ -1,3 +1,6 @@
+#[cfg(test)]
+mod tests;
+
 use crate::num::NonZeroUsize;
 
 use super::waitqueue::{
@@ -198,50 +201,3 @@ pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 {
     (*p).unlock();
     return 0;
 }
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::mem::{self, MaybeUninit};
-    use core::array::FixedSizeArray;
-
-    // Verify that the bytes of initialized RWLock are the same as in
-    // libunwind. If they change, `src/UnwindRustSgx.h` in libunwind needs to
-    // be changed too.
-    #[test]
-    fn test_c_rwlock_initializer() {
-        #[rustfmt::skip]
-        const RWLOCK_INIT: &[u8] = &[
-            /* 0x00 */ 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-            /* 0x10 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-            /* 0x20 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-            /* 0x30 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-            /* 0x40 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-            /* 0x50 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-            /* 0x60 */ 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-            /* 0x70 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-            /* 0x80 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-        ];
-
-        #[inline(never)]
-        fn zero_stack() {
-            test::black_box(MaybeUninit::<[RWLock; 16]>::zeroed());
-        }
-
-        #[inline(never)]
-        unsafe fn rwlock_new(init: &mut MaybeUninit<RWLock>) {
-            init.write(RWLock::new());
-        }
-
-        unsafe {
-            // try hard to make sure that the padding/unused bytes in RWLock
-            // get initialized as 0. If the assertion below fails, that might
-            // just be an issue with the test code and not with the value of
-            // RWLOCK_INIT.
-            zero_stack();
-            let mut init = MaybeUninit::<RWLock>::zeroed();
-            rwlock_new(&mut init);
-            assert_eq!(mem::transmute::<_, [u8; 144]>(init.assume_init()).as_slice(), RWLOCK_INIT)
-        };
-    }
-}
diff --git a/library/std/src/sys/sgx/rwlock/tests.rs b/library/std/src/sys/sgx/rwlock/tests.rs
new file mode 100644
index 00000000000..05b36c633f8
--- /dev/null
+++ b/library/std/src/sys/sgx/rwlock/tests.rs
@@ -0,0 +1,43 @@
+use super::*;
+use crate::mem::{self, MaybeUninit};
+use core::array::FixedSizeArray;
+
+// Verify that the bytes of initialized RWLock are the same as in
+// libunwind. If they change, `src/UnwindRustSgx.h` in libunwind needs to
+// be changed too.
+#[test]
+fn test_c_rwlock_initializer() {
+    #[rustfmt::skip]
+    const RWLOCK_INIT: &[u8] = &[
+        /* 0x00 */ 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+        /* 0x10 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+        /* 0x20 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+        /* 0x30 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+        /* 0x40 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+        /* 0x50 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+        /* 0x60 */ 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+        /* 0x70 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+        /* 0x80 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+    ];
+
+    #[inline(never)]
+    fn zero_stack() {
+        test::black_box(MaybeUninit::<[RWLock; 16]>::zeroed());
+    }
+
+    #[inline(never)]
+    unsafe fn rwlock_new(init: &mut MaybeUninit<RWLock>) {
+        init.write(RWLock::new());
+    }
+
+    unsafe {
+        // try hard to make sure that the padding/unused bytes in RWLock
+        // get initialized as 0. If the assertion below fails, that might
+        // just be an issue with the test code and not with the value of
+        // RWLOCK_INIT.
+        zero_stack();
+        let mut init = MaybeUninit::<RWLock>::zeroed();
+        rwlock_new(&mut init);
+        assert_eq!(mem::transmute::<_, [u8; 144]>(init.assume_init()).as_slice(), RWLOCK_INIT)
+    };
+}
diff --git a/library/std/src/sys/sgx/waitqueue.rs b/library/std/src/sys/sgx/waitqueue.rs
index 070afa55f30..e464dc3ee9d 100644
--- a/library/std/src/sys/sgx/waitqueue.rs
+++ b/library/std/src/sys/sgx/waitqueue.rs
@@ -9,6 +9,18 @@
 //! Since userspace may send spurious wake-ups, the wakeup event state is
 //! recorded in the enclave. The wakeup event state is protected by a spinlock.
 //! The queue and associated wait state are stored in a `WaitVariable`.
+
+#[cfg(test)]
+mod tests;
+
+/// A doubly-linked list where callers are in charge of memory allocation
+/// of the nodes in the list.
+mod unsafe_list;
+
+/// Trivial spinlock-based implementation of `sync::Mutex`.
+// FIXME: Perhaps use Intel TSX to avoid locking?
+mod spin_mutex;
+
 use crate::num::NonZeroUsize;
 use crate::ops::{Deref, DerefMut};
 use crate::time::Duration;
@@ -231,389 +243,3 @@ impl WaitQueue {
         }
     }
 }
-
-/// A doubly-linked list where callers are in charge of memory allocation
-/// of the nodes in the list.
-mod unsafe_list {
-    use crate::mem;
-    use crate::ptr::NonNull;
-
-    pub struct UnsafeListEntry<T> {
-        next: NonNull<UnsafeListEntry<T>>,
-        prev: NonNull<UnsafeListEntry<T>>,
-        value: Option<T>,
-    }
-
-    impl<T> UnsafeListEntry<T> {
-        fn dummy() -> Self {
-            UnsafeListEntry { next: NonNull::dangling(), prev: NonNull::dangling(), value: None }
-        }
-
-        pub fn new(value: T) -> Self {
-            UnsafeListEntry { value: Some(value), ..Self::dummy() }
-        }
-    }
-
-    pub struct UnsafeList<T> {
-        head_tail: NonNull<UnsafeListEntry<T>>,
-        head_tail_entry: Option<UnsafeListEntry<T>>,
-    }
-
-    impl<T> UnsafeList<T> {
-        pub const fn new() -> Self {
-            unsafe {
-                UnsafeList { head_tail: NonNull::new_unchecked(1 as _), head_tail_entry: None }
-            }
-        }
-
-        unsafe fn init(&mut self) {
-            if self.head_tail_entry.is_none() {
-                self.head_tail_entry = Some(UnsafeListEntry::dummy());
-                self.head_tail = NonNull::new_unchecked(self.head_tail_entry.as_mut().unwrap());
-                self.head_tail.as_mut().next = self.head_tail;
-                self.head_tail.as_mut().prev = self.head_tail;
-            }
-        }
-
-        pub fn is_empty(&self) -> bool {
-            unsafe {
-                if self.head_tail_entry.is_some() {
-                    let first = self.head_tail.as_ref().next;
-                    if first == self.head_tail {
-                        // ,-------> /---------\ next ---,
-                        // |         |head_tail|         |
-                        // `--- prev \---------/ <-------`
-                        rtassert!(self.head_tail.as_ref().prev == first);
-                        true
-                    } else {
-                        false
-                    }
-                } else {
-                    true
-                }
-            }
-        }
-
-        /// Pushes an entry onto the back of the list.
-        ///
-        /// # Safety
-        ///
-        /// The entry must remain allocated until the entry is removed from the
-        /// list AND the caller who popped is done using the entry. Special
-        /// care must be taken in the caller of `push` to ensure unwinding does
-        /// not destroy the stack frame containing the entry.
-        pub unsafe fn push<'a>(&mut self, entry: &'a mut UnsafeListEntry<T>) -> &'a T {
-            self.init();
-
-            // BEFORE:
-            //     /---------\ next ---> /---------\
-            // ... |prev_tail|           |head_tail| ...
-            //     \---------/ <--- prev \---------/
-            //
-            // AFTER:
-            //     /---------\ next ---> /-----\ next ---> /---------\
-            // ... |prev_tail|           |entry|           |head_tail| ...
-            //     \---------/ <--- prev \-----/ <--- prev \---------/
-            let mut entry = NonNull::new_unchecked(entry);
-            let mut prev_tail = mem::replace(&mut self.head_tail.as_mut().prev, entry);
-            entry.as_mut().prev = prev_tail;
-            entry.as_mut().next = self.head_tail;
-            prev_tail.as_mut().next = entry;
-            // unwrap ok: always `Some` on non-dummy entries
-            (*entry.as_ptr()).value.as_ref().unwrap()
-        }
-
-        /// Pops an entry from the front of the list.
-        ///
-        /// # Safety
-        ///
-        /// The caller must make sure to synchronize ending the borrow of the
-        /// return value and deallocation of the containing entry.
-        pub unsafe fn pop<'a>(&mut self) -> Option<&'a T> {
-            self.init();
-
-            if self.is_empty() {
-                None
-            } else {
-                // BEFORE:
-                //     /---------\ next ---> /-----\ next ---> /------\
-                // ... |head_tail|           |first|           |second| ...
-                //     \---------/ <--- prev \-----/ <--- prev \------/
-                //
-                // AFTER:
-                //     /---------\ next ---> /------\
-                // ... |head_tail|           |second| ...
-                //     \---------/ <--- prev \------/
-                let mut first = self.head_tail.as_mut().next;
-                let mut second = first.as_mut().next;
-                self.head_tail.as_mut().next = second;
-                second.as_mut().prev = self.head_tail;
-                first.as_mut().next = NonNull::dangling();
-                first.as_mut().prev = NonNull::dangling();
-                // unwrap ok: always `Some` on non-dummy entries
-                Some((*first.as_ptr()).value.as_ref().unwrap())
-            }
-        }
-
-        /// Removes an entry from the list.
-        ///
-        /// # Safety
-        ///
-        /// The caller must ensure that `entry` has been pushed onto `self`
-        /// prior to this call and has not moved since then.
-        pub unsafe fn remove(&mut self, entry: &mut UnsafeListEntry<T>) {
-            rtassert!(!self.is_empty());
-            // BEFORE:
-            //     /----\ next ---> /-----\ next ---> /----\
-            // ... |prev|           |entry|           |next| ...
-            //     \----/ <--- prev \-----/ <--- prev \----/
-            //
-            // AFTER:
-            //     /----\ next ---> /----\
-            // ... |prev|           |next| ...
-            //     \----/ <--- prev \----/
-            let mut prev = entry.prev;
-            let mut next = entry.next;
-            prev.as_mut().next = next;
-            next.as_mut().prev = prev;
-            entry.next = NonNull::dangling();
-            entry.prev = NonNull::dangling();
-        }
-    }
-
-    #[cfg(test)]
-    mod tests {
-        use super::*;
-        use crate::cell::Cell;
-
-        unsafe fn assert_empty<T>(list: &mut UnsafeList<T>) {
-            assert!(list.pop().is_none(), "assertion failed: list is not empty");
-        }
-
-        #[test]
-        fn init_empty() {
-            unsafe {
-                assert_empty(&mut UnsafeList::<i32>::new());
-            }
-        }
-
-        #[test]
-        fn push_pop() {
-            unsafe {
-                let mut node = UnsafeListEntry::new(1234);
-                let mut list = UnsafeList::new();
-                assert_eq!(list.push(&mut node), &1234);
-                assert_eq!(list.pop().unwrap(), &1234);
-                assert_empty(&mut list);
-            }
-        }
-
-        #[test]
-        fn push_remove() {
-            unsafe {
-                let mut node = UnsafeListEntry::new(1234);
-                let mut list = UnsafeList::new();
-                assert_eq!(list.push(&mut node), &1234);
-                list.remove(&mut node);
-                assert_empty(&mut list);
-            }
-        }
-
-        #[test]
-        fn push_remove_pop() {
-            unsafe {
-                let mut node1 = UnsafeListEntry::new(11);
-                let mut node2 = UnsafeListEntry::new(12);
-                let mut node3 = UnsafeListEntry::new(13);
-                let mut node4 = UnsafeListEntry::new(14);
-                let mut node5 = UnsafeListEntry::new(15);
-                let mut list = UnsafeList::new();
-                assert_eq!(list.push(&mut node1), &11);
-                assert_eq!(list.push(&mut node2), &12);
-                assert_eq!(list.push(&mut node3), &13);
-                assert_eq!(list.push(&mut node4), &14);
-                assert_eq!(list.push(&mut node5), &15);
-
-                list.remove(&mut node1);
-                assert_eq!(list.pop().unwrap(), &12);
-                list.remove(&mut node3);
-                assert_eq!(list.pop().unwrap(), &14);
-                list.remove(&mut node5);
-                assert_empty(&mut list);
-
-                assert_eq!(list.push(&mut node1), &11);
-                assert_eq!(list.pop().unwrap(), &11);
-                assert_empty(&mut list);
-
-                assert_eq!(list.push(&mut node3), &13);
-                assert_eq!(list.push(&mut node4), &14);
-                list.remove(&mut node3);
-                list.remove(&mut node4);
-                assert_empty(&mut list);
-            }
-        }
-
-        #[test]
-        fn complex_pushes_pops() {
-            unsafe {
-                let mut node1 = UnsafeListEntry::new(1234);
-                let mut node2 = UnsafeListEntry::new(4567);
-                let mut node3 = UnsafeListEntry::new(9999);
-                let mut node4 = UnsafeListEntry::new(8642);
-                let mut list = UnsafeList::new();
-                list.push(&mut node1);
-                list.push(&mut node2);
-                assert_eq!(list.pop().unwrap(), &1234);
-                list.push(&mut node3);
-                assert_eq!(list.pop().unwrap(), &4567);
-                assert_eq!(list.pop().unwrap(), &9999);
-                assert_empty(&mut list);
-                list.push(&mut node4);
-                assert_eq!(list.pop().unwrap(), &8642);
-                assert_empty(&mut list);
-            }
-        }
-
-        #[test]
-        fn cell() {
-            unsafe {
-                let mut node = UnsafeListEntry::new(Cell::new(0));
-                let mut list = UnsafeList::new();
-                let noderef = list.push(&mut node);
-                assert_eq!(noderef.get(), 0);
-                list.pop().unwrap().set(1);
-                assert_empty(&mut list);
-                assert_eq!(noderef.get(), 1);
-            }
-        }
-    }
-}
-
-/// Trivial spinlock-based implementation of `sync::Mutex`.
-// FIXME: Perhaps use Intel TSX to avoid locking?
-mod spin_mutex {
-    use crate::cell::UnsafeCell;
-    use crate::ops::{Deref, DerefMut};
-    use crate::sync::atomic::{spin_loop_hint, AtomicBool, Ordering};
-
-    #[derive(Default)]
-    pub struct SpinMutex<T> {
-        value: UnsafeCell<T>,
-        lock: AtomicBool,
-    }
-
-    unsafe impl<T: Send> Send for SpinMutex<T> {}
-    unsafe impl<T: Send> Sync for SpinMutex<T> {}
-
-    pub struct SpinMutexGuard<'a, T: 'a> {
-        mutex: &'a SpinMutex<T>,
-    }
-
-    impl<'a, T> !Send for SpinMutexGuard<'a, T> {}
-    unsafe impl<'a, T: Sync> Sync for SpinMutexGuard<'a, T> {}
-
-    impl<T> SpinMutex<T> {
-        pub const fn new(value: T) -> Self {
-            SpinMutex { value: UnsafeCell::new(value), lock: AtomicBool::new(false) }
-        }
-
-        #[inline(always)]
-        pub fn lock(&self) -> SpinMutexGuard<'_, T> {
-            loop {
-                match self.try_lock() {
-                    None => {
-                        while self.lock.load(Ordering::Relaxed) {
-                            spin_loop_hint()
-                        }
-                    }
-                    Some(guard) => return guard,
-                }
-            }
-        }
-
-        #[inline(always)]
-        pub fn try_lock(&self) -> Option<SpinMutexGuard<'_, T>> {
-            if !self.lock.compare_and_swap(false, true, Ordering::Acquire) {
-                Some(SpinMutexGuard { mutex: self })
-            } else {
-                None
-            }
-        }
-    }
-
-    /// Lock the Mutex or return false.
-    pub macro try_lock_or_false($e:expr) {
-        if let Some(v) = $e.try_lock() { v } else { return false }
-    }
-
-    impl<'a, T> Deref for SpinMutexGuard<'a, T> {
-        type Target = T;
-
-        fn deref(&self) -> &T {
-            unsafe { &*self.mutex.value.get() }
-        }
-    }
-
-    impl<'a, T> DerefMut for SpinMutexGuard<'a, T> {
-        fn deref_mut(&mut self) -> &mut T {
-            unsafe { &mut *self.mutex.value.get() }
-        }
-    }
-
-    impl<'a, T> Drop for SpinMutexGuard<'a, T> {
-        fn drop(&mut self) {
-            self.mutex.lock.store(false, Ordering::Release)
-        }
-    }
-
-    #[cfg(test)]
-    mod tests {
-        #![allow(deprecated)]
-
-        use super::*;
-        use crate::sync::Arc;
-        use crate::thread;
-        use crate::time::Duration;
-
-        #[test]
-        fn sleep() {
-            let mutex = Arc::new(SpinMutex::<i32>::default());
-            let mutex2 = mutex.clone();
-            let guard = mutex.lock();
-            let t1 = thread::spawn(move || {
-                *mutex2.lock() = 1;
-            });
-
-            thread::sleep(Duration::from_millis(50));
-
-            assert_eq!(*guard, 0);
-            drop(guard);
-            t1.join().unwrap();
-            assert_eq!(*mutex.lock(), 1);
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::sync::Arc;
-    use crate::thread;
-
-    #[test]
-    fn queue() {
-        let wq = Arc::new(SpinMutex::<WaitVariable<()>>::default());
-        let wq2 = wq.clone();
-
-        let locked = wq.lock();
-
-        let t1 = thread::spawn(move || {
-            // if we obtain the lock, the main thread should be waiting
-            assert!(WaitQueue::notify_one(wq2.lock()).is_ok());
-        });
-
-        WaitQueue::wait(locked, || {});
-
-        t1.join().unwrap();
-    }
-}
diff --git a/library/std/src/sys/sgx/waitqueue/spin_mutex.rs b/library/std/src/sys/sgx/waitqueue/spin_mutex.rs
new file mode 100644
index 00000000000..d99ce895da5
--- /dev/null
+++ b/library/std/src/sys/sgx/waitqueue/spin_mutex.rs
@@ -0,0 +1,76 @@
+#[cfg(test)]
+mod tests;
+
+use crate::cell::UnsafeCell;
+use crate::ops::{Deref, DerefMut};
+use crate::sync::atomic::{spin_loop_hint, AtomicBool, Ordering};
+
+#[derive(Default)]
+pub struct SpinMutex<T> {
+    value: UnsafeCell<T>,
+    lock: AtomicBool,
+}
+
+unsafe impl<T: Send> Send for SpinMutex<T> {}
+unsafe impl<T: Send> Sync for SpinMutex<T> {}
+
+pub struct SpinMutexGuard<'a, T: 'a> {
+    mutex: &'a SpinMutex<T>,
+}
+
+impl<'a, T> !Send for SpinMutexGuard<'a, T> {}
+unsafe impl<'a, T: Sync> Sync for SpinMutexGuard<'a, T> {}
+
+impl<T> SpinMutex<T> {
+    pub const fn new(value: T) -> Self {
+        SpinMutex { value: UnsafeCell::new(value), lock: AtomicBool::new(false) }
+    }
+
+    #[inline(always)]
+    pub fn lock(&self) -> SpinMutexGuard<'_, T> {
+        loop {
+            match self.try_lock() {
+                None => {
+                    while self.lock.load(Ordering::Relaxed) {
+                        spin_loop_hint()
+                    }
+                }
+                Some(guard) => return guard,
+            }
+        }
+    }
+
+    #[inline(always)]
+    pub fn try_lock(&self) -> Option<SpinMutexGuard<'_, T>> {
+        if !self.lock.compare_and_swap(false, true, Ordering::Acquire) {
+            Some(SpinMutexGuard { mutex: self })
+        } else {
+            None
+        }
+    }
+}
+
+/// Lock the Mutex or return false.
+pub macro try_lock_or_false($e:expr) {
+    if let Some(v) = $e.try_lock() { v } else { return false }
+}
+
+impl<'a, T> Deref for SpinMutexGuard<'a, T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe { &*self.mutex.value.get() }
+    }
+}
+
+impl<'a, T> DerefMut for SpinMutexGuard<'a, T> {
+    fn deref_mut(&mut self) -> &mut T {
+        unsafe { &mut *self.mutex.value.get() }
+    }
+}
+
+impl<'a, T> Drop for SpinMutexGuard<'a, T> {
+    fn drop(&mut self) {
+        self.mutex.lock.store(false, Ordering::Release)
+    }
+}
diff --git a/library/std/src/sys/sgx/waitqueue/spin_mutex/tests.rs b/library/std/src/sys/sgx/waitqueue/spin_mutex/tests.rs
new file mode 100644
index 00000000000..4c5994bea61
--- /dev/null
+++ b/library/std/src/sys/sgx/waitqueue/spin_mutex/tests.rs
@@ -0,0 +1,23 @@
+#![allow(deprecated)]
+
+use super::*;
+use crate::sync::Arc;
+use crate::thread;
+use crate::time::Duration;
+
+#[test]
+fn sleep() {
+    let mutex = Arc::new(SpinMutex::<i32>::default());
+    let mutex2 = mutex.clone();
+    let guard = mutex.lock();
+    let t1 = thread::spawn(move || {
+        *mutex2.lock() = 1;
+    });
+
+    thread::sleep(Duration::from_millis(50));
+
+    assert_eq!(*guard, 0);
+    drop(guard);
+    t1.join().unwrap();
+    assert_eq!(*mutex.lock(), 1);
+}
diff --git a/library/std/src/sys/sgx/waitqueue/tests.rs b/library/std/src/sys/sgx/waitqueue/tests.rs
new file mode 100644
index 00000000000..bf91fdd08ed
--- /dev/null
+++ b/library/std/src/sys/sgx/waitqueue/tests.rs
@@ -0,0 +1,20 @@
+use super::*;
+use crate::sync::Arc;
+use crate::thread;
+
+#[test]
+fn queue() {
+    let wq = Arc::new(SpinMutex::<WaitVariable<()>>::default());
+    let wq2 = wq.clone();
+
+    let locked = wq.lock();
+
+    let t1 = thread::spawn(move || {
+        // if we obtain the lock, the main thread should be waiting
+        assert!(WaitQueue::notify_one(wq2.lock()).is_ok());
+    });
+
+    WaitQueue::wait(locked, || {});
+
+    t1.join().unwrap();
+}
diff --git a/library/std/src/sys/sgx/waitqueue/unsafe_list.rs b/library/std/src/sys/sgx/waitqueue/unsafe_list.rs
new file mode 100644
index 00000000000..7a246542739
--- /dev/null
+++ b/library/std/src/sys/sgx/waitqueue/unsafe_list.rs
@@ -0,0 +1,146 @@
+#[cfg(test)]
+mod tests;
+
+use crate::mem;
+use crate::ptr::NonNull;
+
+pub struct UnsafeListEntry<T> {
+    next: NonNull<UnsafeListEntry<T>>,
+    prev: NonNull<UnsafeListEntry<T>>,
+    value: Option<T>,
+}
+
+impl<T> UnsafeListEntry<T> {
+    fn dummy() -> Self {
+        UnsafeListEntry { next: NonNull::dangling(), prev: NonNull::dangling(), value: None }
+    }
+
+    pub fn new(value: T) -> Self {
+        UnsafeListEntry { value: Some(value), ..Self::dummy() }
+    }
+}
+
+pub struct UnsafeList<T> {
+    head_tail: NonNull<UnsafeListEntry<T>>,
+    head_tail_entry: Option<UnsafeListEntry<T>>,
+}
+
+impl<T> UnsafeList<T> {
+    pub const fn new() -> Self {
+        unsafe { UnsafeList { head_tail: NonNull::new_unchecked(1 as _), head_tail_entry: None } }
+    }
+
+    unsafe fn init(&mut self) {
+        if self.head_tail_entry.is_none() {
+            self.head_tail_entry = Some(UnsafeListEntry::dummy());
+            self.head_tail = NonNull::new_unchecked(self.head_tail_entry.as_mut().unwrap());
+            self.head_tail.as_mut().next = self.head_tail;
+            self.head_tail.as_mut().prev = self.head_tail;
+        }
+    }
+
+    pub fn is_empty(&self) -> bool {
+        unsafe {
+            if self.head_tail_entry.is_some() {
+                let first = self.head_tail.as_ref().next;
+                if first == self.head_tail {
+                    // ,-------> /---------\ next ---,
+                    // |         |head_tail|         |
+                    // `--- prev \---------/ <-------`
+                    rtassert!(self.head_tail.as_ref().prev == first);
+                    true
+                } else {
+                    false
+                }
+            } else {
+                true
+            }
+        }
+    }
+
+    /// Pushes an entry onto the back of the list.
+    ///
+    /// # Safety
+    ///
+    /// The entry must remain allocated until the entry is removed from the
+    /// list AND the caller who popped is done using the entry. Special
+    /// care must be taken in the caller of `push` to ensure unwinding does
+    /// not destroy the stack frame containing the entry.
+    pub unsafe fn push<'a>(&mut self, entry: &'a mut UnsafeListEntry<T>) -> &'a T {
+        self.init();
+
+        // BEFORE:
+        //     /---------\ next ---> /---------\
+        // ... |prev_tail|           |head_tail| ...
+        //     \---------/ <--- prev \---------/
+        //
+        // AFTER:
+        //     /---------\ next ---> /-----\ next ---> /---------\
+        // ... |prev_tail|           |entry|           |head_tail| ...
+        //     \---------/ <--- prev \-----/ <--- prev \---------/
+        let mut entry = NonNull::new_unchecked(entry);
+        let mut prev_tail = mem::replace(&mut self.head_tail.as_mut().prev, entry);
+        entry.as_mut().prev = prev_tail;
+        entry.as_mut().next = self.head_tail;
+        prev_tail.as_mut().next = entry;
+        // unwrap ok: always `Some` on non-dummy entries
+        (*entry.as_ptr()).value.as_ref().unwrap()
+    }
+
+    /// Pops an entry from the front of the list.
+    ///
+    /// # Safety
+    ///
+    /// The caller must make sure to synchronize ending the borrow of the
+    /// return value and deallocation of the containing entry.
+    pub unsafe fn pop<'a>(&mut self) -> Option<&'a T> {
+        self.init();
+
+        if self.is_empty() {
+            None
+        } else {
+            // BEFORE:
+            //     /---------\ next ---> /-----\ next ---> /------\
+            // ... |head_tail|           |first|           |second| ...
+            //     \---------/ <--- prev \-----/ <--- prev \------/
+            //
+            // AFTER:
+            //     /---------\ next ---> /------\
+            // ... |head_tail|           |second| ...
+            //     \---------/ <--- prev \------/
+            let mut first = self.head_tail.as_mut().next;
+            let mut second = first.as_mut().next;
+            self.head_tail.as_mut().next = second;
+            second.as_mut().prev = self.head_tail;
+            first.as_mut().next = NonNull::dangling();
+            first.as_mut().prev = NonNull::dangling();
+            // unwrap ok: always `Some` on non-dummy entries
+            Some((*first.as_ptr()).value.as_ref().unwrap())
+        }
+    }
+
+    /// Removes an entry from the list.
+    ///
+    /// # Safety
+    ///
+    /// The caller must ensure that `entry` has been pushed onto `self`
+    /// prior to this call and has not moved since then.
+    pub unsafe fn remove(&mut self, entry: &mut UnsafeListEntry<T>) {
+        rtassert!(!self.is_empty());
+        // BEFORE:
+        //     /----\ next ---> /-----\ next ---> /----\
+        // ... |prev|           |entry|           |next| ...
+        //     \----/ <--- prev \-----/ <--- prev \----/
+        //
+        // AFTER:
+        //     /----\ next ---> /----\
+        // ... |prev|           |next| ...
+        //     \----/ <--- prev \----/
+        let mut prev = entry.prev;
+        let mut next = entry.next;
+        prev.as_mut().next = next;
+        next.as_mut().prev = prev;
+        entry.next = NonNull::dangling();
+        entry.prev = NonNull::dangling();
+    }
+}
diff --git a/library/std/src/sys/sgx/waitqueue/unsafe_list/tests.rs b/library/std/src/sys/sgx/waitqueue/unsafe_list/tests.rs
new file mode 100644
index 00000000000..1f031ed1959
--- /dev/null
+++ b/library/std/src/sys/sgx/waitqueue/unsafe_list/tests.rs
@@ -0,0 +1,103 @@
+use super::*;
+use crate::cell::Cell;
+
+unsafe fn assert_empty<T>(list: &mut UnsafeList<T>) {
+    assert!(list.pop().is_none(), "assertion failed: list is not empty");
+}
+
+#[test]
+fn init_empty() {
+    unsafe {
+        assert_empty(&mut UnsafeList::<i32>::new());
+    }
+}
+
+#[test]
+fn push_pop() {
+    unsafe {
+        let mut node = UnsafeListEntry::new(1234);
+        let mut list = UnsafeList::new();
+        assert_eq!(list.push(&mut node), &1234);
+        assert_eq!(list.pop().unwrap(), &1234);
+        assert_empty(&mut list);
+    }
+}
+
+#[test]
+fn push_remove() {
+    unsafe {
+        let mut node = UnsafeListEntry::new(1234);
+        let mut list = UnsafeList::new();
+        assert_eq!(list.push(&mut node), &1234);
+        list.remove(&mut node);
+        assert_empty(&mut list);
+    }
+}
+
+#[test]
+fn push_remove_pop() {
+    unsafe {
+        let mut node1 = UnsafeListEntry::new(11);
+        let mut node2 = UnsafeListEntry::new(12);
+        let mut node3 = UnsafeListEntry::new(13);
+        let mut node4 = UnsafeListEntry::new(14);
+        let mut node5 = UnsafeListEntry::new(15);
+        let mut list = UnsafeList::new();
+        assert_eq!(list.push(&mut node1), &11);
+        assert_eq!(list.push(&mut node2), &12);
+        assert_eq!(list.push(&mut node3), &13);
+        assert_eq!(list.push(&mut node4), &14);
+        assert_eq!(list.push(&mut node5), &15);
+
+        list.remove(&mut node1);
+        assert_eq!(list.pop().unwrap(), &12);
+        list.remove(&mut node3);
+        assert_eq!(list.pop().unwrap(), &14);
+        list.remove(&mut node5);
+        assert_empty(&mut list);
+
+        assert_eq!(list.push(&mut node1), &11);
+        assert_eq!(list.pop().unwrap(), &11);
+        assert_empty(&mut list);
+
+        assert_eq!(list.push(&mut node3), &13);
+        assert_eq!(list.push(&mut node4), &14);
+        list.remove(&mut node3);
+        list.remove(&mut node4);
+        assert_empty(&mut list);
+    }
+}
+
+#[test]
+fn complex_pushes_pops() {
+    unsafe {
+        let mut node1 = UnsafeListEntry::new(1234);
+        let mut node2 = UnsafeListEntry::new(4567);
+        let mut node3 = UnsafeListEntry::new(9999);
+        let mut node4 = UnsafeListEntry::new(8642);
+        let mut list = UnsafeList::new();
+        list.push(&mut node1);
+        list.push(&mut node2);
+        assert_eq!(list.pop().unwrap(), &1234);
+        list.push(&mut node3);
+        assert_eq!(list.pop().unwrap(), &4567);
+        assert_eq!(list.pop().unwrap(), &9999);
+        assert_empty(&mut list);
+        list.push(&mut node4);
+        assert_eq!(list.pop().unwrap(), &8642);
+        assert_empty(&mut list);
+    }
+}
+
+#[test]
+fn cell() {
+    unsafe {
+        let mut node = UnsafeListEntry::new(Cell::new(0));
+        let mut list = UnsafeList::new();
+        let noderef = list.push(&mut node);
+        assert_eq!(noderef.get(), 0);
+        list.pop().unwrap().set(1);
+        assert_empty(&mut list);
+        assert_eq!(noderef.get(), 1);
+    }
+}
diff --git a/library/std/src/sys/unix/ext/fs.rs b/library/std/src/sys/unix/ext/fs.rs
index b590a0280d1..e48e950928a 100644
--- a/library/std/src/sys/unix/ext/fs.rs
+++ b/library/std/src/sys/unix/ext/fs.rs
@@ -8,6 +8,9 @@ use crate::path::Path;
 use crate::sys;
 use crate::sys::platform::fs::MetadataExt as UnixMetadataExt;
 use crate::sys_common::{AsInner, AsInnerMut, FromInner};
+// Used for `File::read` on intra-doc links
+#[allow(unused_imports)]
+use io::{Read, Write};
 
 /// Unix-specific extensions to [`fs::File`].
 #[stable(feature = "file_offset", since = "1.15.0")]
@@ -24,7 +27,7 @@ pub trait FileExt {
     /// Note that similar to [`File::read`], it is not an error to return with a
     /// short read.
     ///
-    /// [`File::read`]: ../../../../std/fs/struct.File.html#method.read
+    /// [`File::read`]: fs::File::read
     ///
     /// # Examples
     ///
@@ -127,7 +130,7 @@ pub trait FileExt {
     /// Note that similar to [`File::write`], it is not an error to return a
     /// short write.
     ///
-    /// [`File::write`]: ../../../../std/fs/struct.File.html#method.write
+    /// [`File::write`]: fs::File::write
     ///
     /// # Examples
     ///
diff --git a/library/std/src/sys/unix/ext/net.rs b/library/std/src/sys/unix/ext/net.rs
index 55803ddfc43..0e07106f5ce 100644
--- a/library/std/src/sys/unix/ext/net.rs
+++ b/library/std/src/sys/unix/ext/net.rs
@@ -2,6 +2,9 @@
 
 //! Unix-specific networking functionality
 
+#[cfg(all(test, not(target_os = "emscripten")))]
+mod tests;
+
 // FIXME(#43348): Make libc adapt #[doc(cfg(...))] so we don't need these fake definitions here?
 #[cfg(not(unix))]
 #[allow(non_camel_case_types)]
@@ -1620,382 +1623,3 @@ impl IntoRawFd for UnixDatagram {
         self.0.into_inner()
     }
 }
-
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod test {
-    use crate::io::prelude::*;
-    use crate::io::{self, ErrorKind};
-    use crate::sys_common::io::test::tmpdir;
-    use crate::thread;
-    use crate::time::Duration;
-
-    use super::*;
-
-    macro_rules! or_panic {
-        ($e:expr) => {
-            match $e {
-                Ok(e) => e,
-                Err(e) => panic!("{}", e),
-            }
-        };
-    }
-
-    #[test]
-    fn basic() {
-        let dir = tmpdir();
-        let socket_path = dir.path().join("sock");
-        let msg1 = b"hello";
-        let msg2 = b"world!";
-
-        let listener = or_panic!(UnixListener::bind(&socket_path));
-        let thread = thread::spawn(move || {
-            let mut stream = or_panic!(listener.accept()).0;
-            let mut buf = [0; 5];
-            or_panic!(stream.read(&mut buf));
-            assert_eq!(&msg1[..], &buf[..]);
-            or_panic!(stream.write_all(msg2));
-        });
-
-        let mut stream = or_panic!(UnixStream::connect(&socket_path));
-        assert_eq!(Some(&*socket_path), stream.peer_addr().unwrap().as_pathname());
-        or_panic!(stream.write_all(msg1));
-        let mut buf = vec![];
-        or_panic!(stream.read_to_end(&mut buf));
-        assert_eq!(&msg2[..], &buf[..]);
-        drop(stream);
-
-        thread.join().unwrap();
-    }
-
-    #[test]
-    fn vectored() {
-        let (mut s1, mut s2) = or_panic!(UnixStream::pair());
-
-        let len = or_panic!(s1.write_vectored(&[
-            IoSlice::new(b"hello"),
-            IoSlice::new(b" "),
-            IoSlice::new(b"world!")
-        ],));
-        assert_eq!(len, 12);
-
-        let mut buf1 = [0; 6];
-        let mut buf2 = [0; 7];
-        let len = or_panic!(
-            s2.read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2)],)
-        );
-        assert_eq!(len, 12);
-        assert_eq!(&buf1, b"hello ");
-        assert_eq!(&buf2, b"world!\0");
-    }
-
-    #[test]
-    fn pair() {
-        let msg1 = b"hello";
-        let msg2 = b"world!";
-
-        let (mut s1, mut s2) = or_panic!(UnixStream::pair());
-        let thread = thread::spawn(move || {
-            // s1 must be moved in or the test will hang!
-            let mut buf = [0; 5];
-            or_panic!(s1.read(&mut buf));
-            assert_eq!(&msg1[..], &buf[..]);
-            or_panic!(s1.write_all(msg2));
-        });
-
-        or_panic!(s2.write_all(msg1));
-        let mut buf = vec![];
-        or_panic!(s2.read_to_end(&mut buf));
-        assert_eq!(&msg2[..], &buf[..]);
-        drop(s2);
-
-        thread.join().unwrap();
-    }
-
-    #[test]
-    fn try_clone() {
-        let dir = tmpdir();
-        let socket_path = dir.path().join("sock");
-        let msg1 = b"hello";
-        let msg2 = b"world";
-
-        let listener = or_panic!(UnixListener::bind(&socket_path));
-        let thread = thread::spawn(move || {
-            let mut stream = or_panic!(listener.accept()).0;
-            or_panic!(stream.write_all(msg1));
-            or_panic!(stream.write_all(msg2));
-        });
-
-        let mut stream = or_panic!(UnixStream::connect(&socket_path));
-        let mut stream2 = or_panic!(stream.try_clone());
-
-        let mut buf = [0; 5];
-        or_panic!(stream.read(&mut buf));
-        assert_eq!(&msg1[..], &buf[..]);
-        or_panic!(stream2.read(&mut buf));
-        assert_eq!(&msg2[..], &buf[..]);
-
-        thread.join().unwrap();
-    }
-
-    #[test]
-    fn iter() {
-        let dir = tmpdir();
-        let socket_path = dir.path().join("sock");
-
-        let listener = or_panic!(UnixListener::bind(&socket_path));
-        let thread = thread::spawn(move || {
-            for stream in listener.incoming().take(2) {
-                let mut stream = or_panic!(stream);
-                let mut buf = [0];
-                or_panic!(stream.read(&mut buf));
-            }
-        });
-
-        for _ in 0..2 {
-            let mut stream = or_panic!(UnixStream::connect(&socket_path));
-            or_panic!(stream.write_all(&[0]));
-        }
-
-        thread.join().unwrap();
-    }
-
-    #[test]
-    fn long_path() {
-        let dir = tmpdir();
-        let socket_path = dir.path().join(
-            "asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa\
-                                    sasdfasdfasdasdfasdfasdfadfasdfasdfasdfasdfasdf",
-        );
-        match UnixStream::connect(&socket_path) {
-            Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
-            Err(e) => panic!("unexpected error {}", e),
-            Ok(_) => panic!("unexpected success"),
-        }
-
-        match UnixListener::bind(&socket_path) {
-            Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
-            Err(e) => panic!("unexpected error {}", e),
-            Ok(_) => panic!("unexpected success"),
-        }
-
-        match UnixDatagram::bind(&socket_path) {
-            Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
-            Err(e) => panic!("unexpected error {}", e),
-            Ok(_) => panic!("unexpected success"),
-        }
-    }
-
-    #[test]
-    fn timeouts() {
-        let dir = tmpdir();
-        let socket_path = dir.path().join("sock");
-
-        let _listener = or_panic!(UnixListener::bind(&socket_path));
-
-        let stream = or_panic!(UnixStream::connect(&socket_path));
-        let dur = Duration::new(15410, 0);
-
-        assert_eq!(None, or_panic!(stream.read_timeout()));
-
-        or_panic!(stream.set_read_timeout(Some(dur)));
-        assert_eq!(Some(dur), or_panic!(stream.read_timeout()));
-
-        assert_eq!(None, or_panic!(stream.write_timeout()));
-
-        or_panic!(stream.set_write_timeout(Some(dur)));
-        assert_eq!(Some(dur), or_panic!(stream.write_timeout()));
-
-        or_panic!(stream.set_read_timeout(None));
-        assert_eq!(None, or_panic!(stream.read_timeout()));
-
-        or_panic!(stream.set_write_timeout(None));
-        assert_eq!(None, or_panic!(stream.write_timeout()));
-    }
-
-    #[test]
-    fn test_read_timeout() {
-        let dir = tmpdir();
-        let socket_path = dir.path().join("sock");
-
-        let _listener = or_panic!(UnixListener::bind(&socket_path));
-
-        let mut stream = or_panic!(UnixStream::connect(&socket_path));
-        or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
-
-        let mut buf = [0; 10];
-        let kind = stream.read_exact(&mut buf).err().expect("expected error").kind();
-        assert!(
-            kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
-            "unexpected_error: {:?}",
-            kind
-        );
-    }
-
-    #[test]
-    fn test_read_with_timeout() {
-        let dir = tmpdir();
-        let socket_path = dir.path().join("sock");
-
-        let listener = or_panic!(UnixListener::bind(&socket_path));
-
-        let mut stream = or_panic!(UnixStream::connect(&socket_path));
-        or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
-
-        let mut other_end = or_panic!(listener.accept()).0;
-        or_panic!(other_end.write_all(b"hello world"));
-
-        let mut buf = [0; 11];
-        or_panic!(stream.read(&mut buf));
-        assert_eq!(b"hello world", &buf[..]);
-
-        let kind = stream.read_exact(&mut buf).err().expect("expected error").kind();
-        assert!(
-            kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
-            "unexpected_error: {:?}",
-            kind
-        );
-    }
-
-    // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
-    // when passed zero Durations
-    #[test]
-    fn test_unix_stream_timeout_zero_duration() {
-        let dir = tmpdir();
-        let socket_path = dir.path().join("sock");
-
-        let listener = or_panic!(UnixListener::bind(&socket_path));
-        let stream = or_panic!(UnixStream::connect(&socket_path));
-
-        let result = stream.set_write_timeout(Some(Duration::new(0, 0)));
-        let err = result.unwrap_err();
-        assert_eq!(err.kind(), ErrorKind::InvalidInput);
-
-        let result = stream.set_read_timeout(Some(Duration::new(0, 0)));
-        let err = result.unwrap_err();
-        assert_eq!(err.kind(), ErrorKind::InvalidInput);
-
-        drop(listener);
-    }
-
-    #[test]
-    fn test_unix_datagram() {
-        let dir = tmpdir();
-        let path1 = dir.path().join("sock1");
-        let path2 = dir.path().join("sock2");
-
-        let sock1 = or_panic!(UnixDatagram::bind(&path1));
-        let sock2 = or_panic!(UnixDatagram::bind(&path2));
-
-        let msg = b"hello world";
-        or_panic!(sock1.send_to(msg, &path2));
-        let mut buf = [0; 11];
-        or_panic!(sock2.recv_from(&mut buf));
-        assert_eq!(msg, &buf[..]);
-    }
-
-    #[test]
-    fn test_unnamed_unix_datagram() {
-        let dir = tmpdir();
-        let path1 = dir.path().join("sock1");
-
-        let sock1 = or_panic!(UnixDatagram::bind(&path1));
-        let sock2 = or_panic!(UnixDatagram::unbound());
-
-        let msg = b"hello world";
-        or_panic!(sock2.send_to(msg, &path1));
-        let mut buf = [0; 11];
-        let (usize, addr) = or_panic!(sock1.recv_from(&mut buf));
-        assert_eq!(usize, 11);
-        assert!(addr.is_unnamed());
-        assert_eq!(msg, &buf[..]);
-    }
-
-    #[test]
-    fn test_connect_unix_datagram() {
-        let dir = tmpdir();
-        let path1 = dir.path().join("sock1");
-        let path2 = dir.path().join("sock2");
-
-        let bsock1 = or_panic!(UnixDatagram::bind(&path1));
-        let bsock2 = or_panic!(UnixDatagram::bind(&path2));
-        let sock = or_panic!(UnixDatagram::unbound());
-        or_panic!(sock.connect(&path1));
-
-        // Check send()
-        let msg = b"hello there";
-        or_panic!(sock.send(msg));
-        let mut buf = [0; 11];
-        let (usize, addr) = or_panic!(bsock1.recv_from(&mut buf));
-        assert_eq!(usize, 11);
-        assert!(addr.is_unnamed());
-        assert_eq!(msg, &buf[..]);
-
-        // Changing default socket works too
-        or_panic!(sock.connect(&path2));
-        or_panic!(sock.send(msg));
-        or_panic!(bsock2.recv_from(&mut buf));
-    }
-
-    #[test]
-    fn test_unix_datagram_recv() {
-        let dir = tmpdir();
-        let path1 = dir.path().join("sock1");
-
-        let sock1 = or_panic!(UnixDatagram::bind(&path1));
-        let sock2 = or_panic!(UnixDatagram::unbound());
-        or_panic!(sock2.connect(&path1));
-
-        let msg = b"hello world";
-        or_panic!(sock2.send(msg));
-        let mut buf = [0; 11];
-        let size = or_panic!(sock1.recv(&mut buf));
-        assert_eq!(size, 11);
-        assert_eq!(msg, &buf[..]);
-    }
-
-    #[test]
-    fn datagram_pair() {
-        let msg1 = b"hello";
-        let msg2 = b"world!";
-
-        let (s1, s2) = or_panic!(UnixDatagram::pair());
-        let thread = thread::spawn(move || {
-            // s1 must be moved in or the test will hang!
-            let mut buf = [0; 5];
-            or_panic!(s1.recv(&mut buf));
-            assert_eq!(&msg1[..], &buf[..]);
-            or_panic!(s1.send(msg2));
-        });
-
-        or_panic!(s2.send(msg1));
-        let mut buf = [0; 6];
-        or_panic!(s2.recv(&mut buf));
-        assert_eq!(&msg2[..], &buf[..]);
-        drop(s2);
-
-        thread.join().unwrap();
-    }
-
-    // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
-    // when passed zero Durations
-    #[test]
-    fn test_unix_datagram_timeout_zero_duration() {
-        let dir = tmpdir();
-        let path = dir.path().join("sock");
-
-        let datagram = or_panic!(UnixDatagram::bind(&path));
-
-        let result = datagram.set_write_timeout(Some(Duration::new(0, 0)));
-        let err = result.unwrap_err();
-        assert_eq!(err.kind(), ErrorKind::InvalidInput);
-
-        let result = datagram.set_read_timeout(Some(Duration::new(0, 0)));
-        let err = result.unwrap_err();
-        assert_eq!(err.kind(), ErrorKind::InvalidInput);
-    }
-
-    #[test]
-    fn abstract_namespace_not_allowed() {
-        assert!(UnixStream::connect("\0asdf").is_err());
-    }
-}
diff --git a/library/std/src/sys/unix/ext/net/tests.rs b/library/std/src/sys/unix/ext/net/tests.rs
new file mode 100644
index 00000000000..be98766f0f3
--- /dev/null
+++ b/library/std/src/sys/unix/ext/net/tests.rs
@@ -0,0 +1,374 @@
+use crate::io::prelude::*;
+use crate::io::{self, ErrorKind};
+use crate::sys_common::io::test::tmpdir;
+use crate::thread;
+use crate::time::Duration;
+
+use super::*;
+
+macro_rules! or_panic {
+    ($e:expr) => {
+        match $e {
+            Ok(e) => e,
+            Err(e) => panic!("{}", e),
+        }
+    };
+}
+
+#[test]
+fn basic() {
+    let dir = tmpdir();
+    let socket_path = dir.path().join("sock");
+    let msg1 = b"hello";
+    let msg2 = b"world!";
+
+    let listener = or_panic!(UnixListener::bind(&socket_path));
+    let thread = thread::spawn(move || {
+        let mut stream = or_panic!(listener.accept()).0;
+        let mut buf = [0; 5];
+        or_panic!(stream.read(&mut buf));
+        assert_eq!(&msg1[..], &buf[..]);
+        or_panic!(stream.write_all(msg2));
+    });
+
+    let mut stream = or_panic!(UnixStream::connect(&socket_path));
+    assert_eq!(Some(&*socket_path), stream.peer_addr().unwrap().as_pathname());
+    or_panic!(stream.write_all(msg1));
+    let mut buf = vec![];
+    or_panic!(stream.read_to_end(&mut buf));
+    assert_eq!(&msg2[..], &buf[..]);
+    drop(stream);
+
+    thread.join().unwrap();
+}
+
+#[test]
+fn vectored() {
+    let (mut s1, mut s2) = or_panic!(UnixStream::pair());
+
+    let len = or_panic!(s1.write_vectored(&[
+        IoSlice::new(b"hello"),
+        IoSlice::new(b" "),
+        IoSlice::new(b"world!")
+    ],));
+    assert_eq!(len, 12);
+
+    let mut buf1 = [0; 6];
+    let mut buf2 = [0; 7];
+    let len =
+        or_panic!(s2.read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2)],));
+    assert_eq!(len, 12);
+    assert_eq!(&buf1, b"hello ");
+    assert_eq!(&buf2, b"world!\0");
+}
+
+#[test]
+fn pair() {
+    let msg1 = b"hello";
+    let msg2 = b"world!";
+
+    let (mut s1, mut s2) = or_panic!(UnixStream::pair());
+    let thread = thread::spawn(move || {
+        // s1 must be moved in or the test will hang!
+        let mut buf = [0; 5];
+        or_panic!(s1.read(&mut buf));
+        assert_eq!(&msg1[..], &buf[..]);
+        or_panic!(s1.write_all(msg2));
+    });
+
+    or_panic!(s2.write_all(msg1));
+    let mut buf = vec![];
+    or_panic!(s2.read_to_end(&mut buf));
+    assert_eq!(&msg2[..], &buf[..]);
+    drop(s2);
+
+    thread.join().unwrap();
+}
+
+#[test]
+fn try_clone() {
+    let dir = tmpdir();
+    let socket_path = dir.path().join("sock");
+    let msg1 = b"hello";
+    let msg2 = b"world";
+
+    let listener = or_panic!(UnixListener::bind(&socket_path));
+    let thread = thread::spawn(move || {
+        let mut stream = or_panic!(listener.accept()).0;
+        or_panic!(stream.write_all(msg1));
+        or_panic!(stream.write_all(msg2));
+    });
+
+    let mut stream = or_panic!(UnixStream::connect(&socket_path));
+    let mut stream2 = or_panic!(stream.try_clone());
+
+    let mut buf = [0; 5];
+    or_panic!(stream.read(&mut buf));
+    assert_eq!(&msg1[..], &buf[..]);
+    or_panic!(stream2.read(&mut buf));
+    assert_eq!(&msg2[..], &buf[..]);
+
+    thread.join().unwrap();
+}
+
+#[test]
+fn iter() {
+    let dir = tmpdir();
+    let socket_path = dir.path().join("sock");
+
+    let listener = or_panic!(UnixListener::bind(&socket_path));
+    let thread = thread::spawn(move || {
+        for stream in listener.incoming().take(2) {
+            let mut stream = or_panic!(stream);
+            let mut buf = [0];
+            or_panic!(stream.read(&mut buf));
+        }
+    });
+
+    for _ in 0..2 {
+        let mut stream = or_panic!(UnixStream::connect(&socket_path));
+        or_panic!(stream.write_all(&[0]));
+    }
+
+    thread.join().unwrap();
+}
+
+#[test]
+fn long_path() {
+    let dir = tmpdir();
+    let socket_path = dir.path().join(
+        "asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa\
+                                sasdfasdfasdasdfasdfasdfadfasdfasdfasdfasdfasdf",
+    );
+    match UnixStream::connect(&socket_path) {
+        Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
+        Err(e) => panic!("unexpected error {}", e),
+        Ok(_) => panic!("unexpected success"),
+    }
+
+    match UnixListener::bind(&socket_path) {
+        Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
+        Err(e) => panic!("unexpected error {}", e),
+        Ok(_) => panic!("unexpected success"),
+    }
+
+    match UnixDatagram::bind(&socket_path) {
+        Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
+        Err(e) => panic!("unexpected error {}", e),
+        Ok(_) => panic!("unexpected success"),
+    }
+}
+
+#[test]
+fn timeouts() {
+    let dir = tmpdir();
+    let socket_path = dir.path().join("sock");
+
+    let _listener = or_panic!(UnixListener::bind(&socket_path));
+
+    let stream = or_panic!(UnixStream::connect(&socket_path));
+    let dur = Duration::new(15410, 0);
+
+    assert_eq!(None, or_panic!(stream.read_timeout()));
+
+    or_panic!(stream.set_read_timeout(Some(dur)));
+    assert_eq!(Some(dur), or_panic!(stream.read_timeout()));
+
+    assert_eq!(None, or_panic!(stream.write_timeout()));
+
+    or_panic!(stream.set_write_timeout(Some(dur)));
+    assert_eq!(Some(dur), or_panic!(stream.write_timeout()));
+
+    or_panic!(stream.set_read_timeout(None));
+    assert_eq!(None, or_panic!(stream.read_timeout()));
+
+    or_panic!(stream.set_write_timeout(None));
+    assert_eq!(None, or_panic!(stream.write_timeout()));
+}
+
+#[test]
+fn test_read_timeout() {
+    let dir = tmpdir();
+    let socket_path = dir.path().join("sock");
+
+    let _listener = or_panic!(UnixListener::bind(&socket_path));
+
+    let mut stream = or_panic!(UnixStream::connect(&socket_path));
+    or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
+
+    let mut buf = [0; 10];
+    let kind = stream.read_exact(&mut buf).err().expect("expected error").kind();
+    assert!(
+        kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
+        "unexpected_error: {:?}",
+        kind
+    );
+}
+
+#[test]
+fn test_read_with_timeout() {
+    let dir = tmpdir();
+    let socket_path = dir.path().join("sock");
+
+    let listener = or_panic!(UnixListener::bind(&socket_path));
+
+    let mut stream = or_panic!(UnixStream::connect(&socket_path));
+    or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
+
+    let mut other_end = or_panic!(listener.accept()).0;
+    or_panic!(other_end.write_all(b"hello world"));
+
+    let mut buf = [0; 11];
+    or_panic!(stream.read(&mut buf));
+    assert_eq!(b"hello world", &buf[..]);
+
+    let kind = stream.read_exact(&mut buf).err().expect("expected error").kind();
+    assert!(
+        kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
+        "unexpected_error: {:?}",
+        kind
+    );
+}
+
+// Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
+// when passed zero Durations
+#[test]
+fn test_unix_stream_timeout_zero_duration() {
+    let dir = tmpdir();
+    let socket_path = dir.path().join("sock");
+
+    let listener = or_panic!(UnixListener::bind(&socket_path));
+    let stream = or_panic!(UnixStream::connect(&socket_path));
+
+    let result = stream.set_write_timeout(Some(Duration::new(0, 0)));
+    let err = result.unwrap_err();
+    assert_eq!(err.kind(), ErrorKind::InvalidInput);
+
+    let result = stream.set_read_timeout(Some(Duration::new(0, 0)));
+    let err = result.unwrap_err();
+    assert_eq!(err.kind(), ErrorKind::InvalidInput);
+
+    drop(listener);
+}
+
+#[test]
+fn test_unix_datagram() {
+    let dir = tmpdir();
+    let path1 = dir.path().join("sock1");
+    let path2 = dir.path().join("sock2");
+
+    let sock1 = or_panic!(UnixDatagram::bind(&path1));
+    let sock2 = or_panic!(UnixDatagram::bind(&path2));
+
+    let msg = b"hello world";
+    or_panic!(sock1.send_to(msg, &path2));
+    let mut buf = [0; 11];
+    or_panic!(sock2.recv_from(&mut buf));
+    assert_eq!(msg, &buf[..]);
+}
+
+#[test]
+fn test_unnamed_unix_datagram() {
+    let dir = tmpdir();
+    let path1 = dir.path().join("sock1");
+
+    let sock1 = or_panic!(UnixDatagram::bind(&path1));
+    let sock2 = or_panic!(UnixDatagram::unbound());
+
+    let msg = b"hello world";
+    or_panic!(sock2.send_to(msg, &path1));
+    let mut buf = [0; 11];
+    let (usize, addr) = or_panic!(sock1.recv_from(&mut buf));
+    assert_eq!(usize, 11);
+    assert!(addr.is_unnamed());
+    assert_eq!(msg, &buf[..]);
+}
+
+#[test]
+fn test_connect_unix_datagram() {
+    let dir = tmpdir();
+    let path1 = dir.path().join("sock1");
+    let path2 = dir.path().join("sock2");
+
+    let bsock1 = or_panic!(UnixDatagram::bind(&path1));
+    let bsock2 = or_panic!(UnixDatagram::bind(&path2));
+    let sock = or_panic!(UnixDatagram::unbound());
+    or_panic!(sock.connect(&path1));
+
+    // Check send()
+    let msg = b"hello there";
+    or_panic!(sock.send(msg));
+    let mut buf = [0; 11];
+    let (usize, addr) = or_panic!(bsock1.recv_from(&mut buf));
+    assert_eq!(usize, 11);
+    assert!(addr.is_unnamed());
+    assert_eq!(msg, &buf[..]);
+
+    // Changing default socket works too
+    or_panic!(sock.connect(&path2));
+    or_panic!(sock.send(msg));
+    or_panic!(bsock2.recv_from(&mut buf));
+}
+
+#[test]
+fn test_unix_datagram_recv() {
+    let dir = tmpdir();
+    let path1 = dir.path().join("sock1");
+
+    let sock1 = or_panic!(UnixDatagram::bind(&path1));
+    let sock2 = or_panic!(UnixDatagram::unbound());
+    or_panic!(sock2.connect(&path1));
+
+    let msg = b"hello world";
+    or_panic!(sock2.send(msg));
+    let mut buf = [0; 11];
+    let size = or_panic!(sock1.recv(&mut buf));
+    assert_eq!(size, 11);
+    assert_eq!(msg, &buf[..]);
+}
+
+#[test]
+fn datagram_pair() {
+    let msg1 = b"hello";
+    let msg2 = b"world!";
+
+    let (s1, s2) = or_panic!(UnixDatagram::pair());
+    let thread = thread::spawn(move || {
+        // s1 must be moved in or the test will hang!
+        let mut buf = [0; 5];
+        or_panic!(s1.recv(&mut buf));
+        assert_eq!(&msg1[..], &buf[..]);
+        or_panic!(s1.send(msg2));
+    });
+
+    or_panic!(s2.send(msg1));
+    let mut buf = [0; 6];
+    or_panic!(s2.recv(&mut buf));
+    assert_eq!(&msg2[..], &buf[..]);
+    drop(s2);
+
+    thread.join().unwrap();
+}
+
+// Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
+// when passed zero Durations
+#[test]
+fn test_unix_datagram_timeout_zero_duration() {
+    let dir = tmpdir();
+    let path = dir.path().join("sock");
+
+    let datagram = or_panic!(UnixDatagram::bind(&path));
+
+    let result = datagram.set_write_timeout(Some(Duration::new(0, 0)));
+    let err = result.unwrap_err();
+    assert_eq!(err.kind(), ErrorKind::InvalidInput);
+
+    let result = datagram.set_read_timeout(Some(Duration::new(0, 0)));
+    let err = result.unwrap_err();
+    assert_eq!(err.kind(), ErrorKind::InvalidInput);
+}
+
+#[test]
+fn abstract_namespace_not_allowed() {
+    assert!(UnixStream::connect("\0asdf").is_err());
+}
diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs
index ba169b251b0..b2f15eda9d7 100644
--- a/library/std/src/sys/unix/fd.rs
+++ b/library/std/src/sys/unix/fd.rs
@@ -1,5 +1,8 @@
 #![unstable(reason = "not public", issue = "none", feature = "fd")]
 
+#[cfg(test)]
+mod tests;
+
 use crate::cmp;
 use crate::io::{self, Initializer, IoSlice, IoSliceMut, Read};
 use crate::mem;
@@ -279,16 +282,3 @@ impl Drop for FileDesc {
         let _ = unsafe { libc::close(self.fd) };
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use super::{FileDesc, IoSlice};
-    use core::mem::ManuallyDrop;
-
-    #[test]
-    fn limit_vector_count() {
-        let stdout = ManuallyDrop::new(FileDesc { fd: 1 });
-        let bufs = (0..1500).map(|_| IoSlice::new(&[])).collect::<Vec<_>>();
-        assert!(stdout.write_vectored(&bufs).is_ok());
-    }
-}
diff --git a/library/std/src/sys/unix/fd/tests.rs b/library/std/src/sys/unix/fd/tests.rs
new file mode 100644
index 00000000000..a932043cbc6
--- /dev/null
+++ b/library/std/src/sys/unix/fd/tests.rs
@@ -0,0 +1,9 @@
+use super::{FileDesc, IoSlice};
+use core::mem::ManuallyDrop;
+
+#[test]
+fn limit_vector_count() {
+    let stdout = ManuallyDrop::new(FileDesc { fd: 1 });
+    let bufs = (0..1500).map(|_| IoSlice::new(&[])).collect::<Vec<_>>();
+    assert!(stdout.write_vectored(&bufs).is_ok());
+}
diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs
index 2fcb5b9c4e6..4aa61fc5bf6 100644
--- a/library/std/src/sys/unix/os.rs
+++ b/library/std/src/sys/unix/os.rs
@@ -2,6 +2,9 @@
 
 #![allow(unused_imports)] // lots of cfg code here
 
+#[cfg(all(test, target_env = "gnu"))]
+mod tests;
+
 use crate::os::unix::prelude::*;
 
 use crate::error::Error as StdError;
@@ -645,30 +648,3 @@ fn parse_glibc_version(version: &str) -> Option<(usize, usize)> {
         _ => None,
     }
 }
-
-#[cfg(all(test, target_env = "gnu"))]
-mod test {
-    use super::*;
-
-    #[test]
-    fn test_glibc_version() {
-        // This mostly just tests that the weak linkage doesn't panic wildly...
-        glibc_version();
-    }
-
-    #[test]
-    fn test_parse_glibc_version() {
-        let cases = [
-            ("0.0", Some((0, 0))),
-            ("01.+2", Some((1, 2))),
-            ("3.4.5.six", Some((3, 4))),
-            ("1", None),
-            ("1.-2", None),
-            ("1.foo", None),
-            ("foo.1", None),
-        ];
-        for &(version_str, parsed) in cases.iter() {
-            assert_eq!(parsed, parse_glibc_version(version_str));
-        }
-    }
-}
diff --git a/library/std/src/sys/unix/os/tests.rs b/library/std/src/sys/unix/os/tests.rs
new file mode 100644
index 00000000000..0e1dcb390a0
--- /dev/null
+++ b/library/std/src/sys/unix/os/tests.rs
@@ -0,0 +1,23 @@
+use super::*;
+
+#[test]
+fn test_glibc_version() {
+    // This mostly just tests that the weak linkage doesn't panic wildly...
+    glibc_version();
+}
+
+#[test]
+fn test_parse_glibc_version() {
+    let cases = [
+        ("0.0", Some((0, 0))),
+        ("01.+2", Some((1, 2))),
+        ("3.4.5.six", Some((3, 4))),
+        ("1", None),
+        ("1.-2", None),
+        ("1.foo", None),
+        ("foo.1", None),
+    ];
+    for &(version_str, parsed) in cases.iter() {
+        assert_eq!(parsed, parse_glibc_version(version_str));
+    }
+}
diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs
index 6e33cdd3c48..f8666485eec 100644
--- a/library/std/src/sys/unix/process/process_common.rs
+++ b/library/std/src/sys/unix/process/process_common.rs
@@ -1,3 +1,6 @@
+#[cfg(all(test, not(target_os = "emscripten")))]
+mod tests;
+
 use crate::os::unix::prelude::*;
 
 use crate::collections::BTreeMap;
@@ -399,71 +402,3 @@ impl ExitCode {
         self.0 as i32
     }
 }
-
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod tests {
-    use super::*;
-
-    use crate::ffi::OsStr;
-    use crate::mem;
-    use crate::ptr;
-    use crate::sys::cvt;
-
-    macro_rules! t {
-        ($e:expr) => {
-            match $e {
-                Ok(t) => t,
-                Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
-            }
-        };
-    }
-
-    // See #14232 for more information, but it appears that signal delivery to a
-    // newly spawned process may just be raced in the macOS, so to prevent this
-    // test from being flaky we ignore it on macOS.
-    #[test]
-    #[cfg_attr(target_os = "macos", ignore)]
-    // When run under our current QEMU emulation test suite this test fails,
-    // although the reason isn't very clear as to why. For now this test is
-    // ignored there.
-    #[cfg_attr(target_arch = "arm", ignore)]
-    #[cfg_attr(target_arch = "aarch64", ignore)]
-    #[cfg_attr(target_arch = "riscv64", ignore)]
-    fn test_process_mask() {
-        unsafe {
-            // Test to make sure that a signal mask does not get inherited.
-            let mut cmd = Command::new(OsStr::new("cat"));
-
-            let mut set = mem::MaybeUninit::<libc::sigset_t>::uninit();
-            let mut old_set = mem::MaybeUninit::<libc::sigset_t>::uninit();
-            t!(cvt(sigemptyset(set.as_mut_ptr())));
-            t!(cvt(sigaddset(set.as_mut_ptr(), libc::SIGINT)));
-            t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(), old_set.as_mut_ptr())));
-
-            cmd.stdin(Stdio::MakePipe);
-            cmd.stdout(Stdio::MakePipe);
-
-            let (mut cat, mut pipes) = t!(cmd.spawn(Stdio::Null, true));
-            let stdin_write = pipes.stdin.take().unwrap();
-            let stdout_read = pipes.stdout.take().unwrap();
-
-            t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, old_set.as_ptr(), ptr::null_mut())));
-
-            t!(cvt(libc::kill(cat.id() as libc::pid_t, libc::SIGINT)));
-            // We need to wait until SIGINT is definitely delivered. The
-            // easiest way is to write something to cat, and try to read it
-            // back: if SIGINT is unmasked, it'll get delivered when cat is
-            // next scheduled.
-            let _ = stdin_write.write(b"Hello");
-            drop(stdin_write);
-
-            // Either EOF or failure (EPIPE) is okay.
-            let mut buf = [0; 5];
-            if let Ok(ret) = stdout_read.read(&mut buf) {
-                assert_eq!(ret, 0);
-            }
-
-            t!(cat.wait());
-        }
-    }
-}
diff --git a/library/std/src/sys/unix/process/process_common/tests.rs b/library/std/src/sys/unix/process/process_common/tests.rs
new file mode 100644
index 00000000000..e72fbf0beb4
--- /dev/null
+++ b/library/std/src/sys/unix/process/process_common/tests.rs
@@ -0,0 +1,64 @@
+use super::*;
+
+use crate::ffi::OsStr;
+use crate::mem;
+use crate::ptr;
+use crate::sys::cvt;
+
+macro_rules! t {
+    ($e:expr) => {
+        match $e {
+            Ok(t) => t,
+            Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
+        }
+    };
+}
+
+// See #14232 for more information, but it appears that signal delivery to a
+// newly spawned process may just be raced in the macOS, so to prevent this
+// test from being flaky we ignore it on macOS.
+#[test]
+#[cfg_attr(target_os = "macos", ignore)]
+// When run under our current QEMU emulation test suite this test fails,
+// although the reason isn't very clear as to why. For now this test is
+// ignored there.
+#[cfg_attr(target_arch = "arm", ignore)]
+#[cfg_attr(target_arch = "aarch64", ignore)]
+#[cfg_attr(target_arch = "riscv64", ignore)]
+fn test_process_mask() {
+    unsafe {
+        // Test to make sure that a signal mask does not get inherited.
+        let mut cmd = Command::new(OsStr::new("cat"));
+
+        let mut set = mem::MaybeUninit::<libc::sigset_t>::uninit();
+        let mut old_set = mem::MaybeUninit::<libc::sigset_t>::uninit();
+        t!(cvt(sigemptyset(set.as_mut_ptr())));
+        t!(cvt(sigaddset(set.as_mut_ptr(), libc::SIGINT)));
+        t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(), old_set.as_mut_ptr())));
+
+        cmd.stdin(Stdio::MakePipe);
+        cmd.stdout(Stdio::MakePipe);
+
+        let (mut cat, mut pipes) = t!(cmd.spawn(Stdio::Null, true));
+        let stdin_write = pipes.stdin.take().unwrap();
+        let stdout_read = pipes.stdout.take().unwrap();
+
+        t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, old_set.as_ptr(), ptr::null_mut())));
+
+        t!(cvt(libc::kill(cat.id() as libc::pid_t, libc::SIGINT)));
+        // We need to wait until SIGINT is definitely delivered. The
+        // easiest way is to write something to cat, and try to read it
+        // back: if SIGINT is unmasked, it'll get delivered when cat is
+        // next scheduled.
+        let _ = stdin_write.write(b"Hello");
+        drop(stdin_write);
+
+        // Either EOF or failure (EPIPE) is okay.
+        let mut buf = [0; 5];
+        if let Ok(ret) = stdout_read.read(&mut buf) {
+            assert_eq!(ret, 0);
+        }
+
+        t!(cat.wait());
+    }
+}
diff --git a/library/std/src/sys/vxworks/net.rs b/library/std/src/sys/vxworks/net.rs
index 32c27ab6e9e..7613fbec46f 100644
--- a/library/std/src/sys/vxworks/net.rs
+++ b/library/std/src/sys/vxworks/net.rs
@@ -1,3 +1,6 @@
+#[cfg(all(test, taget_env = "gnu"))]
+mod tests;
+
 use crate::cmp;
 use crate::ffi::CStr;
 use crate::io;
@@ -330,30 +333,3 @@ fn on_resolver_failure() {
 
 #[cfg(not(target_env = "gnu"))]
 fn on_resolver_failure() {}
-
-#[cfg(all(test, taget_env = "gnu"))]
-mod test {
-    use super::*;
-
-    #[test]
-    fn test_res_init() {
-        // This mostly just tests that the weak linkage doesn't panic wildly...
-        res_init_if_glibc_before_2_26().unwrap();
-    }
-
-    #[test]
-    fn test_parse_glibc_version() {
-        let cases = [
-            ("0.0", Some((0, 0))),
-            ("01.+2", Some((1, 2))),
-            ("3.4.5.six", Some((3, 4))),
-            ("1", None),
-            ("1.-2", None),
-            ("1.foo", None),
-            ("foo.1", None),
-        ];
-        for &(version_str, parsed) in cases.iter() {
-            assert_eq!(parsed, parse_glibc_version(version_str));
-        }
-    }
-}
diff --git a/library/std/src/sys/vxworks/net/tests.rs b/library/std/src/sys/vxworks/net/tests.rs
new file mode 100644
index 00000000000..e7c6e348f8e
--- /dev/null
+++ b/library/std/src/sys/vxworks/net/tests.rs
@@ -0,0 +1,23 @@
+use super::*;
+
+#[test]
+fn test_res_init() {
+    // This mostly just tests that the weak linkage doesn't panic wildly...
+    res_init_if_glibc_before_2_26().unwrap();
+}
+
+#[test]
+fn test_parse_glibc_version() {
+    let cases = [
+        ("0.0", Some((0, 0))),
+        ("01.+2", Some((1, 2))),
+        ("3.4.5.six", Some((3, 4))),
+        ("1", None),
+        ("1.-2", None),
+        ("1.foo", None),
+        ("foo.1", None),
+    ];
+    for &(version_str, parsed) in cases.iter() {
+        assert_eq!(parsed, parse_glibc_version(version_str));
+    }
+}
diff --git a/library/std/src/sys/wasi/alloc.rs b/library/std/src/sys/wasi/alloc.rs
index 57187851a14..4d0afe27bb8 100644
--- a/library/std/src/sys/wasi/alloc.rs
+++ b/library/std/src/sys/wasi/alloc.rs
@@ -1,26 +1,45 @@
+#![deny(unsafe_op_in_unsafe_fn)]
+
 use crate::alloc::{GlobalAlloc, Layout, System};
 use crate::ptr;
 use crate::sys_common::alloc::{realloc_fallback, MIN_ALIGN};
 
+// SAFETY: All methods implemented follow the contract rules defined
+// in `GlobalAlloc`.
 #[stable(feature = "alloc_system_type", since = "1.28.0")]
 unsafe impl GlobalAlloc for System {
     #[inline]
     unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
         if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
-            libc::malloc(layout.size()) as *mut u8
+            // SAFETY: `libc::malloc` is guaranteed to be safe, it will allocate
+            // `layout.size()` bytes of memory and return a pointer to it
+            unsafe { libc::malloc(layout.size()) as *mut u8 }
         } else {
-            libc::aligned_alloc(layout.align(), layout.size()) as *mut u8
+            // SAFETY: `libc::aligned_alloc` is guaranteed to be safe if
+            // `layout.size()` is a multiple of `layout.align()`. This
+            // constraint can be satisfied if `pad_to_align` is called,
+            // which creates a layout by rounding the size of this layout up
+            // to a multiple of the layout's alignment
+            let aligned_layout = layout.pad_to_align();
+            unsafe { libc::aligned_alloc(aligned_layout.align(), aligned_layout.size()) as *mut u8 }
         }
     }
 
     #[inline]
     unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
         if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
-            libc::calloc(layout.size(), 1) as *mut u8
+            // SAFETY: `libc::calloc` is safe as long that `layout.size() * 1`
+            // would not result in integer overflow which cannot happen,
+            // multiplying by one never overflows
+            unsafe { libc::calloc(layout.size(), 1) as *mut u8 }
         } else {
-            let ptr = self.alloc(layout.clone());
+            // SAFETY: The safety contract for `alloc` must be upheld by the caller
+            let ptr = unsafe { self.alloc(layout.clone()) };
             if !ptr.is_null() {
-                ptr::write_bytes(ptr, 0, layout.size());
+                // SAFETY: in the case of the `ptr` being not null
+                // it will be properly aligned and a valid ptr
+                // which satisfies `ptr::write_bytes` safety constrains
+                unsafe { ptr::write_bytes(ptr, 0, layout.size()) };
             }
             ptr
         }
@@ -28,15 +47,23 @@ unsafe impl GlobalAlloc for System {
 
     #[inline]
     unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
-        libc::free(ptr as *mut libc::c_void)
+        // SAFETY: `libc::free` is guaranteed to be safe if `ptr` is allocated
+        // by this allocator or if `ptr` is NULL
+        unsafe { libc::free(ptr as *mut libc::c_void) }
     }
 
     #[inline]
     unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
         if layout.align() <= MIN_ALIGN && layout.align() <= new_size {
-            libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8
+            // SAFETY: `libc::realloc` is safe if `ptr` is allocated by this
+            // allocator or NULL
+            // - If `new_size` is 0 and `ptr` is not NULL, it will act as `libc::free`
+            // - If `new_size` is not 0 and `ptr` is NULL, it will act as `libc::malloc`
+            // - Else, it will resize the block accordingly
+            unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 }
         } else {
-            realloc_fallback(self, ptr, layout, new_size)
+            // SAFETY: The safety contract for `realloc_fallback` must be upheld by the caller
+            unsafe { realloc_fallback(self, ptr, layout, new_size) }
         }
     }
 }
diff --git a/library/std/src/sys/wasi/args.rs b/library/std/src/sys/wasi/args.rs
index 02aa68d6f3a..9a27218e1fb 100644
--- a/library/std/src/sys/wasi/args.rs
+++ b/library/std/src/sys/wasi/args.rs
@@ -1,3 +1,5 @@
+#![deny(unsafe_op_in_unsafe_fn)]
+
 use crate::ffi::{CStr, OsStr, OsString};
 use crate::marker::PhantomData;
 use crate::os::wasi::ffi::OsStrExt;
diff --git a/library/std/src/sys/wasi/ext/fs.rs b/library/std/src/sys/wasi/ext/fs.rs
index 501ad8ee7d6..4f7cf6018d9 100644
--- a/library/std/src/sys/wasi/ext/fs.rs
+++ b/library/std/src/sys/wasi/ext/fs.rs
@@ -1,5 +1,6 @@
 //! WASI-specific extensions to primitives in the `std::fs` module.
 
+#![deny(unsafe_op_in_unsafe_fn)]
 #![unstable(feature = "wasi_ext", issue = "none")]
 
 use crate::fs::{self, File, Metadata, OpenOptions};
diff --git a/library/std/src/sys/wasi/ext/io.rs b/library/std/src/sys/wasi/ext/io.rs
index e849400d67e..4e8fa65eb20 100644
--- a/library/std/src/sys/wasi/ext/io.rs
+++ b/library/std/src/sys/wasi/ext/io.rs
@@ -1,5 +1,6 @@
 //! WASI-specific extensions to general I/O primitives
 
+#![deny(unsafe_op_in_unsafe_fn)]
 #![unstable(feature = "wasi_ext", issue = "none")]
 
 use crate::fs;
diff --git a/library/std/src/sys/wasi/ext/mod.rs b/library/std/src/sys/wasi/ext/mod.rs
index 58c8c46c969..1cda30edcad 100644
--- a/library/std/src/sys/wasi/ext/mod.rs
+++ b/library/std/src/sys/wasi/ext/mod.rs
@@ -1,3 +1,5 @@
+#![deny(unsafe_op_in_unsafe_fn)]
+
 pub mod ffi;
 pub mod fs;
 pub mod io;
diff --git a/library/std/src/sys/wasi/fd.rs b/library/std/src/sys/wasi/fd.rs
index 8458ded5db0..ba66eba2ad3 100644
--- a/library/std/src/sys/wasi/fd.rs
+++ b/library/std/src/sys/wasi/fd.rs
@@ -1,3 +1,4 @@
+#![deny(unsafe_op_in_unsafe_fn)]
 #![allow(dead_code)]
 
 use super::err2io;
diff --git a/library/std/src/sys/wasi/fs.rs b/library/std/src/sys/wasi/fs.rs
index 8408756f1b3..93a92b49cfc 100644
--- a/library/std/src/sys/wasi/fs.rs
+++ b/library/std/src/sys/wasi/fs.rs
@@ -1,3 +1,5 @@
+#![deny(unsafe_op_in_unsafe_fn)]
+
 use crate::ffi::{CStr, CString, OsStr, OsString};
 use crate::fmt;
 use crate::io::{self, IoSlice, IoSliceMut, SeekFrom};
diff --git a/library/std/src/sys/wasi/io.rs b/library/std/src/sys/wasi/io.rs
index 0ad2e152855..ee017d13a4c 100644
--- a/library/std/src/sys/wasi/io.rs
+++ b/library/std/src/sys/wasi/io.rs
@@ -1,3 +1,5 @@
+#![deny(unsafe_op_in_unsafe_fn)]
+
 use crate::marker::PhantomData;
 use crate::slice;
 
diff --git a/library/std/src/sys/wasi/net.rs b/library/std/src/sys/wasi/net.rs
index e186453588d..8fd4bb76d85 100644
--- a/library/std/src/sys/wasi/net.rs
+++ b/library/std/src/sys/wasi/net.rs
@@ -1,3 +1,5 @@
+#![deny(unsafe_op_in_unsafe_fn)]
+
 use crate::convert::TryFrom;
 use crate::fmt;
 use crate::io::{self, IoSlice, IoSliceMut};
diff --git a/library/std/src/sys/wasi/os.rs b/library/std/src/sys/wasi/os.rs
index 8052c0aa8a8..33c796ae941 100644
--- a/library/std/src/sys/wasi/os.rs
+++ b/library/std/src/sys/wasi/os.rs
@@ -1,3 +1,5 @@
+#![deny(unsafe_op_in_unsafe_fn)]
+
 use crate::any::Any;
 use crate::error::Error as StdError;
 use crate::ffi::{CStr, CString, OsStr, OsString};
diff --git a/library/std/src/sys/wasi/pipe.rs b/library/std/src/sys/wasi/pipe.rs
index 10d0925823e..180fc114d86 100644
--- a/library/std/src/sys/wasi/pipe.rs
+++ b/library/std/src/sys/wasi/pipe.rs
@@ -1,3 +1,5 @@
+#![deny(unsafe_op_in_unsafe_fn)]
+
 use crate::io::{self, IoSlice, IoSliceMut};
 use crate::sys::Void;
 
diff --git a/library/std/src/sys/wasi/process.rs b/library/std/src/sys/wasi/process.rs
index 7156c9ab92f..c69d6376b01 100644
--- a/library/std/src/sys/wasi/process.rs
+++ b/library/std/src/sys/wasi/process.rs
@@ -1,3 +1,5 @@
+#![deny(unsafe_op_in_unsafe_fn)]
+
 use crate::ffi::OsStr;
 use crate::fmt;
 use crate::io;
diff --git a/library/std/src/sys/wasi/stdio.rs b/library/std/src/sys/wasi/stdio.rs
index 23baafabf79..d82f6f41186 100644
--- a/library/std/src/sys/wasi/stdio.rs
+++ b/library/std/src/sys/wasi/stdio.rs
@@ -1,3 +1,5 @@
+#![deny(unsafe_op_in_unsafe_fn)]
+
 use crate::io::{self, IoSlice, IoSliceMut};
 use crate::mem::ManuallyDrop;
 use crate::sys::fd::WasiFd;
diff --git a/library/std/src/sys/wasi/thread.rs b/library/std/src/sys/wasi/thread.rs
index 0d39b1cec32..8eaa5f09cb6 100644
--- a/library/std/src/sys/wasi/thread.rs
+++ b/library/std/src/sys/wasi/thread.rs
@@ -1,3 +1,5 @@
+#![deny(unsafe_op_in_unsafe_fn)]
+
 use crate::ffi::CStr;
 use crate::io;
 use crate::mem;
diff --git a/library/std/src/sys/wasi/time.rs b/library/std/src/sys/wasi/time.rs
index 80ec317b5a2..2e720d11603 100644
--- a/library/std/src/sys/wasi/time.rs
+++ b/library/std/src/sys/wasi/time.rs
@@ -1,3 +1,5 @@
+#![deny(unsafe_op_in_unsafe_fn)]
+
 use crate::time::Duration;
 
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
diff --git a/library/std/src/sys/windows/args.rs b/library/std/src/sys/windows/args.rs
index 5fbea2a2910..bcc2ea9ae00 100644
--- a/library/std/src/sys/windows/args.rs
+++ b/library/std/src/sys/windows/args.rs
@@ -1,5 +1,8 @@
 #![allow(dead_code)] // runtime init functions not used during testing
 
+#[cfg(test)]
+mod tests;
+
 use crate::ffi::OsString;
 use crate::fmt;
 use crate::os::windows::prelude::*;
@@ -198,69 +201,3 @@ impl ExactSizeIterator for Args {
         self.parsed_args_list.len()
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use crate::ffi::OsString;
-    use crate::sys::windows::args::*;
-
-    fn chk(string: &str, parts: &[&str]) {
-        let mut wide: Vec<u16> = OsString::from(string).encode_wide().collect();
-        wide.push(0);
-        let parsed = unsafe {
-            parse_lp_cmd_line(wide.as_ptr() as *const u16, || OsString::from("TEST.EXE"))
-        };
-        let expected: Vec<OsString> = parts.iter().map(|k| OsString::from(k)).collect();
-        assert_eq!(parsed.as_slice(), expected.as_slice());
-    }
-
-    #[test]
-    fn empty() {
-        chk("", &["TEST.EXE"]);
-        chk("\0", &["TEST.EXE"]);
-    }
-
-    #[test]
-    fn single_words() {
-        chk("EXE one_word", &["EXE", "one_word"]);
-        chk("EXE a", &["EXE", "a"]);
-        chk("EXE 😅", &["EXE", "😅"]);
-        chk("EXE 😅🤦", &["EXE", "😅🤦"]);
-    }
-
-    #[test]
-    fn official_examples() {
-        chk(r#"EXE "abc" d e"#, &["EXE", "abc", "d", "e"]);
-        chk(r#"EXE a\\\b d"e f"g h"#, &["EXE", r#"a\\\b"#, "de fg", "h"]);
-        chk(r#"EXE a\\\"b c d"#, &["EXE", r#"a\"b"#, "c", "d"]);
-        chk(r#"EXE a\\\\"b c" d e"#, &["EXE", r#"a\\b c"#, "d", "e"]);
-    }
-
-    #[test]
-    fn whitespace_behavior() {
-        chk(r#" test"#, &["", "test"]);
-        chk(r#"  test"#, &["", "test"]);
-        chk(r#" test test2"#, &["", "test", "test2"]);
-        chk(r#" test  test2"#, &["", "test", "test2"]);
-        chk(r#"test test2 "#, &["test", "test2"]);
-        chk(r#"test  test2 "#, &["test", "test2"]);
-        chk(r#"test "#, &["test"]);
-    }
-
-    #[test]
-    fn genius_quotes() {
-        chk(r#"EXE "" """#, &["EXE", "", ""]);
-        chk(r#"EXE "" """"#, &["EXE", "", "\""]);
-        chk(
-            r#"EXE "this is """all""" in the same argument""#,
-            &["EXE", "this is \"all\" in the same argument"],
-        );
-        chk(r#"EXE "a"""#, &["EXE", "a\""]);
-        chk(r#"EXE "a"" a"#, &["EXE", "a\"", "a"]);
-        // quotes cannot be escaped in command names
-        chk(r#""EXE" check"#, &["EXE", "check"]);
-        chk(r#""EXE check""#, &["EXE check"]);
-        chk(r#""EXE """for""" check"#, &["EXE ", r#"for""#, "check"]);
-        chk(r#""EXE \"for\" check"#, &[r#"EXE \"#, r#"for""#, "check"]);
-    }
-}
diff --git a/library/std/src/sys/windows/args/tests.rs b/library/std/src/sys/windows/args/tests.rs
new file mode 100644
index 00000000000..756a4361ea3
--- /dev/null
+++ b/library/std/src/sys/windows/args/tests.rs
@@ -0,0 +1,61 @@
+use crate::ffi::OsString;
+use crate::sys::windows::args::*;
+
+fn chk(string: &str, parts: &[&str]) {
+    let mut wide: Vec<u16> = OsString::from(string).encode_wide().collect();
+    wide.push(0);
+    let parsed =
+        unsafe { parse_lp_cmd_line(wide.as_ptr() as *const u16, || OsString::from("TEST.EXE")) };
+    let expected: Vec<OsString> = parts.iter().map(|k| OsString::from(k)).collect();
+    assert_eq!(parsed.as_slice(), expected.as_slice());
+}
+
+#[test]
+fn empty() {
+    chk("", &["TEST.EXE"]);
+    chk("\0", &["TEST.EXE"]);
+}
+
+#[test]
+fn single_words() {
+    chk("EXE one_word", &["EXE", "one_word"]);
+    chk("EXE a", &["EXE", "a"]);
+    chk("EXE 😅", &["EXE", "😅"]);
+    chk("EXE 😅🤦", &["EXE", "😅🤦"]);
+}
+
+#[test]
+fn official_examples() {
+    chk(r#"EXE "abc" d e"#, &["EXE", "abc", "d", "e"]);
+    chk(r#"EXE a\\\b d"e f"g h"#, &["EXE", r#"a\\\b"#, "de fg", "h"]);
+    chk(r#"EXE a\\\"b c d"#, &["EXE", r#"a\"b"#, "c", "d"]);
+    chk(r#"EXE a\\\\"b c" d e"#, &["EXE", r#"a\\b c"#, "d", "e"]);
+}
+
+#[test]
+fn whitespace_behavior() {
+    chk(r#" test"#, &["", "test"]);
+    chk(r#"  test"#, &["", "test"]);
+    chk(r#" test test2"#, &["", "test", "test2"]);
+    chk(r#" test  test2"#, &["", "test", "test2"]);
+    chk(r#"test test2 "#, &["test", "test2"]);
+    chk(r#"test  test2 "#, &["test", "test2"]);
+    chk(r#"test "#, &["test"]);
+}
+
+#[test]
+fn genius_quotes() {
+    chk(r#"EXE "" """#, &["EXE", "", ""]);
+    chk(r#"EXE "" """"#, &["EXE", "", "\""]);
+    chk(
+        r#"EXE "this is """all""" in the same argument""#,
+        &["EXE", "this is \"all\" in the same argument"],
+    );
+    chk(r#"EXE "a"""#, &["EXE", "a\""]);
+    chk(r#"EXE "a"" a"#, &["EXE", "a\"", "a"]);
+    // quotes cannot be escaped in command names
+    chk(r#""EXE" check"#, &["EXE", "check"]);
+    chk(r#""EXE check""#, &["EXE check"]);
+    chk(r#""EXE """for""" check"#, &["EXE ", r#"for""#, "check"]);
+    chk(r#""EXE \"for\" check"#, &[r#"EXE \"#, r#"for""#, "check"]);
+}
diff --git a/library/std/src/sys/windows/os.rs b/library/std/src/sys/windows/os.rs
index a0da2498bb7..77c378a66af 100644
--- a/library/std/src/sys/windows/os.rs
+++ b/library/std/src/sys/windows/os.rs
@@ -2,6 +2,9 @@
 
 #![allow(nonstandard_style)]
 
+#[cfg(test)]
+mod tests;
+
 use crate::os::windows::prelude::*;
 
 use crate::error::Error as StdError;
@@ -328,20 +331,3 @@ pub fn exit(code: i32) -> ! {
 pub fn getpid() -> u32 {
     unsafe { c::GetCurrentProcessId() as u32 }
 }
-
-#[cfg(test)]
-mod tests {
-    use crate::io::Error;
-    use crate::sys::c;
-
-    // tests `error_string` above
-    #[test]
-    fn ntstatus_error() {
-        const STATUS_UNSUCCESSFUL: u32 = 0xc000_0001;
-        assert!(
-            !Error::from_raw_os_error((STATUS_UNSUCCESSFUL | c::FACILITY_NT_BIT) as _)
-                .to_string()
-                .contains("FormatMessageW() returned error")
-        );
-    }
-}
diff --git a/library/std/src/sys/windows/os/tests.rs b/library/std/src/sys/windows/os/tests.rs
new file mode 100644
index 00000000000..458d6e11c20
--- /dev/null
+++ b/library/std/src/sys/windows/os/tests.rs
@@ -0,0 +1,13 @@
+use crate::io::Error;
+use crate::sys::c;
+
+// tests `error_string` above
+#[test]
+fn ntstatus_error() {
+    const STATUS_UNSUCCESSFUL: u32 = 0xc000_0001;
+    assert!(
+        !Error::from_raw_os_error((STATUS_UNSUCCESSFUL | c::FACILITY_NT_BIT) as _)
+            .to_string()
+            .contains("FormatMessageW() returned error")
+    );
+}
diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs
index 7d6d4775eec..e18521bb30d 100644
--- a/library/std/src/sys/windows/process.rs
+++ b/library/std/src/sys/windows/process.rs
@@ -1,5 +1,8 @@
 #![unstable(feature = "process_internals", issue = "none")]
 
+#[cfg(test)]
+mod tests;
+
 use crate::borrow::Borrow;
 use crate::collections::BTreeMap;
 use crate::env;
@@ -526,41 +529,3 @@ fn make_dirp(d: Option<&OsString>) -> io::Result<(*const u16, Vec<u16>)> {
         None => Ok((ptr::null(), Vec::new())),
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use super::make_command_line;
-    use crate::ffi::{OsStr, OsString};
-
-    #[test]
-    fn test_make_command_line() {
-        fn test_wrapper(prog: &str, args: &[&str]) -> String {
-            let command_line = &make_command_line(
-                OsStr::new(prog),
-                &args.iter().map(|a| OsString::from(a)).collect::<Vec<OsString>>(),
-            )
-            .unwrap();
-            String::from_utf16(command_line).unwrap()
-        }
-
-        assert_eq!(test_wrapper("prog", &["aaa", "bbb", "ccc"]), "\"prog\" aaa bbb ccc");
-
-        assert_eq!(
-            test_wrapper("C:\\Program Files\\blah\\blah.exe", &["aaa"]),
-            "\"C:\\Program Files\\blah\\blah.exe\" aaa"
-        );
-        assert_eq!(
-            test_wrapper("C:\\Program Files\\test", &["aa\"bb"]),
-            "\"C:\\Program Files\\test\" aa\\\"bb"
-        );
-        assert_eq!(test_wrapper("echo", &["a b c"]), "\"echo\" \"a b c\"");
-        assert_eq!(
-            test_wrapper("echo", &["\" \\\" \\", "\\"]),
-            "\"echo\" \"\\\" \\\\\\\" \\\\\" \\"
-        );
-        assert_eq!(
-            test_wrapper("\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}", &[]),
-            "\"\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}\""
-        );
-    }
-}
diff --git a/library/std/src/sys/windows/process/tests.rs b/library/std/src/sys/windows/process/tests.rs
new file mode 100644
index 00000000000..81627ad139b
--- /dev/null
+++ b/library/std/src/sys/windows/process/tests.rs
@@ -0,0 +1,31 @@
+use super::make_command_line;
+use crate::ffi::{OsStr, OsString};
+
+#[test]
+fn test_make_command_line() {
+    fn test_wrapper(prog: &str, args: &[&str]) -> String {
+        let command_line = &make_command_line(
+            OsStr::new(prog),
+            &args.iter().map(|a| OsString::from(a)).collect::<Vec<OsString>>(),
+        )
+        .unwrap();
+        String::from_utf16(command_line).unwrap()
+    }
+
+    assert_eq!(test_wrapper("prog", &["aaa", "bbb", "ccc"]), "\"prog\" aaa bbb ccc");
+
+    assert_eq!(
+        test_wrapper("C:\\Program Files\\blah\\blah.exe", &["aaa"]),
+        "\"C:\\Program Files\\blah\\blah.exe\" aaa"
+    );
+    assert_eq!(
+        test_wrapper("C:\\Program Files\\test", &["aa\"bb"]),
+        "\"C:\\Program Files\\test\" aa\\\"bb"
+    );
+    assert_eq!(test_wrapper("echo", &["a b c"]), "\"echo\" \"a b c\"");
+    assert_eq!(test_wrapper("echo", &["\" \\\" \\", "\\"]), "\"echo\" \"\\\" \\\\\\\" \\\\\" \\");
+    assert_eq!(
+        test_wrapper("\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}", &[]),
+        "\"\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}\""
+    );
+}
diff --git a/library/std/src/sys_common/bytestring.rs b/library/std/src/sys_common/bytestring.rs
index dccc3bc4a19..97fba60c271 100644
--- a/library/std/src/sys_common/bytestring.rs
+++ b/library/std/src/sys_common/bytestring.rs
@@ -1,5 +1,8 @@
 #![allow(dead_code)]
 
+#[cfg(test)]
+mod tests;
+
 use crate::fmt::{Formatter, Result, Write};
 use core::str::lossy::{Utf8Lossy, Utf8LossyChunk};
 
@@ -21,26 +24,3 @@ pub fn debug_fmt_bytestring(slice: &[u8], f: &mut Formatter<'_>) -> Result {
     }
     f.write_str("\"")
 }
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::fmt::{Debug, Formatter, Result};
-
-    #[test]
-    fn smoke() {
-        struct Helper<'a>(&'a [u8]);
-
-        impl Debug for Helper<'_> {
-            fn fmt(&self, f: &mut Formatter<'_>) -> Result {
-                debug_fmt_bytestring(self.0, f)
-            }
-        }
-
-        let input = b"\xF0hello,\tworld";
-        let expected = r#""\xF0hello,\tworld""#;
-        let output = format!("{:?}", Helper(input));
-
-        assert!(output == expected);
-    }
-}
diff --git a/library/std/src/sys_common/bytestring/tests.rs b/library/std/src/sys_common/bytestring/tests.rs
new file mode 100644
index 00000000000..1685f087d18
--- /dev/null
+++ b/library/std/src/sys_common/bytestring/tests.rs
@@ -0,0 +1,19 @@
+use super::*;
+use crate::fmt::{Debug, Formatter, Result};
+
+#[test]
+fn smoke() {
+    struct Helper<'a>(&'a [u8]);
+
+    impl Debug for Helper<'_> {
+        fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+            debug_fmt_bytestring(self.0, f)
+        }
+    }
+
+    let input = b"\xF0hello,\tworld";
+    let expected = r#""\xF0hello,\tworld""#;
+    let output = format!("{:?}", Helper(input));
+
+    assert!(output == expected);
+}
diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs
index 840f9093e00..28cdfefb12a 100644
--- a/library/std/src/sys_common/mod.rs
+++ b/library/std/src/sys_common/mod.rs
@@ -15,6 +15,9 @@
 #![allow(missing_docs)]
 #![allow(missing_debug_implementations)]
 
+#[cfg(test)]
+mod tests;
+
 use crate::sync::Once;
 use crate::sys;
 
@@ -141,8 +144,3 @@ pub fn mul_div_u64(value: u64, numer: u64, denom: u64) -> u64 {
     // r < denom, so (denom*numer) is the upper bound of (r*numer)
     q * numer + r * numer / denom
 }
-
-#[test]
-fn test_muldiv() {
-    assert_eq!(mul_div_u64(1_000_000_000_001, 1_000_000_000, 1_000_000), 1_000_000_000_001_000);
-}
diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs
index 0bb136078bc..48ba4ddfc0b 100644
--- a/library/std/src/sys_common/net.rs
+++ b/library/std/src/sys_common/net.rs
@@ -1,3 +1,6 @@
+#[cfg(test)]
+mod tests;
+
 use crate::cmp;
 use crate::convert::{TryFrom, TryInto};
 use crate::ffi::CString;
@@ -672,26 +675,3 @@ impl fmt::Debug for UdpSocket {
         res.field(name, &self.inner.as_inner()).finish()
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::collections::HashMap;
-
-    #[test]
-    fn no_lookup_host_duplicates() {
-        let mut addrs = HashMap::new();
-        let lh = match LookupHost::try_from(("localhost", 0)) {
-            Ok(lh) => lh,
-            Err(e) => panic!("couldn't resolve `localhost': {}", e),
-        };
-        for sa in lh {
-            *addrs.entry(sa).or_insert(0) += 1;
-        }
-        assert_eq!(
-            addrs.iter().filter(|&(_, &v)| v > 1).collect::<Vec<_>>(),
-            vec![],
-            "There should be no duplicate localhost entries"
-        );
-    }
-}
diff --git a/library/std/src/sys_common/net/tests.rs b/library/std/src/sys_common/net/tests.rs
new file mode 100644
index 00000000000..7d45621e09a
--- /dev/null
+++ b/library/std/src/sys_common/net/tests.rs
@@ -0,0 +1,19 @@
+use super::*;
+use crate::collections::HashMap;
+
+#[test]
+fn no_lookup_host_duplicates() {
+    let mut addrs = HashMap::new();
+    let lh = match LookupHost::try_from(("localhost", 0)) {
+        Ok(lh) => lh,
+        Err(e) => panic!("couldn't resolve `localhost': {}", e),
+    };
+    for sa in lh {
+        *addrs.entry(sa).or_insert(0) += 1;
+    }
+    assert_eq!(
+        addrs.iter().filter(|&(_, &v)| v > 1).collect::<Vec<_>>(),
+        vec![],
+        "There should be no duplicate localhost entries"
+    );
+}
diff --git a/library/std/src/sys_common/remutex.rs b/library/std/src/sys_common/remutex.rs
index 4f19bbc467f..360337c030b 100644
--- a/library/std/src/sys_common/remutex.rs
+++ b/library/std/src/sys_common/remutex.rs
@@ -1,3 +1,6 @@
+#[cfg(all(test, not(target_os = "emscripten")))]
+mod tests;
+
 use crate::fmt;
 use crate::marker;
 use crate::ops::Deref;
@@ -146,79 +149,3 @@ impl<T> Drop for ReentrantMutexGuard<'_, T> {
         }
     }
 }
-
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod tests {
-    use crate::cell::RefCell;
-    use crate::sync::Arc;
-    use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
-    use crate::thread;
-
-    #[test]
-    fn smoke() {
-        let m = unsafe {
-            let m = ReentrantMutex::new(());
-            m.init();
-            m
-        };
-        {
-            let a = m.lock();
-            {
-                let b = m.lock();
-                {
-                    let c = m.lock();
-                    assert_eq!(*c, ());
-                }
-                assert_eq!(*b, ());
-            }
-            assert_eq!(*a, ());
-        }
-    }
-
-    #[test]
-    fn is_mutex() {
-        let m = unsafe {
-            let m = Arc::new(ReentrantMutex::new(RefCell::new(0)));
-            m.init();
-            m
-        };
-        let m2 = m.clone();
-        let lock = m.lock();
-        let child = thread::spawn(move || {
-            let lock = m2.lock();
-            assert_eq!(*lock.borrow(), 4950);
-        });
-        for i in 0..100 {
-            let lock = m.lock();
-            *lock.borrow_mut() += i;
-        }
-        drop(lock);
-        child.join().unwrap();
-    }
-
-    #[test]
-    fn trylock_works() {
-        let m = unsafe {
-            let m = Arc::new(ReentrantMutex::new(()));
-            m.init();
-            m
-        };
-        let m2 = m.clone();
-        let _lock = m.try_lock();
-        let _lock2 = m.try_lock();
-        thread::spawn(move || {
-            let lock = m2.try_lock();
-            assert!(lock.is_none());
-        })
-        .join()
-        .unwrap();
-        let _lock3 = m.try_lock();
-    }
-
-    pub struct Answer<'a>(pub ReentrantMutexGuard<'a, RefCell<u32>>);
-    impl Drop for Answer<'_> {
-        fn drop(&mut self) {
-            *self.0.borrow_mut() = 42;
-        }
-    }
-}
diff --git a/library/std/src/sys_common/remutex/tests.rs b/library/std/src/sys_common/remutex/tests.rs
new file mode 100644
index 00000000000..9c686e579d7
--- /dev/null
+++ b/library/std/src/sys_common/remutex/tests.rs
@@ -0,0 +1,72 @@
+use crate::cell::RefCell;
+use crate::sync::Arc;
+use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
+use crate::thread;
+
+#[test]
+fn smoke() {
+    let m = unsafe {
+        let m = ReentrantMutex::new(());
+        m.init();
+        m
+    };
+    {
+        let a = m.lock();
+        {
+            let b = m.lock();
+            {
+                let c = m.lock();
+                assert_eq!(*c, ());
+            }
+            assert_eq!(*b, ());
+        }
+        assert_eq!(*a, ());
+    }
+}
+
+#[test]
+fn is_mutex() {
+    let m = unsafe {
+        let m = Arc::new(ReentrantMutex::new(RefCell::new(0)));
+        m.init();
+        m
+    };
+    let m2 = m.clone();
+    let lock = m.lock();
+    let child = thread::spawn(move || {
+        let lock = m2.lock();
+        assert_eq!(*lock.borrow(), 4950);
+    });
+    for i in 0..100 {
+        let lock = m.lock();
+        *lock.borrow_mut() += i;
+    }
+    drop(lock);
+    child.join().unwrap();
+}
+
+#[test]
+fn trylock_works() {
+    let m = unsafe {
+        let m = Arc::new(ReentrantMutex::new(()));
+        m.init();
+        m
+    };
+    let m2 = m.clone();
+    let _lock = m.try_lock();
+    let _lock2 = m.try_lock();
+    thread::spawn(move || {
+        let lock = m2.try_lock();
+        assert!(lock.is_none());
+    })
+    .join()
+    .unwrap();
+    let _lock3 = m.try_lock();
+}
+
+pub struct Answer<'a>(pub ReentrantMutexGuard<'a, RefCell<u32>>);
+impl Drop for Answer<'_> {
+    fn drop(&mut self) {
+        *self.0.borrow_mut() = 42;
+    }
+}
diff --git a/library/std/src/sys_common/tests.rs b/library/std/src/sys_common/tests.rs
new file mode 100644
index 00000000000..1b6446db52d
--- /dev/null
+++ b/library/std/src/sys_common/tests.rs
@@ -0,0 +1,6 @@
+use super::mul_div_u64;
+
+#[test]
+fn test_muldiv() {
+    assert_eq!(mul_div_u64(1_000_000_000_001, 1_000_000_000, 1_000_000), 1_000_000_000_001_000);
+}
diff --git a/library/std/src/sys_common/thread_local_key.rs b/library/std/src/sys_common/thread_local_key.rs
index ac5b128298d..3a2218854a7 100644
--- a/library/std/src/sys_common/thread_local_key.rs
+++ b/library/std/src/sys_common/thread_local_key.rs
@@ -48,6 +48,9 @@
 #![unstable(feature = "thread_local_internals", issue = "none")]
 #![allow(dead_code)] // sys isn't exported yet
 
+#[cfg(test)]
+mod tests;
+
 use crate::sync::atomic::{self, AtomicUsize, Ordering};
 use crate::sys::thread_local_key as imp;
 use crate::sys_common::mutex::Mutex;
@@ -231,41 +234,3 @@ impl Drop for Key {
         // unsafe { imp::destroy(self.key) }
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use super::{Key, StaticKey};
-
-    fn assert_sync<T: Sync>() {}
-    fn assert_send<T: Send>() {}
-
-    #[test]
-    fn smoke() {
-        assert_sync::<Key>();
-        assert_send::<Key>();
-
-        let k1 = Key::new(None);
-        let k2 = Key::new(None);
-        assert!(k1.get().is_null());
-        assert!(k2.get().is_null());
-        k1.set(1 as *mut _);
-        k2.set(2 as *mut _);
-        assert_eq!(k1.get() as usize, 1);
-        assert_eq!(k2.get() as usize, 2);
-    }
-
-    #[test]
-    fn statik() {
-        static K1: StaticKey = StaticKey::new(None);
-        static K2: StaticKey = StaticKey::new(None);
-
-        unsafe {
-            assert!(K1.get().is_null());
-            assert!(K2.get().is_null());
-            K1.set(1 as *mut _);
-            K2.set(2 as *mut _);
-            assert_eq!(K1.get() as usize, 1);
-            assert_eq!(K2.get() as usize, 2);
-        }
-    }
-}
diff --git a/library/std/src/sys_common/thread_local_key/tests.rs b/library/std/src/sys_common/thread_local_key/tests.rs
new file mode 100644
index 00000000000..968738a4180
--- /dev/null
+++ b/library/std/src/sys_common/thread_local_key/tests.rs
@@ -0,0 +1,34 @@
+use super::{Key, StaticKey};
+
+fn assert_sync<T: Sync>() {}
+fn assert_send<T: Send>() {}
+
+#[test]
+fn smoke() {
+    assert_sync::<Key>();
+    assert_send::<Key>();
+
+    let k1 = Key::new(None);
+    let k2 = Key::new(None);
+    assert!(k1.get().is_null());
+    assert!(k2.get().is_null());
+    k1.set(1 as *mut _);
+    k2.set(2 as *mut _);
+    assert_eq!(k1.get() as usize, 1);
+    assert_eq!(k2.get() as usize, 2);
+}
+
+#[test]
+fn statik() {
+    static K1: StaticKey = StaticKey::new(None);
+    static K2: StaticKey = StaticKey::new(None);
+
+    unsafe {
+        assert!(K1.get().is_null());
+        assert!(K2.get().is_null());
+        K1.set(1 as *mut _);
+        K2.set(2 as *mut _);
+        assert_eq!(K1.get() as usize, 1);
+        assert_eq!(K2.get() as usize, 2);
+    }
+}
diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs
index bdb6a05464e..7d4b0d52831 100644
--- a/library/std/src/sys_common/wtf8.rs
+++ b/library/std/src/sys_common/wtf8.rs
@@ -15,6 +15,9 @@
 // unix (it's mostly used on windows), so don't worry about dead code here.
 #![allow(dead_code)]
 
+#[cfg(test)]
+mod tests;
+
 use core::str::next_code_point;
 
 use crate::borrow::Cow;
@@ -879,407 +882,3 @@ impl Hash for Wtf8 {
         0xfeu8.hash(state)
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::borrow::Cow;
-
-    #[test]
-    fn code_point_from_u32() {
-        assert!(CodePoint::from_u32(0).is_some());
-        assert!(CodePoint::from_u32(0xD800).is_some());
-        assert!(CodePoint::from_u32(0x10FFFF).is_some());
-        assert!(CodePoint::from_u32(0x110000).is_none());
-    }
-
-    #[test]
-    fn code_point_to_u32() {
-        fn c(value: u32) -> CodePoint {
-            CodePoint::from_u32(value).unwrap()
-        }
-        assert_eq!(c(0).to_u32(), 0);
-        assert_eq!(c(0xD800).to_u32(), 0xD800);
-        assert_eq!(c(0x10FFFF).to_u32(), 0x10FFFF);
-    }
-
-    #[test]
-    fn code_point_from_char() {
-        assert_eq!(CodePoint::from_char('a').to_u32(), 0x61);
-        assert_eq!(CodePoint::from_char('💩').to_u32(), 0x1F4A9);
-    }
-
-    #[test]
-    fn code_point_to_string() {
-        assert_eq!(format!("{:?}", CodePoint::from_char('a')), "U+0061");
-        assert_eq!(format!("{:?}", CodePoint::from_char('💩')), "U+1F4A9");
-    }
-
-    #[test]
-    fn code_point_to_char() {
-        fn c(value: u32) -> CodePoint {
-            CodePoint::from_u32(value).unwrap()
-        }
-        assert_eq!(c(0x61).to_char(), Some('a'));
-        assert_eq!(c(0x1F4A9).to_char(), Some('💩'));
-        assert_eq!(c(0xD800).to_char(), None);
-    }
-
-    #[test]
-    fn code_point_to_char_lossy() {
-        fn c(value: u32) -> CodePoint {
-            CodePoint::from_u32(value).unwrap()
-        }
-        assert_eq!(c(0x61).to_char_lossy(), 'a');
-        assert_eq!(c(0x1F4A9).to_char_lossy(), '💩');
-        assert_eq!(c(0xD800).to_char_lossy(), '\u{FFFD}');
-    }
-
-    #[test]
-    fn wtf8buf_new() {
-        assert_eq!(Wtf8Buf::new().bytes, b"");
-    }
-
-    #[test]
-    fn wtf8buf_from_str() {
-        assert_eq!(Wtf8Buf::from_str("").bytes, b"");
-        assert_eq!(Wtf8Buf::from_str("aé 💩").bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
-    }
-
-    #[test]
-    fn wtf8buf_from_string() {
-        assert_eq!(Wtf8Buf::from_string(String::from("")).bytes, b"");
-        assert_eq!(
-            Wtf8Buf::from_string(String::from("aé 💩")).bytes,
-            b"a\xC3\xA9 \xF0\x9F\x92\xA9"
-        );
-    }
-
-    #[test]
-    fn wtf8buf_from_wide() {
-        assert_eq!(Wtf8Buf::from_wide(&[]).bytes, b"");
-        assert_eq!(
-            Wtf8Buf::from_wide(&[0x61, 0xE9, 0x20, 0xD83D, 0xD83D, 0xDCA9]).bytes,
-            b"a\xC3\xA9 \xED\xA0\xBD\xF0\x9F\x92\xA9"
-        );
-    }
-
-    #[test]
-    fn wtf8buf_push_str() {
-        let mut string = Wtf8Buf::new();
-        assert_eq!(string.bytes, b"");
-        string.push_str("aé 💩");
-        assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
-    }
-
-    #[test]
-    fn wtf8buf_push_char() {
-        let mut string = Wtf8Buf::from_str("aé ");
-        assert_eq!(string.bytes, b"a\xC3\xA9 ");
-        string.push_char('💩');
-        assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
-    }
-
-    #[test]
-    fn wtf8buf_push() {
-        let mut string = Wtf8Buf::from_str("aé ");
-        assert_eq!(string.bytes, b"a\xC3\xA9 ");
-        string.push(CodePoint::from_char('💩'));
-        assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
-
-        fn c(value: u32) -> CodePoint {
-            CodePoint::from_u32(value).unwrap()
-        }
-
-        let mut string = Wtf8Buf::new();
-        string.push(c(0xD83D)); // lead
-        string.push(c(0xDCA9)); // trail
-        assert_eq!(string.bytes, b"\xF0\x9F\x92\xA9"); // Magic!
-
-        let mut string = Wtf8Buf::new();
-        string.push(c(0xD83D)); // lead
-        string.push(c(0x20)); // not surrogate
-        string.push(c(0xDCA9)); // trail
-        assert_eq!(string.bytes, b"\xED\xA0\xBD \xED\xB2\xA9");
-
-        let mut string = Wtf8Buf::new();
-        string.push(c(0xD800)); // lead
-        string.push(c(0xDBFF)); // lead
-        assert_eq!(string.bytes, b"\xED\xA0\x80\xED\xAF\xBF");
-
-        let mut string = Wtf8Buf::new();
-        string.push(c(0xD800)); // lead
-        string.push(c(0xE000)); // not surrogate
-        assert_eq!(string.bytes, b"\xED\xA0\x80\xEE\x80\x80");
-
-        let mut string = Wtf8Buf::new();
-        string.push(c(0xD7FF)); // not surrogate
-        string.push(c(0xDC00)); // trail
-        assert_eq!(string.bytes, b"\xED\x9F\xBF\xED\xB0\x80");
-
-        let mut string = Wtf8Buf::new();
-        string.push(c(0x61)); // not surrogate, < 3 bytes
-        string.push(c(0xDC00)); // trail
-        assert_eq!(string.bytes, b"\x61\xED\xB0\x80");
-
-        let mut string = Wtf8Buf::new();
-        string.push(c(0xDC00)); // trail
-        assert_eq!(string.bytes, b"\xED\xB0\x80");
-    }
-
-    #[test]
-    fn wtf8buf_push_wtf8() {
-        let mut string = Wtf8Buf::from_str("aé");
-        assert_eq!(string.bytes, b"a\xC3\xA9");
-        string.push_wtf8(Wtf8::from_str(" 💩"));
-        assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
-
-        fn w(v: &[u8]) -> &Wtf8 {
-            unsafe { Wtf8::from_bytes_unchecked(v) }
-        }
-
-        let mut string = Wtf8Buf::new();
-        string.push_wtf8(w(b"\xED\xA0\xBD")); // lead
-        string.push_wtf8(w(b"\xED\xB2\xA9")); // trail
-        assert_eq!(string.bytes, b"\xF0\x9F\x92\xA9"); // Magic!
-
-        let mut string = Wtf8Buf::new();
-        string.push_wtf8(w(b"\xED\xA0\xBD")); // lead
-        string.push_wtf8(w(b" ")); // not surrogate
-        string.push_wtf8(w(b"\xED\xB2\xA9")); // trail
-        assert_eq!(string.bytes, b"\xED\xA0\xBD \xED\xB2\xA9");
-
-        let mut string = Wtf8Buf::new();
-        string.push_wtf8(w(b"\xED\xA0\x80")); // lead
-        string.push_wtf8(w(b"\xED\xAF\xBF")); // lead
-        assert_eq!(string.bytes, b"\xED\xA0\x80\xED\xAF\xBF");
-
-        let mut string = Wtf8Buf::new();
-        string.push_wtf8(w(b"\xED\xA0\x80")); // lead
-        string.push_wtf8(w(b"\xEE\x80\x80")); // not surrogate
-        assert_eq!(string.bytes, b"\xED\xA0\x80\xEE\x80\x80");
-
-        let mut string = Wtf8Buf::new();
-        string.push_wtf8(w(b"\xED\x9F\xBF")); // not surrogate
-        string.push_wtf8(w(b"\xED\xB0\x80")); // trail
-        assert_eq!(string.bytes, b"\xED\x9F\xBF\xED\xB0\x80");
-
-        let mut string = Wtf8Buf::new();
-        string.push_wtf8(w(b"a")); // not surrogate, < 3 bytes
-        string.push_wtf8(w(b"\xED\xB0\x80")); // trail
-        assert_eq!(string.bytes, b"\x61\xED\xB0\x80");
-
-        let mut string = Wtf8Buf::new();
-        string.push_wtf8(w(b"\xED\xB0\x80")); // trail
-        assert_eq!(string.bytes, b"\xED\xB0\x80");
-    }
-
-    #[test]
-    fn wtf8buf_truncate() {
-        let mut string = Wtf8Buf::from_str("aé");
-        string.truncate(1);
-        assert_eq!(string.bytes, b"a");
-    }
-
-    #[test]
-    #[should_panic]
-    fn wtf8buf_truncate_fail_code_point_boundary() {
-        let mut string = Wtf8Buf::from_str("aé");
-        string.truncate(2);
-    }
-
-    #[test]
-    #[should_panic]
-    fn wtf8buf_truncate_fail_longer() {
-        let mut string = Wtf8Buf::from_str("aé");
-        string.truncate(4);
-    }
-
-    #[test]
-    fn wtf8buf_into_string() {
-        let mut string = Wtf8Buf::from_str("aé 💩");
-        assert_eq!(string.clone().into_string(), Ok(String::from("aé 💩")));
-        string.push(CodePoint::from_u32(0xD800).unwrap());
-        assert_eq!(string.clone().into_string(), Err(string));
-    }
-
-    #[test]
-    fn wtf8buf_into_string_lossy() {
-        let mut string = Wtf8Buf::from_str("aé 💩");
-        assert_eq!(string.clone().into_string_lossy(), String::from("aé 💩"));
-        string.push(CodePoint::from_u32(0xD800).unwrap());
-        assert_eq!(string.clone().into_string_lossy(), String::from("aé 💩�"));
-    }
-
-    #[test]
-    fn wtf8buf_from_iterator() {
-        fn f(values: &[u32]) -> Wtf8Buf {
-            values.iter().map(|&c| CodePoint::from_u32(c).unwrap()).collect::<Wtf8Buf>()
-        }
-        assert_eq!(f(&[0x61, 0xE9, 0x20, 0x1F4A9]).bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
-
-        assert_eq!(f(&[0xD83D, 0xDCA9]).bytes, b"\xF0\x9F\x92\xA9"); // Magic!
-        assert_eq!(f(&[0xD83D, 0x20, 0xDCA9]).bytes, b"\xED\xA0\xBD \xED\xB2\xA9");
-        assert_eq!(f(&[0xD800, 0xDBFF]).bytes, b"\xED\xA0\x80\xED\xAF\xBF");
-        assert_eq!(f(&[0xD800, 0xE000]).bytes, b"\xED\xA0\x80\xEE\x80\x80");
-        assert_eq!(f(&[0xD7FF, 0xDC00]).bytes, b"\xED\x9F\xBF\xED\xB0\x80");
-        assert_eq!(f(&[0x61, 0xDC00]).bytes, b"\x61\xED\xB0\x80");
-        assert_eq!(f(&[0xDC00]).bytes, b"\xED\xB0\x80");
-    }
-
-    #[test]
-    fn wtf8buf_extend() {
-        fn e(initial: &[u32], extended: &[u32]) -> Wtf8Buf {
-            fn c(value: &u32) -> CodePoint {
-                CodePoint::from_u32(*value).unwrap()
-            }
-            let mut string = initial.iter().map(c).collect::<Wtf8Buf>();
-            string.extend(extended.iter().map(c));
-            string
-        }
-
-        assert_eq!(e(&[0x61, 0xE9], &[0x20, 0x1F4A9]).bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
-
-        assert_eq!(e(&[0xD83D], &[0xDCA9]).bytes, b"\xF0\x9F\x92\xA9"); // Magic!
-        assert_eq!(e(&[0xD83D, 0x20], &[0xDCA9]).bytes, b"\xED\xA0\xBD \xED\xB2\xA9");
-        assert_eq!(e(&[0xD800], &[0xDBFF]).bytes, b"\xED\xA0\x80\xED\xAF\xBF");
-        assert_eq!(e(&[0xD800], &[0xE000]).bytes, b"\xED\xA0\x80\xEE\x80\x80");
-        assert_eq!(e(&[0xD7FF], &[0xDC00]).bytes, b"\xED\x9F\xBF\xED\xB0\x80");
-        assert_eq!(e(&[0x61], &[0xDC00]).bytes, b"\x61\xED\xB0\x80");
-        assert_eq!(e(&[], &[0xDC00]).bytes, b"\xED\xB0\x80");
-    }
-
-    #[test]
-    fn wtf8buf_show() {
-        let mut string = Wtf8Buf::from_str("a\té \u{7f}💩\r");
-        string.push(CodePoint::from_u32(0xD800).unwrap());
-        assert_eq!(format!("{:?}", string), "\"a\\té \\u{7f}\u{1f4a9}\\r\\u{d800}\"");
-    }
-
-    #[test]
-    fn wtf8buf_as_slice() {
-        assert_eq!(Wtf8Buf::from_str("aé").as_slice(), Wtf8::from_str("aé"));
-    }
-
-    #[test]
-    fn wtf8buf_show_str() {
-        let text = "a\té 💩\r";
-        let string = Wtf8Buf::from_str(text);
-        assert_eq!(format!("{:?}", text), format!("{:?}", string));
-    }
-
-    #[test]
-    fn wtf8_from_str() {
-        assert_eq!(&Wtf8::from_str("").bytes, b"");
-        assert_eq!(&Wtf8::from_str("aé 💩").bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
-    }
-
-    #[test]
-    fn wtf8_len() {
-        assert_eq!(Wtf8::from_str("").len(), 0);
-        assert_eq!(Wtf8::from_str("aé 💩").len(), 8);
-    }
-
-    #[test]
-    fn wtf8_slice() {
-        assert_eq!(&Wtf8::from_str("aé 💩")[1..4].bytes, b"\xC3\xA9 ");
-    }
-
-    #[test]
-    #[should_panic]
-    fn wtf8_slice_not_code_point_boundary() {
-        &Wtf8::from_str("aé 💩")[2..4];
-    }
-
-    #[test]
-    fn wtf8_slice_from() {
-        assert_eq!(&Wtf8::from_str("aé 💩")[1..].bytes, b"\xC3\xA9 \xF0\x9F\x92\xA9");
-    }
-
-    #[test]
-    #[should_panic]
-    fn wtf8_slice_from_not_code_point_boundary() {
-        &Wtf8::from_str("aé 💩")[2..];
-    }
-
-    #[test]
-    fn wtf8_slice_to() {
-        assert_eq!(&Wtf8::from_str("aé 💩")[..4].bytes, b"a\xC3\xA9 ");
-    }
-
-    #[test]
-    #[should_panic]
-    fn wtf8_slice_to_not_code_point_boundary() {
-        &Wtf8::from_str("aé 💩")[5..];
-    }
-
-    #[test]
-    fn wtf8_ascii_byte_at() {
-        let slice = Wtf8::from_str("aé 💩");
-        assert_eq!(slice.ascii_byte_at(0), b'a');
-        assert_eq!(slice.ascii_byte_at(1), b'\xFF');
-        assert_eq!(slice.ascii_byte_at(2), b'\xFF');
-        assert_eq!(slice.ascii_byte_at(3), b' ');
-        assert_eq!(slice.ascii_byte_at(4), b'\xFF');
-    }
-
-    #[test]
-    fn wtf8_code_points() {
-        fn c(value: u32) -> CodePoint {
-            CodePoint::from_u32(value).unwrap()
-        }
-        fn cp(string: &Wtf8Buf) -> Vec<Option<char>> {
-            string.code_points().map(|c| c.to_char()).collect::<Vec<_>>()
-        }
-        let mut string = Wtf8Buf::from_str("é ");
-        assert_eq!(cp(&string), [Some('é'), Some(' ')]);
-        string.push(c(0xD83D));
-        assert_eq!(cp(&string), [Some('é'), Some(' '), None]);
-        string.push(c(0xDCA9));
-        assert_eq!(cp(&string), [Some('é'), Some(' '), Some('💩')]);
-    }
-
-    #[test]
-    fn wtf8_as_str() {
-        assert_eq!(Wtf8::from_str("").as_str(), Some(""));
-        assert_eq!(Wtf8::from_str("aé 💩").as_str(), Some("aé 💩"));
-        let mut string = Wtf8Buf::new();
-        string.push(CodePoint::from_u32(0xD800).unwrap());
-        assert_eq!(string.as_str(), None);
-    }
-
-    #[test]
-    fn wtf8_to_string_lossy() {
-        assert_eq!(Wtf8::from_str("").to_string_lossy(), Cow::Borrowed(""));
-        assert_eq!(Wtf8::from_str("aé 💩").to_string_lossy(), Cow::Borrowed("aé 💩"));
-        let mut string = Wtf8Buf::from_str("aé 💩");
-        string.push(CodePoint::from_u32(0xD800).unwrap());
-        let expected: Cow<'_, str> = Cow::Owned(String::from("aé 💩�"));
-        assert_eq!(string.to_string_lossy(), expected);
-    }
-
-    #[test]
-    fn wtf8_display() {
-        fn d(b: &[u8]) -> String {
-            (&unsafe { Wtf8::from_bytes_unchecked(b) }).to_string()
-        }
-
-        assert_eq!("", d("".as_bytes()));
-        assert_eq!("aé 💩", d("aé 💩".as_bytes()));
-
-        let mut string = Wtf8Buf::from_str("aé 💩");
-        string.push(CodePoint::from_u32(0xD800).unwrap());
-        assert_eq!("aé 💩�", d(string.as_inner()));
-    }
-
-    #[test]
-    fn wtf8_encode_wide() {
-        let mut string = Wtf8Buf::from_str("aé ");
-        string.push(CodePoint::from_u32(0xD83D).unwrap());
-        string.push_char('💩');
-        assert_eq!(
-            string.encode_wide().collect::<Vec<_>>(),
-            vec![0x61, 0xE9, 0x20, 0xD83D, 0xD83D, 0xDCA9]
-        );
-    }
-}
diff --git a/library/std/src/sys_common/wtf8/tests.rs b/library/std/src/sys_common/wtf8/tests.rs
new file mode 100644
index 00000000000..385e01f92fa
--- /dev/null
+++ b/library/std/src/sys_common/wtf8/tests.rs
@@ -0,0 +1,397 @@
+use super::*;
+use crate::borrow::Cow;
+
+#[test]
+fn code_point_from_u32() {
+    assert!(CodePoint::from_u32(0).is_some());
+    assert!(CodePoint::from_u32(0xD800).is_some());
+    assert!(CodePoint::from_u32(0x10FFFF).is_some());
+    assert!(CodePoint::from_u32(0x110000).is_none());
+}
+
+#[test]
+fn code_point_to_u32() {
+    fn c(value: u32) -> CodePoint {
+        CodePoint::from_u32(value).unwrap()
+    }
+    assert_eq!(c(0).to_u32(), 0);
+    assert_eq!(c(0xD800).to_u32(), 0xD800);
+    assert_eq!(c(0x10FFFF).to_u32(), 0x10FFFF);
+}
+
+#[test]
+fn code_point_from_char() {
+    assert_eq!(CodePoint::from_char('a').to_u32(), 0x61);
+    assert_eq!(CodePoint::from_char('💩').to_u32(), 0x1F4A9);
+}
+
+#[test]
+fn code_point_to_string() {
+    assert_eq!(format!("{:?}", CodePoint::from_char('a')), "U+0061");
+    assert_eq!(format!("{:?}", CodePoint::from_char('💩')), "U+1F4A9");
+}
+
+#[test]
+fn code_point_to_char() {
+    fn c(value: u32) -> CodePoint {
+        CodePoint::from_u32(value).unwrap()
+    }
+    assert_eq!(c(0x61).to_char(), Some('a'));
+    assert_eq!(c(0x1F4A9).to_char(), Some('💩'));
+    assert_eq!(c(0xD800).to_char(), None);
+}
+
+#[test]
+fn code_point_to_char_lossy() {
+    fn c(value: u32) -> CodePoint {
+        CodePoint::from_u32(value).unwrap()
+    }
+    assert_eq!(c(0x61).to_char_lossy(), 'a');
+    assert_eq!(c(0x1F4A9).to_char_lossy(), '💩');
+    assert_eq!(c(0xD800).to_char_lossy(), '\u{FFFD}');
+}
+
+#[test]
+fn wtf8buf_new() {
+    assert_eq!(Wtf8Buf::new().bytes, b"");
+}
+
+#[test]
+fn wtf8buf_from_str() {
+    assert_eq!(Wtf8Buf::from_str("").bytes, b"");
+    assert_eq!(Wtf8Buf::from_str("aé 💩").bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
+}
+
+#[test]
+fn wtf8buf_from_string() {
+    assert_eq!(Wtf8Buf::from_string(String::from("")).bytes, b"");
+    assert_eq!(Wtf8Buf::from_string(String::from("aé 💩")).bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
+}
+
+#[test]
+fn wtf8buf_from_wide() {
+    assert_eq!(Wtf8Buf::from_wide(&[]).bytes, b"");
+    assert_eq!(
+        Wtf8Buf::from_wide(&[0x61, 0xE9, 0x20, 0xD83D, 0xD83D, 0xDCA9]).bytes,
+        b"a\xC3\xA9 \xED\xA0\xBD\xF0\x9F\x92\xA9"
+    );
+}
+
+#[test]
+fn wtf8buf_push_str() {
+    let mut string = Wtf8Buf::new();
+    assert_eq!(string.bytes, b"");
+    string.push_str("aé 💩");
+    assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
+}
+
+#[test]
+fn wtf8buf_push_char() {
+    let mut string = Wtf8Buf::from_str("aé ");
+    assert_eq!(string.bytes, b"a\xC3\xA9 ");
+    string.push_char('💩');
+    assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
+}
+
+#[test]
+fn wtf8buf_push() {
+    let mut string = Wtf8Buf::from_str("aé ");
+    assert_eq!(string.bytes, b"a\xC3\xA9 ");
+    string.push(CodePoint::from_char('💩'));
+    assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
+
+    fn c(value: u32) -> CodePoint {
+        CodePoint::from_u32(value).unwrap()
+    }
+
+    let mut string = Wtf8Buf::new();
+    string.push(c(0xD83D)); // lead
+    string.push(c(0xDCA9)); // trail
+    assert_eq!(string.bytes, b"\xF0\x9F\x92\xA9"); // Magic!
+
+    let mut string = Wtf8Buf::new();
+    string.push(c(0xD83D)); // lead
+    string.push(c(0x20)); // not surrogate
+    string.push(c(0xDCA9)); // trail
+    assert_eq!(string.bytes, b"\xED\xA0\xBD \xED\xB2\xA9");
+
+    let mut string = Wtf8Buf::new();
+    string.push(c(0xD800)); // lead
+    string.push(c(0xDBFF)); // lead
+    assert_eq!(string.bytes, b"\xED\xA0\x80\xED\xAF\xBF");
+
+    let mut string = Wtf8Buf::new();
+    string.push(c(0xD800)); // lead
+    string.push(c(0xE000)); // not surrogate
+    assert_eq!(string.bytes, b"\xED\xA0\x80\xEE\x80\x80");
+
+    let mut string = Wtf8Buf::new();
+    string.push(c(0xD7FF)); // not surrogate
+    string.push(c(0xDC00)); // trail
+    assert_eq!(string.bytes, b"\xED\x9F\xBF\xED\xB0\x80");
+
+    let mut string = Wtf8Buf::new();
+    string.push(c(0x61)); // not surrogate, < 3 bytes
+    string.push(c(0xDC00)); // trail
+    assert_eq!(string.bytes, b"\x61\xED\xB0\x80");
+
+    let mut string = Wtf8Buf::new();
+    string.push(c(0xDC00)); // trail
+    assert_eq!(string.bytes, b"\xED\xB0\x80");
+}
+
+#[test]
+fn wtf8buf_push_wtf8() {
+    let mut string = Wtf8Buf::from_str("aé");
+    assert_eq!(string.bytes, b"a\xC3\xA9");
+    string.push_wtf8(Wtf8::from_str(" 💩"));
+    assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
+
+    fn w(v: &[u8]) -> &Wtf8 {
+        unsafe { Wtf8::from_bytes_unchecked(v) }
+    }
+
+    let mut string = Wtf8Buf::new();
+    string.push_wtf8(w(b"\xED\xA0\xBD")); // lead
+    string.push_wtf8(w(b"\xED\xB2\xA9")); // trail
+    assert_eq!(string.bytes, b"\xF0\x9F\x92\xA9"); // Magic!
+
+    let mut string = Wtf8Buf::new();
+    string.push_wtf8(w(b"\xED\xA0\xBD")); // lead
+    string.push_wtf8(w(b" ")); // not surrogate
+    string.push_wtf8(w(b"\xED\xB2\xA9")); // trail
+    assert_eq!(string.bytes, b"\xED\xA0\xBD \xED\xB2\xA9");
+
+    let mut string = Wtf8Buf::new();
+    string.push_wtf8(w(b"\xED\xA0\x80")); // lead
+    string.push_wtf8(w(b"\xED\xAF\xBF")); // lead
+    assert_eq!(string.bytes, b"\xED\xA0\x80\xED\xAF\xBF");
+
+    let mut string = Wtf8Buf::new();
+    string.push_wtf8(w(b"\xED\xA0\x80")); // lead
+    string.push_wtf8(w(b"\xEE\x80\x80")); // not surrogate
+    assert_eq!(string.bytes, b"\xED\xA0\x80\xEE\x80\x80");
+
+    let mut string = Wtf8Buf::new();
+    string.push_wtf8(w(b"\xED\x9F\xBF")); // not surrogate
+    string.push_wtf8(w(b"\xED\xB0\x80")); // trail
+    assert_eq!(string.bytes, b"\xED\x9F\xBF\xED\xB0\x80");
+
+    let mut string = Wtf8Buf::new();
+    string.push_wtf8(w(b"a")); // not surrogate, < 3 bytes
+    string.push_wtf8(w(b"\xED\xB0\x80")); // trail
+    assert_eq!(string.bytes, b"\x61\xED\xB0\x80");
+
+    let mut string = Wtf8Buf::new();
+    string.push_wtf8(w(b"\xED\xB0\x80")); // trail
+    assert_eq!(string.bytes, b"\xED\xB0\x80");
+}
+
+#[test]
+fn wtf8buf_truncate() {
+    let mut string = Wtf8Buf::from_str("aé");
+    string.truncate(1);
+    assert_eq!(string.bytes, b"a");
+}
+
+#[test]
+#[should_panic]
+fn wtf8buf_truncate_fail_code_point_boundary() {
+    let mut string = Wtf8Buf::from_str("aé");
+    string.truncate(2);
+}
+
+#[test]
+#[should_panic]
+fn wtf8buf_truncate_fail_longer() {
+    let mut string = Wtf8Buf::from_str("aé");
+    string.truncate(4);
+}
+
+#[test]
+fn wtf8buf_into_string() {
+    let mut string = Wtf8Buf::from_str("aé 💩");
+    assert_eq!(string.clone().into_string(), Ok(String::from("aé 💩")));
+    string.push(CodePoint::from_u32(0xD800).unwrap());
+    assert_eq!(string.clone().into_string(), Err(string));
+}
+
+#[test]
+fn wtf8buf_into_string_lossy() {
+    let mut string = Wtf8Buf::from_str("aé 💩");
+    assert_eq!(string.clone().into_string_lossy(), String::from("aé 💩"));
+    string.push(CodePoint::from_u32(0xD800).unwrap());
+    assert_eq!(string.clone().into_string_lossy(), String::from("aé 💩�"));
+}
+
+#[test]
+fn wtf8buf_from_iterator() {
+    fn f(values: &[u32]) -> Wtf8Buf {
+        values.iter().map(|&c| CodePoint::from_u32(c).unwrap()).collect::<Wtf8Buf>()
+    }
+    assert_eq!(f(&[0x61, 0xE9, 0x20, 0x1F4A9]).bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
+
+    assert_eq!(f(&[0xD83D, 0xDCA9]).bytes, b"\xF0\x9F\x92\xA9"); // Magic!
+    assert_eq!(f(&[0xD83D, 0x20, 0xDCA9]).bytes, b"\xED\xA0\xBD \xED\xB2\xA9");
+    assert_eq!(f(&[0xD800, 0xDBFF]).bytes, b"\xED\xA0\x80\xED\xAF\xBF");
+    assert_eq!(f(&[0xD800, 0xE000]).bytes, b"\xED\xA0\x80\xEE\x80\x80");
+    assert_eq!(f(&[0xD7FF, 0xDC00]).bytes, b"\xED\x9F\xBF\xED\xB0\x80");
+    assert_eq!(f(&[0x61, 0xDC00]).bytes, b"\x61\xED\xB0\x80");
+    assert_eq!(f(&[0xDC00]).bytes, b"\xED\xB0\x80");
+}
+
+#[test]
+fn wtf8buf_extend() {
+    fn e(initial: &[u32], extended: &[u32]) -> Wtf8Buf {
+        fn c(value: &u32) -> CodePoint {
+            CodePoint::from_u32(*value).unwrap()
+        }
+        let mut string = initial.iter().map(c).collect::<Wtf8Buf>();
+        string.extend(extended.iter().map(c));
+        string
+    }
+
+    assert_eq!(e(&[0x61, 0xE9], &[0x20, 0x1F4A9]).bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
+
+    assert_eq!(e(&[0xD83D], &[0xDCA9]).bytes, b"\xF0\x9F\x92\xA9"); // Magic!
+    assert_eq!(e(&[0xD83D, 0x20], &[0xDCA9]).bytes, b"\xED\xA0\xBD \xED\xB2\xA9");
+    assert_eq!(e(&[0xD800], &[0xDBFF]).bytes, b"\xED\xA0\x80\xED\xAF\xBF");
+    assert_eq!(e(&[0xD800], &[0xE000]).bytes, b"\xED\xA0\x80\xEE\x80\x80");
+    assert_eq!(e(&[0xD7FF], &[0xDC00]).bytes, b"\xED\x9F\xBF\xED\xB0\x80");
+    assert_eq!(e(&[0x61], &[0xDC00]).bytes, b"\x61\xED\xB0\x80");
+    assert_eq!(e(&[], &[0xDC00]).bytes, b"\xED\xB0\x80");
+}
+
+#[test]
+fn wtf8buf_show() {
+    let mut string = Wtf8Buf::from_str("a\té \u{7f}💩\r");
+    string.push(CodePoint::from_u32(0xD800).unwrap());
+    assert_eq!(format!("{:?}", string), "\"a\\té \\u{7f}\u{1f4a9}\\r\\u{d800}\"");
+}
+
+#[test]
+fn wtf8buf_as_slice() {
+    assert_eq!(Wtf8Buf::from_str("aé").as_slice(), Wtf8::from_str("aé"));
+}
+
+#[test]
+fn wtf8buf_show_str() {
+    let text = "a\té 💩\r";
+    let string = Wtf8Buf::from_str(text);
+    assert_eq!(format!("{:?}", text), format!("{:?}", string));
+}
+
+#[test]
+fn wtf8_from_str() {
+    assert_eq!(&Wtf8::from_str("").bytes, b"");
+    assert_eq!(&Wtf8::from_str("aé 💩").bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9");
+}
+
+#[test]
+fn wtf8_len() {
+    assert_eq!(Wtf8::from_str("").len(), 0);
+    assert_eq!(Wtf8::from_str("aé 💩").len(), 8);
+}
+
+#[test]
+fn wtf8_slice() {
+    assert_eq!(&Wtf8::from_str("aé 💩")[1..4].bytes, b"\xC3\xA9 ");
+}
+
+#[test]
+#[should_panic]
+fn wtf8_slice_not_code_point_boundary() {
+    &Wtf8::from_str("aé 💩")[2..4];
+}
+
+#[test]
+fn wtf8_slice_from() {
+    assert_eq!(&Wtf8::from_str("aé 💩")[1..].bytes, b"\xC3\xA9 \xF0\x9F\x92\xA9");
+}
+
+#[test]
+#[should_panic]
+fn wtf8_slice_from_not_code_point_boundary() {
+    &Wtf8::from_str("aé 💩")[2..];
+}
+
+#[test]
+fn wtf8_slice_to() {
+    assert_eq!(&Wtf8::from_str("aé 💩")[..4].bytes, b"a\xC3\xA9 ");
+}
+
+#[test]
+#[should_panic]
+fn wtf8_slice_to_not_code_point_boundary() {
+    &Wtf8::from_str("aé 💩")[5..];
+}
+
+#[test]
+fn wtf8_ascii_byte_at() {
+    let slice = Wtf8::from_str("aé 💩");
+    assert_eq!(slice.ascii_byte_at(0), b'a');
+    assert_eq!(slice.ascii_byte_at(1), b'\xFF');
+    assert_eq!(slice.ascii_byte_at(2), b'\xFF');
+    assert_eq!(slice.ascii_byte_at(3), b' ');
+    assert_eq!(slice.ascii_byte_at(4), b'\xFF');
+}
+
+#[test]
+fn wtf8_code_points() {
+    fn c(value: u32) -> CodePoint {
+        CodePoint::from_u32(value).unwrap()
+    }
+    fn cp(string: &Wtf8Buf) -> Vec<Option<char>> {
+        string.code_points().map(|c| c.to_char()).collect::<Vec<_>>()
+    }
+    let mut string = Wtf8Buf::from_str("é ");
+    assert_eq!(cp(&string), [Some('é'), Some(' ')]);
+    string.push(c(0xD83D));
+    assert_eq!(cp(&string), [Some('é'), Some(' '), None]);
+    string.push(c(0xDCA9));
+    assert_eq!(cp(&string), [Some('é'), Some(' '), Some('💩')]);
+}
+
+#[test]
+fn wtf8_as_str() {
+    assert_eq!(Wtf8::from_str("").as_str(), Some(""));
+    assert_eq!(Wtf8::from_str("aé 💩").as_str(), Some("aé 💩"));
+    let mut string = Wtf8Buf::new();
+    string.push(CodePoint::from_u32(0xD800).unwrap());
+    assert_eq!(string.as_str(), None);
+}
+
+#[test]
+fn wtf8_to_string_lossy() {
+    assert_eq!(Wtf8::from_str("").to_string_lossy(), Cow::Borrowed(""));
+    assert_eq!(Wtf8::from_str("aé 💩").to_string_lossy(), Cow::Borrowed("aé 💩"));
+    let mut string = Wtf8Buf::from_str("aé 💩");
+    string.push(CodePoint::from_u32(0xD800).unwrap());
+    let expected: Cow<'_, str> = Cow::Owned(String::from("aé 💩�"));
+    assert_eq!(string.to_string_lossy(), expected);
+}
+
+#[test]
+fn wtf8_display() {
+    fn d(b: &[u8]) -> String {
+        (&unsafe { Wtf8::from_bytes_unchecked(b) }).to_string()
+    }
+
+    assert_eq!("", d("".as_bytes()));
+    assert_eq!("aé 💩", d("aé 💩".as_bytes()));
+
+    let mut string = Wtf8Buf::from_str("aé 💩");
+    string.push(CodePoint::from_u32(0xD800).unwrap());
+    assert_eq!("aé 💩�", d(string.as_inner()));
+}
+
+#[test]
+fn wtf8_encode_wide() {
+    let mut string = Wtf8Buf::from_str("aé ");
+    string.push(CodePoint::from_u32(0xD83D).unwrap());
+    string.push_char('💩');
+    assert_eq!(
+        string.encode_wide().collect::<Vec<_>>(),
+        vec![0x61, 0xE9, 0x20, 0xD83D, 0xD83D, 0xDCA9]
+    );
+}
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs
index a4562967f0b..9d8c6f1815e 100644
--- a/library/std/src/thread/local.rs
+++ b/library/std/src/thread/local.rs
@@ -2,6 +2,12 @@
 
 #![unstable(feature = "thread_local_internals", issue = "none")]
 
+#[cfg(all(test, not(target_os = "emscripten")))]
+mod tests;
+
+#[cfg(test)]
+mod dynamic_tests;
+
 use crate::error::Error;
 use crate::fmt;
 
@@ -547,203 +553,3 @@ pub mod os {
         key.os.set(ptr::null_mut());
     }
 }
-
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod tests {
-    use crate::cell::{Cell, UnsafeCell};
-    use crate::sync::mpsc::{channel, Sender};
-    use crate::thread;
-
-    struct Foo(Sender<()>);
-
-    impl Drop for Foo {
-        fn drop(&mut self) {
-            let Foo(ref s) = *self;
-            s.send(()).unwrap();
-        }
-    }
-
-    #[test]
-    fn smoke_no_dtor() {
-        thread_local!(static FOO: Cell<i32> = Cell::new(1));
-
-        FOO.with(|f| {
-            assert_eq!(f.get(), 1);
-            f.set(2);
-        });
-        let (tx, rx) = channel();
-        let _t = thread::spawn(move || {
-            FOO.with(|f| {
-                assert_eq!(f.get(), 1);
-            });
-            tx.send(()).unwrap();
-        });
-        rx.recv().unwrap();
-
-        FOO.with(|f| {
-            assert_eq!(f.get(), 2);
-        });
-    }
-
-    #[test]
-    fn states() {
-        struct Foo;
-        impl Drop for Foo {
-            fn drop(&mut self) {
-                assert!(FOO.try_with(|_| ()).is_err());
-            }
-        }
-        thread_local!(static FOO: Foo = Foo);
-
-        thread::spawn(|| {
-            assert!(FOO.try_with(|_| ()).is_ok());
-        })
-        .join()
-        .ok()
-        .expect("thread panicked");
-    }
-
-    #[test]
-    fn smoke_dtor() {
-        thread_local!(static FOO: UnsafeCell<Option<Foo>> = UnsafeCell::new(None));
-
-        let (tx, rx) = channel();
-        let _t = thread::spawn(move || unsafe {
-            let mut tx = Some(tx);
-            FOO.with(|f| {
-                *f.get() = Some(Foo(tx.take().unwrap()));
-            });
-        });
-        rx.recv().unwrap();
-    }
-
-    #[test]
-    fn circular() {
-        struct S1;
-        struct S2;
-        thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None));
-        thread_local!(static K2: UnsafeCell<Option<S2>> = UnsafeCell::new(None));
-        static mut HITS: u32 = 0;
-
-        impl Drop for S1 {
-            fn drop(&mut self) {
-                unsafe {
-                    HITS += 1;
-                    if K2.try_with(|_| ()).is_err() {
-                        assert_eq!(HITS, 3);
-                    } else {
-                        if HITS == 1 {
-                            K2.with(|s| *s.get() = Some(S2));
-                        } else {
-                            assert_eq!(HITS, 3);
-                        }
-                    }
-                }
-            }
-        }
-        impl Drop for S2 {
-            fn drop(&mut self) {
-                unsafe {
-                    HITS += 1;
-                    assert!(K1.try_with(|_| ()).is_ok());
-                    assert_eq!(HITS, 2);
-                    K1.with(|s| *s.get() = Some(S1));
-                }
-            }
-        }
-
-        thread::spawn(move || {
-            drop(S1);
-        })
-        .join()
-        .ok()
-        .expect("thread panicked");
-    }
-
-    #[test]
-    fn self_referential() {
-        struct S1;
-        thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None));
-
-        impl Drop for S1 {
-            fn drop(&mut self) {
-                assert!(K1.try_with(|_| ()).is_err());
-            }
-        }
-
-        thread::spawn(move || unsafe {
-            K1.with(|s| *s.get() = Some(S1));
-        })
-        .join()
-        .ok()
-        .expect("thread panicked");
-    }
-
-    // Note that this test will deadlock if TLS destructors aren't run (this
-    // requires the destructor to be run to pass the test).
-    #[test]
-    fn dtors_in_dtors_in_dtors() {
-        struct S1(Sender<()>);
-        thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None));
-        thread_local!(static K2: UnsafeCell<Option<Foo>> = UnsafeCell::new(None));
-
-        impl Drop for S1 {
-            fn drop(&mut self) {
-                let S1(ref tx) = *self;
-                unsafe {
-                    let _ = K2.try_with(|s| *s.get() = Some(Foo(tx.clone())));
-                }
-            }
-        }
-
-        let (tx, rx) = channel();
-        let _t = thread::spawn(move || unsafe {
-            let mut tx = Some(tx);
-            K1.with(|s| *s.get() = Some(S1(tx.take().unwrap())));
-        });
-        rx.recv().unwrap();
-    }
-}
-
-#[cfg(test)]
-mod dynamic_tests {
-    use crate::cell::RefCell;
-    use crate::collections::HashMap;
-
-    #[test]
-    fn smoke() {
-        fn square(i: i32) -> i32 {
-            i * i
-        }
-        thread_local!(static FOO: i32 = square(3));
-
-        FOO.with(|f| {
-            assert_eq!(*f, 9);
-        });
-    }
-
-    #[test]
-    fn hashmap() {
-        fn map() -> RefCell<HashMap<i32, i32>> {
-            let mut m = HashMap::new();
-            m.insert(1, 2);
-            RefCell::new(m)
-        }
-        thread_local!(static FOO: RefCell<HashMap<i32, i32>> = map());
-
-        FOO.with(|map| {
-            assert_eq!(map.borrow()[&1], 2);
-        });
-    }
-
-    #[test]
-    fn refcell_vec() {
-        thread_local!(static FOO: RefCell<Vec<u32>> = RefCell::new(vec![1, 2, 3]));
-
-        FOO.with(|vec| {
-            assert_eq!(vec.borrow().len(), 3);
-            vec.borrow_mut().push(4);
-            assert_eq!(vec.borrow()[3], 4);
-        });
-    }
-}
diff --git a/library/std/src/thread/local/dynamic_tests.rs b/library/std/src/thread/local/dynamic_tests.rs
new file mode 100644
index 00000000000..dd180041648
--- /dev/null
+++ b/library/std/src/thread/local/dynamic_tests.rs
@@ -0,0 +1,40 @@
+use crate::cell::RefCell;
+use crate::collections::HashMap;
+use crate::thread_local;
+
+#[test]
+fn smoke() {
+    fn square(i: i32) -> i32 {
+        i * i
+    }
+    thread_local!(static FOO: i32 = square(3));
+
+    FOO.with(|f| {
+        assert_eq!(*f, 9);
+    });
+}
+
+#[test]
+fn hashmap() {
+    fn map() -> RefCell<HashMap<i32, i32>> {
+        let mut m = HashMap::new();
+        m.insert(1, 2);
+        RefCell::new(m)
+    }
+    thread_local!(static FOO: RefCell<HashMap<i32, i32>> = map());
+
+    FOO.with(|map| {
+        assert_eq!(map.borrow()[&1], 2);
+    });
+}
+
+#[test]
+fn refcell_vec() {
+    thread_local!(static FOO: RefCell<Vec<u32>> = RefCell::new(vec![1, 2, 3]));
+
+    FOO.with(|vec| {
+        assert_eq!(vec.borrow().len(), 3);
+        vec.borrow_mut().push(4);
+        assert_eq!(vec.borrow()[3], 4);
+    });
+}
diff --git a/library/std/src/thread/local/tests.rs b/library/std/src/thread/local/tests.rs
new file mode 100644
index 00000000000..4fb0a089082
--- /dev/null
+++ b/library/std/src/thread/local/tests.rs
@@ -0,0 +1,154 @@
+use crate::cell::{Cell, UnsafeCell};
+use crate::sync::mpsc::{channel, Sender};
+use crate::thread;
+use crate::thread_local;
+
+struct Foo(Sender<()>);
+
+impl Drop for Foo {
+    fn drop(&mut self) {
+        let Foo(ref s) = *self;
+        s.send(()).unwrap();
+    }
+}
+
+#[test]
+fn smoke_no_dtor() {
+    thread_local!(static FOO: Cell<i32> = Cell::new(1));
+
+    FOO.with(|f| {
+        assert_eq!(f.get(), 1);
+        f.set(2);
+    });
+    let (tx, rx) = channel();
+    let _t = thread::spawn(move || {
+        FOO.with(|f| {
+            assert_eq!(f.get(), 1);
+        });
+        tx.send(()).unwrap();
+    });
+    rx.recv().unwrap();
+
+    FOO.with(|f| {
+        assert_eq!(f.get(), 2);
+    });
+}
+
+#[test]
+fn states() {
+    struct Foo;
+    impl Drop for Foo {
+        fn drop(&mut self) {
+            assert!(FOO.try_with(|_| ()).is_err());
+        }
+    }
+    thread_local!(static FOO: Foo = Foo);
+
+    thread::spawn(|| {
+        assert!(FOO.try_with(|_| ()).is_ok());
+    })
+    .join()
+    .ok()
+    .expect("thread panicked");
+}
+
+#[test]
+fn smoke_dtor() {
+    thread_local!(static FOO: UnsafeCell<Option<Foo>> = UnsafeCell::new(None));
+
+    let (tx, rx) = channel();
+    let _t = thread::spawn(move || unsafe {
+        let mut tx = Some(tx);
+        FOO.with(|f| {
+            *f.get() = Some(Foo(tx.take().unwrap()));
+        });
+    });
+    rx.recv().unwrap();
+}
+
+#[test]
+fn circular() {
+    struct S1;
+    struct S2;
+    thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None));
+    thread_local!(static K2: UnsafeCell<Option<S2>> = UnsafeCell::new(None));
+    static mut HITS: u32 = 0;
+
+    impl Drop for S1 {
+        fn drop(&mut self) {
+            unsafe {
+                HITS += 1;
+                if K2.try_with(|_| ()).is_err() {
+                    assert_eq!(HITS, 3);
+                } else {
+                    if HITS == 1 {
+                        K2.with(|s| *s.get() = Some(S2));
+                    } else {
+                        assert_eq!(HITS, 3);
+                    }
+                }
+            }
+        }
+    }
+    impl Drop for S2 {
+        fn drop(&mut self) {
+            unsafe {
+                HITS += 1;
+                assert!(K1.try_with(|_| ()).is_ok());
+                assert_eq!(HITS, 2);
+                K1.with(|s| *s.get() = Some(S1));
+            }
+        }
+    }
+
+    thread::spawn(move || {
+        drop(S1);
+    })
+    .join()
+    .ok()
+    .expect("thread panicked");
+}
+
+#[test]
+fn self_referential() {
+    struct S1;
+    thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None));
+
+    impl Drop for S1 {
+        fn drop(&mut self) {
+            assert!(K1.try_with(|_| ()).is_err());
+        }
+    }
+
+    thread::spawn(move || unsafe {
+        K1.with(|s| *s.get() = Some(S1));
+    })
+    .join()
+    .ok()
+    .expect("thread panicked");
+}
+
+// Note that this test will deadlock if TLS destructors aren't run (this
+// requires the destructor to be run to pass the test).
+#[test]
+fn dtors_in_dtors_in_dtors() {
+    struct S1(Sender<()>);
+    thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None));
+    thread_local!(static K2: UnsafeCell<Option<Foo>> = UnsafeCell::new(None));
+
+    impl Drop for S1 {
+        fn drop(&mut self) {
+            let S1(ref tx) = *self;
+            unsafe {
+                let _ = K2.try_with(|s| *s.get() = Some(Foo(tx.clone())));
+            }
+        }
+    }
+
+    let (tx, rx) = channel();
+    let _t = thread::spawn(move || unsafe {
+        let mut tx = Some(tx);
+        K1.with(|s| *s.get() = Some(S1(tx.take().unwrap())));
+    });
+    rx.recv().unwrap();
+}
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index 0b9849517c2..6d6be8560aa 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -145,6 +145,9 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+#[cfg(all(test, not(target_os = "emscripten")))]
+mod tests;
+
 use crate::any::Any;
 use crate::cell::UnsafeCell;
 use crate::ffi::{CStr, CString};
@@ -1470,273 +1473,3 @@ fn _assert_sync_and_send() {
     _assert_both::<JoinHandle<()>>();
     _assert_both::<Thread>();
 }
-
-////////////////////////////////////////////////////////////////////////////////
-// Tests
-////////////////////////////////////////////////////////////////////////////////
-
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod tests {
-    use super::Builder;
-    use crate::any::Any;
-    use crate::mem;
-    use crate::result;
-    use crate::sync::mpsc::{channel, Sender};
-    use crate::thread::{self, ThreadId};
-    use crate::time::Duration;
-
-    // !!! These tests are dangerous. If something is buggy, they will hang, !!!
-    // !!! instead of exiting cleanly. This might wedge the buildbots.       !!!
-
-    #[test]
-    fn test_unnamed_thread() {
-        thread::spawn(move || {
-            assert!(thread::current().name().is_none());
-        })
-        .join()
-        .ok()
-        .expect("thread panicked");
-    }
-
-    #[test]
-    fn test_named_thread() {
-        Builder::new()
-            .name("ada lovelace".to_string())
-            .spawn(move || {
-                assert!(thread::current().name().unwrap() == "ada lovelace".to_string());
-            })
-            .unwrap()
-            .join()
-            .unwrap();
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_invalid_named_thread() {
-        let _ = Builder::new().name("ada l\0velace".to_string()).spawn(|| {});
-    }
-
-    #[test]
-    fn test_run_basic() {
-        let (tx, rx) = channel();
-        thread::spawn(move || {
-            tx.send(()).unwrap();
-        });
-        rx.recv().unwrap();
-    }
-
-    #[test]
-    fn test_join_panic() {
-        match thread::spawn(move || panic!()).join() {
-            result::Result::Err(_) => (),
-            result::Result::Ok(()) => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_spawn_sched() {
-        let (tx, rx) = channel();
-
-        fn f(i: i32, tx: Sender<()>) {
-            let tx = tx.clone();
-            thread::spawn(move || {
-                if i == 0 {
-                    tx.send(()).unwrap();
-                } else {
-                    f(i - 1, tx);
-                }
-            });
-        }
-        f(10, tx);
-        rx.recv().unwrap();
-    }
-
-    #[test]
-    fn test_spawn_sched_childs_on_default_sched() {
-        let (tx, rx) = channel();
-
-        thread::spawn(move || {
-            thread::spawn(move || {
-                tx.send(()).unwrap();
-            });
-        });
-
-        rx.recv().unwrap();
-    }
-
-    fn avoid_copying_the_body<F>(spawnfn: F)
-    where
-        F: FnOnce(Box<dyn Fn() + Send>),
-    {
-        let (tx, rx) = channel();
-
-        let x: Box<_> = box 1;
-        let x_in_parent = (&*x) as *const i32 as usize;
-
-        spawnfn(Box::new(move || {
-            let x_in_child = (&*x) as *const i32 as usize;
-            tx.send(x_in_child).unwrap();
-        }));
-
-        let x_in_child = rx.recv().unwrap();
-        assert_eq!(x_in_parent, x_in_child);
-    }
-
-    #[test]
-    fn test_avoid_copying_the_body_spawn() {
-        avoid_copying_the_body(|v| {
-            thread::spawn(move || v());
-        });
-    }
-
-    #[test]
-    fn test_avoid_copying_the_body_thread_spawn() {
-        avoid_copying_the_body(|f| {
-            thread::spawn(move || {
-                f();
-            });
-        })
-    }
-
-    #[test]
-    fn test_avoid_copying_the_body_join() {
-        avoid_copying_the_body(|f| {
-            let _ = thread::spawn(move || f()).join();
-        })
-    }
-
-    #[test]
-    fn test_child_doesnt_ref_parent() {
-        // If the child refcounts the parent thread, this will stack overflow when
-        // climbing the thread tree to dereference each ancestor. (See #1789)
-        // (well, it would if the constant were 8000+ - I lowered it to be more
-        // valgrind-friendly. try this at home, instead..!)
-        const GENERATIONS: u32 = 16;
-        fn child_no(x: u32) -> Box<dyn Fn() + Send> {
-            return Box::new(move || {
-                if x < GENERATIONS {
-                    thread::spawn(move || child_no(x + 1)());
-                }
-            });
-        }
-        thread::spawn(|| child_no(0)());
-    }
-
-    #[test]
-    fn test_simple_newsched_spawn() {
-        thread::spawn(move || {});
-    }
-
-    #[test]
-    fn test_try_panic_message_static_str() {
-        match thread::spawn(move || {
-            panic!("static string");
-        })
-        .join()
-        {
-            Err(e) => {
-                type T = &'static str;
-                assert!(e.is::<T>());
-                assert_eq!(*e.downcast::<T>().unwrap(), "static string");
-            }
-            Ok(()) => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_try_panic_message_owned_str() {
-        match thread::spawn(move || {
-            panic!("owned string".to_string());
-        })
-        .join()
-        {
-            Err(e) => {
-                type T = String;
-                assert!(e.is::<T>());
-                assert_eq!(*e.downcast::<T>().unwrap(), "owned string".to_string());
-            }
-            Ok(()) => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_try_panic_message_any() {
-        match thread::spawn(move || {
-            panic!(box 413u16 as Box<dyn Any + Send>);
-        })
-        .join()
-        {
-            Err(e) => {
-                type T = Box<dyn Any + Send>;
-                assert!(e.is::<T>());
-                let any = e.downcast::<T>().unwrap();
-                assert!(any.is::<u16>());
-                assert_eq!(*any.downcast::<u16>().unwrap(), 413);
-            }
-            Ok(()) => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_try_panic_message_unit_struct() {
-        struct Juju;
-
-        match thread::spawn(move || panic!(Juju)).join() {
-            Err(ref e) if e.is::<Juju>() => {}
-            Err(_) | Ok(()) => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_park_timeout_unpark_before() {
-        for _ in 0..10 {
-            thread::current().unpark();
-            thread::park_timeout(Duration::from_millis(u32::MAX as u64));
-        }
-    }
-
-    #[test]
-    fn test_park_timeout_unpark_not_called() {
-        for _ in 0..10 {
-            thread::park_timeout(Duration::from_millis(10));
-        }
-    }
-
-    #[test]
-    fn test_park_timeout_unpark_called_other_thread() {
-        for _ in 0..10 {
-            let th = thread::current();
-
-            let _guard = thread::spawn(move || {
-                super::sleep(Duration::from_millis(50));
-                th.unpark();
-            });
-
-            thread::park_timeout(Duration::from_millis(u32::MAX as u64));
-        }
-    }
-
-    #[test]
-    fn sleep_ms_smoke() {
-        thread::sleep(Duration::from_millis(2));
-    }
-
-    #[test]
-    fn test_size_of_option_thread_id() {
-        assert_eq!(mem::size_of::<Option<ThreadId>>(), mem::size_of::<ThreadId>());
-    }
-
-    #[test]
-    fn test_thread_id_equal() {
-        assert!(thread::current().id() == thread::current().id());
-    }
-
-    #[test]
-    fn test_thread_id_not_equal() {
-        let spawned_id = thread::spawn(|| thread::current().id()).join().unwrap();
-        assert!(thread::current().id() != spawned_id);
-    }
-
-    // NOTE: the corresponding test for stderr is in ui/thread-stderr, due
-    // to the test harness apparently interfering with stderr configuration.
-}
diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs
new file mode 100644
index 00000000000..16ad366fc12
--- /dev/null
+++ b/library/std/src/thread/tests.rs
@@ -0,0 +1,262 @@
+use super::Builder;
+use crate::any::Any;
+use crate::mem;
+use crate::result;
+use crate::sync::mpsc::{channel, Sender};
+use crate::thread::{self, ThreadId};
+use crate::time::Duration;
+
+// !!! These tests are dangerous. If something is buggy, they will hang, !!!
+// !!! instead of exiting cleanly. This might wedge the buildbots.       !!!
+
+#[test]
+fn test_unnamed_thread() {
+    thread::spawn(move || {
+        assert!(thread::current().name().is_none());
+    })
+    .join()
+    .ok()
+    .expect("thread panicked");
+}
+
+#[test]
+fn test_named_thread() {
+    Builder::new()
+        .name("ada lovelace".to_string())
+        .spawn(move || {
+            assert!(thread::current().name().unwrap() == "ada lovelace".to_string());
+        })
+        .unwrap()
+        .join()
+        .unwrap();
+}
+
+#[test]
+#[should_panic]
+fn test_invalid_named_thread() {
+    let _ = Builder::new().name("ada l\0velace".to_string()).spawn(|| {});
+}
+
+#[test]
+fn test_run_basic() {
+    let (tx, rx) = channel();
+    thread::spawn(move || {
+        tx.send(()).unwrap();
+    });
+    rx.recv().unwrap();
+}
+
+#[test]
+fn test_join_panic() {
+    match thread::spawn(move || panic!()).join() {
+        result::Result::Err(_) => (),
+        result::Result::Ok(()) => panic!(),
+    }
+}
+
+#[test]
+fn test_spawn_sched() {
+    let (tx, rx) = channel();
+
+    fn f(i: i32, tx: Sender<()>) {
+        let tx = tx.clone();
+        thread::spawn(move || {
+            if i == 0 {
+                tx.send(()).unwrap();
+            } else {
+                f(i - 1, tx);
+            }
+        });
+    }
+    f(10, tx);
+    rx.recv().unwrap();
+}
+
+#[test]
+fn test_spawn_sched_childs_on_default_sched() {
+    let (tx, rx) = channel();
+
+    thread::spawn(move || {
+        thread::spawn(move || {
+            tx.send(()).unwrap();
+        });
+    });
+
+    rx.recv().unwrap();
+}
+
+fn avoid_copying_the_body<F>(spawnfn: F)
+where
+    F: FnOnce(Box<dyn Fn() + Send>),
+{
+    let (tx, rx) = channel();
+
+    let x: Box<_> = box 1;
+    let x_in_parent = (&*x) as *const i32 as usize;
+
+    spawnfn(Box::new(move || {
+        let x_in_child = (&*x) as *const i32 as usize;
+        tx.send(x_in_child).unwrap();
+    }));
+
+    let x_in_child = rx.recv().unwrap();
+    assert_eq!(x_in_parent, x_in_child);
+}
+
+#[test]
+fn test_avoid_copying_the_body_spawn() {
+    avoid_copying_the_body(|v| {
+        thread::spawn(move || v());
+    });
+}
+
+#[test]
+fn test_avoid_copying_the_body_thread_spawn() {
+    avoid_copying_the_body(|f| {
+        thread::spawn(move || {
+            f();
+        });
+    })
+}
+
+#[test]
+fn test_avoid_copying_the_body_join() {
+    avoid_copying_the_body(|f| {
+        let _ = thread::spawn(move || f()).join();
+    })
+}
+
+#[test]
+fn test_child_doesnt_ref_parent() {
+    // If the child refcounts the parent thread, this will stack overflow when
+    // climbing the thread tree to dereference each ancestor. (See #1789)
+    // (well, it would if the constant were 8000+ - I lowered it to be more
+    // valgrind-friendly. try this at home, instead..!)
+    const GENERATIONS: u32 = 16;
+    fn child_no(x: u32) -> Box<dyn Fn() + Send> {
+        return Box::new(move || {
+            if x < GENERATIONS {
+                thread::spawn(move || child_no(x + 1)());
+            }
+        });
+    }
+    thread::spawn(|| child_no(0)());
+}
+
+#[test]
+fn test_simple_newsched_spawn() {
+    thread::spawn(move || {});
+}
+
+#[test]
+fn test_try_panic_message_static_str() {
+    match thread::spawn(move || {
+        panic!("static string");
+    })
+    .join()
+    {
+        Err(e) => {
+            type T = &'static str;
+            assert!(e.is::<T>());
+            assert_eq!(*e.downcast::<T>().unwrap(), "static string");
+        }
+        Ok(()) => panic!(),
+    }
+}
+
+#[test]
+fn test_try_panic_message_owned_str() {
+    match thread::spawn(move || {
+        panic!("owned string".to_string());
+    })
+    .join()
+    {
+        Err(e) => {
+            type T = String;
+            assert!(e.is::<T>());
+            assert_eq!(*e.downcast::<T>().unwrap(), "owned string".to_string());
+        }
+        Ok(()) => panic!(),
+    }
+}
+
+#[test]
+fn test_try_panic_message_any() {
+    match thread::spawn(move || {
+        panic!(box 413u16 as Box<dyn Any + Send>);
+    })
+    .join()
+    {
+        Err(e) => {
+            type T = Box<dyn Any + Send>;
+            assert!(e.is::<T>());
+            let any = e.downcast::<T>().unwrap();
+            assert!(any.is::<u16>());
+            assert_eq!(*any.downcast::<u16>().unwrap(), 413);
+        }
+        Ok(()) => panic!(),
+    }
+}
+
+#[test]
+fn test_try_panic_message_unit_struct() {
+    struct Juju;
+
+    match thread::spawn(move || panic!(Juju)).join() {
+        Err(ref e) if e.is::<Juju>() => {}
+        Err(_) | Ok(()) => panic!(),
+    }
+}
+
+#[test]
+fn test_park_timeout_unpark_before() {
+    for _ in 0..10 {
+        thread::current().unpark();
+        thread::park_timeout(Duration::from_millis(u32::MAX as u64));
+    }
+}
+
+#[test]
+fn test_park_timeout_unpark_not_called() {
+    for _ in 0..10 {
+        thread::park_timeout(Duration::from_millis(10));
+    }
+}
+
+#[test]
+fn test_park_timeout_unpark_called_other_thread() {
+    for _ in 0..10 {
+        let th = thread::current();
+
+        let _guard = thread::spawn(move || {
+            super::sleep(Duration::from_millis(50));
+            th.unpark();
+        });
+
+        thread::park_timeout(Duration::from_millis(u32::MAX as u64));
+    }
+}
+
+#[test]
+fn sleep_ms_smoke() {
+    thread::sleep(Duration::from_millis(2));
+}
+
+#[test]
+fn test_size_of_option_thread_id() {
+    assert_eq!(mem::size_of::<Option<ThreadId>>(), mem::size_of::<ThreadId>());
+}
+
+#[test]
+fn test_thread_id_equal() {
+    assert!(thread::current().id() == thread::current().id());
+}
+
+#[test]
+fn test_thread_id_not_equal() {
+    let spawned_id = thread::spawn(|| thread::current().id()).join().unwrap();
+    assert!(thread::current().id() != spawned_id);
+}
+
+// NOTE: the corresponding test for stderr is in ui/thread-stderr, due
+// to the test harness apparently interfering with stderr configuration.
diff --git a/library/std/src/time.rs b/library/std/src/time.rs
index c8aee1da39b..73c0a7b403a 100644
--- a/library/std/src/time.rs
+++ b/library/std/src/time.rs
@@ -12,6 +12,9 @@
 
 #![stable(feature = "time", since = "1.3.0")]
 
+#[cfg(test)]
+mod tests;
+
 use crate::cmp;
 use crate::error::Error;
 use crate::fmt;
@@ -630,172 +633,3 @@ impl FromInner<time::SystemTime> for SystemTime {
         SystemTime(time)
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use super::{Duration, Instant, SystemTime, UNIX_EPOCH};
-
-    macro_rules! assert_almost_eq {
-        ($a:expr, $b:expr) => {{
-            let (a, b) = ($a, $b);
-            if a != b {
-                let (a, b) = if a > b { (a, b) } else { (b, a) };
-                assert!(a - Duration::new(0, 1000) <= b, "{:?} is not almost equal to {:?}", a, b);
-            }
-        }};
-    }
-
-    #[test]
-    fn instant_monotonic() {
-        let a = Instant::now();
-        let b = Instant::now();
-        assert!(b >= a);
-    }
-
-    #[test]
-    fn instant_elapsed() {
-        let a = Instant::now();
-        a.elapsed();
-    }
-
-    #[test]
-    fn instant_math() {
-        let a = Instant::now();
-        let b = Instant::now();
-        println!("a: {:?}", a);
-        println!("b: {:?}", b);
-        let dur = b.duration_since(a);
-        println!("dur: {:?}", dur);
-        assert_almost_eq!(b - dur, a);
-        assert_almost_eq!(a + dur, b);
-
-        let second = Duration::new(1, 0);
-        assert_almost_eq!(a - second + second, a);
-        assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a);
-
-        // checked_add_duration will not panic on overflow
-        let mut maybe_t = Some(Instant::now());
-        let max_duration = Duration::from_secs(u64::MAX);
-        // in case `Instant` can store `>= now + max_duration`.
-        for _ in 0..2 {
-            maybe_t = maybe_t.and_then(|t| t.checked_add(max_duration));
-        }
-        assert_eq!(maybe_t, None);
-
-        // checked_add_duration calculates the right time and will work for another year
-        let year = Duration::from_secs(60 * 60 * 24 * 365);
-        assert_eq!(a + year, a.checked_add(year).unwrap());
-    }
-
-    #[test]
-    fn instant_math_is_associative() {
-        let now = Instant::now();
-        let offset = Duration::from_millis(5);
-        // Changing the order of instant math shouldn't change the results,
-        // especially when the expression reduces to X + identity.
-        assert_eq!((now + offset) - now, (now - now) + offset);
-    }
-
-    #[test]
-    #[should_panic]
-    fn instant_duration_since_panic() {
-        let a = Instant::now();
-        (a - Duration::new(1, 0)).duration_since(a);
-    }
-
-    #[test]
-    fn instant_checked_duration_since_nopanic() {
-        let now = Instant::now();
-        let earlier = now - Duration::new(1, 0);
-        let later = now + Duration::new(1, 0);
-        assert_eq!(earlier.checked_duration_since(now), None);
-        assert_eq!(later.checked_duration_since(now), Some(Duration::new(1, 0)));
-        assert_eq!(now.checked_duration_since(now), Some(Duration::new(0, 0)));
-    }
-
-    #[test]
-    fn instant_saturating_duration_since_nopanic() {
-        let a = Instant::now();
-        let ret = (a - Duration::new(1, 0)).saturating_duration_since(a);
-        assert_eq!(ret, Duration::new(0, 0));
-    }
-
-    #[test]
-    fn system_time_math() {
-        let a = SystemTime::now();
-        let b = SystemTime::now();
-        match b.duration_since(a) {
-            Ok(dur) if dur == Duration::new(0, 0) => {
-                assert_almost_eq!(a, b);
-            }
-            Ok(dur) => {
-                assert!(b > a);
-                assert_almost_eq!(b - dur, a);
-                assert_almost_eq!(a + dur, b);
-            }
-            Err(dur) => {
-                let dur = dur.duration();
-                assert!(a > b);
-                assert_almost_eq!(b + dur, a);
-                assert_almost_eq!(a - dur, b);
-            }
-        }
-
-        let second = Duration::new(1, 0);
-        assert_almost_eq!(a.duration_since(a - second).unwrap(), second);
-        assert_almost_eq!(a.duration_since(a + second).unwrap_err().duration(), second);
-
-        assert_almost_eq!(a - second + second, a);
-        assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a);
-
-        let one_second_from_epoch = UNIX_EPOCH + Duration::new(1, 0);
-        let one_second_from_epoch2 =
-            UNIX_EPOCH + Duration::new(0, 500_000_000) + Duration::new(0, 500_000_000);
-        assert_eq!(one_second_from_epoch, one_second_from_epoch2);
-
-        // checked_add_duration will not panic on overflow
-        let mut maybe_t = Some(SystemTime::UNIX_EPOCH);
-        let max_duration = Duration::from_secs(u64::MAX);
-        // in case `SystemTime` can store `>= UNIX_EPOCH + max_duration`.
-        for _ in 0..2 {
-            maybe_t = maybe_t.and_then(|t| t.checked_add(max_duration));
-        }
-        assert_eq!(maybe_t, None);
-
-        // checked_add_duration calculates the right time and will work for another year
-        let year = Duration::from_secs(60 * 60 * 24 * 365);
-        assert_eq!(a + year, a.checked_add(year).unwrap());
-    }
-
-    #[test]
-    fn system_time_elapsed() {
-        let a = SystemTime::now();
-        drop(a.elapsed());
-    }
-
-    #[test]
-    fn since_epoch() {
-        let ts = SystemTime::now();
-        let a = ts.duration_since(UNIX_EPOCH + Duration::new(1, 0)).unwrap();
-        let b = ts.duration_since(UNIX_EPOCH).unwrap();
-        assert!(b > a);
-        assert_eq!(b - a, Duration::new(1, 0));
-
-        let thirty_years = Duration::new(1, 0) * 60 * 60 * 24 * 365 * 30;
-
-        // Right now for CI this test is run in an emulator, and apparently the
-        // aarch64 emulator's sense of time is that we're still living in the
-        // 70s. This is also true for riscv (also qemu)
-        //
-        // Otherwise let's assume that we're all running computers later than
-        // 2000.
-        if !cfg!(target_arch = "aarch64") && !cfg!(target_arch = "riscv64") {
-            assert!(a > thirty_years);
-        }
-
-        // let's assume that we're all running computers earlier than 2090.
-        // Should give us ~70 years to fix this!
-        let hundred_twenty_years = thirty_years * 4;
-        assert!(a < hundred_twenty_years);
-    }
-}
diff --git a/library/std/src/time/tests.rs b/library/std/src/time/tests.rs
new file mode 100644
index 00000000000..783bf49f315
--- /dev/null
+++ b/library/std/src/time/tests.rs
@@ -0,0 +1,165 @@
+use super::{Duration, Instant, SystemTime, UNIX_EPOCH};
+
+macro_rules! assert_almost_eq {
+    ($a:expr, $b:expr) => {{
+        let (a, b) = ($a, $b);
+        if a != b {
+            let (a, b) = if a > b { (a, b) } else { (b, a) };
+            assert!(a - Duration::new(0, 1000) <= b, "{:?} is not almost equal to {:?}", a, b);
+        }
+    }};
+}
+
+#[test]
+fn instant_monotonic() {
+    let a = Instant::now();
+    let b = Instant::now();
+    assert!(b >= a);
+}
+
+#[test]
+fn instant_elapsed() {
+    let a = Instant::now();
+    a.elapsed();
+}
+
+#[test]
+fn instant_math() {
+    let a = Instant::now();
+    let b = Instant::now();
+    println!("a: {:?}", a);
+    println!("b: {:?}", b);
+    let dur = b.duration_since(a);
+    println!("dur: {:?}", dur);
+    assert_almost_eq!(b - dur, a);
+    assert_almost_eq!(a + dur, b);
+
+    let second = Duration::new(1, 0);
+    assert_almost_eq!(a - second + second, a);
+    assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a);
+
+    // checked_add_duration will not panic on overflow
+    let mut maybe_t = Some(Instant::now());
+    let max_duration = Duration::from_secs(u64::MAX);
+    // in case `Instant` can store `>= now + max_duration`.
+    for _ in 0..2 {
+        maybe_t = maybe_t.and_then(|t| t.checked_add(max_duration));
+    }
+    assert_eq!(maybe_t, None);
+
+    // checked_add_duration calculates the right time and will work for another year
+    let year = Duration::from_secs(60 * 60 * 24 * 365);
+    assert_eq!(a + year, a.checked_add(year).unwrap());
+}
+
+#[test]
+fn instant_math_is_associative() {
+    let now = Instant::now();
+    let offset = Duration::from_millis(5);
+    // Changing the order of instant math shouldn't change the results,
+    // especially when the expression reduces to X + identity.
+    assert_eq!((now + offset) - now, (now - now) + offset);
+}
+
+#[test]
+#[should_panic]
+fn instant_duration_since_panic() {
+    let a = Instant::now();
+    (a - Duration::new(1, 0)).duration_since(a);
+}
+
+#[test]
+fn instant_checked_duration_since_nopanic() {
+    let now = Instant::now();
+    let earlier = now - Duration::new(1, 0);
+    let later = now + Duration::new(1, 0);
+    assert_eq!(earlier.checked_duration_since(now), None);
+    assert_eq!(later.checked_duration_since(now), Some(Duration::new(1, 0)));
+    assert_eq!(now.checked_duration_since(now), Some(Duration::new(0, 0)));
+}
+
+#[test]
+fn instant_saturating_duration_since_nopanic() {
+    let a = Instant::now();
+    let ret = (a - Duration::new(1, 0)).saturating_duration_since(a);
+    assert_eq!(ret, Duration::new(0, 0));
+}
+
+#[test]
+fn system_time_math() {
+    let a = SystemTime::now();
+    let b = SystemTime::now();
+    match b.duration_since(a) {
+        Ok(dur) if dur == Duration::new(0, 0) => {
+            assert_almost_eq!(a, b);
+        }
+        Ok(dur) => {
+            assert!(b > a);
+            assert_almost_eq!(b - dur, a);
+            assert_almost_eq!(a + dur, b);
+        }
+        Err(dur) => {
+            let dur = dur.duration();
+            assert!(a > b);
+            assert_almost_eq!(b + dur, a);
+            assert_almost_eq!(a - dur, b);
+        }
+    }
+
+    let second = Duration::new(1, 0);
+    assert_almost_eq!(a.duration_since(a - second).unwrap(), second);
+    assert_almost_eq!(a.duration_since(a + second).unwrap_err().duration(), second);
+
+    assert_almost_eq!(a - second + second, a);
+    assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a);
+
+    let one_second_from_epoch = UNIX_EPOCH + Duration::new(1, 0);
+    let one_second_from_epoch2 =
+        UNIX_EPOCH + Duration::new(0, 500_000_000) + Duration::new(0, 500_000_000);
+    assert_eq!(one_second_from_epoch, one_second_from_epoch2);
+
+    // checked_add_duration will not panic on overflow
+    let mut maybe_t = Some(SystemTime::UNIX_EPOCH);
+    let max_duration = Duration::from_secs(u64::MAX);
+    // in case `SystemTime` can store `>= UNIX_EPOCH + max_duration`.
+    for _ in 0..2 {
+        maybe_t = maybe_t.and_then(|t| t.checked_add(max_duration));
+    }
+    assert_eq!(maybe_t, None);
+
+    // checked_add_duration calculates the right time and will work for another year
+    let year = Duration::from_secs(60 * 60 * 24 * 365);
+    assert_eq!(a + year, a.checked_add(year).unwrap());
+}
+
+#[test]
+fn system_time_elapsed() {
+    let a = SystemTime::now();
+    drop(a.elapsed());
+}
+
+#[test]
+fn since_epoch() {
+    let ts = SystemTime::now();
+    let a = ts.duration_since(UNIX_EPOCH + Duration::new(1, 0)).unwrap();
+    let b = ts.duration_since(UNIX_EPOCH).unwrap();
+    assert!(b > a);
+    assert_eq!(b - a, Duration::new(1, 0));
+
+    let thirty_years = Duration::new(1, 0) * 60 * 60 * 24 * 365 * 30;
+
+    // Right now for CI this test is run in an emulator, and apparently the
+    // aarch64 emulator's sense of time is that we're still living in the
+    // 70s. This is also true for riscv (also qemu)
+    //
+    // Otherwise let's assume that we're all running computers later than
+    // 2000.
+    if !cfg!(target_arch = "aarch64") && !cfg!(target_arch = "riscv64") {
+        assert!(a > thirty_years);
+    }
+
+    // let's assume that we're all running computers earlier than 2090.
+    // Should give us ~70 years to fix this!
+    let hundred_twenty_years = thirty_years * 4;
+    assert!(a < hundred_twenty_years);
+}
diff --git a/src/README.md b/src/README.md
index 2f8e9da179a..ef0dec1c45b 100644
--- a/src/README.md
+++ b/src/README.md
@@ -1,5 +1,5 @@
 This directory contains the source code of the rust project, including:
-- `rustc` and its tests
+- The test suite
 - The bootstrapping build system
 - Various submodules for tools, like rustdoc, rls, etc.
 
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index c4918d7f2e7..faec2c53742 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -5,7 +5,6 @@ version = "0.0.0"
 edition = "2018"
 
 [lib]
-name = "bootstrap"
 path = "lib.rs"
 doctest = false
 
diff --git a/src/bootstrap/README.md b/src/bootstrap/README.md
index 86de3d5c6d8..975b8be02c8 100644
--- a/src/bootstrap/README.md
+++ b/src/bootstrap/README.md
@@ -274,7 +274,7 @@ directory, but rather the compiler is split into three different Cargo projects:
 
 * `library/std` - the standard library
 * `library/test` - testing support, depends on libstd
-* `src/rustc` - the actual compiler itself
+* `compiler/rustc` - the actual compiler itself
 
 Each "project" has a corresponding Cargo.lock file with all dependencies, and
 this means that building the compiler involves running Cargo three times. The
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 54eb2e99b8f..cecc9ef75ea 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -1041,15 +1041,11 @@ impl<'a> Builder<'a> {
             }
         }
 
-        // FIXME: Don't use LLD with MSVC if we're compiling libtest, since it fails to link it.
-        // See https://github.com/rust-lang/rust/issues/68647.
-        let can_use_lld = mode != Mode::Std;
-
-        if let Some(host_linker) = self.linker(compiler.host, can_use_lld) {
+        if let Some(host_linker) = self.linker(compiler.host, true) {
             cargo.env("RUSTC_HOST_LINKER", host_linker);
         }
 
-        if let Some(target_linker) = self.linker(target, can_use_lld) {
+        if let Some(target_linker) = self.linker(target, true) {
             let target = crate::envify(&target.triple);
             cargo.env(&format!("CARGO_TARGET_{}_LINKER", target), target_linker);
         }
diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs
index 5b6c327896b..aeb0d713ef0 100644
--- a/src/bootstrap/builder/tests.rs
+++ b/src/bootstrap/builder/tests.rs
@@ -8,7 +8,7 @@ fn configure(host: &[&str], target: &[&str]) -> Config {
     config.save_toolstates = None;
     config.skip_only_host_steps = false;
     config.dry_run = true;
-    config.ninja = false;
+    config.ninja_in_file = false;
     // try to avoid spurious failures in dist where we create/delete each others file
     let dir = config
         .out
@@ -371,7 +371,7 @@ mod dist {
         let mut builder = Builder::new(&build);
         builder.run_step_descriptions(
             &Builder::get_step_descriptions(Kind::Build),
-            &["src/rustc".into(), "library/std".into()],
+            &["compiler/rustc".into(), "library/std".into()],
         );
 
         let a = TargetSelection::from_user("A");
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 373e240cb8e..7814ca8e5bb 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -449,7 +449,7 @@ impl Step for Rustc {
     const DEFAULT: bool = false;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.path("src/rustc")
+        run.path("compiler/rustc")
     }
 
     fn make_run(run: RunConfig<'_>) {
@@ -524,7 +524,7 @@ pub fn rustc_cargo(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelec
         .arg("--features")
         .arg(builder.rustc_features())
         .arg("--manifest-path")
-        .arg(builder.src.join("src/rustc/Cargo.toml"));
+        .arg(builder.src.join("compiler/rustc/Cargo.toml"));
     rustc_cargo_env(builder, cargo, target);
 }
 
@@ -819,7 +819,7 @@ impl Step for Assemble {
 
         // Link the compiler binary itself into place
         let out_dir = builder.cargo_out(build_compiler, Mode::Rustc, host);
-        let rustc = out_dir.join(exe("rustc_binary", host));
+        let rustc = out_dir.join(exe("rustc-main", host));
         let bindir = sysroot.join("bin");
         t!(fs::create_dir_all(&bindir));
         let compiler = builder.rustc(target_compiler);
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index f549de6570f..ad2f4877867 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -32,7 +32,8 @@ use serde::Deserialize;
 #[derive(Default)]
 pub struct Config {
     pub ccache: Option<String>,
-    pub ninja: bool,
+    /// Call Build::ninja() instead of this.
+    pub ninja_in_file: bool,
     pub verbose: usize,
     pub submodules: bool,
     pub fast_submodules: bool,
@@ -450,7 +451,7 @@ impl Config {
     pub fn default_opts() -> Config {
         let mut config = Config::default();
         config.llvm_optimize = true;
-        config.ninja = true;
+        config.ninja_in_file = true;
         config.llvm_version_check = true;
         config.backtrace = true;
         config.rust_optimize = true;
@@ -606,7 +607,7 @@ impl Config {
                 }
                 Some(StringOrBool::Bool(false)) | None => {}
             }
-            set(&mut config.ninja, llvm.ninja);
+            set(&mut config.ninja_in_file, llvm.ninja);
             llvm_assertions = llvm.assertions;
             llvm_skip_rebuild = llvm_skip_rebuild.or(llvm.skip_rebuild);
             set(&mut config.llvm_optimize, llvm.optimize);
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index d021feafbe4..c1022099a02 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -1097,7 +1097,7 @@ impl Step for PlainSourceTarball {
             "Cargo.toml",
             "Cargo.lock",
         ];
-        let src_dirs = ["src", "library"];
+        let src_dirs = ["src", "compiler", "library"];
 
         copy_src_dirs(builder, &builder.src, &src_dirs, &[], &plain_dst_src);
 
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 2a8f43950db..d7f3a888edd 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -694,6 +694,7 @@ impl Step for UnstableBookGen {
         builder.remove_dir(&out);
         let mut cmd = builder.tool_cmd(Tool::UnstableBookGen);
         cmd.arg(builder.src.join("library"));
+        cmd.arg(builder.src.join("compiler"));
         cmd.arg(builder.src.join("src"));
         cmd.arg(out);
 
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index 38b3a32e3b5..2db4bb07a9f 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -385,7 +385,7 @@ Arguments:
         ./x.py test src/test/ui --bless
         ./x.py test src/test/ui --compare-mode nll
 
-    Note that `test src/test/* --stage N` does NOT depend on `build src/rustc --stage N`;
+    Note that `test src/test/* --stage N` does NOT depend on `build compiler/rustc --stage N`;
     just like `build library/std --stage N` it tests the compiler produced by the previous
     stage.
 
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 191cc5b0b64..54651214363 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -650,7 +650,7 @@ impl Build {
             }
         } else {
             let base = self.llvm_out(self.config.build).join("build");
-            let base = if !self.config.ninja && self.config.build.contains("msvc") {
+            let base = if !self.ninja() && self.config.build.contains("msvc") {
                 if self.config.llvm_optimize {
                     if self.config.llvm_release_debuginfo {
                         base.join("RelWithDebInfo")
@@ -1328,6 +1328,43 @@ impl Build {
         }
         fs::remove_file(f).unwrap_or_else(|_| panic!("failed to remove {:?}", f));
     }
+
+    /// Returns if config.ninja is enabled, and checks for ninja existence,
+    /// exiting with a nicer error message if not.
+    fn ninja(&self) -> bool {
+        let mut cmd_finder = crate::sanity::Finder::new();
+
+        if self.config.ninja_in_file {
+            // Some Linux distros rename `ninja` to `ninja-build`.
+            // CMake can work with either binary name.
+            if cmd_finder.maybe_have("ninja-build").is_none()
+                && cmd_finder.maybe_have("ninja").is_none()
+            {
+                eprintln!(
+                    "
+Couldn't find required command: ninja
+You should install ninja, or set ninja=false in config.toml
+"
+                );
+                std::process::exit(1);
+            }
+        }
+
+        // If ninja isn't enabled but we're building for MSVC then we try
+        // doubly hard to enable it. It was realized in #43767 that the msbuild
+        // CMake generator for MSVC doesn't respect configuration options like
+        // disabling LLVM assertions, which can often be quite important!
+        //
+        // In these cases we automatically enable Ninja if we find it in the
+        // environment.
+        if !self.config.ninja_in_file && self.config.build.contains("msvc") {
+            if cmd_finder.maybe_have("ninja").is_some() {
+                return true;
+            }
+        }
+
+        self.config.ninja_in_file
+    }
 }
 
 #[cfg(unix)]
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index e9d0c017c7b..a0c79e38f9d 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -56,7 +56,7 @@ pub fn prebuilt_llvm_config(
     let out_dir = builder.llvm_out(target);
 
     let mut llvm_config_ret_dir = builder.llvm_out(builder.config.build);
-    if !builder.config.build.contains("msvc") || builder.config.ninja {
+    if !builder.config.build.contains("msvc") || builder.ninja() {
         llvm_config_ret_dir.push("build");
     }
     llvm_config_ret_dir.push("bin");
@@ -363,7 +363,7 @@ fn configure_cmake(
     // own build directories.
     cfg.env("DESTDIR", "");
 
-    if builder.config.ninja {
+    if builder.ninja() {
         cfg.generator("Ninja");
     }
     cfg.target(&target.triple).host(&builder.config.build.triple);
@@ -395,7 +395,7 @@ fn configure_cmake(
     // MSVC with CMake uses msbuild by default which doesn't respect these
     // vars that we'd otherwise configure. In that case we just skip this
     // entirely.
-    if target.contains("msvc") && !builder.config.ninja {
+    if target.contains("msvc") && !builder.ninja() {
         return;
     }
 
@@ -405,7 +405,7 @@ fn configure_cmake(
     };
 
     // Handle msvc + ninja + ccache specially (this is what the bots use)
-    if target.contains("msvc") && builder.config.ninja && builder.config.ccache.is_some() {
+    if target.contains("msvc") && builder.ninja() && builder.config.ccache.is_some() {
         let mut wrap_cc = env::current_exe().expect("failed to get cwd");
         wrap_cc.set_file_name("sccache-plus-cl.exe");
 
diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs
index 533b5c79777..4d6612a376a 100644
--- a/src/bootstrap/sanity.rs
+++ b/src/bootstrap/sanity.rs
@@ -20,17 +20,17 @@ use build_helper::{output, t};
 use crate::config::Target;
 use crate::Build;
 
-struct Finder {
+pub struct Finder {
     cache: HashMap<OsString, Option<PathBuf>>,
     path: OsString,
 }
 
 impl Finder {
-    fn new() -> Self {
+    pub fn new() -> Self {
         Self { cache: HashMap::new(), path: env::var_os("PATH").unwrap_or_default() }
     }
 
-    fn maybe_have<S: AsRef<OsStr>>(&mut self, cmd: S) -> Option<PathBuf> {
+    pub fn maybe_have<S: AsRef<OsStr>>(&mut self, cmd: S) -> Option<PathBuf> {
         let cmd: OsString = cmd.as_ref().into();
         let path = &self.path;
         self.cache
@@ -54,7 +54,7 @@ impl Finder {
             .clone()
     }
 
-    fn must_have<S: AsRef<OsStr>>(&mut self, cmd: S) -> PathBuf {
+    pub fn must_have<S: AsRef<OsStr>>(&mut self, cmd: S) -> PathBuf {
         self.maybe_have(&cmd).unwrap_or_else(|| {
             panic!("\n\ncouldn't find required command: {:?}\n\n", cmd.as_ref());
         })
@@ -95,38 +95,6 @@ pub fn check(build: &mut Build) {
         cmd_finder.must_have("cmake");
     }
 
-    // Ninja is currently only used for LLVM itself.
-    if building_llvm {
-        if build.config.ninja {
-            // Some Linux distros rename `ninja` to `ninja-build`.
-            // CMake can work with either binary name.
-            if cmd_finder.maybe_have("ninja-build").is_none()
-                && cmd_finder.maybe_have("ninja").is_none()
-            {
-                eprintln!(
-                    "
-Couldn't find required command: ninja
-You should install ninja, or set ninja=false in config.toml
-"
-                );
-                std::process::exit(1);
-            }
-        }
-
-        // If ninja isn't enabled but we're building for MSVC then we try
-        // doubly hard to enable it. It was realized in #43767 that the msbuild
-        // CMake generator for MSVC doesn't respect configuration options like
-        // disabling LLVM assertions, which can often be quite important!
-        //
-        // In these cases we automatically enable Ninja if we find it in the
-        // environment.
-        if !build.config.ninja && build.config.build.contains("msvc") {
-            if cmd_finder.maybe_have("ninja").is_some() {
-                build.config.ninja = true;
-            }
-        }
-    }
-
     build.config.python = build
         .config
         .python
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index ac833a55d4c..a7c9b99f45f 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -734,7 +734,7 @@ impl Step for Tidy {
     /// for the `dev` or `nightly` channels.
     fn run(self, builder: &Builder<'_>) {
         let mut cmd = builder.tool_cmd(Tool::Tidy);
-        cmd.arg(builder.src.join("src"));
+        cmd.arg(&builder.src);
         cmd.arg(&builder.initial_cargo);
         if builder.is_verbose() {
             cmd.arg("--verbose");
diff --git a/src/build_helper/Cargo.toml b/src/build_helper/Cargo.toml
index 04c7820b456..2420f1b7f18 100644
--- a/src/build_helper/Cargo.toml
+++ b/src/build_helper/Cargo.toml
@@ -5,5 +5,4 @@ authors = ["The Rust Project Developers"]
 edition = "2018"
 
 [lib]
-name = "build_helper"
 path = "lib.rs"
diff --git a/src/doc/book b/src/doc/book
-Subproject c0a6a61b8205da14ac955425f74258ffd8ee065
+Subproject e5ed97128302d5fa45dbac0e64426bc7649a558
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
-Subproject bd6e4a9f59c5c1545f572266af77f5c7a5bad6d
+Subproject 81f16863014de60b53de401d71ff904d163ee03
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 1b6c4b0afab97c0230433466c97167bbbe8445f
+Subproject 25391dba46262f882fa846beefaff54a966a8fa
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject 80a10e22140e28392b99d24ed02f4c6d8cb770a
+Subproject 19f0a0372af497b34369cf182d9d16156cab296
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index 7b0280d5b78..bed10ca16d3 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -44,13 +44,13 @@ incremental builds the default is 256 which allows caching to be more granular.
 
 ## control-flow-guard
 
-This flag controls whether LLVM enables the Windows [Control Flow 
-Guard](https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard) 
-platform security feature. This flag is currently ignored for non-Windows targets. 
+This flag controls whether LLVM enables the Windows [Control Flow
+Guard](https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard)
+platform security feature. This flag is currently ignored for non-Windows targets.
 It takes one of the following values:
 
 * `y`, `yes`, `on`, `checks`, or no value: enable Control Flow Guard.
-* `nochecks`: emit Control Flow Guard metadata without runtime enforcement checks (this 
+* `nochecks`: emit Control Flow Guard metadata without runtime enforcement checks (this
 should only be used for testing purposes as it does not provide security enforcement).
 * `n`, `no`, `off`: do not enable Control Flow Guard (the default).
 
@@ -200,6 +200,18 @@ the following values:
 An example of when this flag might be useful is when trying to construct code coverage
 metrics.
 
+## link-self-contained
+
+On targets that support it this flag controls whether the linker will use libraries and objects
+shipped with Rust instead or those in the system.
+It takes one of the following values:
+
+* no value: rustc will use heuristic to disable self-contained mode if system has necessary tools.
+* `y`, `yes`, `on`: use only libraries/objects shipped with Rust.
+* `n`, `no`, or `off`: rely on the user or the linker to provide non-Rust libraries/objects.
+
+This allows overriding cases when detection fails or user wants to use shipped libraries.
+
 ## linker
 
 This flag controls which linker `rustc` invokes to link your code. It takes a
diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md
index d1d6bc1c1fe..8e2869fef55 100644
--- a/src/doc/rustdoc/src/lints.md
+++ b/src/doc/rustdoc/src/lints.md
@@ -51,7 +51,7 @@ warning: missing documentation for a function
 
 ## missing_doc_code_examples
 
-This lint is **allowed by default**. It detects when a documentation block
+This lint is **allowed by default** and is **nightly-only**. It detects when a documentation block
 is missing a code example. For example:
 
 ```rust
diff --git a/src/librustc_ast/Cargo.toml b/src/librustc_ast/Cargo.toml
deleted file mode 100644
index 73c5e33753f..00000000000
--- a/src/librustc_ast/Cargo.toml
+++ /dev/null
@@ -1,21 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_ast"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_ast"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc_serialize = { path = "../librustc_serialize" }
-tracing = "0.1"
-rustc_span = { path = "../librustc_span" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_index = { path = "../librustc_index" }
-rustc_lexer = { path = "../librustc_lexer" }
-rustc_macros = { path = "../librustc_macros" }
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
-bitflags = "1.2.1"
diff --git a/src/librustc_ast_lowering/Cargo.toml b/src/librustc_ast_lowering/Cargo.toml
deleted file mode 100644
index bf7e69a31ab..00000000000
--- a/src/librustc_ast_lowering/Cargo.toml
+++ /dev/null
@@ -1,24 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_ast_lowering"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_ast_lowering"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc_arena = { path = "../librustc_arena" }
-tracing = "0.1"
-rustc_ast_pretty = { path = "../librustc_ast_pretty" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_target = { path = "../librustc_target" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_index = { path = "../librustc_index" }
-rustc_span = { path = "../librustc_span" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_session = { path = "../librustc_session" }
-rustc_ast = { path = "../librustc_ast" }
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_ast_passes/Cargo.toml b/src/librustc_ast_passes/Cargo.toml
deleted file mode 100644
index 6db9bce3164..00000000000
--- a/src/librustc_ast_passes/Cargo.toml
+++ /dev/null
@@ -1,22 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_ast_passes"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_ast_passes"
-path = "lib.rs"
-
-[dependencies]
-itertools = "0.8"
-tracing = "0.1"
-rustc_ast_pretty = { path = "../librustc_ast_pretty" }
-rustc_attr = { path = "../librustc_attr" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_feature = { path = "../librustc_feature" }
-rustc_parse = { path = "../librustc_parse" }
-rustc_session = { path = "../librustc_session" }
-rustc_span = { path = "../librustc_span" }
-rustc_ast = { path = "../librustc_ast" }
diff --git a/src/librustc_ast_pretty/Cargo.toml b/src/librustc_ast_pretty/Cargo.toml
deleted file mode 100644
index d26205c791d..00000000000
--- a/src/librustc_ast_pretty/Cargo.toml
+++ /dev/null
@@ -1,16 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_ast_pretty"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_ast_pretty"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-tracing = "0.1"
-rustc_span = { path = "../librustc_span" }
-rustc_ast = { path = "../librustc_ast" }
-rustc_target = { path = "../librustc_target" }
diff --git a/src/librustc_attr/Cargo.toml b/src/librustc_attr/Cargo.toml
deleted file mode 100644
index 35bdf747f08..00000000000
--- a/src/librustc_attr/Cargo.toml
+++ /dev/null
@@ -1,23 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_attr"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_attr"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc_ast_pretty = { path = "../librustc_ast_pretty" }
-rustc_serialize = { path = "../librustc_serialize" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_span = { path = "../librustc_span" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_feature = { path = "../librustc_feature" }
-rustc_lexer = { path = "../librustc_lexer" }
-rustc_macros = { path = "../librustc_macros" }
-rustc_session = { path = "../librustc_session" }
-rustc_ast = { path = "../librustc_ast" }
-version_check = "0.9"
diff --git a/src/librustc_builtin_macros/Cargo.toml b/src/librustc_builtin_macros/Cargo.toml
deleted file mode 100644
index dee6fed317e..00000000000
--- a/src/librustc_builtin_macros/Cargo.toml
+++ /dev/null
@@ -1,26 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_builtin_macros"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_builtin_macros"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc_parse_format = { path = "../librustc_parse_format" }
-tracing = "0.1"
-rustc_ast_pretty = { path = "../librustc_ast_pretty" }
-rustc_attr = { path = "../librustc_attr" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_feature = { path = "../librustc_feature" }
-rustc_parse = { path = "../librustc_parse" }
-rustc_target = { path = "../librustc_target" }
-rustc_session = { path = "../librustc_session" }
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
-rustc_ast = { path = "../librustc_ast" }
-rustc_expand = { path = "../librustc_expand" }
-rustc_span = { path = "../librustc_span" }
diff --git a/src/librustc_codegen_llvm/Cargo.toml b/src/librustc_codegen_llvm/Cargo.toml
deleted file mode 100644
index d8ccaf16e28..00000000000
--- a/src/librustc_codegen_llvm/Cargo.toml
+++ /dev/null
@@ -1,36 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_codegen_llvm"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_codegen_llvm"
-path = "lib.rs"
-test = false
-doctest = false
-
-[dependencies]
-bitflags = "1.0"
-libc = "0.2"
-measureme = "0.7.1"
-snap = "1"
-tracing = "0.1"
-rustc_middle = { path = "../librustc_middle" }
-rustc-demangle = "0.1"
-rustc_attr = { path = "../librustc_attr" }
-rustc_codegen_ssa = { path = "../librustc_codegen_ssa" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_feature = { path = "../librustc_feature" }
-rustc_fs_util = { path = "../librustc_fs_util" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_incremental = { path = "../librustc_incremental" }
-rustc_index = { path = "../librustc_index" }
-rustc_llvm = { path = "../librustc_llvm" }
-rustc_session = { path = "../librustc_session" }
-rustc_serialize = { path = "../librustc_serialize" }
-rustc_target = { path = "../librustc_target" }
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
-rustc_ast = { path = "../librustc_ast" }
-rustc_span = { path = "../librustc_span" }
diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml
deleted file mode 100644
index 5707d3cd0ed..00000000000
--- a/src/librustc_codegen_ssa/Cargo.toml
+++ /dev/null
@@ -1,38 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_codegen_ssa"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_codegen_ssa"
-path = "lib.rs"
-test = false
-
-[dependencies]
-bitflags = "1.2.1"
-cc = "1.0.1"
-num_cpus = "1.0"
-memmap = "0.7"
-tracing = "0.1"
-libc = "0.2.50"
-jobserver = "0.1.11"
-tempfile = "3.1"
-pathdiff = "0.2.0"
-
-rustc_serialize = { path = "../librustc_serialize" }
-rustc_ast = { path = "../librustc_ast" }
-rustc_span = { path = "../librustc_span" }
-rustc_middle = { path = "../librustc_middle" }
-rustc_apfloat = { path = "../librustc_apfloat" }
-rustc_attr = { path = "../librustc_attr" }
-rustc_symbol_mangling = { path = "../librustc_symbol_mangling" }
-rustc_data_structures = { path = "../librustc_data_structures"}
-rustc_errors = { path = "../librustc_errors" }
-rustc_fs_util = { path = "../librustc_fs_util" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_incremental = { path = "../librustc_incremental" }
-rustc_index = { path = "../librustc_index" }
-rustc_macros = { path = "../librustc_macros" }
-rustc_target = { path = "../librustc_target" }
-rustc_session = { path = "../librustc_session" }
diff --git a/src/librustc_data_structures/jobserver.rs b/src/librustc_data_structures/jobserver.rs
deleted file mode 100644
index a811c88839d..00000000000
--- a/src/librustc_data_structures/jobserver.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-pub use jobserver_crate::Client;
-use lazy_static::lazy_static;
-
-lazy_static! {
-    // We can only call `from_env` once per process
-
-    // Note that this is unsafe because it may misinterpret file descriptors
-    // on Unix as jobserver file descriptors. We hopefully execute this near
-    // the beginning of the process though to ensure we don't get false
-    // positives, or in other words we try to execute this before we open
-    // any file descriptors ourselves.
-    //
-    // Pick a "reasonable maximum" if we don't otherwise have
-    // a jobserver in our environment, capping out at 32 so we
-    // don't take everything down by hogging the process run queue.
-    // The fixed number is used to have deterministic compilation
-    // across machines.
-    //
-    // Also note that we stick this in a global because there could be
-    // multiple rustc instances in this process, and the jobserver is
-    // per-process.
-    static ref GLOBAL_CLIENT: Client = unsafe {
-        Client::from_env().unwrap_or_else(|| {
-            let client = Client::new(32).expect("failed to create jobserver");
-            // Acquire a token for the main thread which we can release later
-            client.acquire_raw().ok();
-            client
-        })
-    };
-}
-
-pub fn client() -> Client {
-    GLOBAL_CLIENT.clone()
-}
-
-pub fn acquire_thread() {
-    GLOBAL_CLIENT.acquire_raw().ok();
-}
-
-pub fn release_thread() {
-    GLOBAL_CLIENT.release_raw().ok();
-}
diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml
deleted file mode 100644
index 46331c63113..00000000000
--- a/src/librustc_driver/Cargo.toml
+++ /dev/null
@@ -1,43 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_driver"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_driver"
-path = "lib.rs"
-crate-type = ["dylib"]
-
-[dependencies]
-lazy_static = "1.0"
-libc = "0.2"
-tracing = { version = "0.1.18", features = ["release_max_level_info"]  }
-tracing-subscriber = { version = "0.2.10", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
-rustc_middle = { path = "../librustc_middle" }
-rustc_ast_pretty = { path = "../librustc_ast_pretty" }
-rustc_target = { path = "../librustc_target" }
-rustc_lint = { path = "../librustc_lint" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_feature = { path = "../librustc_feature" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_hir_pretty = { path = "../librustc_hir_pretty" }
-rustc_metadata = { path = "../librustc_metadata" }
-rustc_mir = { path = "../librustc_mir" }
-rustc_parse = { path = "../librustc_parse" }
-rustc_plugin_impl = { path = "../librustc_plugin_impl" }
-rustc_save_analysis = { path = "../librustc_save_analysis" }
-rustc_codegen_ssa = { path = "../librustc_codegen_ssa" }
-rustc_session = { path = "../librustc_session" }
-rustc_error_codes = { path = "../librustc_error_codes" }
-rustc_interface = { path = "../librustc_interface" }
-rustc_serialize = { path = "../librustc_serialize" }
-rustc_ast = { path = "../librustc_ast" }
-rustc_span = { path = "../librustc_span" }
-
-[target.'cfg(windows)'.dependencies]
-winapi = { version = "0.3", features = ["consoleapi", "debugapi", "processenv"] }
-
-[features]
-llvm = ['rustc_interface/llvm']
diff --git a/src/librustc_expand/Cargo.toml b/src/librustc_expand/Cargo.toml
deleted file mode 100644
index 55a1862971b..00000000000
--- a/src/librustc_expand/Cargo.toml
+++ /dev/null
@@ -1,28 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_expand"
-version = "0.0.0"
-edition = "2018"
-build = false
-
-[lib]
-name = "rustc_expand"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc_serialize = { path = "../librustc_serialize" }
-tracing = "0.1"
-rustc_span = { path = "../librustc_span" }
-rustc_ast_pretty = { path = "../librustc_ast_pretty" }
-rustc_ast_passes = { path = "../librustc_ast_passes" }
-rustc_attr = { path = "../librustc_attr" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_feature = { path = "../librustc_feature" }
-rustc_macros = { path = "../librustc_macros" }
-rustc_lexer = { path = "../librustc_lexer" }
-rustc_parse = { path = "../librustc_parse" }
-rustc_session = { path = "../librustc_session" }
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
-rustc_ast = { path = "../librustc_ast" }
diff --git a/src/librustc_expand/parse/lexer/tests.rs b/src/librustc_expand/parse/lexer/tests.rs
deleted file mode 100644
index 87184444283..00000000000
--- a/src/librustc_expand/parse/lexer/tests.rs
+++ /dev/null
@@ -1,252 +0,0 @@
-use rustc_ast::ast::AttrStyle;
-use rustc_ast::token::{self, CommentKind, Token, TokenKind};
-use rustc_data_structures::sync::Lrc;
-use rustc_errors::{emitter::EmitterWriter, Handler};
-use rustc_parse::lexer::StringReader;
-use rustc_session::parse::ParseSess;
-use rustc_span::source_map::{FilePathMapping, SourceMap};
-use rustc_span::symbol::Symbol;
-use rustc_span::with_default_session_globals;
-use rustc_span::{BytePos, Span};
-
-use std::io;
-use std::path::PathBuf;
-
-fn mk_sess(sm: Lrc<SourceMap>) -> ParseSess {
-    let emitter = EmitterWriter::new(
-        Box::new(io::sink()),
-        Some(sm.clone()),
-        false,
-        false,
-        false,
-        None,
-        false,
-    );
-    ParseSess::with_span_handler(Handler::with_emitter(true, None, Box::new(emitter)), sm)
-}
-
-// Creates a string reader for the given string.
-fn setup<'a>(sm: &SourceMap, sess: &'a ParseSess, teststr: String) -> StringReader<'a> {
-    let sf = sm.new_source_file(PathBuf::from(teststr.clone()).into(), teststr);
-    StringReader::new(sess, sf, None)
-}
-
-#[test]
-fn t1() {
-    with_default_session_globals(|| {
-        let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-        let sh = mk_sess(sm.clone());
-        let mut string_reader = setup(
-            &sm,
-            &sh,
-            "/* my source file */ fn main() { println!(\"zebra\"); }\n".to_string(),
-        );
-        assert_eq!(string_reader.next_token(), token::Comment);
-        assert_eq!(string_reader.next_token(), token::Whitespace);
-        let tok1 = string_reader.next_token();
-        let tok2 = Token::new(mk_ident("fn"), Span::with_root_ctxt(BytePos(21), BytePos(23)));
-        assert_eq!(tok1.kind, tok2.kind);
-        assert_eq!(tok1.span, tok2.span);
-        assert_eq!(string_reader.next_token(), token::Whitespace);
-        // Read another token.
-        let tok3 = string_reader.next_token();
-        assert_eq!(string_reader.pos(), BytePos(28));
-        let tok4 = Token::new(mk_ident("main"), Span::with_root_ctxt(BytePos(24), BytePos(28)));
-        assert_eq!(tok3.kind, tok4.kind);
-        assert_eq!(tok3.span, tok4.span);
-
-        assert_eq!(string_reader.next_token(), token::OpenDelim(token::Paren));
-        assert_eq!(string_reader.pos(), BytePos(29))
-    })
-}
-
-// Checks that the given reader produces the desired stream
-// of tokens (stop checking after exhausting `expected`).
-fn check_tokenization(mut string_reader: StringReader<'_>, expected: Vec<TokenKind>) {
-    for expected_tok in &expected {
-        assert_eq!(&string_reader.next_token(), expected_tok);
-    }
-}
-
-// Makes the identifier by looking up the string in the interner.
-fn mk_ident(id: &str) -> TokenKind {
-    token::Ident(Symbol::intern(id), false)
-}
-
-fn mk_lit(kind: token::LitKind, symbol: &str, suffix: Option<&str>) -> TokenKind {
-    TokenKind::lit(kind, Symbol::intern(symbol), suffix.map(Symbol::intern))
-}
-
-#[test]
-fn doublecolon_parsing() {
-    with_default_session_globals(|| {
-        let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-        let sh = mk_sess(sm.clone());
-        check_tokenization(
-            setup(&sm, &sh, "a b".to_string()),
-            vec![mk_ident("a"), token::Whitespace, mk_ident("b")],
-        );
-    })
-}
-
-#[test]
-fn doublecolon_parsing_2() {
-    with_default_session_globals(|| {
-        let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-        let sh = mk_sess(sm.clone());
-        check_tokenization(
-            setup(&sm, &sh, "a::b".to_string()),
-            vec![mk_ident("a"), token::Colon, token::Colon, mk_ident("b")],
-        );
-    })
-}
-
-#[test]
-fn doublecolon_parsing_3() {
-    with_default_session_globals(|| {
-        let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-        let sh = mk_sess(sm.clone());
-        check_tokenization(
-            setup(&sm, &sh, "a ::b".to_string()),
-            vec![mk_ident("a"), token::Whitespace, token::Colon, token::Colon, mk_ident("b")],
-        );
-    })
-}
-
-#[test]
-fn doublecolon_parsing_4() {
-    with_default_session_globals(|| {
-        let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-        let sh = mk_sess(sm.clone());
-        check_tokenization(
-            setup(&sm, &sh, "a:: b".to_string()),
-            vec![mk_ident("a"), token::Colon, token::Colon, token::Whitespace, mk_ident("b")],
-        );
-    })
-}
-
-#[test]
-fn character_a() {
-    with_default_session_globals(|| {
-        let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-        let sh = mk_sess(sm.clone());
-        assert_eq!(setup(&sm, &sh, "'a'".to_string()).next_token(), mk_lit(token::Char, "a", None),);
-    })
-}
-
-#[test]
-fn character_space() {
-    with_default_session_globals(|| {
-        let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-        let sh = mk_sess(sm.clone());
-        assert_eq!(setup(&sm, &sh, "' '".to_string()).next_token(), mk_lit(token::Char, " ", None),);
-    })
-}
-
-#[test]
-fn character_escaped() {
-    with_default_session_globals(|| {
-        let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-        let sh = mk_sess(sm.clone());
-        assert_eq!(
-            setup(&sm, &sh, "'\\n'".to_string()).next_token(),
-            mk_lit(token::Char, "\\n", None),
-        );
-    })
-}
-
-#[test]
-fn lifetime_name() {
-    with_default_session_globals(|| {
-        let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-        let sh = mk_sess(sm.clone());
-        assert_eq!(
-            setup(&sm, &sh, "'abc".to_string()).next_token(),
-            token::Lifetime(Symbol::intern("'abc")),
-        );
-    })
-}
-
-#[test]
-fn raw_string() {
-    with_default_session_globals(|| {
-        let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-        let sh = mk_sess(sm.clone());
-        assert_eq!(
-            setup(&sm, &sh, "r###\"\"#a\\b\x00c\"\"###".to_string()).next_token(),
-            mk_lit(token::StrRaw(3), "\"#a\\b\x00c\"", None),
-        );
-    })
-}
-
-#[test]
-fn literal_suffixes() {
-    with_default_session_globals(|| {
-        let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-        let sh = mk_sess(sm.clone());
-        macro_rules! test {
-            ($input: expr, $tok_type: ident, $tok_contents: expr) => {{
-                assert_eq!(
-                    setup(&sm, &sh, format!("{}suffix", $input)).next_token(),
-                    mk_lit(token::$tok_type, $tok_contents, Some("suffix")),
-                );
-                // with a whitespace separator
-                assert_eq!(
-                    setup(&sm, &sh, format!("{} suffix", $input)).next_token(),
-                    mk_lit(token::$tok_type, $tok_contents, None),
-                );
-            }};
-        }
-
-        test!("'a'", Char, "a");
-        test!("b'a'", Byte, "a");
-        test!("\"a\"", Str, "a");
-        test!("b\"a\"", ByteStr, "a");
-        test!("1234", Integer, "1234");
-        test!("0b101", Integer, "0b101");
-        test!("0xABC", Integer, "0xABC");
-        test!("1.0", Float, "1.0");
-        test!("1.0e10", Float, "1.0e10");
-
-        assert_eq!(
-            setup(&sm, &sh, "2us".to_string()).next_token(),
-            mk_lit(token::Integer, "2", Some("us")),
-        );
-        assert_eq!(
-            setup(&sm, &sh, "r###\"raw\"###suffix".to_string()).next_token(),
-            mk_lit(token::StrRaw(3), "raw", Some("suffix")),
-        );
-        assert_eq!(
-            setup(&sm, &sh, "br###\"raw\"###suffix".to_string()).next_token(),
-            mk_lit(token::ByteStrRaw(3), "raw", Some("suffix")),
-        );
-    })
-}
-
-#[test]
-fn nested_block_comments() {
-    with_default_session_globals(|| {
-        let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-        let sh = mk_sess(sm.clone());
-        let mut lexer = setup(&sm, &sh, "/* /* */ */'a'".to_string());
-        assert_eq!(lexer.next_token(), token::Comment);
-        assert_eq!(lexer.next_token(), mk_lit(token::Char, "a", None));
-    })
-}
-
-#[test]
-fn crlf_comments() {
-    with_default_session_globals(|| {
-        let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-        let sh = mk_sess(sm.clone());
-        let mut lexer = setup(&sm, &sh, "// test\r\n/// test\r\n".to_string());
-        let comment = lexer.next_token();
-        assert_eq!(comment.kind, token::Comment);
-        assert_eq!((comment.span.lo(), comment.span.hi()), (BytePos(0), BytePos(7)));
-        assert_eq!(lexer.next_token(), token::Whitespace);
-        assert_eq!(
-            lexer.next_token(),
-            token::DocComment(CommentKind::Line, AttrStyle::Outer, Symbol::intern(" test"))
-        );
-    })
-}
diff --git a/src/librustc_feature/Cargo.toml b/src/librustc_feature/Cargo.toml
deleted file mode 100644
index 96fd15ef304..00000000000
--- a/src/librustc_feature/Cargo.toml
+++ /dev/null
@@ -1,15 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_feature"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_feature"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc_data_structures = { path = "../librustc_data_structures" }
-lazy_static = "1.0.0"
-rustc_span = { path = "../librustc_span" }
diff --git a/src/librustc_hir/Cargo.toml b/src/librustc_hir/Cargo.toml
deleted file mode 100644
index a473a8edcdd..00000000000
--- a/src/librustc_hir/Cargo.toml
+++ /dev/null
@@ -1,22 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_hir"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_hir"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc_target = { path = "../librustc_target" }
-rustc_macros = { path = "../librustc_macros" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_index = { path = "../librustc_index" }
-rustc_span = { path = "../librustc_span" }
-rustc_serialize = { path = "../librustc_serialize" }
-rustc_ast = { path = "../librustc_ast" }
-lazy_static = "1"
-tracing = "0.1"
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_hir_pretty/Cargo.toml b/src/librustc_hir_pretty/Cargo.toml
deleted file mode 100644
index ccd3e9b6e43..00000000000
--- a/src/librustc_hir_pretty/Cargo.toml
+++ /dev/null
@@ -1,17 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_hir_pretty"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_hir_pretty"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc_ast_pretty = { path = "../librustc_ast_pretty" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_target = { path = "../librustc_target" }
-rustc_span = { path = "../librustc_span" }
-rustc_ast = { path = "../librustc_ast" }
diff --git a/src/librustc_incremental/Cargo.toml b/src/librustc_incremental/Cargo.toml
deleted file mode 100644
index 1f7e3725412..00000000000
--- a/src/librustc_incremental/Cargo.toml
+++ /dev/null
@@ -1,24 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_incremental"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_incremental"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc_graphviz = { path = "../librustc_graphviz" }
-tracing = "0.1"
-rand = "0.7"
-rustc_middle = { path = "../librustc_middle" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_serialize = { path = "../librustc_serialize" }
-rustc_ast = { path = "../librustc_ast" }
-rustc_macros = { path = "../librustc_macros" }
-rustc_span = { path = "../librustc_span" }
-rustc_fs_util = { path = "../librustc_fs_util" }
-rustc_session = { path = "../librustc_session" }
diff --git a/src/librustc_infer/Cargo.toml b/src/librustc_infer/Cargo.toml
deleted file mode 100644
index e1698d66323..00000000000
--- a/src/librustc_infer/Cargo.toml
+++ /dev/null
@@ -1,26 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_infer"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_infer"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc_graphviz = { path = "../librustc_graphviz" }
-tracing = "0.1"
-rustc_middle = { path = "../librustc_middle" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_index = { path = "../librustc_index" }
-rustc_macros = { path = "../librustc_macros" }
-rustc_session = { path = "../librustc_session" }
-rustc_serialize = { path = "../librustc_serialize" }
-rustc_span = { path = "../librustc_span" }
-rustc_target = { path = "../librustc_target" }
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
-rustc_ast = { path = "../librustc_ast" }
diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml
deleted file mode 100644
index b9837c6ade9..00000000000
--- a/src/librustc_interface/Cargo.toml
+++ /dev/null
@@ -1,57 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_interface"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_interface"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-libc = "0.2"
-tracing = "0.1"
-rayon = { version = "0.3.0", package = "rustc-rayon" }
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
-rustc_ast = { path = "../librustc_ast" }
-rustc_attr = { path = "../librustc_attr" }
-rustc_builtin_macros = { path = "../librustc_builtin_macros" }
-rustc_expand = { path = "../librustc_expand" }
-rustc_parse = { path = "../librustc_parse" }
-rustc_session = { path = "../librustc_session" }
-rustc_span = { path = "../librustc_span" }
-rustc_serialize = { path = "../librustc_serialize" }
-rustc_middle = { path = "../librustc_middle" }
-rustc_ast_lowering = { path = "../librustc_ast_lowering" }
-rustc_ast_passes = { path = "../librustc_ast_passes" }
-rustc_incremental = { path = "../librustc_incremental" }
-rustc_traits = { path = "../librustc_traits" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_codegen_ssa = { path = "../librustc_codegen_ssa" }
-rustc_symbol_mangling = { path = "../librustc_symbol_mangling" }
-rustc_codegen_llvm = { path = "../librustc_codegen_llvm", optional = true }
-rustc_hir = { path = "../librustc_hir" }
-rustc_metadata = { path = "../librustc_metadata" }
-rustc_mir = { path = "../librustc_mir" }
-rustc_mir_build = { path = "../librustc_mir_build" }
-rustc_passes = { path = "../librustc_passes" }
-rustc_typeck = { path = "../librustc_typeck" }
-rustc_lint = { path = "../librustc_lint" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_plugin_impl = { path = "../librustc_plugin_impl" }
-rustc_privacy = { path = "../librustc_privacy" }
-rustc_resolve = { path = "../librustc_resolve" }
-rustc_trait_selection = { path = "../librustc_trait_selection" }
-rustc_ty = { path = "../librustc_ty" }
-tempfile = "3.0.5"
-once_cell = "1"
-
-[target.'cfg(windows)'.dependencies]
-winapi = { version = "0.3", features = ["libloaderapi"] }
-
-[dev-dependencies]
-rustc_target = { path = "../librustc_target" }
-
-[features]
-llvm = ['rustc_codegen_llvm']
diff --git a/src/librustc_lexer/src/tests.rs b/src/librustc_lexer/src/tests.rs
deleted file mode 100644
index a1ea5ceb1f6..00000000000
--- a/src/librustc_lexer/src/tests.rs
+++ /dev/null
@@ -1,167 +0,0 @@
-use super::*;
-
-use expect_test::{expect, Expect};
-
-fn check_raw_str(s: &str, expected_hashes: u16, expected_err: Option<RawStrError>) {
-    let s = &format!("r{}", s);
-    let mut cursor = Cursor::new(s);
-    cursor.bump();
-    let (n_hashes, err) = cursor.raw_double_quoted_string(0);
-    assert_eq!(n_hashes, expected_hashes);
-    assert_eq!(err, expected_err);
-}
-
-#[test]
-fn test_naked_raw_str() {
-    check_raw_str(r#""abc""#, 0, None);
-}
-
-#[test]
-fn test_raw_no_start() {
-    check_raw_str(r##""abc"#"##, 0, None);
-}
-
-#[test]
-fn test_too_many_terminators() {
-    // this error is handled in the parser later
-    check_raw_str(r###"#"abc"##"###, 1, None);
-}
-
-#[test]
-fn test_unterminated() {
-    check_raw_str(
-        r#"#"abc"#,
-        1,
-        Some(RawStrError::NoTerminator { expected: 1, found: 0, possible_terminator_offset: None }),
-    );
-    check_raw_str(
-        r###"##"abc"#"###,
-        2,
-        Some(RawStrError::NoTerminator {
-            expected: 2,
-            found: 1,
-            possible_terminator_offset: Some(7),
-        }),
-    );
-    // We're looking for "# not just any #
-    check_raw_str(
-        r###"##"abc#"###,
-        2,
-        Some(RawStrError::NoTerminator { expected: 2, found: 0, possible_terminator_offset: None }),
-    )
-}
-
-#[test]
-fn test_invalid_start() {
-    check_raw_str(r##"#~"abc"#"##, 1, Some(RawStrError::InvalidStarter { bad_char: '~' }));
-}
-
-#[test]
-fn test_unterminated_no_pound() {
-    // https://github.com/rust-lang/rust/issues/70677
-    check_raw_str(
-        r#"""#,
-        0,
-        Some(RawStrError::NoTerminator { expected: 0, found: 0, possible_terminator_offset: None }),
-    );
-}
-
-#[test]
-fn test_valid_shebang() {
-    // https://github.com/rust-lang/rust/issues/70528
-    let input = "#!/usr/bin/rustrun\nlet x = 5;";
-    assert_eq!(strip_shebang(input), Some(18));
-}
-
-#[test]
-fn test_invalid_shebang_valid_rust_syntax() {
-    // https://github.com/rust-lang/rust/issues/70528
-    let input = "#!    [bad_attribute]";
-    assert_eq!(strip_shebang(input), None);
-}
-
-#[test]
-fn test_shebang_second_line() {
-    // Because shebangs are interpreted by the kernel, they must be on the first line
-    let input = "\n#!/bin/bash";
-    assert_eq!(strip_shebang(input), None);
-}
-
-#[test]
-fn test_shebang_space() {
-    let input = "#!    /bin/bash";
-    assert_eq!(strip_shebang(input), Some(input.len()));
-}
-
-#[test]
-fn test_shebang_empty_shebang() {
-    let input = "#!    \n[attribute(foo)]";
-    assert_eq!(strip_shebang(input), None);
-}
-
-#[test]
-fn test_invalid_shebang_comment() {
-    let input = "#!//bin/ami/a/comment\n[";
-    assert_eq!(strip_shebang(input), None)
-}
-
-#[test]
-fn test_invalid_shebang_another_comment() {
-    let input = "#!/*bin/ami/a/comment*/\n[attribute";
-    assert_eq!(strip_shebang(input), None)
-}
-
-#[test]
-fn test_shebang_valid_rust_after() {
-    let input = "#!/*bin/ami/a/comment*/\npub fn main() {}";
-    assert_eq!(strip_shebang(input), Some(23))
-}
-
-#[test]
-fn test_shebang_followed_by_attrib() {
-    let input = "#!/bin/rust-scripts\n#![allow_unused(true)]";
-    assert_eq!(strip_shebang(input), Some(19));
-}
-
-fn check_lexing(src: &str, expect: Expect) {
-    let actual: String = tokenize(src).map(|token| format!("{:?}\n", token)).collect();
-    expect.assert_eq(&actual)
-}
-
-#[test]
-fn comment_flavors() {
-    check_lexing(
-        r"
-// line
-//// line as well
-/// outer doc line
-//! inner doc line
-/* block */
-/**/
-/*** also block */
-/** outer doc block */
-/*! inner doc block */
-",
-        expect![[r#"
-                Token { kind: Whitespace, len: 1 }
-                Token { kind: LineComment { doc_style: None }, len: 7 }
-                Token { kind: Whitespace, len: 1 }
-                Token { kind: LineComment { doc_style: None }, len: 17 }
-                Token { kind: Whitespace, len: 1 }
-                Token { kind: LineComment { doc_style: Some(Outer) }, len: 18 }
-                Token { kind: Whitespace, len: 1 }
-                Token { kind: LineComment { doc_style: Some(Inner) }, len: 18 }
-                Token { kind: Whitespace, len: 1 }
-                Token { kind: BlockComment { doc_style: None, terminated: true }, len: 11 }
-                Token { kind: Whitespace, len: 1 }
-                Token { kind: BlockComment { doc_style: None, terminated: true }, len: 4 }
-                Token { kind: Whitespace, len: 1 }
-                Token { kind: BlockComment { doc_style: None, terminated: true }, len: 18 }
-                Token { kind: Whitespace, len: 1 }
-                Token { kind: BlockComment { doc_style: Some(Outer), terminated: true }, len: 22 }
-                Token { kind: Whitespace, len: 1 }
-                Token { kind: BlockComment { doc_style: Some(Inner), terminated: true }, len: 22 }
-                Token { kind: Whitespace, len: 1 }
-            "#]],
-    )
-}
diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml
deleted file mode 100644
index d779f15f19a..00000000000
--- a/src/librustc_lint/Cargo.toml
+++ /dev/null
@@ -1,26 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_lint"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_lint"
-path = "lib.rs"
-
-[dependencies]
-tracing = "0.1"
-unicode-security = "0.0.5"
-rustc_middle = { path = "../librustc_middle" }
-rustc_ast_pretty = { path = "../librustc_ast_pretty" }
-rustc_attr = { path = "../librustc_attr" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_target = { path = "../librustc_target" }
-rustc_ast = { path = "../librustc_ast" }
-rustc_span = { path = "../librustc_span" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_feature = { path = "../librustc_feature" }
-rustc_index = { path = "../librustc_index" }
-rustc_session = { path = "../librustc_session" }
-rustc_trait_selection = { path = "../librustc_trait_selection" }
diff --git a/src/librustc_llvm/Cargo.toml b/src/librustc_llvm/Cargo.toml
index 9f2711eec10..7120f2e991a 100644
--- a/src/librustc_llvm/Cargo.toml
+++ b/src/librustc_llvm/Cargo.toml
@@ -5,7 +5,6 @@ version = "0.0.0"
 edition = "2018"
 
 [lib]
-name = "rustc_llvm"
 path = "lib.rs"
 
 [features]
diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml
deleted file mode 100644
index 76e11bd689c..00000000000
--- a/src/librustc_metadata/Cargo.toml
+++ /dev/null
@@ -1,35 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_metadata"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_metadata"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-libc = "0.2"
-snap = "1"
-tracing = "0.1"
-memmap = "0.7"
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
-rustc_middle = { path = "../librustc_middle" }
-rustc_attr = { path = "../librustc_attr" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_hir_pretty = { path = "../librustc_hir_pretty" }
-rustc_target = { path = "../librustc_target" }
-rustc_index = { path = "../librustc_index" }
-rustc_macros = { path = "../librustc_macros" }
-rustc_serialize = { path = "../librustc_serialize" }
-stable_deref_trait = "1.0.0"
-rustc_ast = { path = "../librustc_ast" }
-rustc_expand = { path = "../librustc_expand" }
-rustc_span = { path = "../librustc_span" }
-rustc_session = { path = "../librustc_session" }
-
-[target.'cfg(windows)'.dependencies]
-winapi = { version = "0.3", features = ["errhandlingapi", "libloaderapi"] }
diff --git a/src/librustc_middle/Cargo.toml b/src/librustc_middle/Cargo.toml
deleted file mode 100644
index 311126361bc..00000000000
--- a/src/librustc_middle/Cargo.toml
+++ /dev/null
@@ -1,35 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_middle"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_middle"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc_arena = { path = "../librustc_arena" }
-bitflags = "1.2.1"
-tracing = "0.1"
-rustc-rayon-core = "0.3.0"
-polonius-engine = "0.12.0"
-rustc_apfloat = { path = "../librustc_apfloat" }
-rustc_attr = { path = "../librustc_attr" }
-rustc_feature = { path = "../librustc_feature" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_target = { path = "../librustc_target" }
-rustc_macros = { path = "../librustc_macros" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_query_system = { path = "../librustc_query_system" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_index = { path = "../librustc_index" }
-rustc_serialize = { path = "../librustc_serialize" }
-rustc_ast = { path = "../librustc_ast" }
-rustc_span = { path = "../librustc_span" }
-byteorder = { version = "1.3" }
-chalk-ir = "0.14.0"
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
-measureme = "0.7.1"
-rustc_session = { path = "../librustc_session" }
diff --git a/src/librustc_middle/ty/print/obsolete.rs b/src/librustc_middle/ty/print/obsolete.rs
deleted file mode 100644
index 2ea7cd2a6dc..00000000000
--- a/src/librustc_middle/ty/print/obsolete.rs
+++ /dev/null
@@ -1,251 +0,0 @@
-//! Allows for producing a unique string key for a mono item.
-//! These keys are used by the handwritten auto-tests, so they need to be
-//! predictable and human-readable.
-//!
-//! 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 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;
-use std::iter;
-
-/// Same as `unique_type_name()` but with the result pushed onto the given
-/// `output` parameter.
-pub struct DefPathBasedNames<'tcx> {
-    tcx: TyCtxt<'tcx>,
-    omit_disambiguators: bool,
-    omit_local_crate_name: bool,
-}
-
-impl DefPathBasedNames<'tcx> {
-    pub fn new(tcx: TyCtxt<'tcx>, omit_disambiguators: bool, omit_local_crate_name: bool) -> Self {
-        DefPathBasedNames { tcx, omit_disambiguators, omit_local_crate_name }
-    }
-
-    // Pushes the type name of the specified type to the provided string.
-    // If `debug` is true, printing normally unprintable types is allowed
-    // (e.g. `ty::GeneratorWitness`). This parameter should only be set when
-    // this method is being used for logging purposes (e.g. with `debug!` or `info!`)
-    // When being used for codegen purposes, `debug` should be set to `false`
-    // in order to catch unexpected types that should never end up in a type name.
-    pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) {
-        match t.kind {
-            ty::Bool => output.push_str("bool"),
-            ty::Char => output.push_str("char"),
-            ty::Str => output.push_str("str"),
-            ty::Never => output.push_str("!"),
-            ty::Int(ty) => output.push_str(ty.name_str()),
-            ty::Uint(ty) => output.push_str(ty.name_str()),
-            ty::Float(ty) => output.push_str(ty.name_str()),
-            ty::Adt(adt_def, substs) => {
-                self.push_def_path(adt_def.did, output);
-                self.push_generic_params(substs, iter::empty(), output, debug);
-            }
-            ty::Tuple(component_types) => {
-                output.push('(');
-                for component_type in component_types {
-                    self.push_type_name(component_type.expect_ty(), output, debug);
-                    output.push_str(", ");
-                }
-                if !component_types.is_empty() {
-                    output.pop();
-                    output.pop();
-                }
-                output.push(')');
-            }
-            ty::RawPtr(ty::TypeAndMut { ty: inner_type, mutbl }) => {
-                output.push('*');
-                match mutbl {
-                    hir::Mutability::Not => output.push_str("const "),
-                    hir::Mutability::Mut => output.push_str("mut "),
-                }
-
-                self.push_type_name(inner_type, output, debug);
-            }
-            ty::Ref(_, inner_type, mutbl) => {
-                output.push('&');
-                output.push_str(mutbl.prefix_str());
-
-                self.push_type_name(inner_type, output, debug);
-            }
-            ty::Array(inner_type, len) => {
-                output.push('[');
-                self.push_type_name(inner_type, output, debug);
-                let len = len.eval_usize(self.tcx, ty::ParamEnv::reveal_all());
-                write!(output, "; {}", len).unwrap();
-                output.push(']');
-            }
-            ty::Slice(inner_type) => {
-                output.push('[');
-                self.push_type_name(inner_type, output, debug);
-                output.push(']');
-            }
-            ty::Dynamic(ref trait_data, ..) => {
-                if let Some(principal) = trait_data.principal() {
-                    self.push_def_path(principal.def_id(), output);
-                    self.push_generic_params(
-                        principal.skip_binder().substs,
-                        trait_data.projection_bounds(),
-                        output,
-                        debug,
-                    );
-                } else {
-                    output.push_str("dyn '_");
-                }
-            }
-            ty::Foreign(did) => self.push_def_path(did, output),
-            ty::FnDef(..) | ty::FnPtr(_) => {
-                let sig = t.fn_sig(self.tcx);
-                output.push_str(sig.unsafety().prefix_str());
-
-                let abi = sig.abi();
-                if abi != ::rustc_target::spec::abi::Abi::Rust {
-                    output.push_str("extern \"");
-                    output.push_str(abi.name());
-                    output.push_str("\" ");
-                }
-
-                output.push_str("fn(");
-
-                let sig =
-                    self.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
-
-                if !sig.inputs().is_empty() {
-                    for &parameter_type in sig.inputs() {
-                        self.push_type_name(parameter_type, output, debug);
-                        output.push_str(", ");
-                    }
-                    output.pop();
-                    output.pop();
-                }
-
-                if sig.c_variadic {
-                    if !sig.inputs().is_empty() {
-                        output.push_str(", ...");
-                    } else {
-                        output.push_str("...");
-                    }
-                }
-
-                output.push(')');
-
-                if !sig.output().is_unit() {
-                    output.push_str(" -> ");
-                    self.push_type_name(sig.output(), output, debug);
-                }
-            }
-            ty::Generator(def_id, substs, _) | ty::Closure(def_id, substs) => {
-                self.push_def_path(def_id, output);
-                let generics = self.tcx.generics_of(self.tcx.closure_base_def_id(def_id));
-                let substs = substs.truncate_to(self.tcx, generics);
-                self.push_generic_params(substs, iter::empty(), output, debug);
-            }
-            ty::Param(_) => {
-                output.push_str(&t.to_string());
-            }
-            ty::Error(_)
-            | ty::Bound(..)
-            | ty::Infer(_)
-            | ty::Placeholder(..)
-            | ty::Projection(..)
-            | ty::GeneratorWitness(_)
-            | ty::Opaque(..) => {
-                if debug {
-                    output.push_str(&format!("`{:?}`", t));
-                } else {
-                    bug!(
-                        "DefPathBasedNames: trying to create type name for unexpected type: {:?}",
-                        t,
-                    );
-                }
-            }
-        }
-    }
-
-    // Pushes the the name of the specified const to the provided string.
-    // If `debug` is true, the unprintable types of constants will be printed with `fmt::Debug`
-    // (see `push_type_name` for more details).
-    pub fn push_const_name(&self, ct: &Const<'tcx>, output: &mut String, debug: bool) {
-        write!(output, "{}", ct).unwrap();
-        output.push_str(": ");
-        self.push_type_name(ct.ty, output, debug);
-    }
-
-    pub fn push_def_path(&self, def_id: DefId, output: &mut String) {
-        let def_path = self.tcx.def_path(def_id);
-
-        // some_crate::
-        if !(self.omit_local_crate_name && def_id.is_local()) {
-            output.push_str(&self.tcx.crate_name(def_path.krate).as_str());
-            output.push_str("::");
-        }
-
-        // foo::bar::ItemName::
-        for part in self.tcx.def_path(def_id).data {
-            if self.omit_disambiguators {
-                write!(output, "{}::", part.data.as_symbol()).unwrap();
-            } else {
-                write!(output, "{}[{}]::", part.data.as_symbol(), part.disambiguator).unwrap();
-            }
-        }
-
-        // remove final "::"
-        output.pop();
-        output.pop();
-    }
-
-    fn push_generic_params<I>(
-        &self,
-        substs: SubstsRef<'tcx>,
-        projections: I,
-        output: &mut String,
-        debug: bool,
-    ) where
-        I: Iterator<Item = ty::PolyExistentialProjection<'tcx>>,
-    {
-        let mut projections = projections.peekable();
-        if substs.non_erasable_generics().next().is_none() && projections.peek().is_none() {
-            return;
-        }
-
-        output.push('<');
-
-        for type_parameter in substs.types() {
-            self.push_type_name(type_parameter, output, debug);
-            output.push_str(", ");
-        }
-
-        for projection in projections {
-            let projection = projection.skip_binder();
-            let name = &self.tcx.associated_item(projection.item_def_id).ident.as_str();
-            output.push_str(name);
-            output.push_str("=");
-            self.push_type_name(projection.ty, output, debug);
-            output.push_str(", ");
-        }
-
-        for const_parameter in substs.consts() {
-            self.push_const_name(const_parameter, output, debug);
-            output.push_str(", ");
-        }
-
-        output.pop();
-        output.pop();
-
-        output.push('>');
-    }
-
-    pub fn push_instance_as_string(
-        &self,
-        instance: Instance<'tcx>,
-        output: &mut String,
-        debug: bool,
-    ) {
-        self.push_def_path(instance.def_id(), output);
-        self.push_generic_params(instance.substs, iter::empty(), output, debug);
-    }
-}
diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml
deleted file mode 100644
index 2693d29e41c..00000000000
--- a/src/librustc_mir/Cargo.toml
+++ /dev/null
@@ -1,35 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_mir"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_mir"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-either = "1.5.0"
-rustc_graphviz = { path = "../librustc_graphviz" }
-itertools = "0.8"
-tracing = "0.1"
-log_settings = "0.1.1"
-polonius-engine = "0.12.0"
-rustc_middle = { path = "../librustc_middle" }
-rustc_attr = { path = "../librustc_attr" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_index = { path = "../librustc_index" }
-rustc_infer = { path = "../librustc_infer" }
-rustc_lexer = { path = "../librustc_lexer" }
-rustc_macros = { path = "../librustc_macros" }
-rustc_serialize = { path = "../librustc_serialize" }
-rustc_session = { path = "../librustc_session" }
-rustc_target = { path = "../librustc_target" }
-rustc_trait_selection = { path = "../librustc_trait_selection" }
-rustc_ast = { path = "../librustc_ast" }
-rustc_span = { path = "../librustc_span" }
-rustc_apfloat = { path = "../librustc_apfloat" }
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_mir_build/Cargo.toml b/src/librustc_mir_build/Cargo.toml
deleted file mode 100644
index 97621f205fb..00000000000
--- a/src/librustc_mir_build/Cargo.toml
+++ /dev/null
@@ -1,29 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_mir_build"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_mir_build"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc_arena = { path = "../librustc_arena" }
-tracing = "0.1"
-rustc_middle = { path = "../librustc_middle" }
-rustc_apfloat = { path = "../librustc_apfloat" }
-rustc_attr = { path = "../librustc_attr" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_index = { path = "../librustc_index" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_infer = { path = "../librustc_infer" }
-rustc_serialize = { path = "../librustc_serialize" }
-rustc_session = { path = "../librustc_session" }
-rustc_span = { path = "../librustc_span" }
-rustc_target = { path = "../librustc_target" }
-rustc_trait_selection = { path = "../librustc_trait_selection" }
-rustc_ast = { path = "../librustc_ast" }
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_parse/Cargo.toml b/src/librustc_parse/Cargo.toml
deleted file mode 100644
index 31d858849af..00000000000
--- a/src/librustc_parse/Cargo.toml
+++ /dev/null
@@ -1,24 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_parse"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_parse"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-bitflags = "1.0"
-tracing = "0.1"
-rustc_ast_pretty = { path = "../librustc_ast_pretty" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_feature = { path = "../librustc_feature" }
-rustc_lexer = { path = "../librustc_lexer" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_session = { path = "../librustc_session" }
-rustc_span = { path = "../librustc_span" }
-rustc_ast = { path = "../librustc_ast" }
-unicode-normalization = "0.1.11"
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_parse_format/Cargo.toml b/src/librustc_parse_format/Cargo.toml
deleted file mode 100644
index 646509569f3..00000000000
--- a/src/librustc_parse_format/Cargo.toml
+++ /dev/null
@@ -1,13 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_parse_format"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_parse_format"
-path = "lib.rs"
-
-[dependencies]
-rustc_span = { path = "../librustc_span" }
-rustc_lexer = { path = "../librustc_lexer" }
diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml
deleted file mode 100644
index db481c0d0d4..00000000000
--- a/src/librustc_passes/Cargo.toml
+++ /dev/null
@@ -1,23 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_passes"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_passes"
-path = "lib.rs"
-
-[dependencies]
-tracing = "0.1"
-rustc_middle = { path = "../librustc_middle" }
-rustc_attr = { path = "../librustc_attr" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_index = { path = "../librustc_index" }
-rustc_session = { path = "../librustc_session" }
-rustc_target = { path = "../librustc_target" }
-rustc_ast = { path = "../librustc_ast" }
-rustc_span = { path = "../librustc_span" }
-rustc_trait_selection = { path = "../librustc_trait_selection" }
diff --git a/src/librustc_plugin_impl/Cargo.toml b/src/librustc_plugin_impl/Cargo.toml
deleted file mode 100644
index 38cfbd48de2..00000000000
--- a/src/librustc_plugin_impl/Cargo.toml
+++ /dev/null
@@ -1,21 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_plugin_impl"
-version = "0.0.0"
-build = false
-edition = "2018"
-
-[lib]
-name = "rustc_plugin_impl"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc_middle = { path = "../librustc_middle" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_lint = { path = "../librustc_lint" }
-rustc_metadata = { path = "../librustc_metadata" }
-rustc_ast = { path = "../librustc_ast" }
-rustc_session = { path = "../librustc_session" }
-rustc_span = { path = "../librustc_span" }
diff --git a/src/librustc_privacy/Cargo.toml b/src/librustc_privacy/Cargo.toml
deleted file mode 100644
index 3641f0f8a31..00000000000
--- a/src/librustc_privacy/Cargo.toml
+++ /dev/null
@@ -1,20 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_privacy"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_privacy"
-path = "lib.rs"
-
-[dependencies]
-rustc_middle = { path = "../librustc_middle" }
-rustc_attr = { path = "../librustc_attr" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_typeck = { path = "../librustc_typeck" }
-rustc_session = { path = "../librustc_session" }
-rustc_span = { path = "../librustc_span" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-tracing = "0.1"
diff --git a/src/librustc_query_system/Cargo.toml b/src/librustc_query_system/Cargo.toml
deleted file mode 100644
index 1e89d379cb7..00000000000
--- a/src/librustc_query_system/Cargo.toml
+++ /dev/null
@@ -1,23 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_query_system"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_query_system"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc_arena = { path = "../librustc_arena" }
-tracing = "0.1"
-rustc-rayon-core = "0.3.0"
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_macros = { path = "../librustc_macros" }
-rustc_index = { path = "../librustc_index" }
-rustc_serialize = { path = "../librustc_serialize" }
-rustc_span = { path = "../librustc_span" }
-parking_lot = "0.10"
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml
deleted file mode 100644
index e5260866f29..00000000000
--- a/src/librustc_resolve/Cargo.toml
+++ /dev/null
@@ -1,31 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_resolve"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_resolve"
-path = "lib.rs"
-test = false
-doctest = false
-
-[dependencies]
-bitflags = "1.2.1"
-tracing = "0.1"
-rustc_ast = { path = "../librustc_ast" }
-rustc_arena = { path = "../librustc_arena" }
-rustc_middle = { path = "../librustc_middle" }
-rustc_ast_lowering = { path = "../librustc_ast_lowering" }
-rustc_ast_pretty = { path = "../librustc_ast_pretty" }
-rustc_attr = { path = "../librustc_attr" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_expand = { path = "../librustc_expand" }
-rustc_feature = { path = "../librustc_feature" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_index = { path = "../librustc_index" }
-rustc_metadata = { path = "../librustc_metadata" }
-rustc_session = { path = "../librustc_session" }
-rustc_span = { path = "../librustc_span" }
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_save_analysis/Cargo.toml b/src/librustc_save_analysis/Cargo.toml
deleted file mode 100644
index 979a8da2a9f..00000000000
--- a/src/librustc_save_analysis/Cargo.toml
+++ /dev/null
@@ -1,24 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_save_analysis"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_save_analysis"
-path = "lib.rs"
-
-[dependencies]
-tracing = "0.1"
-rustc_middle = { path = "../librustc_middle" }
-rustc_ast = { path = "../librustc_ast" }
-rustc_ast_pretty = { path = "../librustc_ast_pretty" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_hir_pretty = { path = "../librustc_hir_pretty" }
-rustc_lexer = { path = "../librustc_lexer" }
-serde_json = "1"
-rustc_session = { path = "../librustc_session" }
-rustc_span = { path = "../librustc_span" }
-rls-data = "0.19"
-rls-span = "0.5"
diff --git a/src/librustc_session/Cargo.toml b/src/librustc_session/Cargo.toml
deleted file mode 100644
index 208bba1d962..00000000000
--- a/src/librustc_session/Cargo.toml
+++ /dev/null
@@ -1,24 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_session"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_session"
-path = "lib.rs"
-
-[dependencies]
-bitflags = "1.2.1"
-getopts = "0.2"
-rustc_macros = { path = "../librustc_macros" }
-tracing = "0.1"
-rustc_errors = { path = "../librustc_errors" }
-rustc_feature = { path = "../librustc_feature" }
-rustc_target = { path = "../librustc_target" }
-rustc_serialize = { path = "../librustc_serialize" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_span = { path = "../librustc_span" }
-rustc_fs_util = { path = "../librustc_fs_util" }
-num_cpus = "1.0"
-rustc_ast = { path = "../librustc_ast" }
diff --git a/src/librustc_span/Cargo.toml b/src/librustc_span/Cargo.toml
deleted file mode 100644
index dd4928d4e32..00000000000
--- a/src/librustc_span/Cargo.toml
+++ /dev/null
@@ -1,23 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_span"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_span"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc_serialize = { path = "../librustc_serialize" }
-rustc_macros = { path = "../librustc_macros" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_index = { path = "../librustc_index" }
-rustc_arena = { path = "../librustc_arena" }
-scoped-tls = "1.0"
-unicode-width = "0.1.4"
-cfg-if = "0.1.2"
-tracing = "0.1"
-sha-1 = "0.8"
-md-5 = "0.8"
diff --git a/src/librustc_symbol_mangling/Cargo.toml b/src/librustc_symbol_mangling/Cargo.toml
deleted file mode 100644
index b44c0e4e027..00000000000
--- a/src/librustc_symbol_mangling/Cargo.toml
+++ /dev/null
@@ -1,23 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_symbol_mangling"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_symbol_mangling"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-tracing = "0.1"
-punycode = "0.4.0"
-rustc-demangle = "0.1.16"
-
-rustc_ast = { path = "../librustc_ast" }
-rustc_span = { path = "../librustc_span" }
-rustc_middle = { path = "../librustc_middle" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_target = { path = "../librustc_target" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_session = { path = "../librustc_session" }
diff --git a/src/librustc_target/Cargo.toml b/src/librustc_target/Cargo.toml
deleted file mode 100644
index d2b50f44e43..00000000000
--- a/src/librustc_target/Cargo.toml
+++ /dev/null
@@ -1,18 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_target"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_target"
-path = "lib.rs"
-
-[dependencies]
-bitflags = "1.2.1"
-tracing = "0.1"
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_macros = { path = "../librustc_macros" }
-rustc_serialize = { path = "../librustc_serialize" }
-rustc_span = { path = "../librustc_span" }
-rustc_index = { path = "../librustc_index" }
diff --git a/src/librustc_trait_selection/Cargo.toml b/src/librustc_trait_selection/Cargo.toml
deleted file mode 100644
index 444023baa69..00000000000
--- a/src/librustc_trait_selection/Cargo.toml
+++ /dev/null
@@ -1,27 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_trait_selection"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_trait_selection"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc_parse_format = { path = "../librustc_parse_format" }
-tracing = "0.1"
-rustc_attr = { path = "../librustc_attr" }
-rustc_middle = { path = "../librustc_middle" }
-rustc_ast = { path = "../librustc_ast" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_index = { path = "../librustc_index" }
-rustc_infer = { path = "../librustc_infer" }
-rustc_macros = { path = "../librustc_macros" }
-rustc_session = { path = "../librustc_session" }
-rustc_span = { path = "../librustc_span" }
-rustc_target = { path = "../librustc_target" }
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml
deleted file mode 100644
index f5545f56293..00000000000
--- a/src/librustc_traits/Cargo.toml
+++ /dev/null
@@ -1,23 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_traits"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_traits"
-path = "lib.rs"
-
-[dependencies]
-tracing = "0.1"
-rustc_middle = { path = "../librustc_middle" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_index = { path = "../librustc_index" }
-rustc_ast = { path = "../librustc_ast" }
-rustc_span = { path = "../librustc_span" }
-chalk-ir = "0.14.0"
-chalk-solve = "0.14.0"
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
-rustc_infer = { path = "../librustc_infer" }
-rustc_trait_selection = { path = "../librustc_trait_selection" }
diff --git a/src/librustc_ty/Cargo.toml b/src/librustc_ty/Cargo.toml
deleted file mode 100644
index adc9740c2c1..00000000000
--- a/src/librustc_ty/Cargo.toml
+++ /dev/null
@@ -1,21 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_ty"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_ty"
-path = "lib.rs"
-
-[dependencies]
-tracing = "0.1"
-rustc_middle = { path = "../librustc_middle" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_infer = { path = "../librustc_infer" }
-rustc_span = { path = "../librustc_span" }
-rustc_session = { path = "../librustc_session" }
-rustc_target = { path = "../librustc_target" }
-rustc_trait_selection = { path = "../librustc_trait_selection" }
diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml
deleted file mode 100644
index 82c6ac7a0cd..00000000000
--- a/src/librustc_typeck/Cargo.toml
+++ /dev/null
@@ -1,29 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_typeck"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc_typeck"
-path = "lib.rs"
-test = false
-doctest = false
-
-[dependencies]
-rustc_arena = { path = "../librustc_arena" }
-tracing = "0.1"
-rustc_middle = { path = "../librustc_middle" }
-rustc_attr = { path = "../librustc_attr" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_hir_pretty = { path = "../librustc_hir_pretty" }
-rustc_target = { path = "../librustc_target" }
-rustc_session = { path = "../librustc_session" }
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
-rustc_ast = { path = "../librustc_ast" }
-rustc_span = { path = "../librustc_span" }
-rustc_index = { path = "../librustc_index" }
-rustc_infer = { path = "../librustc_infer" }
-rustc_trait_selection = { path = "../librustc_trait_selection" }
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index 09afb3cae5b..ede52394468 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -5,7 +5,6 @@ version = "0.0.0"
 edition = "2018"
 
 [lib]
-name = "rustdoc"
 path = "lib.rs"
 
 [dependencies]
@@ -19,4 +18,4 @@ tempfile = "3"
 itertools = "0.8"
 
 [dev-dependencies]
-expect-test = "0.1"
+expect-test = "1.0"
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index 3d2785541be..484fbd0316d 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -75,8 +75,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                     }
                 });
                 debug!(
-                    "get_blanket_impls: found applicable impl: {}\
-                        for trait_ref={:?}, ty={:?}",
+                    "get_blanket_impls: found applicable impl: {} for trait_ref={:?}, ty={:?}",
                     may_apply, trait_ref, ty
                 );
                 if !may_apply {
diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs
index 96f0a1b7a7c..794a7bcaf1c 100644
--- a/src/librustdoc/clean/cfg/tests.rs
+++ b/src/librustdoc/clean/cfg/tests.rs
@@ -391,26 +391,25 @@ fn test_render_long_html() {
             (word_cfg("unix") & word_cfg("windows") & word_cfg("debug_assertions"))
                 .render_long_html(),
             "This is supported on <strong>Unix and Windows and debug-assertions enabled\
-                </strong> only."
+             </strong> only."
         );
         assert_eq!(
             (word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions"))
                 .render_long_html(),
             "This is supported on <strong>Unix or Windows or debug-assertions enabled\
-                </strong> only."
+             </strong> only."
         );
         assert_eq!(
             (!(word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions")))
                 .render_long_html(),
             "This is supported on <strong>neither Unix nor Windows nor debug-assertions \
-                enabled</strong>."
+             enabled</strong>."
         );
         assert_eq!(
             ((word_cfg("unix") & name_value_cfg("target_arch", "x86_64"))
                 | (word_cfg("windows") & name_value_cfg("target_pointer_width", "64")))
             .render_long_html(),
-            "This is supported on <strong>Unix and x86-64, or Windows and 64-bit</strong> \
-                only."
+            "This is supported on <strong>Unix and x86-64, or Windows and 64-bit</strong> only."
         );
         assert_eq!(
             (!(word_cfg("unix") & word_cfg("windows"))).render_long_html(),
@@ -420,7 +419,7 @@ fn test_render_long_html() {
             ((word_cfg("debug_assertions") | word_cfg("windows")) & word_cfg("unix"))
                 .render_long_html(),
             "This is supported on <strong>(debug-assertions enabled or Windows) and Unix\
-            </strong> only."
+             </strong> only."
         );
         assert_eq!(
             name_value_cfg("target_feature", "sse2").render_long_html(),
@@ -430,7 +429,7 @@ fn test_render_long_html() {
             (name_value_cfg("target_arch", "x86_64") & name_value_cfg("target_feature", "sse2"))
                 .render_long_html(),
             "This is supported on <strong>x86-64 and target feature \
-            <code>sse2</code></strong> only."
+             <code>sse2</code></strong> only."
         );
     })
 }
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 75fdcd5ec1c..8255bdab4f5 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -422,14 +422,13 @@ pub fn name_from_pat(p: &hir::Pat<'_>) -> String {
         PatKind::Ref(ref p, _) => name_from_pat(&**p),
         PatKind::Lit(..) => {
             warn!(
-                "tried to get argument name from PatKind::Lit, \
-                  which is silly in function arguments"
+                "tried to get argument name from PatKind::Lit, which is silly in function arguments"
             );
             "()".to_string()
         }
         PatKind::Range(..) => panic!(
             "tried to get argument name from PatKind::Range, \
-                              which is not allowed in function arguments"
+             which is not allowed in function arguments"
         ),
         PatKind::Slice(ref begin, ref mid, ref end) => {
             let begin = begin.iter().map(|p| name_from_pat(&**p));
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 14df4e7aa8e..a5fc0757816 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -416,14 +416,12 @@ impl Options {
                     return Err(1);
                 } else if !ret.is_empty() {
                     diag.struct_warn(&format!(
-                        "theme file \"{}\" is missing CSS rules from the \
-                                               default theme",
+                        "theme file \"{}\" is missing CSS rules from the default theme",
                         theme_s
                     ))
                     .warn("the theme may appear incorrect when loaded")
                     .help(&format!(
-                        "to see what rules are missing, call `rustdoc \
-                                        --check-theme \"{}\"`",
+                        "to see what rules are missing, call `rustdoc  --check-theme \"{}\"`",
                         theme_s
                     ))
                     .emit();
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 7c89b38a92c..074a43f2a70 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -561,8 +561,7 @@ fn run_global_ctxt(
     if let Some(ref m) = krate.module {
         if let None | Some("") = m.doc_value() {
             let help = "The following guide may be of use:\n\
-                    https://doc.rust-lang.org/nightly/rustdoc/how-to-write-documentation\
-                    .html";
+                https://doc.rust-lang.org/nightly/rustdoc/how-to-write-documentation.html";
             tcx.struct_lint_node(
                 rustc_lint::builtin::MISSING_CRATE_LEVEL_DOCS,
                 ctxt.as_local_hir_id(m.def_id).unwrap(),
@@ -581,7 +580,7 @@ fn run_global_ctxt(
             .struct_warn(&format!("the `#![doc({})]` attribute is considered deprecated", name));
         msg.warn(
             "see issue #44136 <https://github.com/rust-lang/rust/issues/44136> \
-                for more information",
+             for more information",
         );
 
         if name == "no_default_passes" {
@@ -614,7 +613,7 @@ fn run_global_ctxt(
                     report_deprecated_attr("plugins = \"...\"", diag);
                     eprintln!(
                         "WARNING: `#![doc(plugins = \"...\")]` \
-                            no longer functions; see CVE-2018-1000622"
+                         no longer functions; see CVE-2018-1000622"
                     );
                     continue;
                 }
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 699f8c36cba..2da9c68b196 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -833,7 +833,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
                             write!(
                                 f,
                                 "<a class=\"type\" href=\"{url}#{shortty}.{name}\" \
-                                   title=\"type {path}::{name}\">{name}</a>",
+                                    title=\"type {path}::{name}\">{name}</a>",
                                 url = url,
                                 shortty = ItemType::AssocType,
                                 name = name,
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 26557fc1cb7..4769edc50ff 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -27,7 +27,7 @@ pub fn render_with_highlighting(
         write!(
             out,
             "<div class='information'><div class='tooltip {}'>ⓘ<span \
-                     class='tooltiptext'>{}</span></div></div>",
+                  class='tooltiptext'>{}</span></div></div>",
             class, tooltip
         )
         .unwrap();
diff --git a/src/librustdoc/html/highlight/tests.rs b/src/librustdoc/html/highlight/tests.rs
index 398cd4f670e..c79471b1fae 100644
--- a/src/librustdoc/html/highlight/tests.rs
+++ b/src/librustdoc/html/highlight/tests.rs
@@ -9,7 +9,7 @@ fn test_html_highlighting() {
         write_code(&mut out, src);
         format!("{}<pre><code>{}</code></pre>\n", STYLE, out)
     };
-    expect_file!["src/librustdoc/html/highlight/fixtures/sample.html"].assert_eq(&html);
+    expect_file!["fixtures/sample.html"].assert_eq(&html);
 }
 
 const STYLE: &str = r#"
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index fd67a66395d..287c85b8c22 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -210,8 +210,8 @@ pub fn render<T: Print, S: Print>(
             .collect::<String>(),
         filter_crates = if layout.generate_search_filter {
             "<select id=\"crate-search\">\
-            <option value=\"All crates\">All crates</option>\
-        </select>"
+                 <option value=\"All crates\">All crates</option>\
+             </select>"
         } else {
             ""
         },
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 894d868dcc6..098ece9a1d5 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -519,8 +519,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for Footnotes<'a, I> {
                 Some(Event::FootnoteReference(ref reference)) => {
                     let entry = self.get_entry(&reference);
                     let reference = format!(
-                        "<sup id=\"fnref{0}\"><a href=\"#fn{0}\">{0}\
-                                             </a></sup>",
+                        "<sup id=\"fnref{0}\"><a href=\"#fn{0}\">{0}</a></sup>",
                         (*entry).1
                     );
                     return Some(Event::Html(reference.into()));
diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs
index f071f3d5b4e..8e618733f07 100644
--- a/src/librustdoc/html/markdown/tests.rs
+++ b/src/librustdoc/html/markdown/tests.rs
@@ -140,25 +140,26 @@ fn test_header() {
 
     t(
         "# Foo bar",
-        "<h1 id=\"foo-bar\" class=\"section-header\">\
-      <a href=\"#foo-bar\">Foo bar</a></h1>",
+        "<h1 id=\"foo-bar\" class=\"section-header\"><a href=\"#foo-bar\">Foo bar</a></h1>",
     );
     t(
         "## Foo-bar_baz qux",
-        "<h2 id=\"foo-bar_baz-qux\" class=\"section-\
-      header\"><a href=\"#foo-bar_baz-qux\">Foo-bar_baz qux</a></h2>",
+        "<h2 id=\"foo-bar_baz-qux\" class=\"section-header\">\
+         <a href=\"#foo-bar_baz-qux\">Foo-bar_baz qux</a></h2>",
     );
     t(
         "### **Foo** *bar* baz!?!& -_qux_-%",
         "<h3 id=\"foo-bar-baz--qux-\" class=\"section-header\">\
-      <a href=\"#foo-bar-baz--qux-\"><strong>Foo</strong> \
-      <em>bar</em> baz!?!&amp; -<em>qux</em>-%</a></h3>",
+            <a href=\"#foo-bar-baz--qux-\"><strong>Foo</strong> \
+            <em>bar</em> baz!?!&amp; -<em>qux</em>-%</a>\
+         </h3>",
     );
     t(
         "#### **Foo?** & \\*bar?!*  _`baz`_ ❤ #qux",
         "<h4 id=\"foo--bar--baz--qux\" class=\"section-header\">\
-      <a href=\"#foo--bar--baz--qux\"><strong>Foo?</strong> &amp; *bar?!*  \
-      <em><code>baz</code></em> ❤ #qux</a></h4>",
+             <a href=\"#foo--bar--baz--qux\"><strong>Foo?</strong> &amp; *bar?!*  \
+             <em><code>baz</code></em> ❤ #qux</a>\
+         </h4>",
     );
 }
 
@@ -174,38 +175,32 @@ fn test_header_ids_multiple_blocks() {
     t(
         &mut map,
         "# Example",
-        "<h1 id=\"example\" class=\"section-header\">\
-        <a href=\"#example\">Example</a></h1>",
+        "<h1 id=\"example\" class=\"section-header\"><a href=\"#example\">Example</a></h1>",
     );
     t(
         &mut map,
         "# Panics",
-        "<h1 id=\"panics\" class=\"section-header\">\
-        <a href=\"#panics\">Panics</a></h1>",
+        "<h1 id=\"panics\" class=\"section-header\"><a href=\"#panics\">Panics</a></h1>",
     );
     t(
         &mut map,
         "# Example",
-        "<h1 id=\"example-1\" class=\"section-header\">\
-        <a href=\"#example-1\">Example</a></h1>",
+        "<h1 id=\"example-1\" class=\"section-header\"><a href=\"#example-1\">Example</a></h1>",
     );
     t(
         &mut map,
         "# Main",
-        "<h1 id=\"main-1\" class=\"section-header\">\
-        <a href=\"#main-1\">Main</a></h1>",
+        "<h1 id=\"main-1\" class=\"section-header\"><a href=\"#main-1\">Main</a></h1>",
     );
     t(
         &mut map,
         "# Example",
-        "<h1 id=\"example-2\" class=\"section-header\">\
-        <a href=\"#example-2\">Example</a></h1>",
+        "<h1 id=\"example-2\" class=\"section-header\"><a href=\"#example-2\">Example</a></h1>",
     );
     t(
         &mut map,
         "# Panics",
-        "<h1 id=\"panics-1\" class=\"section-header\">\
-        <a href=\"#panics-1\">Panics</a></h1>",
+        "<h1 id=\"panics-1\" class=\"section-header\"><a href=\"#panics-1\">Panics</a></h1>",
     );
 }
 
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 90206d27781..57b3b9502a3 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -1061,13 +1061,14 @@ themePicker.onblur = handleThemeButtonsBlur;
 
             let content = format!(
                 "<h1 class='fqn'>\
-     <span class='in-band'>List of all crates</span>\
-</h1><ul class='mod'>{}</ul>",
+                     <span class='in-band'>List of all crates</span>\
+                </h1>\
+                <ul class='crate mod'>{}</ul>",
                 krates
                     .iter()
                     .map(|s| {
                         format!(
-                            "<li><a class=\"mod\" href=\"{}index.html\">{}</a></li>",
+                            "<li><a class=\"crate mod\" href=\"{}index.html\">{}</a></li>",
                             ensure_trailing_slash(s),
                             s
                         )
@@ -1311,15 +1312,16 @@ impl AllTypes {
         write!(
             f,
             "<h1 class='fqn'>\
-        <span class='out-of-band'>\
-            <span id='render-detail'>\
-                <a id=\"toggle-all-docs\" href=\"javascript:void(0)\" title=\"collapse all docs\">\
-                    [<span class='inner'>&#x2212;</span>]\
-                </a>\
-            </span>
-        </span>
-        <span class='in-band'>List of all items</span>\
-    </h1>"
+                 <span class='out-of-band'>\
+                     <span id='render-detail'>\
+                         <a id=\"toggle-all-docs\" href=\"javascript:void(0)\" \
+                            title=\"collapse all docs\">\
+                             [<span class='inner'>&#x2212;</span>]\
+                         </a>\
+                     </span>
+                 </span>
+                 <span class='in-band'>List of all items</span>\
+             </h1>"
         );
         print_entries(f, &self.structs, "Structs", "structs");
         print_entries(f, &self.enums, "Enums", "enums");
@@ -1349,20 +1351,20 @@ impl Setting {
         match *self {
             Setting::Section { ref description, ref sub_settings } => format!(
                 "<div class='setting-line'>\
-                        <div class='title'>{}</div>\
-                        <div class='sub-settings'>{}</div>
-                    </div>",
+                     <div class='title'>{}</div>\
+                     <div class='sub-settings'>{}</div>
+                 </div>",
                 description,
                 sub_settings.iter().map(|s| s.display()).collect::<String>()
             ),
             Setting::Entry { ref js_data_name, ref description, ref default_value } => format!(
                 "<div class='setting-line'>\
-                        <label class='toggle'>\
-                        <input type='checkbox' id='{}' {}>\
-                        <span class='slider'></span>\
-                        </label>\
-                        <div>{}</div>\
-                    </div>",
+                     <label class='toggle'>\
+                     <input type='checkbox' id='{}' {}>\
+                     <span class='slider'></span>\
+                     </label>\
+                     <div>{}</div>\
+                 </div>",
                 js_data_name,
                 if *default_value { " checked" } else { "" },
                 description,
@@ -1880,30 +1882,29 @@ fn document_non_exhaustive(w: &mut Buffer, item: &clean::Item) {
             write!(
                 w,
                 "Non-exhaustive structs could have additional fields added in future. \
-                       Therefore, non-exhaustive structs cannot be constructed in external crates \
-                       using the traditional <code>Struct {{ .. }}</code> syntax; cannot be \
-                       matched against without a wildcard <code>..</code>; and \
-                       struct update syntax will not work."
+                 Therefore, non-exhaustive structs cannot be constructed in external crates \
+                 using the traditional <code>Struct {{ .. }}</code> syntax; cannot be \
+                 matched against without a wildcard <code>..</code>; and \
+                 struct update syntax will not work."
             );
         } else if item.is_enum() {
             write!(
                 w,
                 "Non-exhaustive enums could have additional variants added in future. \
-                       Therefore, when matching against variants of non-exhaustive enums, an \
-                       extra wildcard arm must be added to account for any future variants."
+                 Therefore, when matching against variants of non-exhaustive enums, an \
+                 extra wildcard arm must be added to account for any future variants."
             );
         } else if item.is_variant() {
             write!(
                 w,
                 "Non-exhaustive enum variants could have additional fields added in future. \
-                       Therefore, non-exhaustive enum variants cannot be constructed in external \
-                       crates and cannot be matched against."
+                 Therefore, non-exhaustive enum variants cannot be constructed in external \
+                 crates and cannot be matched against."
             );
         } else {
             write!(
                 w,
-                "This type will require a wildcard arm in any match statements or \
-                       constructors."
+                "This type will require a wildcard arm in any match statements or constructors."
             );
         }
 
@@ -2100,12 +2101,11 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
                 let doc_value = myitem.doc_value().unwrap_or("");
                 write!(
                     w,
-                    "\
-                       <tr class='{stab}{add}module-item'>\
-                           <td><a class=\"{class}\" href=\"{href}\" \
-                                  title='{title}'>{name}</a>{unsafety_flag}</td>\
-                           <td class='docblock-short'>{stab_tags}{docs}</td>\
-                       </tr>",
+                    "<tr class='{stab}{add}module-item'>\
+                         <td><a class=\"{class}\" href=\"{href}\" \
+                             title='{title}'>{name}</a>{unsafety_flag}</td>\
+                         <td class='docblock-short'>{stab_tags}{docs}</td>\
+                     </tr>",
                     name = *myitem.name.as_ref().unwrap(),
                     stab_tags = stability_tags(myitem),
                     docs = MarkdownSummaryLine(doc_value, &myitem.links()).into_string(),
@@ -2254,8 +2254,7 @@ fn item_constant(w: &mut Buffer, cx: &Context, it: &clean::Item, c: &clean::Cons
 
     write!(
         w,
-        "{vis}const \
-               {name}: {typ}",
+        "{vis}const {name}: {typ}",
         vis = it.visibility.print_with_space(),
         name = it.name.as_ref().unwrap(),
         typ = c.type_.print(),
@@ -2289,8 +2288,7 @@ fn item_static(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Static
     render_attributes(w, it, false);
     write!(
         w,
-        "{vis}static {mutability}\
-               {name}: {typ}</pre>",
+        "{vis}static {mutability} {name}: {typ}</pre>",
         vis = it.visibility.print_with_space(),
         mutability = s.mutability.print_with_space(),
         name = it.name.as_ref().unwrap(),
@@ -2316,7 +2314,7 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func
     write!(
         w,
         "{vis}{constness}{asyncness}{unsafety}{abi}fn \
-           {name}{generics}{decl}{spotlight}{where_clause}</pre>",
+         {name}{generics}{decl}{spotlight}{where_clause}</pre>",
         vis = it.visibility.print_with_space(),
         constness = f.header.constness.print_with_space(),
         asyncness = f.header.asyncness.print_with_space(),
@@ -2507,10 +2505,9 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
     fn write_small_section_header(w: &mut Buffer, id: &str, title: &str, extra_content: &str) {
         write!(
             w,
-            "
-            <h2 id='{0}' class='small-section-header'>\
-              {1}<a href='#{0}' class='anchor'></a>\
-            </h2>{2}",
+            "<h2 id='{0}' class='small-section-header'>\
+                {1}<a href='#{0}' class='anchor'></a>\
+             </h2>{2}",
             id, title, extra_content
         )
     }
@@ -2839,7 +2836,7 @@ fn render_assoc_item(
         write!(
             w,
             "{}{}{}{}{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
-                   {generics}{decl}{spotlight}{where_clause}",
+             {generics}{decl}{spotlight}{where_clause}",
             if parent == ItemType::Trait { "    " } else { "" },
             meth.visibility.print_with_space(),
             header.constness.print_with_space(),
@@ -2914,9 +2911,9 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct
                 write!(
                     w,
                     "<span id=\"{id}\" class=\"{item_type} small-section-header\">\
-                           <a href=\"#{id}\" class=\"anchor field\"></a>\
-                           <code>{name}: {ty}</code>\
-                           </span>",
+                         <a href=\"#{id}\" class=\"anchor field\"></a>\
+                         <code>{name}: {ty}</code>\
+                     </span>",
                     item_type = ItemType::StructField,
                     id = id,
                     name = field.name.as_ref().unwrap(),
@@ -2958,9 +2955,9 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union,
             write!(
                 w,
                 "<span id=\"{id}\" class=\"{shortty} small-section-header\">\
-                           <a href=\"#{id}\" class=\"anchor field\"></a>\
-                           <code>{name}: {ty}</code>\
-                       </span>",
+                     <a href=\"#{id}\" class=\"anchor field\"></a>\
+                     <code>{name}: {ty}</code>\
+                 </span>",
                 id = id,
                 name = name,
                 shortty = ItemType::StructField,
@@ -3085,9 +3082,9 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca
                         write!(
                             w,
                             "<span id=\"{id}\" class=\"variant small-section-header\">\
-                                   <a href=\"#{id}\" class=\"anchor field\"></a>\
-                                   <code>{f}:&nbsp;{t}\
-                                   </code></span>",
+                                 <a href=\"#{id}\" class=\"anchor field\"></a>\
+                                 <code>{f}:&nbsp;{t}</code>\
+                             </span>",
                             id = id,
                             f = field.name.as_ref().unwrap(),
                             t = ty.print()
@@ -3300,23 +3297,19 @@ fn render_assoc_items(
             AssocItemRender::All => {
                 write!(
                     w,
-                    "\
-                    <h2 id='implementations' class='small-section-header'>\
-                      Implementations<a href='#implementations' class='anchor'></a>\
-                    </h2>\
-                "
+                    "<h2 id='implementations' class='small-section-header'>\
+                         Implementations<a href='#implementations' class='anchor'></a>\
+                    </h2>"
                 );
                 RenderMode::Normal
             }
             AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
                 write!(
                     w,
-                    "\
-                    <h2 id='deref-methods' class='small-section-header'>\
-                      Methods from {}&lt;Target = {}&gt;\
-                      <a href='#deref-methods' class='anchor'></a>\
-                    </h2>\
-                ",
+                    "<h2 id='deref-methods' class='small-section-header'>\
+                         Methods from {}&lt;Target = {}&gt;\
+                         <a href='#deref-methods' class='anchor'></a>\
+                     </h2>",
                     trait_.print(),
                     type_.print()
                 );
@@ -3363,11 +3356,10 @@ fn render_assoc_items(
         if !impls.is_empty() {
             write!(
                 w,
-                "\
-                <h2 id='trait-implementations' class='small-section-header'>\
-                  Trait Implementations<a href='#trait-implementations' class='anchor'></a>\
-                </h2>\
-                <div id='trait-implementations-list'>{}</div>",
+                "<h2 id='trait-implementations' class='small-section-header'>\
+                     Trait Implementations<a href='#trait-implementations' class='anchor'></a>\
+                 </h2>\
+                 <div id='trait-implementations-list'>{}</div>",
                 impls
             );
         }
@@ -3375,13 +3367,11 @@ fn render_assoc_items(
         if !synthetic.is_empty() {
             write!(
                 w,
-                "\
-                <h2 id='synthetic-implementations' class='small-section-header'>\
-                  Auto Trait Implementations\
-                  <a href='#synthetic-implementations' class='anchor'></a>\
-                </h2>\
-                <div id='synthetic-implementations-list'>\
-            "
+                "<h2 id='synthetic-implementations' class='small-section-header'>\
+                     Auto Trait Implementations\
+                     <a href='#synthetic-implementations' class='anchor'></a>\
+                 </h2>\
+                 <div id='synthetic-implementations-list'>"
             );
             render_impls(cx, w, &synthetic, containing_item, cache);
             write!(w, "</div>");
@@ -3390,13 +3380,11 @@ fn render_assoc_items(
         if !blanket_impl.is_empty() {
             write!(
                 w,
-                "\
-                <h2 id='blanket-implementations' class='small-section-header'>\
-                  Blanket Implementations\
-                  <a href='#blanket-implementations' class='anchor'></a>\
-                </h2>\
-                <div id='blanket-implementations-list'>\
-            "
+                "<h2 id='blanket-implementations' class='small-section-header'>\
+                     Blanket Implementations\
+                     <a href='#blanket-implementations' class='anchor'></a>\
+                 </h2>\
+                 <div id='blanket-implementations-list'>"
             );
             render_impls(cx, w, &blanket_impl, containing_item, cache);
             write!(w, "</div>");
@@ -3477,7 +3465,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String {
                     if out.is_empty() {
                         out.push_str(&format!(
                             "<h3 class=\"notable\">Notable traits for {}</h3>\
-                                      <code class=\"content\">",
+                             <code class=\"content\">",
                             impl_.for_.print()
                         ));
                         trait_.push_str(&impl_.for_.print().to_string());
@@ -3913,8 +3901,8 @@ fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer, cache: &Ca
             write!(
                 buffer,
                 "<div class='block version'>\
-                    <p>Version {}</p>\
-                    </div>",
+                     <p>Version {}</p>\
+                 </div>",
                 Escape(version)
             );
         }
@@ -4189,7 +4177,7 @@ fn sidebar_struct(buf: &mut Buffer, it: &clean::Item, s: &clean::Struct) {
         if let doctree::Plain = s.struct_type {
             sidebar.push_str(&format!(
                 "<a class=\"sidebar-title\" href=\"#fields\">Fields</a>\
-                                       <div class=\"sidebar-links\">{}</div>",
+                 <div class=\"sidebar-links\">{}</div>",
                 fields
             ));
         }
@@ -4316,8 +4304,8 @@ fn sidebar_trait(buf: &mut Buffer, it: &clean::Item, t: &clean::Trait) {
             res.sort();
             sidebar.push_str(&format!(
                 "<a class=\"sidebar-title\" href=\"#foreign-impls\">\
-                    Implementations on Foreign Types</a><div \
-                    class=\"sidebar-links\">{}</div>",
+                    Implementations on Foreign Types</a>\
+                 <div class=\"sidebar-links\">{}</div>",
                 res.into_iter()
                     .map(|(name, id)| format!("<a href=\"#{}\">{}</a>", id, Escape(&name)))
                     .collect::<Vec<_>>()
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index aaa73b100c2..02a7362bb3b 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -52,7 +52,7 @@ impl<'a> DocFolder for SourceCollector<'a> {
                 Err(e) => {
                     println!(
                         "warning: source code was requested to be rendered, \
-                              but processing `{}` had an error: {}",
+                         but processing `{}` had an error: {}",
                         item.source.filename, e
                     );
                     println!("         skipping rendering of source code");
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index a1eef5c1202..1b3eb2011af 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -2740,10 +2740,17 @@ function defocusSearchBar() {
         });
     }
 
+    function enableSearchInput() {
+        if (search_input) {
+            search_input.removeAttribute('disabled');
+        }
+    }
+
     window.addSearchOptions = function(crates) {
         var elem = document.getElementById("crate-search");
 
         if (!elem) {
+            enableSearchInput();
             return;
         }
         var crates_text = [];
@@ -2781,10 +2788,7 @@ function defocusSearchBar() {
                 elem.value = savedCrate;
             }
         }
-
-        if (search_input) {
-            search_input.removeAttribute('disabled');
-        }
+        enableSearchInput();
     };
 
     function buildHelperPopup() {
diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css
index f910bfffc22..b4571018270 100644
--- a/src/librustdoc/html/static/themes/ayu.css
+++ b/src/librustdoc/html/static/themes/ayu.css
@@ -178,6 +178,9 @@ pre {
 .content span.externcrate, .content span.mod, .content a.mod {
 	color: #acccf9;
 }
+.content ul.crate a.crate {
+	font: 16px/1.6 "Fira Sans";
+}
 .content span.struct, .content a.struct {
 	color: #ffa0a5;
 }
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 8658b39b455..73a783d5406 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -153,7 +153,7 @@ fn opts() -> Vec<RustcOptGroup> {
                 "",
                 "passes",
                 "list of passes to also run, you might want to pass it multiple times; a value of \
-                        `list` will print available passes",
+                 `list` will print available passes",
                 "PASSES",
             )
         }),
@@ -183,7 +183,7 @@ fn opts() -> Vec<RustcOptGroup> {
                 "",
                 "html-in-header",
                 "files to include inline in the <head> section of a rendered Markdown file \
-                        or generated documentation",
+                 or generated documentation",
                 "FILES",
             )
         }),
@@ -192,7 +192,7 @@ fn opts() -> Vec<RustcOptGroup> {
                 "",
                 "html-before-content",
                 "files to include inline between <body> and the content of a rendered \
-                        Markdown file or generated documentation",
+                 Markdown file or generated documentation",
                 "FILES",
             )
         }),
@@ -201,7 +201,7 @@ fn opts() -> Vec<RustcOptGroup> {
                 "",
                 "html-after-content",
                 "files to include inline between the content and </body> of a rendered \
-                        Markdown file or generated documentation",
+                 Markdown file or generated documentation",
                 "FILES",
             )
         }),
@@ -210,7 +210,7 @@ fn opts() -> Vec<RustcOptGroup> {
                 "",
                 "markdown-before-content",
                 "files to include inline between <body> and the content of a rendered \
-                        Markdown file or generated documentation",
+                 Markdown file or generated documentation",
                 "FILES",
             )
         }),
@@ -219,7 +219,7 @@ fn opts() -> Vec<RustcOptGroup> {
                 "",
                 "markdown-after-content",
                 "files to include inline between the content and </body> of a rendered \
-                        Markdown file or generated documentation",
+                 Markdown file or generated documentation",
                 "FILES",
             )
         }),
@@ -234,8 +234,8 @@ fn opts() -> Vec<RustcOptGroup> {
                 "e",
                 "extend-css",
                 "To add some CSS rules with a given file to generate doc with your \
-                        own theme. However, your theme might break if the rustdoc's generated HTML \
-                        changes, so be careful!",
+                 own theme. However, your theme might break if the rustdoc's generated HTML \
+                 changes, so be careful!",
                 "PATH",
             )
         }),
@@ -248,7 +248,7 @@ fn opts() -> Vec<RustcOptGroup> {
                 "",
                 "playground-url",
                 "URL to send code snippets to, may be reset by --markdown-playground-url \
-                        or `#![doc(html_playground_url=...)]`",
+                 or `#![doc(html_playground_url=...)]`",
                 "URL",
             )
         }),
@@ -281,7 +281,7 @@ fn opts() -> Vec<RustcOptGroup> {
                 "",
                 "resource-suffix",
                 "suffix to add to CSS and JavaScript files, e.g., \"light.css\" will become \
-                      \"light-suffix.css\"",
+                 \"light-suffix.css\"",
                 "PATH",
             )
         }),
@@ -343,7 +343,7 @@ fn opts() -> Vec<RustcOptGroup> {
                 "",
                 "static-root-path",
                 "Path string to force loading static files from in output pages. \
-                        If not set, uses combinations of '../' to reach the documentation root.",
+                 If not set, uses combinations of '../' to reach the documentation root.",
                 "PATH",
             )
         }),
diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
index d1f2c12ccd6..beb1f13ca6f 100644
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/check_code_block_syntax.rs
@@ -1,7 +1,6 @@
-use rustc_ast::token;
 use rustc_data_structures::sync::{Lock, Lrc};
 use rustc_errors::{emitter::Emitter, Applicability, Diagnostic, Handler};
-use rustc_parse::lexer::StringReader as Lexer;
+use rustc_parse::parse_stream_from_source_str;
 use rustc_session::parse::ParseSess;
 use rustc_span::source_map::{FilePathMapping, SourceMap};
 use rustc_span::{FileName, InnerSpan};
@@ -28,49 +27,34 @@ struct SyntaxChecker<'a, 'tcx> {
 
 impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
     fn check_rust_syntax(&self, item: &clean::Item, dox: &str, code_block: RustCodeBlock) {
-        let buffered_messages = Lrc::new(Lock::new(vec![]));
-
-        let emitter = BufferEmitter { messages: Lrc::clone(&buffered_messages) };
+        let buffer = Lrc::new(Lock::new(Buffer::default()));
+        let emitter = BufferEmitter { buffer: Lrc::clone(&buffer) };
 
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let handler = Handler::with_emitter(false, None, Box::new(emitter));
+        let source = dox[code_block.code].to_owned();
         let sess = ParseSess::with_span_handler(handler, sm);
-        let source_file = sess.source_map().new_source_file(
-            FileName::Custom(String::from("doctest")),
-            dox[code_block.code].to_owned(),
-        );
-
-        let validation_status = rustc_driver::catch_fatal_errors(|| {
-            let mut has_syntax_errors = false;
-            let mut only_whitespace = true;
-            // even if there is a syntax error, we need to run the lexer over the whole file
-            let mut lexer = Lexer::new(&sess, source_file, None);
-            loop {
-                match lexer.next_token().kind {
-                    token::Eof => break,
-                    token::Whitespace => (),
-                    token::Unknown(..) => has_syntax_errors = true,
-                    _ => only_whitespace = false,
-                }
-            }
 
-            if has_syntax_errors {
-                Some(CodeBlockInvalid::SyntaxError)
-            } else if only_whitespace {
-                Some(CodeBlockInvalid::Empty)
-            } else {
-                None
-            }
+        let is_empty = rustc_driver::catch_fatal_errors(|| {
+            parse_stream_from_source_str(
+                FileName::Custom(String::from("doctest")),
+                source,
+                &sess,
+                None,
+            )
+            .is_empty()
         })
-        .unwrap_or(Some(CodeBlockInvalid::SyntaxError));
+        .unwrap_or(false);
+        let buffer = buffer.borrow();
 
-        if let Some(code_block_invalid) = validation_status {
+        if buffer.has_errors || is_empty {
             let mut diag = if let Some(sp) =
                 super::source_span_for_markdown_range(self.cx, &dox, &code_block.range, &item.attrs)
             {
-                let warning_message = match code_block_invalid {
-                    CodeBlockInvalid::SyntaxError => "could not parse code block as Rust code",
-                    CodeBlockInvalid::Empty => "Rust code block is empty",
+                let warning_message = if buffer.has_errors {
+                    "could not parse code block as Rust code"
+                } else {
+                    "Rust code block is empty"
                 };
 
                 let mut diag = self.cx.sess().struct_span_warn(sp, warning_message);
@@ -102,7 +86,7 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
             };
 
             // FIXME(#67563): Provide more context for these errors by displaying the spans inline.
-            for message in buffered_messages.borrow().iter() {
+            for message in buffer.messages.iter() {
                 diag.note(&message);
             }
 
@@ -125,21 +109,26 @@ impl<'a, 'tcx> DocFolder for SyntaxChecker<'a, 'tcx> {
     }
 }
 
+#[derive(Default)]
+struct Buffer {
+    messages: Vec<String>,
+    has_errors: bool,
+}
+
 struct BufferEmitter {
-    messages: Lrc<Lock<Vec<String>>>,
+    buffer: Lrc<Lock<Buffer>>,
 }
 
 impl Emitter for BufferEmitter {
     fn emit_diagnostic(&mut self, diag: &Diagnostic) {
-        self.messages.borrow_mut().push(format!("error from rustc: {}", diag.message[0].0));
+        let mut buffer = self.buffer.borrow_mut();
+        buffer.messages.push(format!("error from rustc: {}", diag.message[0].0));
+        if diag.is_error() {
+            buffer.has_errors = true;
+        }
     }
 
     fn source_map(&self) -> Option<&Lrc<SourceMap>> {
         None
     }
 }
-
-enum CodeBlockInvalid {
-    SyntaxError,
-    Empty,
-}
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 8d4eb67204f..f497f341e11 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1157,7 +1157,7 @@ fn report_diagnostic(
                 // Print the line containing the `link_range` and manually mark it with '^'s.
                 diag.note(&format!(
                     "the link appears in this line:\n\n{line}\n\
-                         {indicator: <before$}{indicator:^<found$}",
+                     {indicator: <before$}{indicator:^<found$}",
                     line = line,
                     indicator = "",
                     before = link_range.start - last_new_line_offset,
diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs
index 0eebdbd87ed..75a65966667 100644
--- a/src/librustdoc/passes/mod.rs
+++ b/src/librustdoc/passes/mod.rs
@@ -284,8 +284,7 @@ impl<'a> DocFolder for ImplStripper<'a> {
                     if let Some(did) = typaram.def_id() {
                         if did.is_local() && !self.retained.contains(&did) {
                             debug!(
-                                "ImplStripper: stripped item in trait's generics; \
-                                    removing impl"
+                                "ImplStripper: stripped item in trait's generics; removing impl"
                             );
                             return None;
                         }
diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs
index f244956e503..9173d8e9605 100644
--- a/src/librustdoc/passes/strip_private.rs
+++ b/src/librustdoc/passes/strip_private.rs
@@ -9,7 +9,7 @@ pub const STRIP_PRIVATE: Pass = Pass {
     name: "strip-private",
     run: strip_private,
     description: "strips all private items from a crate which cannot be seen externally, \
-        implies strip-priv-imports",
+                  implies strip-priv-imports",
 };
 
 /// Strip private items from the point of view of a crate or externally from a
diff --git a/src/test/codegen-units/item-collection/cross-crate-generic-functions.rs b/src/test/codegen-units/item-collection/cross-crate-generic-functions.rs
index e1991046d43..7289ceee95b 100644
--- a/src/test/codegen-units/item-collection/cross-crate-generic-functions.rs
+++ b/src/test/codegen-units/item-collection/cross-crate-generic-functions.rs
@@ -6,15 +6,15 @@
 // aux-build:cgu_generic_function.rs
 extern crate cgu_generic_function;
 
-//~ MONO_ITEM fn cross_crate_generic_functions::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
-    //~ MONO_ITEM fn cgu_generic_function::bar[0]<u32>
-    //~ MONO_ITEM fn cgu_generic_function::foo[0]<u32>
+    //~ MONO_ITEM fn cgu_generic_function::bar::<u32>
+    //~ MONO_ITEM fn cgu_generic_function::foo::<u32>
     let _ = cgu_generic_function::foo(1u32);
 
-    //~ MONO_ITEM fn cgu_generic_function::bar[0]<u64>
-    //~ MONO_ITEM fn cgu_generic_function::foo[0]<u64>
+    //~ MONO_ITEM fn cgu_generic_function::bar::<u64>
+    //~ MONO_ITEM fn cgu_generic_function::foo::<u64>
     let _ = cgu_generic_function::foo(2u64);
 
     // This should not introduce a codegen item
diff --git a/src/test/codegen-units/item-collection/cross-crate-trait-method.rs b/src/test/codegen-units/item-collection/cross-crate-trait-method.rs
index 442438b64b6..dc0984c8a98 100644
--- a/src/test/codegen-units/item-collection/cross-crate-trait-method.rs
+++ b/src/test/codegen-units/item-collection/cross-crate-trait-method.rs
@@ -8,7 +8,7 @@ extern crate cgu_export_trait_method;
 
 use cgu_export_trait_method::Trait;
 
-//~ MONO_ITEM fn cross_crate_trait_method::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
     // The object code of these methods is contained in the external crate, so
@@ -19,31 +19,31 @@ fn start(_: isize, _: *const *const u8) -> isize {
     // Currently, no object code is generated for trait methods with default
     // implementations, unless they are actually called from somewhere. Therefore
     // we cannot import the implementations and have to create our own inline.
-    //~ MONO_ITEM fn cgu_export_trait_method::Trait[0]::with_default_impl[0]<u32>
+    //~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::with_default_impl
     let _ = Trait::with_default_impl(0u32);
-    //~ MONO_ITEM fn cgu_export_trait_method::Trait[0]::with_default_impl[0]<char>
+    //~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::with_default_impl
     let _ = Trait::with_default_impl('c');
 
 
 
-    //~ MONO_ITEM fn cgu_export_trait_method::Trait[0]::with_default_impl_generic[0]<u32, &str>
+    //~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::with_default_impl_generic::<&str>
     let _ = Trait::with_default_impl_generic(0u32, "abc");
-    //~ MONO_ITEM fn cgu_export_trait_method::Trait[0]::with_default_impl_generic[0]<u32, bool>
+    //~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::with_default_impl_generic::<bool>
     let _ = Trait::with_default_impl_generic(0u32, false);
 
-    //~ MONO_ITEM fn cgu_export_trait_method::Trait[0]::with_default_impl_generic[0]<char, i16>
+    //~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::with_default_impl_generic::<i16>
     let _ = Trait::with_default_impl_generic('x', 1i16);
-    //~ MONO_ITEM fn cgu_export_trait_method::Trait[0]::with_default_impl_generic[0]<char, i32>
+    //~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::with_default_impl_generic::<i32>
     let _ = Trait::with_default_impl_generic('y', 0i32);
 
-    //~ MONO_ITEM fn cgu_export_trait_method::{{impl}}[1]::without_default_impl_generic[0]<char>
+    //~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::without_default_impl_generic::<char>
     let _: (u32, char) = Trait::without_default_impl_generic('c');
-    //~ MONO_ITEM fn cgu_export_trait_method::{{impl}}[1]::without_default_impl_generic[0]<bool>
+    //~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::without_default_impl_generic::<bool>
     let _: (u32, bool) = Trait::without_default_impl_generic(false);
 
-    //~ MONO_ITEM fn cgu_export_trait_method::{{impl}}[0]::without_default_impl_generic[0]<char>
+    //~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::without_default_impl_generic::<char>
     let _: (char, char) = Trait::without_default_impl_generic('c');
-    //~ MONO_ITEM fn cgu_export_trait_method::{{impl}}[0]::without_default_impl_generic[0]<bool>
+    //~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::without_default_impl_generic::<bool>
     let _: (char, bool) = Trait::without_default_impl_generic(false);
 
     0
diff --git a/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs
index 27fb3cb1380..adde5745feb 100644
--- a/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs
+++ b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs
@@ -4,19 +4,19 @@
 
 #![feature(start)]
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<drop_in_place_intrinsic::StructWithDtor[0]> @@ drop_in_place_intrinsic-cgu.0[Internal]
+//~ MONO_ITEM fn std::intrinsics::drop_in_place::<StructWithDtor> - shim(Some(StructWithDtor)) @@ drop_in_place_intrinsic-cgu.0[Internal]
 struct StructWithDtor(u32);
 
 impl Drop for StructWithDtor {
-    //~ MONO_ITEM fn drop_in_place_intrinsic::{{impl}}[0]::drop[0]
+    //~ MONO_ITEM fn <StructWithDtor as std::ops::Drop>::drop
     fn drop(&mut self) {}
 }
 
-//~ MONO_ITEM fn drop_in_place_intrinsic::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]; 2]> @@ drop_in_place_intrinsic-cgu.0[Internal]
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<[StructWithDtor; 2]> - shim(Some([StructWithDtor; 2])) @@ drop_in_place_intrinsic-cgu.0[Internal]
     let x = [StructWithDtor(0), StructWithDtor(1)];
 
     drop_slice_in_place(&x);
@@ -24,13 +24,13 @@ fn start(_: isize, _: *const *const u8) -> isize {
     0
 }
 
-//~ MONO_ITEM fn drop_in_place_intrinsic::drop_slice_in_place[0]
+//~ MONO_ITEM fn drop_slice_in_place
 fn drop_slice_in_place(x: &[StructWithDtor]) {
     unsafe {
         // This is the interesting thing in this test case: Normally we would
         // not have drop-glue for the unsized [StructWithDtor]. This has to be
         // generated though when the drop_in_place() intrinsic is used.
-        //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]]> @@ drop_in_place_intrinsic-cgu.0[Internal]
-        ::std::ptr::drop_in_place(x as *const _ as *mut [StructWithDtor]);
+        //~ MONO_ITEM fn std::intrinsics::drop_in_place::<[StructWithDtor]> - shim(Some([StructWithDtor])) @@ drop_in_place_intrinsic-cgu.0[Internal]
+        ::std::intrinsics::drop_in_place(x as *const _ as *mut [StructWithDtor]);
     }
 }
diff --git a/src/test/codegen-units/item-collection/function-as-argument.rs b/src/test/codegen-units/item-collection/function-as-argument.rs
index 3f61f124d24..2329dec385f 100644
--- a/src/test/codegen-units/item-collection/function-as-argument.rs
+++ b/src/test/codegen-units/item-collection/function-as-argument.rs
@@ -1,3 +1,4 @@
+// ignore-tidy-linelength
 // compile-flags:-Zprint-mono-items=eager
 
 #![deny(dead_code)]
@@ -13,26 +14,26 @@ fn take_fn_pointer<T1, T2>(f: fn(T1, T2), x: T1, y: T2) {
     (f)(x, y)
 }
 
-//~ MONO_ITEM fn function_as_argument::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
 
-    //~ MONO_ITEM fn function_as_argument::take_fn_once[0]<u32, &str, fn(u32, &str)>
-    //~ MONO_ITEM fn function_as_argument::function[0]<u32, &str>
-    //~ MONO_ITEM fn core::ops[0]::function[0]::FnOnce[0]::call_once[0]<fn(u32, &str), (u32, &str)>
+    //~ MONO_ITEM fn take_fn_once::<u32, &str, fn(u32, &str) {function::<u32, &str>}>
+    //~ MONO_ITEM fn function::<u32, &str>
+    //~ MONO_ITEM fn <fn(u32, &str) {function::<u32, &str>} as std::ops::FnOnce<(u32, &str)>>::call_once - shim(fn(u32, &str) {function::<u32, &str>})
     take_fn_once(function, 0u32, "abc");
 
-    //~ MONO_ITEM fn function_as_argument::take_fn_once[0]<char, f64, fn(char, f64)>
-    //~ MONO_ITEM fn function_as_argument::function[0]<char, f64>
-    //~ MONO_ITEM fn core::ops[0]::function[0]::FnOnce[0]::call_once[0]<fn(char, f64), (char, f64)>
+    //~ MONO_ITEM fn take_fn_once::<char, f64, fn(char, f64) {function::<char, f64>}>
+    //~ MONO_ITEM fn function::<char, f64>
+    //~ MONO_ITEM fn <fn(char, f64) {function::<char, f64>} as std::ops::FnOnce<(char, f64)>>::call_once - shim(fn(char, f64) {function::<char, f64>})
     take_fn_once(function, 'c', 0f64);
 
-    //~ MONO_ITEM fn function_as_argument::take_fn_pointer[0]<i32, ()>
-    //~ MONO_ITEM fn function_as_argument::function[0]<i32, ()>
+    //~ MONO_ITEM fn take_fn_pointer::<i32, ()>
+    //~ MONO_ITEM fn function::<i32, ()>
     take_fn_pointer(function, 0i32, ());
 
-    //~ MONO_ITEM fn function_as_argument::take_fn_pointer[0]<f32, i64>
-    //~ MONO_ITEM fn function_as_argument::function[0]<f32, i64>
+    //~ MONO_ITEM fn take_fn_pointer::<f32, i64>
+    //~ MONO_ITEM fn function::<f32, i64>
     take_fn_pointer(function, 0f32, 0i64);
 
     0
diff --git a/src/test/codegen-units/item-collection/generic-drop-glue.rs b/src/test/codegen-units/item-collection/generic-drop-glue.rs
index 675bdfdb4d2..45e4a0d6d76 100644
--- a/src/test/codegen-units/item-collection/generic-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/generic-drop-glue.rs
@@ -37,22 +37,22 @@ enum EnumNoDrop<T1, T2> {
 struct NonGenericNoDrop(i32);
 
 struct NonGenericWithDrop(i32);
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::NonGenericWithDrop[0]> @@ generic_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn std::intrinsics::drop_in_place::<NonGenericWithDrop> - shim(Some(NonGenericWithDrop)) @@ generic_drop_glue-cgu.0[Internal]
 
 impl Drop for NonGenericWithDrop {
-    //~ MONO_ITEM fn generic_drop_glue::{{impl}}[2]::drop[0]
+    //~ MONO_ITEM fn <NonGenericWithDrop as std::ops::Drop>::drop
     fn drop(&mut self) {}
 }
 
-//~ MONO_ITEM fn generic_drop_glue::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<i8, char>> @@ generic_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn generic_drop_glue::{{impl}}[0]::drop[0]<i8, char>
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<StructWithDrop<i8, char>> - shim(Some(StructWithDrop<i8, char>)) @@ generic_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn <StructWithDrop<i8, char> as std::ops::Drop>::drop
     let _ = StructWithDrop { x: 0i8, y: 'a' }.x;
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]>> @@ generic_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn generic_drop_glue::{{impl}}[0]::drop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]>
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<StructWithDrop<&str, NonGenericNoDrop>> - shim(Some(StructWithDrop<&str, NonGenericNoDrop>)) @@ generic_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn <StructWithDrop<&str, NonGenericNoDrop> as std::ops::Drop>::drop
     let _ = StructWithDrop { x: "&str", y: NonGenericNoDrop(0) }.y;
 
     // Should produce no drop glue
@@ -60,18 +60,18 @@ fn start(_: isize, _: *const *const u8) -> isize {
 
     // This is supposed to generate drop-glue because it contains a field that
     // needs to be dropped.
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructNoDrop[0]<generic_drop_glue::NonGenericWithDrop[0], f64>> @@ generic_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<StructNoDrop<NonGenericWithDrop, f64>> - shim(Some(StructNoDrop<NonGenericWithDrop, f64>)) @@ generic_drop_glue-cgu.0[Internal]
     let _ = StructNoDrop { x: NonGenericWithDrop(0), y: 0f64 }.y;
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<i32, i64>> @@ generic_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn generic_drop_glue::{{impl}}[1]::drop[0]<i32, i64>
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<EnumWithDrop<i32, i64>> - shim(Some(EnumWithDrop<i32, i64>)) @@ generic_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn <EnumWithDrop<i32, i64> as std::ops::Drop>::drop
     let _ = match EnumWithDrop::A::<i32, i64>(0) {
         EnumWithDrop::A(x) => x,
         EnumWithDrop::B(x) => x as i32
     };
 
-    //~MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<f64, f32>> @@ generic_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn generic_drop_glue::{{impl}}[1]::drop[0]<f64, f32>
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<EnumWithDrop<f64, f32>> - shim(Some(EnumWithDrop<f64, f32>)) @@ generic_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn <EnumWithDrop<f64, f32> as std::ops::Drop>::drop
     let _ = match EnumWithDrop::B::<f64, f32>(1.0) {
         EnumWithDrop::A(x) => x,
         EnumWithDrop::B(x) => x as f64
diff --git a/src/test/codegen-units/item-collection/generic-functions.rs b/src/test/codegen-units/item-collection/generic-functions.rs
index 83909704204..04383bb8edb 100644
--- a/src/test/codegen-units/item-collection/generic-functions.rs
+++ b/src/test/codegen-units/item-collection/generic-functions.rs
@@ -16,39 +16,39 @@ fn foo3<T1, T2, T3>(a: T1, b: T2, c: T3) -> (T1, T2, T3) {
 }
 
 // This function should be instantiated even if no used
-//~ MONO_ITEM fn generic_functions::lifetime_only[0]
+//~ MONO_ITEM fn lifetime_only
 pub fn lifetime_only<'a>(a: &'a u32) -> &'a u32 {
     a
 }
 
-//~ MONO_ITEM fn generic_functions::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
-    //~ MONO_ITEM fn generic_functions::foo1[0]<i32>
+    //~ MONO_ITEM fn foo1::<i32>
     let _ = foo1(2i32);
-    //~ MONO_ITEM fn generic_functions::foo1[0]<i64>
+    //~ MONO_ITEM fn foo1::<i64>
     let _ = foo1(2i64);
-    //~ MONO_ITEM fn generic_functions::foo1[0]<&str>
+    //~ MONO_ITEM fn foo1::<&str>
     let _ = foo1("abc");
-    //~ MONO_ITEM fn generic_functions::foo1[0]<char>
+    //~ MONO_ITEM fn foo1::<char>
     let _ = foo1('v');
 
-    //~ MONO_ITEM fn generic_functions::foo2[0]<i32, i32>
+    //~ MONO_ITEM fn foo2::<i32, i32>
     let _ = foo2(2i32, 2i32);
-    //~ MONO_ITEM fn generic_functions::foo2[0]<i64, &str>
+    //~ MONO_ITEM fn foo2::<i64, &str>
     let _ = foo2(2i64, "abc");
-    //~ MONO_ITEM fn generic_functions::foo2[0]<&str, usize>
+    //~ MONO_ITEM fn foo2::<&str, usize>
     let _ = foo2("a", 2usize);
-    //~ MONO_ITEM fn generic_functions::foo2[0]<char, ()>
+    //~ MONO_ITEM fn foo2::<char, ()>
     let _ = foo2('v', ());
 
-    //~ MONO_ITEM fn generic_functions::foo3[0]<i32, i32, i32>
+    //~ MONO_ITEM fn foo3::<i32, i32, i32>
     let _ = foo3(2i32, 2i32, 2i32);
-    //~ MONO_ITEM fn generic_functions::foo3[0]<i64, &str, char>
+    //~ MONO_ITEM fn foo3::<i64, &str, char>
     let _ = foo3(2i64, "abc", 'c');
-    //~ MONO_ITEM fn generic_functions::foo3[0]<i16, &str, usize>
+    //~ MONO_ITEM fn foo3::<i16, &str, usize>
     let _ = foo3(0i16, "a", 2usize);
-    //~ MONO_ITEM fn generic_functions::foo3[0]<char, (), ()>
+    //~ MONO_ITEM fn foo3::<char, (), ()>
     let _ = foo3('v', (), ());
 
     0
diff --git a/src/test/codegen-units/item-collection/generic-impl.rs b/src/test/codegen-units/item-collection/generic-impl.rs
index 571bb4fa867..dd5367ef038 100644
--- a/src/test/codegen-units/item-collection/generic-impl.rs
+++ b/src/test/codegen-units/item-collection/generic-impl.rs
@@ -30,41 +30,41 @@ pub struct LifeTimeOnly<'a> {
 
 impl<'a> LifeTimeOnly<'a> {
 
-    //~ MONO_ITEM fn generic_impl::{{impl}}[1]::foo[0]
+    //~ MONO_ITEM fn LifeTimeOnly::foo
     pub fn foo(&self) {}
-    //~ MONO_ITEM fn generic_impl::{{impl}}[1]::bar[0]
+    //~ MONO_ITEM fn LifeTimeOnly::bar
     pub fn bar(&'a self) {}
-    //~ MONO_ITEM fn generic_impl::{{impl}}[1]::baz[0]
+    //~ MONO_ITEM fn LifeTimeOnly::baz
     pub fn baz<'b>(&'b self) {}
 
     pub fn non_instantiated<T>(&self) {}
 }
 
-//~ MONO_ITEM fn generic_impl::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
-    //~ MONO_ITEM fn generic_impl::{{impl}}[0]::new[0]<i32>
-    //~ MONO_ITEM fn generic_impl::id[0]<i32>
-    //~ MONO_ITEM fn generic_impl::{{impl}}[0]::get[0]<i32, i16>
+    //~ MONO_ITEM fn Struct::<i32>::new
+    //~ MONO_ITEM fn id::<i32>
+    //~ MONO_ITEM fn Struct::<i32>::get::<i16>
     let _ = Struct::new(0i32).get(0i16);
 
-    //~ MONO_ITEM fn generic_impl::{{impl}}[0]::new[0]<i64>
-    //~ MONO_ITEM fn generic_impl::id[0]<i64>
-    //~ MONO_ITEM fn generic_impl::{{impl}}[0]::get[0]<i64, i16>
+    //~ MONO_ITEM fn Struct::<i64>::new
+    //~ MONO_ITEM fn id::<i64>
+    //~ MONO_ITEM fn Struct::<i64>::get::<i16>
     let _ = Struct::new(0i64).get(0i16);
 
-    //~ MONO_ITEM fn generic_impl::{{impl}}[0]::new[0]<char>
-    //~ MONO_ITEM fn generic_impl::id[0]<char>
-    //~ MONO_ITEM fn generic_impl::{{impl}}[0]::get[0]<char, i16>
+    //~ MONO_ITEM fn Struct::<char>::new
+    //~ MONO_ITEM fn id::<char>
+    //~ MONO_ITEM fn Struct::<char>::get::<i16>
     let _ = Struct::new('c').get(0i16);
 
-    //~ MONO_ITEM fn generic_impl::{{impl}}[0]::new[0]<&str>
-    //~ MONO_ITEM fn generic_impl::id[0]<&str>
-    //~ MONO_ITEM fn generic_impl::{{impl}}[0]::get[0]<generic_impl::Struct[0]<&str>, i16>
+    //~ MONO_ITEM fn Struct::<&str>::new
+    //~ MONO_ITEM fn id::<&str>
+    //~ MONO_ITEM fn Struct::<Struct<&str>>::get::<i16>
     let _ = Struct::new(Struct::new("str")).get(0i16);
 
-    //~ MONO_ITEM fn generic_impl::{{impl}}[0]::new[0]<generic_impl::Struct[0]<&str>>
-    //~ MONO_ITEM fn generic_impl::id[0]<generic_impl::Struct[0]<&str>>
+    //~ MONO_ITEM fn Struct::<Struct<&str>>::new
+    //~ MONO_ITEM fn id::<Struct<&str>>
     let _ = (Struct::new(Struct::new("str")).f)(Struct::new("str"));
 
     0
diff --git a/src/test/codegen-units/item-collection/impl-in-non-instantiated-generic.rs b/src/test/codegen-units/item-collection/impl-in-non-instantiated-generic.rs
index e45644cd375..c01398eb234 100644
--- a/src/test/codegen-units/item-collection/impl-in-non-instantiated-generic.rs
+++ b/src/test/codegen-units/item-collection/impl-in-non-instantiated-generic.rs
@@ -11,14 +11,14 @@ trait SomeTrait {
 // discovered.
 pub fn generic_function<T>(x: T) -> (T, i32) {
     impl SomeTrait for i64 {
-        //~ MONO_ITEM fn impl_in_non_instantiated_generic::generic_function[0]::{{impl}}[0]::foo[0]
+        //~ MONO_ITEM fn generic_function::<impl SomeTrait for i64>::foo
         fn foo(&self) {}
     }
 
     (x, 0)
 }
 
-//~ MONO_ITEM fn impl_in_non_instantiated_generic::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
     0i64.foo();
diff --git a/src/test/codegen-units/item-collection/instantiation-through-vtable.rs b/src/test/codegen-units/item-collection/instantiation-through-vtable.rs
index db0390b58c8..63966a7ec97 100644
--- a/src/test/codegen-units/item-collection/instantiation-through-vtable.rs
+++ b/src/test/codegen-units/item-collection/instantiation-through-vtable.rs
@@ -19,20 +19,20 @@ impl<T> Trait for Struct<T> {
     fn bar(&self) {}
 }
 
-//~ MONO_ITEM fn instantiation_through_vtable::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
     let s1 = Struct { _a: 0u32 };
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<instantiation_through_vtable::Struct[0]<u32>> @@ instantiation_through_vtable-cgu.0[Internal]
-    //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::foo[0]<u32>
-    //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::bar[0]<u32>
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<Struct<u32>> - shim(None) @@ instantiation_through_vtable-cgu.0[Internal]
+    //~ MONO_ITEM fn <Struct<u32> as Trait>::foo
+    //~ MONO_ITEM fn <Struct<u32> as Trait>::bar
     let _ = &s1 as &Trait;
 
     let s1 = Struct { _a: 0u64 };
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<instantiation_through_vtable::Struct[0]<u64>> @@ instantiation_through_vtable-cgu.0[Internal]
-    //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::foo[0]<u64>
-    //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::bar[0]<u64>
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<Struct<u64>> - shim(None) @@ instantiation_through_vtable-cgu.0[Internal]
+    //~ MONO_ITEM fn <Struct<u64> as Trait>::foo
+    //~ MONO_ITEM fn <Struct<u64> as Trait>::bar
     let _ = &s1 as &Trait;
 
     0
diff --git a/src/test/codegen-units/item-collection/items-within-generic-items.rs b/src/test/codegen-units/item-collection/items-within-generic-items.rs
index 10bc52f6a8d..d37d7f7d9b2 100644
--- a/src/test/codegen-units/item-collection/items-within-generic-items.rs
+++ b/src/test/codegen-units/item-collection/items-within-generic-items.rs
@@ -4,13 +4,13 @@
 #![feature(start)]
 
 fn generic_fn<T>(a: T) -> (T, i32) {
-    //~ MONO_ITEM fn items_within_generic_items::generic_fn[0]::nested_fn[0]
+    //~ MONO_ITEM fn generic_fn::nested_fn
     fn nested_fn(a: i32) -> i32 {
         a + 1
     }
 
     let x = {
-        //~ MONO_ITEM fn items_within_generic_items::generic_fn[0]::nested_fn[1]
+        //~ MONO_ITEM fn generic_fn::nested_fn
         fn nested_fn(a: i32) -> i32 {
             a + 2
         }
@@ -21,14 +21,14 @@ fn generic_fn<T>(a: T) -> (T, i32) {
     return (a, x + nested_fn(0));
 }
 
-//~ MONO_ITEM fn items_within_generic_items::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
-    //~ MONO_ITEM fn items_within_generic_items::generic_fn[0]<i64>
+    //~ MONO_ITEM fn generic_fn::<i64>
     let _ = generic_fn(0i64);
-    //~ MONO_ITEM fn items_within_generic_items::generic_fn[0]<u16>
+    //~ MONO_ITEM fn generic_fn::<u16>
     let _ = generic_fn(0u16);
-    //~ MONO_ITEM fn items_within_generic_items::generic_fn[0]<i8>
+    //~ MONO_ITEM fn generic_fn::<i8>
     let _ = generic_fn(0i8);
 
     0
diff --git a/src/test/codegen-units/item-collection/non-generic-drop-glue.rs b/src/test/codegen-units/item-collection/non-generic-drop-glue.rs
index a899b8b2c8b..b5837716814 100644
--- a/src/test/codegen-units/item-collection/non-generic-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/non-generic-drop-glue.rs
@@ -5,13 +5,13 @@
 #![deny(dead_code)]
 #![feature(start)]
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<non_generic_drop_glue::StructWithDrop[0]> @@ non_generic_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn std::intrinsics::drop_in_place::<StructWithDrop> - shim(Some(StructWithDrop)) @@ non_generic_drop_glue-cgu.0[Internal]
 struct StructWithDrop {
     x: i32
 }
 
 impl Drop for StructWithDrop {
-    //~ MONO_ITEM fn non_generic_drop_glue::{{impl}}[0]::drop[0]
+    //~ MONO_ITEM fn <StructWithDrop as std::ops::Drop>::drop
     fn drop(&mut self) {}
 }
 
@@ -19,13 +19,13 @@ struct StructNoDrop {
     x: i32
 }
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<non_generic_drop_glue::EnumWithDrop[0]> @@ non_generic_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn std::intrinsics::drop_in_place::<EnumWithDrop> - shim(Some(EnumWithDrop)) @@ non_generic_drop_glue-cgu.0[Internal]
 enum EnumWithDrop {
     A(i32)
 }
 
 impl Drop for EnumWithDrop {
-    //~ MONO_ITEM fn non_generic_drop_glue::{{impl}}[1]::drop[0]
+    //~ MONO_ITEM fn <EnumWithDrop as std::ops::Drop>::drop
     fn drop(&mut self) {}
 }
 
@@ -33,7 +33,7 @@ enum EnumNoDrop {
     A(i32)
 }
 
-//~ MONO_ITEM fn non_generic_drop_glue::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
     let _ = StructWithDrop { x: 0 }.x;
diff --git a/src/test/codegen-units/item-collection/non-generic-functions.rs b/src/test/codegen-units/item-collection/non-generic-functions.rs
index 26d2fb1b421..092e64562c5 100644
--- a/src/test/codegen-units/item-collection/non-generic-functions.rs
+++ b/src/test/codegen-units/item-collection/non-generic-functions.rs
@@ -3,24 +3,24 @@
 #![deny(dead_code)]
 #![feature(start)]
 
-//~ MONO_ITEM fn non_generic_functions::foo[0]
+//~ MONO_ITEM fn foo
 fn foo() {
     {
-        //~ MONO_ITEM fn non_generic_functions::foo[0]::foo[0]
+        //~ MONO_ITEM fn foo::foo
         fn foo() {}
         foo();
     }
 
     {
-        //~ MONO_ITEM fn non_generic_functions::foo[0]::foo[1]
+        //~ MONO_ITEM fn foo::foo
         fn foo() {}
         foo();
     }
 }
 
-//~ MONO_ITEM fn non_generic_functions::bar[0]
+//~ MONO_ITEM fn bar
 fn bar() {
-    //~ MONO_ITEM fn non_generic_functions::bar[0]::baz[0]
+    //~ MONO_ITEM fn bar::baz
     fn baz() {}
     baz();
 }
@@ -28,38 +28,38 @@ fn bar() {
 struct Struct { _x: i32 }
 
 impl Struct {
-    //~ MONO_ITEM fn non_generic_functions::{{impl}}[0]::foo[0]
+    //~ MONO_ITEM fn Struct::foo
     fn foo() {
         {
-            //~ MONO_ITEM fn non_generic_functions::{{impl}}[0]::foo[0]::foo[0]
+            //~ MONO_ITEM fn Struct::foo::foo
             fn foo() {}
             foo();
         }
 
         {
-            //~ MONO_ITEM fn non_generic_functions::{{impl}}[0]::foo[0]::foo[1]
+            //~ MONO_ITEM fn Struct::foo::foo
             fn foo() {}
             foo();
         }
     }
 
-    //~ MONO_ITEM fn non_generic_functions::{{impl}}[0]::bar[0]
+    //~ MONO_ITEM fn Struct::bar
     fn bar(&self) {
         {
-            //~ MONO_ITEM fn non_generic_functions::{{impl}}[0]::bar[0]::foo[0]
+            //~ MONO_ITEM fn Struct::bar::foo
             fn foo() {}
             foo();
         }
 
         {
-            //~ MONO_ITEM fn non_generic_functions::{{impl}}[0]::bar[0]::foo[1]
+            //~ MONO_ITEM fn Struct::bar::foo
             fn foo() {}
             foo();
         }
     }
 }
 
-//~ MONO_ITEM fn non_generic_functions::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
     foo();
diff --git a/src/test/codegen-units/item-collection/overloaded-operators.rs b/src/test/codegen-units/item-collection/overloaded-operators.rs
index 0b4c97723d6..2be7eba1d84 100644
--- a/src/test/codegen-units/item-collection/overloaded-operators.rs
+++ b/src/test/codegen-units/item-collection/overloaded-operators.rs
@@ -12,7 +12,7 @@ pub struct Indexable {
 impl Index<usize> for Indexable {
     type Output = u8;
 
-    //~ MONO_ITEM fn overloaded_operators::{{impl}}[0]::index[0]
+    //~ MONO_ITEM fn <Indexable as std::ops::Index<usize>>::index
     fn index(&self, index: usize) -> &Self::Output {
         if index >= 3 {
             &self.data[0]
@@ -23,7 +23,7 @@ impl Index<usize> for Indexable {
 }
 
 impl IndexMut<usize> for Indexable {
-    //~ MONO_ITEM fn overloaded_operators::{{impl}}[1]::index_mut[0]
+    //~ MONO_ITEM fn <Indexable as std::ops::IndexMut<usize>>::index_mut
     fn index_mut(&mut self, index: usize) -> &mut Self::Output {
         if index >= 3 {
             &mut self.data[0]
@@ -34,8 +34,8 @@ impl IndexMut<usize> for Indexable {
 }
 
 
-//~ MONO_ITEM fn overloaded_operators::{{impl}}[5]::eq[0]
-//~ MONO_ITEM fn overloaded_operators::{{impl}}[5]::ne[0]
+//~ MONO_ITEM fn <Equatable as std::cmp::PartialEq>::eq
+//~ MONO_ITEM fn <Equatable as std::cmp::PartialEq>::ne
 #[derive(PartialEq)]
 pub struct Equatable(u32);
 
@@ -43,7 +43,7 @@ pub struct Equatable(u32);
 impl Add<u32> for Equatable {
     type Output = u32;
 
-    //~ MONO_ITEM fn overloaded_operators::{{impl}}[2]::add[0]
+    //~ MONO_ITEM fn <Equatable as std::ops::Add<u32>>::add
     fn add(self, rhs: u32) -> u32 {
         self.0 + rhs
     }
@@ -52,7 +52,7 @@ impl Add<u32> for Equatable {
 impl Deref for Equatable {
     type Target = u32;
 
-    //~ MONO_ITEM fn overloaded_operators::{{impl}}[3]::deref[0]
+    //~ MONO_ITEM fn <Equatable as std::ops::Deref>::deref
     fn deref(&self) -> &Self::Target {
         &self.0
     }
diff --git a/src/test/codegen-units/item-collection/static-init.rs b/src/test/codegen-units/item-collection/static-init.rs
index 9d79171c4cb..287ec8f24eb 100644
--- a/src/test/codegen-units/item-collection/static-init.rs
+++ b/src/test/codegen-units/item-collection/static-init.rs
@@ -6,10 +6,10 @@ pub static FN : fn() = foo::<i32>;
 
 pub fn foo<T>() { }
 
-//~ MONO_ITEM fn static_init::foo[0]<T>
-//~ MONO_ITEM static static_init::FN[0]
+//~ MONO_ITEM fn foo::<T>
+//~ MONO_ITEM static FN
 
-//~ MONO_ITEM fn static_init::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
     0
diff --git a/src/test/codegen-units/item-collection/statics-and-consts.rs b/src/test/codegen-units/item-collection/statics-and-consts.rs
index 7e28ba58b63..49a8d3dff63 100644
--- a/src/test/codegen-units/item-collection/statics-and-consts.rs
+++ b/src/test/codegen-units/item-collection/statics-and-consts.rs
@@ -37,7 +37,7 @@ fn foo() {
     };
 }
 
-//~ MONO_ITEM fn statics_and_consts::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
     foo();
@@ -46,9 +46,9 @@ fn start(_: isize, _: *const *const u8) -> isize {
     0
 }
 
-//~ MONO_ITEM static statics_and_consts::STATIC1[0]
+//~ MONO_ITEM static STATIC1
 
-//~ MONO_ITEM fn statics_and_consts::foo[0]
-//~ MONO_ITEM static statics_and_consts::foo[0]::STATIC2[0]
-//~ MONO_ITEM static statics_and_consts::foo[0]::STATIC2[1]
-//~ MONO_ITEM static statics_and_consts::foo[0]::STATIC2[2]
+//~ MONO_ITEM fn foo
+//~ MONO_ITEM static foo::STATIC2
+//~ MONO_ITEM static foo::STATIC2
+//~ MONO_ITEM static foo::STATIC2
diff --git a/src/test/codegen-units/item-collection/trait-implementations.rs b/src/test/codegen-units/item-collection/trait-implementations.rs
index f090c0c8d13..a816cb03241 100644
--- a/src/test/codegen-units/item-collection/trait-implementations.rs
+++ b/src/test/codegen-units/item-collection/trait-implementations.rs
@@ -10,7 +10,7 @@ pub trait SomeTrait {
 
 impl SomeTrait for i64 {
 
-    //~ MONO_ITEM fn trait_implementations::{{impl}}[0]::foo[0]
+    //~ MONO_ITEM fn <i64 as SomeTrait>::foo
     fn foo(&self) {}
 
     fn bar<T>(&self, _: T) {}
@@ -18,7 +18,7 @@ impl SomeTrait for i64 {
 
 impl SomeTrait for i32 {
 
-    //~ MONO_ITEM fn trait_implementations::{{impl}}[1]::foo[0]
+    //~ MONO_ITEM fn <i32 as SomeTrait>::foo
     fn foo(&self) {}
 
     fn bar<T>(&self, _: T) {}
@@ -32,7 +32,7 @@ pub trait SomeGenericTrait<T> {
 // Concrete impl of generic trait
 impl SomeGenericTrait<u32> for f64 {
 
-    //~ MONO_ITEM fn trait_implementations::{{impl}}[2]::foo[0]
+    //~ MONO_ITEM fn <f64 as SomeGenericTrait<u32>>::foo
     fn foo(&self, _: u32) {}
 
     fn bar<T2>(&self, _: u32, _: T2) {}
@@ -45,28 +45,28 @@ impl<T> SomeGenericTrait<T> for f32 {
     fn bar<T2>(&self, _: T, _: T2) {}
 }
 
-//~ MONO_ITEM fn trait_implementations::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
-   //~ MONO_ITEM fn trait_implementations::{{impl}}[1]::bar[0]<char>
+   //~ MONO_ITEM fn <i32 as SomeTrait>::bar::<char>
    0i32.bar('x');
 
-   //~ MONO_ITEM fn trait_implementations::{{impl}}[2]::bar[0]<&str>
+   //~ MONO_ITEM fn <f64 as SomeGenericTrait<u32>>::bar::<&str>
    0f64.bar(0u32, "&str");
 
-   //~ MONO_ITEM fn trait_implementations::{{impl}}[2]::bar[0]<()>
+   //~ MONO_ITEM fn <f64 as SomeGenericTrait<u32>>::bar::<()>
    0f64.bar(0u32, ());
 
-   //~ MONO_ITEM fn trait_implementations::{{impl}}[3]::foo[0]<char>
+   //~ MONO_ITEM fn <f32 as SomeGenericTrait<char>>::foo
    0f32.foo('x');
 
-   //~ MONO_ITEM fn trait_implementations::{{impl}}[3]::foo[0]<i64>
+   //~ MONO_ITEM fn <f32 as SomeGenericTrait<i64>>::foo
    0f32.foo(-1i64);
 
-   //~ MONO_ITEM fn trait_implementations::{{impl}}[3]::bar[0]<u32, ()>
+   //~ MONO_ITEM fn <f32 as SomeGenericTrait<u32>>::bar::<()>
    0f32.bar(0u32, ());
 
-   //~ MONO_ITEM fn trait_implementations::{{impl}}[3]::bar[0]<&str, &str>
+   //~ MONO_ITEM fn <f32 as SomeGenericTrait<&str>>::bar::<&str>
    0f32.bar("&str", "&str");
 
    0
diff --git a/src/test/codegen-units/item-collection/trait-method-as-argument.rs b/src/test/codegen-units/item-collection/trait-method-as-argument.rs
index 27ace8e31ad..6817b33c611 100644
--- a/src/test/codegen-units/item-collection/trait-method-as-argument.rs
+++ b/src/test/codegen-units/item-collection/trait-method-as-argument.rs
@@ -1,3 +1,4 @@
+// ignore-tidy-linelength
 // compile-flags:-Zprint-mono-items=eager
 
 #![deny(dead_code)]
@@ -26,33 +27,33 @@ fn take_foo_mut<T, F: FnMut(T) -> T>(mut f: F, arg: T) -> T {
     (f)(arg)
 }
 
-//~ MONO_ITEM fn trait_method_as_argument::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
-    //~ MONO_ITEM fn trait_method_as_argument::take_foo_once[0]<u32, fn(u32) -> u32>
-    //~ MONO_ITEM fn trait_method_as_argument::{{impl}}[0]::foo[0]
-    //~ MONO_ITEM fn core::ops[0]::function[0]::FnOnce[0]::call_once[0]<fn(u32) -> u32, (u32)>
+    //~ MONO_ITEM fn take_foo_once::<u32, fn(u32) -> u32 {<u32 as Trait>::foo}>
+    //~ MONO_ITEM fn <u32 as Trait>::foo
+    //~ MONO_ITEM fn <fn(u32) -> u32 {<u32 as Trait>::foo} as std::ops::FnOnce<(u32,)>>::call_once - shim(fn(u32) -> u32 {<u32 as Trait>::foo})
     take_foo_once(Trait::foo, 0u32);
 
-    //~ MONO_ITEM fn trait_method_as_argument::take_foo_once[0]<char, fn(char) -> char>
-    //~ MONO_ITEM fn trait_method_as_argument::Trait[0]::foo[0]<char>
-    //~ MONO_ITEM fn core::ops[0]::function[0]::FnOnce[0]::call_once[0]<fn(char) -> char, (char)>
+    //~ MONO_ITEM fn take_foo_once::<char, fn(char) -> char {<char as Trait>::foo}>
+    //~ MONO_ITEM fn <char as Trait>::foo
+    //~ MONO_ITEM fn <fn(char) -> char {<char as Trait>::foo} as std::ops::FnOnce<(char,)>>::call_once - shim(fn(char) -> char {<char as Trait>::foo})
     take_foo_once(Trait::foo, 'c');
 
-    //~ MONO_ITEM fn trait_method_as_argument::take_foo[0]<u32, fn(u32) -> u32>
-    //~ MONO_ITEM fn core::ops[0]::function[0]::Fn[0]::call[0]<fn(u32) -> u32, (u32)>
+    //~ MONO_ITEM fn take_foo::<u32, fn(u32) -> u32 {<u32 as Trait>::foo}>
+    //~ MONO_ITEM fn <fn(u32) -> u32 {<u32 as Trait>::foo} as std::ops::Fn<(u32,)>>::call - shim(fn(u32) -> u32 {<u32 as Trait>::foo})
     take_foo(Trait::foo, 0u32);
 
-    //~ MONO_ITEM fn trait_method_as_argument::take_foo[0]<char, fn(char) -> char>
-    //~ MONO_ITEM fn core::ops[0]::function[0]::Fn[0]::call[0]<fn(char) -> char, (char)>
+    //~ MONO_ITEM fn take_foo::<char, fn(char) -> char {<char as Trait>::foo}>
+    //~ MONO_ITEM fn <fn(char) -> char {<char as Trait>::foo} as std::ops::Fn<(char,)>>::call - shim(fn(char) -> char {<char as Trait>::foo})
     take_foo(Trait::foo, 'c');
 
-    //~ MONO_ITEM fn trait_method_as_argument::take_foo_mut[0]<u32, fn(u32) -> u32>
-    //~ MONO_ITEM fn core::ops[0]::function[0]::FnMut[0]::call_mut[0]<fn(char) -> char, (char)>
+    //~ MONO_ITEM fn take_foo_mut::<u32, fn(u32) -> u32 {<u32 as Trait>::foo}>
+    //~ MONO_ITEM fn <fn(u32) -> u32 {<u32 as Trait>::foo} as std::ops::FnMut<(u32,)>>::call_mut - shim(fn(u32) -> u32 {<u32 as Trait>::foo})
     take_foo_mut(Trait::foo, 0u32);
 
-    //~ MONO_ITEM fn trait_method_as_argument::take_foo_mut[0]<char, fn(char) -> char>
-    //~ MONO_ITEM fn core::ops[0]::function[0]::FnMut[0]::call_mut[0]<fn(u32) -> u32, (u32)>
+    //~ MONO_ITEM fn take_foo_mut::<char, fn(char) -> char {<char as Trait>::foo}>
+    //~ MONO_ITEM fn <fn(char) -> char {<char as Trait>::foo} as std::ops::FnMut<(char,)>>::call_mut - shim(fn(char) -> char {<char as Trait>::foo})
     take_foo_mut(Trait::foo, 'c');
 
     0
diff --git a/src/test/codegen-units/item-collection/trait-method-default-impl.rs b/src/test/codegen-units/item-collection/trait-method-default-impl.rs
index 6cf59fdc396..bfcdb6fa142 100644
--- a/src/test/codegen-units/item-collection/trait-method-default-impl.rs
+++ b/src/test/codegen-units/item-collection/trait-method-default-impl.rs
@@ -13,7 +13,7 @@ impl SomeTrait for i8 {
 
     // For the non-generic foo(), we should generate a codegen-item even if it
     // is not called anywhere
-    //~ MONO_ITEM fn trait_method_default_impl::SomeTrait[0]::foo[0]<i8>
+    //~ MONO_ITEM fn <i8 as SomeTrait>::foo
 }
 
 trait SomeGenericTrait<T1> {
@@ -27,7 +27,7 @@ impl SomeGenericTrait<u64> for i32 {
 
     // For the non-generic foo(), we should generate a codegen-item even if it
     // is not called anywhere
-    //~ MONO_ITEM fn trait_method_default_impl::SomeGenericTrait[0]::foo[0]<i32, T1>
+    //~ MONO_ITEM fn <i32 as SomeGenericTrait<T1>>::foo
 }
 
 // Non-generic impl of generic trait
@@ -36,25 +36,25 @@ impl<T1> SomeGenericTrait<T1> for u32 {
     // since nothing is monomorphic here, nothing should be generated unless used somewhere.
 }
 
-//~ MONO_ITEM fn trait_method_default_impl::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
-    //~ MONO_ITEM fn trait_method_default_impl::SomeTrait[0]::bar[0]<i8, char>
+    //~ MONO_ITEM fn <i8 as SomeTrait>::bar::<char>
     let _ = 1i8.bar('c');
 
-    //~ MONO_ITEM fn trait_method_default_impl::SomeTrait[0]::bar[0]<i8, &str>
+    //~ MONO_ITEM fn <i8 as SomeTrait>::bar::<&str>
     let _ = 2i8.bar("&str");
 
-    //~ MONO_ITEM fn trait_method_default_impl::SomeGenericTrait[0]::bar[0]<i32, u64, char>
+    //~ MONO_ITEM fn <i32 as SomeGenericTrait<u64>>::bar::<char>
     0i32.bar(0u64, 'c');
 
-    //~ MONO_ITEM fn trait_method_default_impl::SomeGenericTrait[0]::bar[0]<i32, u64, &str>
+    //~ MONO_ITEM fn <i32 as SomeGenericTrait<u64>>::bar::<&str>
     0i32.bar(0u64, "&str");
 
-    //~ MONO_ITEM fn trait_method_default_impl::SomeGenericTrait[0]::bar[0]<u32, i8, &[char; 1]>
+    //~ MONO_ITEM fn <u32 as SomeGenericTrait<i8>>::bar::<&[char; 1]>
     0u32.bar(0i8, &['c']);
 
-    //~ MONO_ITEM fn trait_method_default_impl::SomeGenericTrait[0]::bar[0]<u32, i16, ()>
+    //~ MONO_ITEM fn <u32 as SomeGenericTrait<i16>>::bar::<()>
     0u32.bar(0i16, ());
 
     0
diff --git a/src/test/codegen-units/item-collection/transitive-drop-glue.rs b/src/test/codegen-units/item-collection/transitive-drop-glue.rs
index 7e29af43538..c0489a6a259 100644
--- a/src/test/codegen-units/item-collection/transitive-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/transitive-drop-glue.rs
@@ -5,15 +5,15 @@
 #![deny(dead_code)]
 #![feature(start)]
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Root[0]> @@ transitive_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn std::intrinsics::drop_in_place::<Root> - shim(Some(Root)) @@ transitive_drop_glue-cgu.0[Internal]
 struct Root(Intermediate);
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Intermediate[0]> @@ transitive_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn std::intrinsics::drop_in_place::<Intermediate> - shim(Some(Intermediate)) @@ transitive_drop_glue-cgu.0[Internal]
 struct Intermediate(Leaf);
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Leaf[0]> @@ transitive_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn std::intrinsics::drop_in_place::<Leaf> - shim(Some(Leaf)) @@ transitive_drop_glue-cgu.0[Internal]
 struct Leaf;
 
 impl Drop for Leaf {
-    //~ MONO_ITEM fn transitive_drop_glue::{{impl}}[0]::drop[0]
+    //~ MONO_ITEM fn <Leaf as std::ops::Drop>::drop
     fn drop(&mut self) {}
 }
 
@@ -25,21 +25,21 @@ impl<T> Drop for LeafGen<T> {
     fn drop(&mut self) {}
 }
 
-//~ MONO_ITEM fn transitive_drop_glue::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
     let _ = Root(Intermediate(Leaf));
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::RootGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::LeafGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn transitive_drop_glue::{{impl}}[1]::drop[0]<u32>
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<RootGen<u32>> - shim(Some(RootGen<u32>)) @@ transitive_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<IntermediateGen<u32>> - shim(Some(IntermediateGen<u32>)) @@ transitive_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<LeafGen<u32>> - shim(Some(LeafGen<u32>)) @@ transitive_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn <LeafGen<u32> as std::ops::Drop>::drop
     let _ = RootGen(IntermediateGen(LeafGen(0u32)));
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::RootGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::LeafGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn transitive_drop_glue::{{impl}}[1]::drop[0]<i16>
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<RootGen<i16>> - shim(Some(RootGen<i16>)) @@ transitive_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<IntermediateGen<i16>> - shim(Some(IntermediateGen<i16>)) @@ transitive_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<LeafGen<i16>> - shim(Some(LeafGen<i16>)) @@ transitive_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn <LeafGen<i16> as std::ops::Drop>::drop
     let _ = RootGen(IntermediateGen(LeafGen(0i16)));
 
     0
diff --git a/src/test/codegen-units/item-collection/tuple-drop-glue.rs b/src/test/codegen-units/item-collection/tuple-drop-glue.rs
index d77de53ce01..d34835ae691 100644
--- a/src/test/codegen-units/item-collection/tuple-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/tuple-drop-glue.rs
@@ -5,22 +5,22 @@
 #![deny(dead_code)]
 #![feature(start)]
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<tuple_drop_glue::Dropped[0]> @@ tuple_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn std::intrinsics::drop_in_place::<Dropped> - shim(Some(Dropped)) @@ tuple_drop_glue-cgu.0[Internal]
 struct Dropped;
 
 impl Drop for Dropped {
-    //~ MONO_ITEM fn tuple_drop_glue::{{impl}}[0]::drop[0]
+    //~ MONO_ITEM fn <Dropped as std::ops::Drop>::drop
     fn drop(&mut self) {}
 }
 
-//~ MONO_ITEM fn tuple_drop_glue::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, tuple_drop_glue::Dropped[0])> @@ tuple_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<(u32, Dropped)> - shim(Some((u32, Dropped))) @@ tuple_drop_glue-cgu.0[Internal]
     let x = (0u32, Dropped);
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(i16, (tuple_drop_glue::Dropped[0], bool))> @@ tuple_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(tuple_drop_glue::Dropped[0], bool)> @@ tuple_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<(i16, (Dropped, bool))> - shim(Some((i16, (Dropped, bool)))) @@ tuple_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<(Dropped, bool)> - shim(Some((Dropped, bool)))  @@ tuple_drop_glue-cgu.0[Internal]
     let x = (0i16, (Dropped, true));
 
     0
diff --git a/src/test/codegen-units/item-collection/unreferenced-const-fn.rs b/src/test/codegen-units/item-collection/unreferenced-const-fn.rs
index ec6be0ecf43..17b92eae00d 100644
--- a/src/test/codegen-units/item-collection/unreferenced-const-fn.rs
+++ b/src/test/codegen-units/item-collection/unreferenced-const-fn.rs
@@ -3,7 +3,7 @@
 #![deny(dead_code)]
 #![crate_type = "rlib"]
 
-//~ MONO_ITEM fn unreferenced_const_fn::foo[0] @@ unreferenced_const_fn-cgu.0[External]
+//~ MONO_ITEM fn foo @@ unreferenced_const_fn-cgu.0[External]
 pub const fn foo(x: u32) -> u32 {
     x + 0xf00
 }
diff --git a/src/test/codegen-units/item-collection/unsizing.rs b/src/test/codegen-units/item-collection/unsizing.rs
index 1ed60dcf265..9421bf106ba 100644
--- a/src/test/codegen-units/item-collection/unsizing.rs
+++ b/src/test/codegen-units/item-collection/unsizing.rs
@@ -43,19 +43,19 @@ struct Wrapper<T: ?Sized>(*const T);
 
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Wrapper<U>> for Wrapper<T> {}
 
-//~ MONO_ITEM fn unsizing::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
     // simple case
     let bool_sized = &true;
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<bool> @@ unsizing-cgu.0[Internal]
-    //~ MONO_ITEM fn unsizing::{{impl}}[0]::foo[0]
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<bool> - shim(None) @@ unsizing-cgu.0[Internal]
+    //~ MONO_ITEM fn <bool as Trait>::foo
     let _bool_unsized = bool_sized as &Trait;
 
     let char_sized = &'a';
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<char> @@ unsizing-cgu.0[Internal]
-    //~ MONO_ITEM fn unsizing::{{impl}}[1]::foo[0]
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<char> - shim(None) @@ unsizing-cgu.0[Internal]
+    //~ MONO_ITEM fn <char as Trait>::foo
     let _char_unsized = char_sized as &Trait;
 
     // struct field
@@ -64,14 +64,14 @@ fn start(_: isize, _: *const *const u8) -> isize {
         _b: 2,
         _c: 3.0f64
     };
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<f64> @@ unsizing-cgu.0[Internal]
-    //~ MONO_ITEM fn unsizing::{{impl}}[2]::foo[0]
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<f64> - shim(None) @@ unsizing-cgu.0[Internal]
+    //~ MONO_ITEM fn <f64 as Trait>::foo
     let _struct_unsized = struct_sized as &Struct<Trait>;
 
     // custom coercion
     let wrapper_sized = Wrapper(&0u32);
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<u32> @@ unsizing-cgu.0[Internal]
-    //~ MONO_ITEM fn unsizing::{{impl}}[3]::foo[0]
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<u32> - shim(None) @@ unsizing-cgu.0[Internal]
+    //~ MONO_ITEM fn <u32 as Trait>::foo
     let _wrapper_sized = wrapper_sized as Wrapper<Trait>;
 
     0
diff --git a/src/test/codegen-units/item-collection/unused-traits-and-generics.rs b/src/test/codegen-units/item-collection/unused-traits-and-generics.rs
index 4a5e294ea0f..561dc1a5c07 100644
--- a/src/test/codegen-units/item-collection/unused-traits-and-generics.rs
+++ b/src/test/codegen-units/item-collection/unused-traits-and-generics.rs
@@ -74,4 +74,4 @@ impl NonGeneric {
 }
 
 // Only the non-generic methods should be instantiated:
-//~ MONO_ITEM fn unused_traits_and_generics::{{impl}}[3]::foo[0]
+//~ MONO_ITEM fn NonGeneric::foo
diff --git a/src/test/codegen-units/partitioning/extern-drop-glue.rs b/src/test/codegen-units/partitioning/extern-drop-glue.rs
index 1cb85382239..3de1bdb86c1 100644
--- a/src/test/codegen-units/partitioning/extern-drop-glue.rs
+++ b/src/test/codegen-units/partitioning/extern-drop-glue.rs
@@ -12,13 +12,13 @@
 // aux-build:cgu_extern_drop_glue.rs
 extern crate cgu_extern_drop_glue;
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<cgu_extern_drop_glue::Struct[0]> @@ extern_drop_glue-fallback.cgu[External]
+//~ MONO_ITEM fn std::intrinsics::drop_in_place::<cgu_extern_drop_glue::Struct> - shim(Some(cgu_extern_drop_glue::Struct)) @@ extern_drop_glue-fallback.cgu[External]
 
 struct LocalStruct(cgu_extern_drop_glue::Struct);
 
-//~ MONO_ITEM fn extern_drop_glue::user[0] @@ extern_drop_glue[External]
+//~ MONO_ITEM fn user @@ extern_drop_glue[External]
 pub fn user() {
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::LocalStruct[0]> @@ extern_drop_glue-fallback.cgu[External]
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<LocalStruct> - shim(Some(LocalStruct)) @@ extern_drop_glue-fallback.cgu[External]
     let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
 }
 
@@ -27,9 +27,9 @@ pub mod mod1 {
 
     struct LocalStruct(cgu_extern_drop_glue::Struct);
 
-    //~ MONO_ITEM fn extern_drop_glue::mod1[0]::user[0] @@ extern_drop_glue-mod1[External]
+    //~ MONO_ITEM fn mod1::user @@ extern_drop_glue-mod1[External]
     pub fn user() {
-        //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::mod1[0]::LocalStruct[0]> @@ extern_drop_glue-fallback.cgu[External]
+        //~ MONO_ITEM fn std::intrinsics::drop_in_place::<mod1::LocalStruct> - shim(Some(mod1::LocalStruct)) @@ extern_drop_glue-fallback.cgu[External]
         let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
     }
 }
diff --git a/src/test/codegen-units/partitioning/extern-generic.rs b/src/test/codegen-units/partitioning/extern-generic.rs
index 88d6116a987..02930f96bd1 100644
--- a/src/test/codegen-units/partitioning/extern-generic.rs
+++ b/src/test/codegen-units/partitioning/extern-generic.rs
@@ -9,7 +9,7 @@
 // aux-build:cgu_generic_function.rs
 extern crate cgu_generic_function;
 
-//~ MONO_ITEM fn extern_generic::user[0] @@ extern_generic[Internal]
+//~ MONO_ITEM fn user @@ extern_generic[Internal]
 fn user() {
     let _ = cgu_generic_function::foo("abc");
 }
@@ -17,7 +17,7 @@ fn user() {
 mod mod1 {
     use cgu_generic_function;
 
-    //~ MONO_ITEM fn extern_generic::mod1[0]::user[0] @@ extern_generic-mod1[Internal]
+    //~ MONO_ITEM fn mod1::user @@ extern_generic-mod1[Internal]
     fn user() {
         let _ = cgu_generic_function::foo("abc");
     }
@@ -25,7 +25,7 @@ mod mod1 {
     mod mod1 {
         use cgu_generic_function;
 
-        //~ MONO_ITEM fn extern_generic::mod1[0]::mod1[0]::user[0] @@ extern_generic-mod1-mod1[Internal]
+        //~ MONO_ITEM fn mod1::mod1::user @@ extern_generic-mod1-mod1[Internal]
         fn user() {
             let _ = cgu_generic_function::foo("abc");
         }
@@ -35,18 +35,18 @@ mod mod1 {
 mod mod2 {
     use cgu_generic_function;
 
-    //~ MONO_ITEM fn extern_generic::mod2[0]::user[0] @@ extern_generic-mod2[Internal]
+    //~ MONO_ITEM fn mod2::user @@ extern_generic-mod2[Internal]
     fn user() {
         let _ = cgu_generic_function::foo("abc");
     }
 }
 
 mod mod3 {
-    //~ MONO_ITEM fn extern_generic::mod3[0]::non_user[0] @@ extern_generic-mod3[Internal]
+    //~ MONO_ITEM fn mod3::non_user @@ extern_generic-mod3[Internal]
     fn non_user() {}
 }
 
 // Make sure the two generic functions from the extern crate get instantiated
 // once for the current crate
-//~ MONO_ITEM fn cgu_generic_function::foo[0]<&str> @@ cgu_generic_function-in-extern_generic.volatile[External]
-//~ MONO_ITEM fn cgu_generic_function::bar[0]<&str> @@ cgu_generic_function-in-extern_generic.volatile[External]
+//~ MONO_ITEM fn cgu_generic_function::foo::<&str> @@ cgu_generic_function-in-extern_generic.volatile[External]
+//~ MONO_ITEM fn cgu_generic_function::bar::<&str> @@ cgu_generic_function-in-extern_generic.volatile[External]
diff --git a/src/test/codegen-units/partitioning/incremental-merging.rs b/src/test/codegen-units/partitioning/incremental-merging.rs
index ca2df19096e..91ae6022931 100644
--- a/src/test/codegen-units/partitioning/incremental-merging.rs
+++ b/src/test/codegen-units/partitioning/incremental-merging.rs
@@ -1,4 +1,3 @@
-// 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
@@ -14,28 +13,28 @@
 // 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]
+    //~ MONO_ITEM fn aaa::foo @@ 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]
+    //~ MONO_ITEM fn bbb::foo @@ 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]
+    //~ MONO_ITEM fn ccc::foo @@ 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]
+    //~ MONO_ITEM fn ddd::foo @@ incremental_merging-ddd[External]
     pub fn foo(a: u64, b: u64, c: u64, d: u64) -> u64 {
         a + b + c + d + 1
     }
diff --git a/src/test/codegen-units/partitioning/inlining-from-extern-crate.rs b/src/test/codegen-units/partitioning/inlining-from-extern-crate.rs
index 7afeb0a0f36..410b77b0050 100644
--- a/src/test/codegen-units/partitioning/inlining-from-extern-crate.rs
+++ b/src/test/codegen-units/partitioning/inlining-from-extern-crate.rs
@@ -12,10 +12,10 @@ extern crate cgu_explicit_inlining;
 // This test makes sure that items inlined from external crates are privately
 // instantiated in every codegen unit they are used in.
 
-//~ MONO_ITEM fn cgu_explicit_inlining::inlined[0] @@ inlining_from_extern_crate[Internal] inlining_from_extern_crate-mod1[Internal]
-//~ MONO_ITEM fn cgu_explicit_inlining::always_inlined[0] @@ inlining_from_extern_crate[Internal] inlining_from_extern_crate-mod2[Internal]
+//~ MONO_ITEM fn cgu_explicit_inlining::inlined @@ inlining_from_extern_crate[Internal] inlining_from_extern_crate-mod1[Internal]
+//~ MONO_ITEM fn cgu_explicit_inlining::always_inlined @@ inlining_from_extern_crate[Internal] inlining_from_extern_crate-mod2[Internal]
 
-//~ MONO_ITEM fn inlining_from_extern_crate::user[0] @@ inlining_from_extern_crate[External]
+//~ MONO_ITEM fn user @@ inlining_from_extern_crate[External]
 pub fn user()
 {
     cgu_explicit_inlining::inlined();
@@ -28,7 +28,7 @@ pub fn user()
 pub mod mod1 {
     use cgu_explicit_inlining;
 
-    //~ MONO_ITEM fn inlining_from_extern_crate::mod1[0]::user[0] @@ inlining_from_extern_crate-mod1[External]
+    //~ MONO_ITEM fn mod1::user @@ inlining_from_extern_crate-mod1[External]
     pub fn user()
     {
         cgu_explicit_inlining::inlined();
@@ -41,7 +41,7 @@ pub mod mod1 {
 pub mod mod2 {
     use cgu_explicit_inlining;
 
-    //~ MONO_ITEM fn inlining_from_extern_crate::mod2[0]::user[0] @@ inlining_from_extern_crate-mod2[External]
+    //~ MONO_ITEM fn mod2::user @@ inlining_from_extern_crate-mod2[External]
     pub fn user()
     {
         cgu_explicit_inlining::always_inlined();
diff --git a/src/test/codegen-units/partitioning/local-drop-glue.rs b/src/test/codegen-units/partitioning/local-drop-glue.rs
index c082b408278..98108615ce9 100644
--- a/src/test/codegen-units/partitioning/local-drop-glue.rs
+++ b/src/test/codegen-units/partitioning/local-drop-glue.rs
@@ -8,22 +8,22 @@
 #![allow(dead_code)]
 #![crate_type = "rlib"]
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::Struct[0]> @@ local_drop_glue-fallback.cgu[External]
+//~ MONO_ITEM fn std::intrinsics::drop_in_place::<Struct> - shim(Some(Struct)) @@ local_drop_glue-fallback.cgu[External]
 struct Struct {
     _a: u32,
 }
 
 impl Drop for Struct {
-    //~ MONO_ITEM fn local_drop_glue::{{impl}}[0]::drop[0] @@ local_drop_glue-fallback.cgu[External]
+    //~ MONO_ITEM fn <Struct as std::ops::Drop>::drop @@ local_drop_glue-fallback.cgu[External]
     fn drop(&mut self) {}
 }
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::Outer[0]> @@ local_drop_glue-fallback.cgu[External]
+//~ MONO_ITEM fn std::intrinsics::drop_in_place::<Outer> - shim(Some(Outer)) @@ local_drop_glue-fallback.cgu[External]
 struct Outer {
     _a: Struct,
 }
 
-//~ MONO_ITEM fn local_drop_glue::user[0] @@ local_drop_glue[External]
+//~ MONO_ITEM fn user @@ local_drop_glue[External]
 pub fn user() {
     let _ = Outer { _a: Struct { _a: 0 } };
 }
@@ -31,14 +31,14 @@ pub fn user() {
 pub mod mod1 {
     use super::Struct;
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::mod1[0]::Struct2[0]> @@ local_drop_glue-fallback.cgu[External]
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<mod1::Struct2> - shim(Some(mod1::Struct2)) @@ local_drop_glue-fallback.cgu[External]
     struct Struct2 {
         _a: Struct,
-        //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-fallback.cgu[Internal]
+        //~ MONO_ITEM fn std::intrinsics::drop_in_place::<(u32, Struct)> - shim(Some((u32, Struct))) @@ local_drop_glue-fallback.cgu[Internal]
         _b: (u32, Struct),
     }
 
-    //~ MONO_ITEM fn local_drop_glue::mod1[0]::user[0] @@ local_drop_glue-mod1[External]
+    //~ MONO_ITEM fn mod1::user @@ local_drop_glue-mod1[External]
     pub fn user() {
         let _ = Struct2 { _a: Struct { _a: 0 }, _b: (0, Struct { _a: 0 }) };
     }
diff --git a/src/test/codegen-units/partitioning/local-generic.rs b/src/test/codegen-units/partitioning/local-generic.rs
index 4518166a1c9..9a7743bbf46 100644
--- a/src/test/codegen-units/partitioning/local-generic.rs
+++ b/src/test/codegen-units/partitioning/local-generic.rs
@@ -1,4 +1,3 @@
-// ignore-tidy-linelength
 // We specify -C incremental here because we want to test the partitioning for
 // incremental compilation
 // compile-flags:-Zprint-mono-items=eager -Cincremental=tmp/partitioning-tests/local-generic
@@ -6,13 +5,13 @@
 #![allow(dead_code)]
 #![crate_type="lib"]
 
-//~ MONO_ITEM fn local_generic::generic[0]<u32> @@ local_generic.volatile[External]
-//~ MONO_ITEM fn local_generic::generic[0]<u64> @@ local_generic.volatile[External]
-//~ MONO_ITEM fn local_generic::generic[0]<char> @@ local_generic.volatile[External]
-//~ MONO_ITEM fn local_generic::generic[0]<&str> @@ local_generic.volatile[External]
+//~ MONO_ITEM fn generic::<u32> @@ local_generic.volatile[External]
+//~ MONO_ITEM fn generic::<u64> @@ local_generic.volatile[External]
+//~ MONO_ITEM fn generic::<char> @@ local_generic.volatile[External]
+//~ MONO_ITEM fn generic::<&str> @@ local_generic.volatile[External]
 pub fn generic<T>(x: T) -> T { x }
 
-//~ MONO_ITEM fn local_generic::user[0] @@ local_generic[Internal]
+//~ MONO_ITEM fn user @@ local_generic[Internal]
 fn user() {
     let _ = generic(0u32);
 }
@@ -20,7 +19,7 @@ fn user() {
 mod mod1 {
     pub use super::generic;
 
-    //~ MONO_ITEM fn local_generic::mod1[0]::user[0] @@ local_generic-mod1[Internal]
+    //~ MONO_ITEM fn mod1::user @@ local_generic-mod1[Internal]
     fn user() {
         let _ = generic(0u64);
     }
@@ -28,7 +27,7 @@ mod mod1 {
     mod mod1 {
         use super::generic;
 
-        //~ MONO_ITEM fn local_generic::mod1[0]::mod1[0]::user[0] @@ local_generic-mod1-mod1[Internal]
+        //~ MONO_ITEM fn mod1::mod1::user @@ local_generic-mod1-mod1[Internal]
         fn user() {
             let _ = generic('c');
         }
@@ -38,7 +37,7 @@ mod mod1 {
 mod mod2 {
     use super::generic;
 
-    //~ MONO_ITEM fn local_generic::mod2[0]::user[0] @@ local_generic-mod2[Internal]
+    //~ MONO_ITEM fn mod2::user @@ local_generic-mod2[Internal]
     fn user() {
         let _ = generic("abc");
     }
diff --git a/src/test/codegen-units/partitioning/local-inlining-but-not-all.rs b/src/test/codegen-units/partitioning/local-inlining-but-not-all.rs
index 6322f55d2b7..a24943348f3 100644
--- a/src/test/codegen-units/partitioning/local-inlining-but-not-all.rs
+++ b/src/test/codegen-units/partitioning/local-inlining-but-not-all.rs
@@ -9,7 +9,7 @@
 
 mod inline {
 
-    //~ MONO_ITEM fn local_inlining_but_not_all::inline[0]::inlined_function[0] @@ local_inlining_but_not_all-inline[External]
+    //~ MONO_ITEM fn inline::inlined_function @@ local_inlining_but_not_all-inline[External]
     #[inline]
     pub fn inlined_function()
     {
@@ -20,7 +20,7 @@ mod inline {
 pub mod user1 {
     use super::inline;
 
-    //~ MONO_ITEM fn local_inlining_but_not_all::user1[0]::foo[0] @@ local_inlining_but_not_all-user1[External]
+    //~ MONO_ITEM fn user1::foo @@ local_inlining_but_not_all-user1[External]
     pub fn foo() {
         inline::inlined_function();
     }
@@ -29,7 +29,7 @@ pub mod user1 {
 pub mod user2 {
     use super::inline;
 
-    //~ MONO_ITEM fn local_inlining_but_not_all::user2[0]::bar[0] @@ local_inlining_but_not_all-user2[External]
+    //~ MONO_ITEM fn user2::bar @@ local_inlining_but_not_all-user2[External]
     pub fn bar() {
         inline::inlined_function();
     }
@@ -37,7 +37,7 @@ pub mod user2 {
 
 pub mod non_user {
 
-    //~ MONO_ITEM fn local_inlining_but_not_all::non_user[0]::baz[0] @@ local_inlining_but_not_all-non_user[External]
+    //~ MONO_ITEM fn non_user::baz @@ local_inlining_but_not_all-non_user[External]
     pub fn baz() {
 
     }
diff --git a/src/test/codegen-units/partitioning/local-inlining.rs b/src/test/codegen-units/partitioning/local-inlining.rs
index d75dfc91262..0cc652eeb52 100644
--- a/src/test/codegen-units/partitioning/local-inlining.rs
+++ b/src/test/codegen-units/partitioning/local-inlining.rs
@@ -10,7 +10,7 @@
 mod inline {
 
     // Important: This function should show up in all codegen units where it is inlined
-    //~ MONO_ITEM fn local_inlining::inline[0]::inlined_function[0] @@ local_inlining-user1[Internal] local_inlining-user2[Internal]
+    //~ MONO_ITEM fn inline::inlined_function @@ local_inlining-user1[Internal] local_inlining-user2[Internal]
     #[inline(always)]
     pub fn inlined_function()
     {
@@ -21,7 +21,7 @@ mod inline {
 pub mod user1 {
     use super::inline;
 
-    //~ MONO_ITEM fn local_inlining::user1[0]::foo[0] @@ local_inlining-user1[External]
+    //~ MONO_ITEM fn user1::foo @@ local_inlining-user1[External]
     pub fn foo() {
         inline::inlined_function();
     }
@@ -30,7 +30,7 @@ pub mod user1 {
 pub mod user2 {
     use super::inline;
 
-    //~ MONO_ITEM fn local_inlining::user2[0]::bar[0] @@ local_inlining-user2[External]
+    //~ MONO_ITEM fn user2::bar @@ local_inlining-user2[External]
     pub fn bar() {
         inline::inlined_function();
     }
@@ -38,7 +38,7 @@ pub mod user2 {
 
 pub mod non_user {
 
-    //~ MONO_ITEM fn local_inlining::non_user[0]::baz[0] @@ local_inlining-non_user[External]
+    //~ MONO_ITEM fn non_user::baz @@ local_inlining-non_user[External]
     pub fn baz() {
 
     }
diff --git a/src/test/codegen-units/partitioning/local-transitive-inlining.rs b/src/test/codegen-units/partitioning/local-transitive-inlining.rs
index 3cf03966865..0c8a67aeb3d 100644
--- a/src/test/codegen-units/partitioning/local-transitive-inlining.rs
+++ b/src/test/codegen-units/partitioning/local-transitive-inlining.rs
@@ -9,7 +9,7 @@
 
 mod inline {
 
-    //~ MONO_ITEM fn local_transitive_inlining::inline[0]::inlined_function[0] @@ local_transitive_inlining-indirect_user[Internal]
+    //~ MONO_ITEM fn inline::inlined_function @@ local_transitive_inlining-indirect_user[Internal]
     #[inline(always)]
     pub fn inlined_function()
     {
@@ -20,7 +20,7 @@ mod inline {
 mod direct_user {
     use super::inline;
 
-    //~ MONO_ITEM fn local_transitive_inlining::direct_user[0]::foo[0] @@ local_transitive_inlining-indirect_user[Internal]
+    //~ MONO_ITEM fn direct_user::foo @@ local_transitive_inlining-indirect_user[Internal]
     #[inline(always)]
     pub fn foo() {
         inline::inlined_function();
@@ -30,7 +30,7 @@ mod direct_user {
 pub mod indirect_user {
     use super::direct_user;
 
-    //~ MONO_ITEM fn local_transitive_inlining::indirect_user[0]::bar[0] @@ local_transitive_inlining-indirect_user[External]
+    //~ MONO_ITEM fn indirect_user::bar @@ local_transitive_inlining-indirect_user[External]
     pub fn bar() {
         direct_user::foo();
     }
@@ -38,7 +38,7 @@ pub mod indirect_user {
 
 pub mod non_user {
 
-    //~ MONO_ITEM fn local_transitive_inlining::non_user[0]::baz[0] @@ local_transitive_inlining-non_user[External]
+    //~ MONO_ITEM fn non_user::baz @@ local_transitive_inlining-non_user[External]
     pub fn baz() {
 
     }
diff --git a/src/test/codegen-units/partitioning/regular-modules.rs b/src/test/codegen-units/partitioning/regular-modules.rs
index c8ceeafd0bf..f9b8f52b0bb 100644
--- a/src/test/codegen-units/partitioning/regular-modules.rs
+++ b/src/test/codegen-units/partitioning/regular-modules.rs
@@ -1,4 +1,3 @@
-// ignore-tidy-linelength
 // We specify -C incremental here because we want to test the partitioning for
 // incremental compilation
 // compile-flags:-Zprint-mono-items=eager -Cincremental=tmp/partitioning-tests/regular-modules
@@ -6,67 +5,67 @@
 #![allow(dead_code)]
 #![crate_type="lib"]
 
-//~ MONO_ITEM fn regular_modules::foo[0] @@ regular_modules[Internal]
+//~ MONO_ITEM fn foo @@ regular_modules[Internal]
 fn foo() {}
 
-//~ MONO_ITEM fn regular_modules::bar[0] @@ regular_modules[Internal]
+//~ MONO_ITEM fn bar @@ regular_modules[Internal]
 fn bar() {}
 
-//~ MONO_ITEM static regular_modules::BAZ[0] @@ regular_modules[Internal]
+//~ MONO_ITEM static BAZ @@ regular_modules[Internal]
 static BAZ: u64 = 0;
 
 mod mod1 {
 
-    //~ MONO_ITEM fn regular_modules::mod1[0]::foo[0] @@ regular_modules-mod1[Internal]
+    //~ MONO_ITEM fn mod1::foo @@ regular_modules-mod1[Internal]
     fn foo() {}
-    //~ MONO_ITEM fn regular_modules::mod1[0]::bar[0] @@ regular_modules-mod1[Internal]
+    //~ MONO_ITEM fn mod1::bar @@ regular_modules-mod1[Internal]
     fn bar() {}
-    //~ MONO_ITEM static regular_modules::mod1[0]::BAZ[0] @@ regular_modules-mod1[Internal]
+    //~ MONO_ITEM static mod1::BAZ @@ regular_modules-mod1[Internal]
     static BAZ: u64 = 0;
 
     mod mod1 {
-        //~ MONO_ITEM fn regular_modules::mod1[0]::mod1[0]::foo[0] @@ regular_modules-mod1-mod1[Internal]
+        //~ MONO_ITEM fn mod1::mod1::foo @@ regular_modules-mod1-mod1[Internal]
         fn foo() {}
-        //~ MONO_ITEM fn regular_modules::mod1[0]::mod1[0]::bar[0] @@ regular_modules-mod1-mod1[Internal]
+        //~ MONO_ITEM fn mod1::mod1::bar @@ regular_modules-mod1-mod1[Internal]
         fn bar() {}
-        //~ MONO_ITEM static regular_modules::mod1[0]::mod1[0]::BAZ[0] @@ regular_modules-mod1-mod1[Internal]
+        //~ MONO_ITEM static mod1::mod1::BAZ @@ regular_modules-mod1-mod1[Internal]
         static BAZ: u64 = 0;
     }
 
     mod mod2 {
-        //~ MONO_ITEM fn regular_modules::mod1[0]::mod2[0]::foo[0] @@ regular_modules-mod1-mod2[Internal]
+        //~ MONO_ITEM fn mod1::mod2::foo @@ regular_modules-mod1-mod2[Internal]
         fn foo() {}
-        //~ MONO_ITEM fn regular_modules::mod1[0]::mod2[0]::bar[0] @@ regular_modules-mod1-mod2[Internal]
+        //~ MONO_ITEM fn mod1::mod2::bar @@ regular_modules-mod1-mod2[Internal]
         fn bar() {}
-        //~ MONO_ITEM static regular_modules::mod1[0]::mod2[0]::BAZ[0] @@ regular_modules-mod1-mod2[Internal]
+        //~ MONO_ITEM static mod1::mod2::BAZ @@ regular_modules-mod1-mod2[Internal]
         static BAZ: u64 = 0;
     }
 }
 
 mod mod2 {
 
-    //~ MONO_ITEM fn regular_modules::mod2[0]::foo[0] @@ regular_modules-mod2[Internal]
+    //~ MONO_ITEM fn mod2::foo @@ regular_modules-mod2[Internal]
     fn foo() {}
-    //~ MONO_ITEM fn regular_modules::mod2[0]::bar[0] @@ regular_modules-mod2[Internal]
+    //~ MONO_ITEM fn mod2::bar @@ regular_modules-mod2[Internal]
     fn bar() {}
-    //~ MONO_ITEM static regular_modules::mod2[0]::BAZ[0] @@ regular_modules-mod2[Internal]
+    //~ MONO_ITEM static mod2::BAZ @@ regular_modules-mod2[Internal]
     static BAZ: u64 = 0;
 
     mod mod1 {
-        //~ MONO_ITEM fn regular_modules::mod2[0]::mod1[0]::foo[0] @@ regular_modules-mod2-mod1[Internal]
+        //~ MONO_ITEM fn mod2::mod1::foo @@ regular_modules-mod2-mod1[Internal]
         fn foo() {}
-        //~ MONO_ITEM fn regular_modules::mod2[0]::mod1[0]::bar[0] @@ regular_modules-mod2-mod1[Internal]
+        //~ MONO_ITEM fn mod2::mod1::bar @@ regular_modules-mod2-mod1[Internal]
         fn bar() {}
-        //~ MONO_ITEM static regular_modules::mod2[0]::mod1[0]::BAZ[0] @@ regular_modules-mod2-mod1[Internal]
+        //~ MONO_ITEM static mod2::mod1::BAZ @@ regular_modules-mod2-mod1[Internal]
         static BAZ: u64 = 0;
     }
 
     mod mod2 {
-        //~ MONO_ITEM fn regular_modules::mod2[0]::mod2[0]::foo[0] @@ regular_modules-mod2-mod2[Internal]
+        //~ MONO_ITEM fn mod2::mod2::foo @@ regular_modules-mod2-mod2[Internal]
         fn foo() {}
-        //~ MONO_ITEM fn regular_modules::mod2[0]::mod2[0]::bar[0] @@ regular_modules-mod2-mod2[Internal]
+        //~ MONO_ITEM fn mod2::mod2::bar @@ regular_modules-mod2-mod2[Internal]
         fn bar() {}
-        //~ MONO_ITEM static regular_modules::mod2[0]::mod2[0]::BAZ[0] @@ regular_modules-mod2-mod2[Internal]
+        //~ MONO_ITEM static mod2::mod2::BAZ @@ regular_modules-mod2-mod2[Internal]
         static BAZ: u64 = 0;
     }
 }
diff --git a/src/test/codegen-units/partitioning/shared-generics.rs b/src/test/codegen-units/partitioning/shared-generics.rs
index 99142dd6b7e..eb3196439ba 100644
--- a/src/test/codegen-units/partitioning/shared-generics.rs
+++ b/src/test/codegen-units/partitioning/shared-generics.rs
@@ -9,10 +9,10 @@
 // aux-build:shared_generics_aux.rs
 extern crate shared_generics_aux;
 
-//~ MONO_ITEM fn shared_generics::foo[0]
+//~ MONO_ITEM fn foo
 pub fn foo() {
 
-    //~ MONO_ITEM fn shared_generics_aux::generic_fn[0]<u16> @@ shared_generics_aux-in-shared_generics.volatile[External]
+    //~ MONO_ITEM fn shared_generics_aux::generic_fn::<u16> @@ shared_generics_aux-in-shared_generics.volatile[External]
     let _ = shared_generics_aux::generic_fn(0u16, 1u16);
 
     // This should not generate a monomorphization because it's already
diff --git a/src/test/codegen-units/partitioning/statics.rs b/src/test/codegen-units/partitioning/statics.rs
index 5eac046b810..02d6467577f 100644
--- a/src/test/codegen-units/partitioning/statics.rs
+++ b/src/test/codegen-units/partitioning/statics.rs
@@ -4,34 +4,34 @@
 
 #![crate_type="rlib"]
 
-//~ MONO_ITEM static statics::FOO[0] @@ statics[Internal]
+//~ MONO_ITEM static FOO @@ statics[Internal]
 static FOO: u32 = 0;
 
-//~ MONO_ITEM static statics::BAR[0] @@ statics[Internal]
+//~ MONO_ITEM static BAR @@ statics[Internal]
 static BAR: u32 = 0;
 
-//~ MONO_ITEM fn statics::function[0] @@ statics[External]
+//~ MONO_ITEM fn function @@ statics[External]
 pub fn function() {
-    //~ MONO_ITEM static statics::function[0]::FOO[0] @@ statics[Internal]
+    //~ MONO_ITEM static function::FOO @@ statics[Internal]
     static FOO: u32 = 0;
 
-    //~ MONO_ITEM static statics::function[0]::BAR[0] @@ statics[Internal]
+    //~ MONO_ITEM static function::BAR @@ statics[Internal]
     static BAR: u32 = 0;
 }
 
 pub mod mod1 {
-    //~ MONO_ITEM static statics::mod1[0]::FOO[0] @@ statics-mod1[Internal]
+    //~ MONO_ITEM static mod1::FOO @@ statics-mod1[Internal]
     static FOO: u32 = 0;
 
-    //~ MONO_ITEM static statics::mod1[0]::BAR[0] @@ statics-mod1[Internal]
+    //~ MONO_ITEM static mod1::BAR @@ statics-mod1[Internal]
     static BAR: u32 = 0;
 
-    //~ MONO_ITEM fn statics::mod1[0]::function[0] @@ statics-mod1[External]
+    //~ MONO_ITEM fn mod1::function @@ statics-mod1[External]
     pub fn function() {
-        //~ MONO_ITEM static statics::mod1[0]::function[0]::FOO[0] @@ statics-mod1[Internal]
+        //~ MONO_ITEM static mod1::function::FOO @@ statics-mod1[Internal]
         static FOO: u32 = 0;
 
-        //~ MONO_ITEM static statics::mod1[0]::function[0]::BAR[0] @@ statics-mod1[Internal]
+        //~ MONO_ITEM static mod1::function::BAR @@ statics-mod1[Internal]
         static BAR: u32 = 0;
     }
 }
diff --git a/src/test/codegen-units/partitioning/vtable-through-const.rs b/src/test/codegen-units/partitioning/vtable-through-const.rs
index 5a1d95d2669..03dbac6179d 100644
--- a/src/test/codegen-units/partitioning/vtable-through-const.rs
+++ b/src/test/codegen-units/partitioning/vtable-through-const.rs
@@ -28,7 +28,7 @@ mod mod1 {
         fn do_something_else(&self, x: T) -> T { x }
     }
 
-    //~ MONO_ITEM fn vtable_through_const::mod1[0]::id[0]<i64> @@ vtable_through_const-mod1.volatile[Internal]
+    //~ MONO_ITEM fn mod1::id::<i64> @@ vtable_through_const-mod1.volatile[Internal]
     fn id<T>(x: T) -> T { x }
 
     // These are referenced, so they produce mono-items (see start())
@@ -43,8 +43,8 @@ mod mod1 {
         fn do_something_else(&self) {}
     }
 
-    //~ MONO_ITEM fn vtable_through_const::mod1[0]::Trait2[0]::do_something[0]<u32> @@ vtable_through_const-mod1.volatile[Internal]
-    //~ MONO_ITEM fn vtable_through_const::mod1[0]::Trait2[0]::do_something_else[0]<u32> @@ vtable_through_const-mod1.volatile[Internal]
+    //~ MONO_ITEM fn <u32 as mod1::Trait2>::do_something @@ vtable_through_const-mod1.volatile[Internal]
+    //~ MONO_ITEM fn <u32 as mod1::Trait2>::do_something_else @@ vtable_through_const-mod1.volatile[Internal]
     impl Trait2 for u32 {}
 
     pub trait Trait2Gen<T> {
@@ -63,30 +63,30 @@ mod mod1 {
     pub const ID_I64: fn(i64) -> i64 = id::<i64>;
 }
 
-//~ MONO_ITEM fn vtable_through_const::start[0]
+//~ MONO_ITEM fn start
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<u32> @@ vtable_through_const[Internal]
+    //~ MONO_ITEM fn std::intrinsics::drop_in_place::<u32> - shim(None) @@ vtable_through_const[Internal]
 
     // Since Trait1::do_something() is instantiated via its default implementation,
     // it is considered a generic and is instantiated here only because it is
     // referenced in this module.
-    //~ MONO_ITEM fn vtable_through_const::mod1[0]::Trait1[0]::do_something_else[0]<u32> @@ vtable_through_const-mod1.volatile[External]
+    //~ MONO_ITEM fn <u32 as mod1::Trait1>::do_something_else @@ vtable_through_const-mod1.volatile[External]
 
     // Although it is never used, Trait1::do_something_else() has to be
     // instantiated locally here too, otherwise the <&u32 as &Trait1> vtable
     // could not be fully constructed.
-    //~ MONO_ITEM fn vtable_through_const::mod1[0]::Trait1[0]::do_something[0]<u32> @@ vtable_through_const-mod1.volatile[External]
+    //~ MONO_ITEM fn <u32 as mod1::Trait1>::do_something @@ vtable_through_const-mod1.volatile[External]
     mod1::TRAIT1_REF.do_something();
 
     // Same as above
-    //~ MONO_ITEM fn vtable_through_const::mod1[0]::{{impl}}[1]::do_something[0]<u8> @@ vtable_through_const-mod1.volatile[External]
-    //~ MONO_ITEM fn vtable_through_const::mod1[0]::{{impl}}[1]::do_something_else[0]<u8> @@ vtable_through_const-mod1.volatile[External]
-    //~ MONO_ITEM fn vtable_through_const::mod1[0]::{{impl}}[3]::do_something[0]<u8> @@ vtable_through_const-mod1.volatile[Internal]
-    //~ MONO_ITEM fn vtable_through_const::mod1[0]::{{impl}}[3]::do_something_else[0]<u8> @@ vtable_through_const-mod1.volatile[Internal]
+    //~ MONO_ITEM fn <u32 as mod1::Trait1Gen<u8>>::do_something @@ vtable_through_const-mod1.volatile[External]
+    //~ MONO_ITEM fn <u32 as mod1::Trait1Gen<u8>>::do_something_else @@ vtable_through_const-mod1.volatile[External]
+    //~ MONO_ITEM fn <u32 as mod1::Trait2Gen<u8>>::do_something @@ vtable_through_const-mod1.volatile[Internal]
+    //~ MONO_ITEM fn <u32 as mod1::Trait2Gen<u8>>::do_something_else @@ vtable_through_const-mod1.volatile[Internal]
     mod1::TRAIT1_GEN_REF.do_something(0u8);
 
-    //~ MONO_ITEM fn vtable_through_const::mod1[0]::id[0]<char> @@ vtable_through_const-mod1.volatile[External]
+    //~ MONO_ITEM fn mod1::id::<char> @@ vtable_through_const-mod1.volatile[External]
     mod1::ID_CHAR('x');
 
     0
diff --git a/src/test/codegen-units/polymorphization/unused_type_parameters.rs b/src/test/codegen-units/polymorphization/unused_type_parameters.rs
index 403f68bb170..13be99635a5 100644
--- a/src/test/codegen-units/polymorphization/unused_type_parameters.rs
+++ b/src/test/codegen-units/polymorphization/unused_type_parameters.rs
@@ -1,5 +1,4 @@
 // compile-flags:-Zpolymorphize=on -Zprint-mono-items=lazy -Copt-level=1
-// ignore-tidy-linelength
 
 #![crate_type = "rlib"]
 
@@ -10,44 +9,44 @@ mod functions {
     // Function doesn't have any type parameters to be unused.
     pub fn no_parameters() {}
 
-//~ MONO_ITEM fn unused_type_parameters::functions[0]::no_parameters[0]
+//~ MONO_ITEM fn functions::no_parameters
 
     // Function has an unused type parameter.
     pub fn unused<T>() {
     }
 
-//~ MONO_ITEM fn unused_type_parameters::functions[0]::unused[0]<T>
+//~ MONO_ITEM fn functions::unused::<T>
 
     // Function uses type parameter in value of a binding.
     pub fn used_binding_value<T: Default>() {
         let _: T = Default::default();
     }
 
-//~ MONO_ITEM fn unused_type_parameters::functions[0]::used_binding_value[0]<u32>
-//~ MONO_ITEM fn unused_type_parameters::functions[0]::used_binding_value[0]<u64>
+//~ MONO_ITEM fn functions::used_binding_value::<u32>
+//~ MONO_ITEM fn functions::used_binding_value::<u64>
 
     // Function uses type parameter in type of a binding.
     pub fn used_binding_type<T>() {
         let _: Option<T> = None;
     }
 
-//~ MONO_ITEM fn unused_type_parameters::functions[0]::used_binding_type[0]<u32>
-//~ MONO_ITEM fn unused_type_parameters::functions[0]::used_binding_type[0]<u64>
+//~ MONO_ITEM fn functions::used_binding_type::<u32>
+//~ MONO_ITEM fn functions::used_binding_type::<u64>
 
     // Function uses type parameter in argument.
     pub fn used_argument<T>(_: T) {
     }
 
-//~ MONO_ITEM fn unused_type_parameters::functions[0]::used_argument[0]<u32>
-//~ MONO_ITEM fn unused_type_parameters::functions[0]::used_argument[0]<u64>
+//~ MONO_ITEM fn functions::used_argument::<u32>
+//~ MONO_ITEM fn functions::used_argument::<u64>
 //
     // Function uses type parameter in substitutions to another function.
     pub fn used_substs<T>() {
         unused::<T>()
     }
 
-//~ MONO_ITEM fn unused_type_parameters::functions[0]::used_substs[0]<u32>
-//~ MONO_ITEM fn unused_type_parameters::functions[0]::used_substs[0]<u64>
+//~ MONO_ITEM fn functions::used_substs::<u32>
+//~ MONO_ITEM fn functions::used_substs::<u64>
 }
 
 
@@ -57,7 +56,7 @@ mod closures {
         let _ = || {};
     }
 
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::no_parameters[0]
+//~ MONO_ITEM fn closures::no_parameters
 
     // Function has an unused type parameter in parent and closure.
     pub fn unused<T>() -> u32 {
@@ -65,8 +64,8 @@ mod closures {
         add_one(3)
     }
 
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::unused[0]::{{closure}}[0]<T, i8, extern "rust-call" fn((u32)) -> u32, ()>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::unused[0]<T>
+//~ MONO_ITEM fn closures::unused::<T>::{{closure}}#0
+//~ MONO_ITEM fn closures::unused::<T>
 
     // Function has an unused type parameter in closure, but not in parent.
     pub fn used_parent<T: Default>() -> u32 {
@@ -75,9 +74,9 @@ mod closures {
         add_one(3)
     }
 
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_parent[0]::{{closure}}[0]<T, i8, extern "rust-call" fn((u32)) -> u32, ()>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_parent[0]<u32>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_parent[0]<u64>
+//~ MONO_ITEM fn closures::used_parent::<T>::{{closure}}#0
+//~ MONO_ITEM fn closures::used_parent::<u32>
+//~ MONO_ITEM fn closures::used_parent::<u64>
 
     // Function uses type parameter in value of a binding in closure.
     pub fn used_binding_value<T: Default>() -> T {
@@ -89,10 +88,10 @@ mod closures {
         x()
     }
 
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_binding_value[0]::{{closure}}[0]<u32, i8, extern "rust-call" fn(()) -> u32, ()>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_binding_value[0]::{{closure}}[0]<u64, i8, extern "rust-call" fn(()) -> u64, ()>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_binding_value[0]<u32>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_binding_value[0]<u64>
+//~ MONO_ITEM fn closures::used_binding_value::<u32>::{{closure}}#0
+//~ MONO_ITEM fn closures::used_binding_value::<u64>::{{closure}}#0
+//~ MONO_ITEM fn closures::used_binding_value::<u32>
+//~ MONO_ITEM fn closures::used_binding_value::<u64>
 
     // Function uses type parameter in type of a binding in closure.
     pub fn used_binding_type<T>() -> Option<T> {
@@ -104,10 +103,10 @@ mod closures {
         x()
     }
 
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_binding_type[0]::{{closure}}[0]<u32, i8, extern "rust-call" fn(()) -> core::option[0]::Option[0]<u32>, ()>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_binding_type[0]::{{closure}}[0]<u64, i8, extern "rust-call" fn(()) -> core::option[0]::Option[0]<u64>, ()>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_binding_type[0]<u32>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_binding_type[0]<u64>
+//~ MONO_ITEM fn closures::used_binding_type::<u32>::{{closure}}#0
+//~ MONO_ITEM fn closures::used_binding_type::<u64>::{{closure}}#0
+//~ MONO_ITEM fn closures::used_binding_type::<u32>
+//~ MONO_ITEM fn closures::used_binding_type::<u64>
 
     // Function and closure uses type parameter in argument.
     pub fn used_argument<T>(t: T) -> u32 {
@@ -115,10 +114,10 @@ mod closures {
         x(t)
     }
 
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_argument[0]::{{closure}}[0]<u32, i8, extern "rust-call" fn((u32)) -> u32, ()>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_argument[0]::{{closure}}[0]<u64, i8, extern "rust-call" fn((u64)) -> u32, ()>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_argument[0]<u32>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_argument[0]<u64>
+//~ MONO_ITEM fn closures::used_argument::<u32>::{{closure}}#0
+//~ MONO_ITEM fn closures::used_argument::<u64>::{{closure}}#0
+//~ MONO_ITEM fn closures::used_argument::<u32>
+//~ MONO_ITEM fn closures::used_argument::<u64>
 
     // Closure uses type parameter in argument.
     pub fn used_argument_closure<T: Default>() -> u32 {
@@ -127,10 +126,10 @@ mod closures {
         x(t)
     }
 
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_argument_closure[0]::{{closure}}[0]<u32, i8, extern "rust-call" fn((u32)) -> u32, ()>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_argument_closure[0]::{{closure}}[0]<u64, i8, extern "rust-call" fn((u64)) -> u32, ()>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_argument_closure[0]<u32>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_argument_closure[0]<u64>
+//~ MONO_ITEM fn closures::used_argument_closure::<u32>::{{closure}}#0
+//~ MONO_ITEM fn closures::used_argument_closure::<u64>::{{closure}}#0
+//~ MONO_ITEM fn closures::used_argument_closure::<u32>
+//~ MONO_ITEM fn closures::used_argument_closure::<u64>
 
     // Closure uses type parameter as upvar.
     pub fn used_upvar<T: Default>() -> T {
@@ -139,10 +138,10 @@ mod closures {
         y()
     }
 
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_upvar[0]::{{closure}}[0]<u32, i32, extern "rust-call" fn(()) -> u32, (u32)>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_upvar[0]::{{closure}}[0]<u64, i32, extern "rust-call" fn(()) -> u64, (u64)>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_upvar[0]<u32>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_upvar[0]<u64>
+//~ MONO_ITEM fn closures::used_upvar::<u32>::{{closure}}#0
+//~ MONO_ITEM fn closures::used_upvar::<u64>::{{closure}}#0
+//~ MONO_ITEM fn closures::used_upvar::<u32>
+//~ MONO_ITEM fn closures::used_upvar::<u64>
 
     // Closure uses type parameter in substitutions to another function.
     pub fn used_substs<T>() {
@@ -150,10 +149,10 @@ mod closures {
         x()
     }
 
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_substs[0]::{{closure}}[0]<u32, i8, extern "rust-call" fn(()), ()>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_substs[0]::{{closure}}[0]<u64, i8, extern "rust-call" fn(()), ()>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_substs[0]<u32>
-//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_substs[0]<u64>
+//~ MONO_ITEM fn closures::used_substs::<u32>::{{closure}}#0
+//~ MONO_ITEM fn closures::used_substs::<u64>::{{closure}}#0
+//~ MONO_ITEM fn closures::used_substs::<u32>
+//~ MONO_ITEM fn closures::used_substs::<u64>
 }
 
 mod methods {
@@ -164,29 +163,29 @@ mod methods {
         pub fn unused_impl() {
         }
 
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::unused_impl[0]<F>
+//~ MONO_ITEM fn methods::Foo::<F>::unused_impl
 
         // Function has an unused type parameter from impl and fn.
         pub fn unused_both<G: Default>() {
         }
 
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::unused_both[0]<F, G>
+//~ MONO_ITEM fn methods::Foo::<F>::unused_both::<G>
 
         // Function uses type parameter from impl.
         pub fn used_impl() {
             let _: F = Default::default();
         }
 
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::used_impl[0]<u32>
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::used_impl[0]<u64>
+//~ MONO_ITEM fn methods::Foo::<u32>::used_impl
+//~ MONO_ITEM fn methods::Foo::<u64>::used_impl
 
         // Function uses type parameter from impl.
         pub fn used_fn<G: Default>() {
             let _: G = Default::default();
         }
 
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::used_fn[0]<F, u32>
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::used_fn[0]<F, u64>
+//~ MONO_ITEM fn methods::Foo::<F>::used_fn::<u32>
+//~ MONO_ITEM fn methods::Foo::<F>::used_fn::<u64>
 
         // Function uses type parameter from impl.
         pub fn used_both<G: Default>() {
@@ -194,16 +193,16 @@ mod methods {
             let _: G = Default::default();
         }
 
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::used_both[0]<u32, u32>
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::used_both[0]<u64, u64>
+//~ MONO_ITEM fn methods::Foo::<u32>::used_both::<u32>
+//~ MONO_ITEM fn methods::Foo::<u64>::used_both::<u64>
 
         // Function uses type parameter in substitutions to another function.
         pub fn used_substs() {
             super::functions::unused::<F>()
         }
 
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::used_substs[0]<u32>
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::used_substs[0]<u64>
+//~ MONO_ITEM fn methods::Foo::<u32>::used_substs
+//~ MONO_ITEM fn methods::Foo::<u64>::used_substs
 
         // Function has an unused type parameter from impl and fn.
         pub fn closure_unused_all<G: Default>() -> u32 {
@@ -211,8 +210,8 @@ mod methods {
             add_one(3)
         }
 
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_unused_all[0]::{{closure}}[0]<F, G, i8, extern "rust-call" fn((u32)) -> u32, ()>
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_unused_all[0]<F, G>
+//~ MONO_ITEM fn methods::Foo::<F>::closure_unused_all::<G>::{{closure}}#0
+//~ MONO_ITEM fn methods::Foo::<F>::closure_unused_all::<G>
 
         // Function uses type parameter from impl and fn in closure.
         pub fn closure_used_both<G: Default>() -> u32 {
@@ -225,10 +224,10 @@ mod methods {
             add_one(3)
         }
 
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_both[0]::{{closure}}[0]<u32, u32, i8, extern "rust-call" fn((u32)) -> u32, ()>
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_both[0]::{{closure}}[0]<u64, u64, i8, extern "rust-call" fn((u32)) -> u32, ()>
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_both[0]<u32, u32>
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_both[0]<u64, u64>
+//~ MONO_ITEM fn methods::Foo::<u32>::closure_used_both::<u32>::{{closure}}#0
+//~ MONO_ITEM fn methods::Foo::<u64>::closure_used_both::<u64>::{{closure}}#0
+//~ MONO_ITEM fn methods::Foo::<u32>::closure_used_both::<u32>
+//~ MONO_ITEM fn methods::Foo::<u64>::closure_used_both::<u64>
 
         // Function uses type parameter from fn in closure.
         pub fn closure_used_fn<G: Default>() -> u32 {
@@ -240,10 +239,10 @@ mod methods {
             add_one(3)
         }
 
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_fn[0]::{{closure}}[0]<F, u32, i8, extern "rust-call" fn((u32)) -> u32, ()>
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_fn[0]::{{closure}}[0]<F, u64, i8, extern "rust-call" fn((u32)) -> u32, ()>
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_fn[0]<F, u32>
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_fn[0]<F, u64>
+//~ MONO_ITEM fn methods::Foo::<F>::closure_used_fn::<u32>::{{closure}}#0
+//~ MONO_ITEM fn methods::Foo::<F>::closure_used_fn::<u64>::{{closure}}#0
+//~ MONO_ITEM fn methods::Foo::<F>::closure_used_fn::<u32>
+//~ MONO_ITEM fn methods::Foo::<F>::closure_used_fn::<u64>
 
         // Function uses type parameter from impl in closure.
         pub fn closure_used_impl<G: Default>() -> u32 {
@@ -255,10 +254,10 @@ mod methods {
             add_one(3)
         }
 
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_impl[0]::{{closure}}[0]<u32, G, i8, extern "rust-call" fn((u32)) -> u32, ()>
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_impl[0]::{{closure}}[0]<u64, G, i8, extern "rust-call" fn((u32)) -> u32, ()>
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_impl[0]<u32, G>
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_impl[0]<u64, G>
+//~ MONO_ITEM fn methods::Foo::<u32>::closure_used_impl::<G>::{{closure}}#0
+//~ MONO_ITEM fn methods::Foo::<u64>::closure_used_impl::<G>::{{closure}}#0
+//~ MONO_ITEM fn methods::Foo::<u32>::closure_used_impl::<G>
+//~ MONO_ITEM fn methods::Foo::<u64>::closure_used_impl::<G>
 
         // Closure uses type parameter in substitutions to another function.
         pub fn closure_used_substs() {
@@ -266,10 +265,10 @@ mod methods {
             x()
         }
 
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_substs[0]::{{closure}}[0]<u32, i8, extern "rust-call" fn(()), ()>
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_substs[0]::{{closure}}[0]<u64, i8, extern "rust-call" fn(()), ()>
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_substs[0]<u32>
-//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_substs[0]<u64>
+//~ MONO_ITEM fn methods::Foo::<u32>::closure_used_substs::{{closure}}#0
+//~ MONO_ITEM fn methods::Foo::<u64>::closure_used_substs::{{closure}}#0
+//~ MONO_ITEM fn methods::Foo::<u32>::closure_used_substs
+//~ MONO_ITEM fn methods::Foo::<u64>::closure_used_substs
     }
 }
 
@@ -306,8 +305,8 @@ fn dispatch<T: Default>() {
     let _ = methods::Foo::<T>::closure_used_substs();
 }
 
-//~ MONO_ITEM fn unused_type_parameters::dispatch[0]<u32>
-//~ MONO_ITEM fn unused_type_parameters::dispatch[0]<u64>
+//~ MONO_ITEM fn dispatch::<u32>
+//~ MONO_ITEM fn dispatch::<u64>
 
 pub fn foo() {
     // Generate two copies of each function to check that where the type parameter is unused,
@@ -316,8 +315,8 @@ pub fn foo() {
     dispatch::<u64>();
 }
 
-//~ MONO_ITEM fn unused_type_parameters::foo[0] @@ unused_type_parameters-cgu.0[External]
+//~ MONO_ITEM fn foo @@ unused_type_parameters-cgu.0[External]
 
 // These are all the items that aren't relevant to the test.
-//~ MONO_ITEM fn core::default[0]::{{impl}}[6]::default[0]
-//~ MONO_ITEM fn core::default[0]::{{impl}}[7]::default[0]
+//~ MONO_ITEM fn <u32 as std::default::Default>::default
+//~ MONO_ITEM fn <u64 as std::default::Default>::default
diff --git a/src/test/codegen/enum-bounds-check-derived-idx.rs b/src/test/codegen/enum-bounds-check-derived-idx.rs
new file mode 100644
index 00000000000..7e3773b6a3e
--- /dev/null
+++ b/src/test/codegen/enum-bounds-check-derived-idx.rs
@@ -0,0 +1,25 @@
+// This test checks an optimization that is not guaranteed to work. This test case should not block
+// a future LLVM update.
+// compile-flags: -O
+// min-llvm-version: 11.0
+
+#![crate_type = "lib"]
+
+pub enum Bar {
+    A = 1,
+    B = 3,
+}
+
+// CHECK-LABEL: @lookup_inc
+#[no_mangle]
+pub fn lookup_inc(buf: &[u8; 5], f: Bar) -> u8 {
+    // CHECK-NOT: panic_bounds_check
+    buf[f as usize + 1]
+}
+
+// CHECK-LABEL: @lookup_dec
+#[no_mangle]
+pub fn lookup_dec(buf: &[u8; 5], f: Bar) -> u8 {
+    // CHECK-NOT: panic_bounds_check
+    buf[f as usize - 1]
+}
diff --git a/src/test/codegen/enum-bounds-check-issue-13926.rs b/src/test/codegen/enum-bounds-check-issue-13926.rs
new file mode 100644
index 00000000000..ad029f0fa73
--- /dev/null
+++ b/src/test/codegen/enum-bounds-check-issue-13926.rs
@@ -0,0 +1,19 @@
+// This test checks an optimization that is not guaranteed to work. This test case should not block
+// a future LLVM update.
+// compile-flags: -O
+// min-llvm-version: 11.0
+
+#![crate_type = "lib"]
+
+#[repr(u8)]
+pub enum Exception {
+    Low = 5,
+    High = 10,
+}
+
+// CHECK-LABEL: @access
+#[no_mangle]
+pub fn access(array: &[usize; 12], exc: Exception) -> usize {
+    // CHECK-NOT: panic_bounds_check
+    array[(exc as u8 - 4) as usize]
+}
diff --git a/src/test/codegen/enum-bounds-check.rs b/src/test/codegen/enum-bounds-check.rs
index 21a27c9f35d..17322d5911b 100644
--- a/src/test/codegen/enum-bounds-check.rs
+++ b/src/test/codegen/enum-bounds-check.rs
@@ -12,3 +12,15 @@ pub fn lookup(buf: &[u8; 2], f: Foo) -> u8 {
     // CHECK-NOT: panic_bounds_check
     buf[f as usize]
 }
+
+pub enum Bar {
+    A = 2,
+    B = 3
+}
+
+// CHECK-LABEL: @lookup_unmodified
+#[no_mangle]
+pub fn lookup_unmodified(buf: &[u8; 5], f: Bar) -> u8 {
+    // CHECK-NOT: panic_bounds_check
+    buf[f as usize]
+}
diff --git a/src/test/mir-opt/inline/inline-async.rs b/src/test/mir-opt/inline/inline-async.rs
new file mode 100644
index 00000000000..5c838159b98
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-async.rs
@@ -0,0 +1,18 @@
+// Checks that inliner doesn't introduce cycles when optimizing generators.
+// The outcome of optimization is not verfied, just the absence of the cycle.
+// Regression test for #76181.
+//
+// edition:2018
+
+#![crate_type = "lib"]
+
+pub struct S;
+
+impl S {
+    pub async fn g(&mut self) {
+        self.h();
+    }
+    pub fn h(&mut self) {
+        let _ = self.g();
+    }
+}
diff --git a/src/test/mir-opt/spanview-block.rs b/src/test/mir-opt/spanview-block.rs
new file mode 100644
index 00000000000..fc1d6e0ede6
--- /dev/null
+++ b/src/test/mir-opt/spanview-block.rs
@@ -0,0 +1,5 @@
+// Test spanview block output
+// compile-flags: -Z dump-mir-spanview=block
+
+// EMIT_MIR spanview_block.main.mir_map.0.html
+fn main() {}
diff --git a/src/test/mir-opt/spanview-statement.rs b/src/test/mir-opt/spanview-statement.rs
new file mode 100644
index 00000000000..a43ad5e71a3
--- /dev/null
+++ b/src/test/mir-opt/spanview-statement.rs
@@ -0,0 +1,5 @@
+// Test spanview output (the default value for `-Z dump-mir-spanview` is "statement")
+// compile-flags: -Z dump-mir-spanview
+
+// EMIT_MIR spanview_statement.main.mir_map.0.html
+fn main() {}
diff --git a/src/test/mir-opt/spanview-terminator.rs b/src/test/mir-opt/spanview-terminator.rs
new file mode 100644
index 00000000000..92e1411eadb
--- /dev/null
+++ b/src/test/mir-opt/spanview-terminator.rs
@@ -0,0 +1,5 @@
+// Test spanview terminator output
+// compile-flags: -Z dump-mir-spanview=terminator
+
+// EMIT_MIR spanview_terminator.main.mir_map.0.html
+fn main() {}
diff --git a/src/test/mir-opt/spanview_block.main.mir_map.0.html b/src/test/mir-opt/spanview_block.main.mir_map.0.html
new file mode 100644
index 00000000000..7c1b7bc3b84
--- /dev/null
+++ b/src/test/mir-opt/spanview_block.main.mir_map.0.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>coverage_of_if_else - Code Regions</title>
+    <style>
+    .line {
+        counter-increment: line;
+    }
+    .line:before {
+        content: counter(line) ": ";
+        font-family: Menlo, Monaco, monospace;
+        font-style: italic;
+        width: 3.8em;
+        display: inline-block;
+        text-align: right;
+        filter: opacity(50%);
+        -webkit-user-select: none;
+    }
+    .code {
+        color: #dddddd;
+        background-color: #222222;
+        font-family: Menlo, Monaco, monospace;
+        line-height: 1.4em;
+        border-bottom: 2px solid #222222;
+        white-space: pre;
+        display: inline-block;
+    }
+    .odd {
+        background-color: #55bbff;
+        color: #223311;
+    }
+    .even {
+        background-color: #ee7756;
+        color: #551133;
+    }
+    .code {
+        --index: calc(var(--layer) - 1);
+        padding-top: calc(var(--index) * 0.15em);
+        filter:
+            hue-rotate(calc(var(--index) * 25deg))
+            saturate(calc(100% - (var(--index) * 2%)))
+            brightness(calc(100% - (var(--index) * 1.5%)));
+    }
+    .annotation {
+        color: #4444ff;
+        font-family: monospace;
+        font-style: italic;
+        display: none;
+        -webkit-user-select: none;
+    }
+    body:active .annotation {
+        /* requires holding mouse down anywhere on the page */
+        display: inline-block;
+    }
+    span:hover .annotation {
+        /* requires hover over a span ONLY on its first line */
+        display: inline-block;
+    }
+    </style>
+</head>
+<body>
+<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() </span><span><span class="code even" style="--layer: 1" title="bb0: $DIR/spanview-block.rs:5:11: 5:13:
+    5:11-5:13: Assign: _0 = const ()
+    5:13-5:13: Goto: goto -&gt; bb2"><span class="annotation">@bb0:</span> {}</span></span><span><span class="code even" style="--layer: 1" title="bb2: $DIR/spanview-block.rs:5:13: 5:13:
+    5:13-5:13: Return: return"><span class="annotation">@bb2</span></span></span></span></div>
+</body>
+</html>
diff --git a/src/test/mir-opt/spanview_statement.main.mir_map.0.html b/src/test/mir-opt/spanview_statement.main.mir_map.0.html
new file mode 100644
index 00000000000..f8662a3277a
--- /dev/null
+++ b/src/test/mir-opt/spanview_statement.main.mir_map.0.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>coverage_of_if_else - Code Regions</title>
+    <style>
+    .line {
+        counter-increment: line;
+    }
+    .line:before {
+        content: counter(line) ": ";
+        font-family: Menlo, Monaco, monospace;
+        font-style: italic;
+        width: 3.8em;
+        display: inline-block;
+        text-align: right;
+        filter: opacity(50%);
+        -webkit-user-select: none;
+    }
+    .code {
+        color: #dddddd;
+        background-color: #222222;
+        font-family: Menlo, Monaco, monospace;
+        line-height: 1.4em;
+        border-bottom: 2px solid #222222;
+        white-space: pre;
+        display: inline-block;
+    }
+    .odd {
+        background-color: #55bbff;
+        color: #223311;
+    }
+    .even {
+        background-color: #ee7756;
+        color: #551133;
+    }
+    .code {
+        --index: calc(var(--layer) - 1);
+        padding-top: calc(var(--index) * 0.15em);
+        filter:
+            hue-rotate(calc(var(--index) * 25deg))
+            saturate(calc(100% - (var(--index) * 2%)))
+            brightness(calc(100% - (var(--index) * 1.5%)));
+    }
+    .annotation {
+        color: #4444ff;
+        font-family: monospace;
+        font-style: italic;
+        display: none;
+        -webkit-user-select: none;
+    }
+    body:active .annotation {
+        /* requires holding mouse down anywhere on the page */
+        display: inline-block;
+    }
+    span:hover .annotation {
+        /* requires hover over a span ONLY on its first line */
+        display: inline-block;
+    }
+    </style>
+</head>
+<body>
+<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() </span><span><span class="code even" style="--layer: 1" title="bb0[0]: $DIR/spanview-statement.rs:5:11: 5:13:
+    5:11-5:13: Assign: _0 = const ()"><span class="annotation">@bb0[0]:</span> {}</span></span><span><span class="code even" style="--layer: 1" title="bb0`Goto`: $DIR/spanview-statement.rs:5:13: 5:13:
+    5:13-5:13: Goto: goto -&gt; bb2"><span class="annotation">@bb0`Goto`</span></span></span><span><span class="code even" style="--layer: 1" title="bb2`Return`: $DIR/spanview-statement.rs:5:13: 5:13:
+    5:13-5:13: Return: return"><span class="annotation">@bb2`Return`</span></span></span></span></div>
+</body>
+</html>
diff --git a/src/test/mir-opt/spanview_terminator.main.mir_map.0.html b/src/test/mir-opt/spanview_terminator.main.mir_map.0.html
new file mode 100644
index 00000000000..d0a11a8d262
--- /dev/null
+++ b/src/test/mir-opt/spanview_terminator.main.mir_map.0.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>coverage_of_if_else - Code Regions</title>
+    <style>
+    .line {
+        counter-increment: line;
+    }
+    .line:before {
+        content: counter(line) ": ";
+        font-family: Menlo, Monaco, monospace;
+        font-style: italic;
+        width: 3.8em;
+        display: inline-block;
+        text-align: right;
+        filter: opacity(50%);
+        -webkit-user-select: none;
+    }
+    .code {
+        color: #dddddd;
+        background-color: #222222;
+        font-family: Menlo, Monaco, monospace;
+        line-height: 1.4em;
+        border-bottom: 2px solid #222222;
+        white-space: pre;
+        display: inline-block;
+    }
+    .odd {
+        background-color: #55bbff;
+        color: #223311;
+    }
+    .even {
+        background-color: #ee7756;
+        color: #551133;
+    }
+    .code {
+        --index: calc(var(--layer) - 1);
+        padding-top: calc(var(--index) * 0.15em);
+        filter:
+            hue-rotate(calc(var(--index) * 25deg))
+            saturate(calc(100% - (var(--index) * 2%)))
+            brightness(calc(100% - (var(--index) * 1.5%)));
+    }
+    .annotation {
+        color: #4444ff;
+        font-family: monospace;
+        font-style: italic;
+        display: none;
+        -webkit-user-select: none;
+    }
+    body:active .annotation {
+        /* requires holding mouse down anywhere on the page */
+        display: inline-block;
+    }
+    span:hover .annotation {
+        /* requires hover over a span ONLY on its first line */
+        display: inline-block;
+    }
+    </style>
+</head>
+<body>
+<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() {}</span><span><span class="code even" style="--layer: 1" title="bb0`Goto`: $DIR/spanview-terminator.rs:5:13: 5:13:
+    5:13-5:13: Goto: goto -&gt; bb2"><span class="annotation">@bb0`Goto`</span></span></span><span><span class="code even" style="--layer: 1" title="bb2`Return`: $DIR/spanview-terminator.rs:5:13: 5:13:
+    5:13-5:13: Return: return"><span class="annotation">@bb2`Return`</span></span></span></span></div>
+</body>
+</html>
diff --git a/src/test/rustdoc/index-page.rs b/src/test/rustdoc/index-page.rs
index f0476f083b8..be668a1276a 100644
--- a/src/test/rustdoc/index-page.rs
+++ b/src/test/rustdoc/index-page.rs
@@ -6,6 +6,6 @@
 
 // @has foo/../index.html
 // @has - '//span[@class="in-band"]' 'List of all crates'
-// @has - '//ul[@class="mod"]//a[@href="foo/index.html"]' 'foo'
-// @has - '//ul[@class="mod"]//a[@href="all_item_types/index.html"]' 'all_item_types'
+// @has - '//ul[@class="crate mod"]//a[@href="foo/index.html"]' 'foo'
+// @has - '//ul[@class="crate mod"]//a[@href="all_item_types/index.html"]' 'all_item_types'
 pub struct Foo;
diff --git a/src/test/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs b/src/test/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs
index 75bf320dd5b..7a88c3df2e4 100644
--- a/src/test/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs
+++ b/src/test/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs
@@ -1,7 +1,7 @@
 // Test that attempt to reborrow an `&mut` pointer in an aliasable
 // location yields an error.
 //
-// Example from src/librustc_borrowck/borrowck/README.md
+// Example from compiler/rustc_borrowck/borrowck/README.md
 
 fn foo(t0: & &mut isize) {
     let t1 = t0;
diff --git a/src/test/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs b/src/test/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs
index 2839a9195a0..5ef282c0ca0 100644
--- a/src/test/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs
+++ b/src/test/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs
@@ -5,7 +5,7 @@
 // Test that freezing an `&mut` pointer while referent is
 // frozen is legal.
 //
-// Example from src/librustc_borrowck/borrowck/README.md
+// Example from compiler/rustc_borrowck/borrowck/README.md
 
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/borrowck/borrowck-move-mut-base-ptr.rs b/src/test/ui/borrowck/borrowck-move-mut-base-ptr.rs
index 10fc1437253..fa2d5531b13 100644
--- a/src/test/ui/borrowck/borrowck-move-mut-base-ptr.rs
+++ b/src/test/ui/borrowck/borrowck-move-mut-base-ptr.rs
@@ -1,7 +1,7 @@
 // Test that attempt to move `&mut` pointer while pointee is borrowed
 // yields an error.
 //
-// Example from src/librustc_borrowck/borrowck/README.md
+// Example from compiler/rustc_borrowck/borrowck/README.md
 
 
 
diff --git a/src/test/ui/borrowck/borrowck-mut-borrow-of-mut-base-ptr.rs b/src/test/ui/borrowck/borrowck-mut-borrow-of-mut-base-ptr.rs
index 32caa466475..6174893bae9 100644
--- a/src/test/ui/borrowck/borrowck-mut-borrow-of-mut-base-ptr.rs
+++ b/src/test/ui/borrowck/borrowck-mut-borrow-of-mut-base-ptr.rs
@@ -1,7 +1,7 @@
 // Test that attempt to mutably borrow `&mut` pointer while pointee is
 // borrowed yields an error.
 //
-// Example from src/librustc_borrowck/borrowck/README.md
+// Example from compiler/rustc_borrowck/borrowck/README.md
 
 
 
diff --git a/src/test/ui/borrowck/borrowck-swap-mut-base-ptr.rs b/src/test/ui/borrowck/borrowck-swap-mut-base-ptr.rs
index 3d40d319226..8170323efc5 100644
--- a/src/test/ui/borrowck/borrowck-swap-mut-base-ptr.rs
+++ b/src/test/ui/borrowck/borrowck-swap-mut-base-ptr.rs
@@ -1,7 +1,7 @@
 // Test that attempt to swap `&mut` pointer while pointee is borrowed
 // yields an error.
 //
-// Example from src/librustc_borrowck/borrowck/README.md
+// Example from compiler/rustc_borrowck/borrowck/README.md
 
 use std::mem::swap;
 
diff --git a/src/test/ui/codemap_tests/bad-format-args.rs b/src/test/ui/codemap_tests/bad-format-args.rs
index dff248344a5..e89a45a84f5 100644
--- a/src/test/ui/codemap_tests/bad-format-args.rs
+++ b/src/test/ui/codemap_tests/bad-format-args.rs
@@ -1,5 +1,5 @@
 fn main() {
     format!(); //~ ERROR requires at least a format string argument
-    format!("" 1); //~ ERROR expected token: `,`
+    format!("" 1); //~ ERROR expected `,`, found `1`
     format!("", 1 1); //~ ERROR expected one of
 }
diff --git a/src/test/ui/codemap_tests/bad-format-args.stderr b/src/test/ui/codemap_tests/bad-format-args.stderr
index 96d7b07b0e2..5ed023e1f21 100644
--- a/src/test/ui/codemap_tests/bad-format-args.stderr
+++ b/src/test/ui/codemap_tests/bad-format-args.stderr
@@ -6,7 +6,7 @@ LL |     format!();
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: expected token: `,`
+error: expected `,`, found `1`
   --> $DIR/bad-format-args.rs:3:16
    |
 LL |     format!("" 1);
diff --git a/src/test/ui/const-generics/argument_order.stderr b/src/test/ui/const-generics/argument_order.full.stderr
index d6546a768d2..b52e5050703 100644
--- a/src/test/ui/const-generics/argument_order.stderr
+++ b/src/test/ui/const-generics/argument_order.full.stderr
@@ -1,11 +1,11 @@
 error: lifetime parameters must be declared prior to const parameters
-  --> $DIR/argument_order.rs:9:32
+  --> $DIR/argument_order.rs:12:32
    |
 LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {
    |               -----------------^^-----^^-------------------- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, const N: usize, T, const M: usize, U>`
 
 error[E0747]: lifetime provided when a type was expected
-  --> $DIR/argument_order.rs:16:23
+  --> $DIR/argument_order.rs:20:23
    |
 LL |     let _: AlsoBad<7, 'static, u32, 'static, 17, u16>;
    |                       ^^^^^^^
diff --git a/src/test/ui/const-generics/argument_order.min.stderr b/src/test/ui/const-generics/argument_order.min.stderr
new file mode 100644
index 00000000000..728ae69b41f
--- /dev/null
+++ b/src/test/ui/const-generics/argument_order.min.stderr
@@ -0,0 +1,30 @@
+error: type parameters must be declared prior to const parameters
+  --> $DIR/argument_order.rs:6:28
+   |
+LL | struct Bad<const N: usize, T> {
+   |           -----------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const N: usize>`
+
+error: lifetime parameters must be declared prior to const parameters
+  --> $DIR/argument_order.rs:12:32
+   |
+LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {
+   |               -----------------^^-----^^-------------------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T, U, const N: usize, const M: usize>`
+
+error: type parameters must be declared prior to const parameters
+  --> $DIR/argument_order.rs:12:36
+   |
+LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {
+   |               ---------------------^----------------------^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T, U, const N: usize, const M: usize>`
+
+error[E0747]: lifetime provided when a type was expected
+  --> $DIR/argument_order.rs:20:23
+   |
+LL |     let _: AlsoBad<7, 'static, u32, 'static, 17, u16>;
+   |                       ^^^^^^^
+   |
+   = note: lifetime arguments must be provided before type arguments
+   = help: reorder the arguments: lifetimes, then types, then consts: `<'a, 'b, T, U, N, M>`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0747`.
diff --git a/src/test/ui/const-generics/argument_order.rs b/src/test/ui/const-generics/argument_order.rs
index 9e071e674e7..507baf5fd75 100644
--- a/src/test/ui/const-generics/argument_order.rs
+++ b/src/test/ui/const-generics/argument_order.rs
@@ -1,13 +1,17 @@
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 struct Bad<const N: usize, T> {
+    //[min]~^ ERROR type parameters must be declared prior to const parameters
     arr: [u8; { N }],
     another: T,
 }
 
 struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {
     //~^ ERROR lifetime parameters must be declared prior
+    //[min]~^^ ERROR type parameters must be declared prior to const parameters
     a: &'a T,
     b: &'b U,
 }
diff --git a/src/test/ui/const-generics/array-wrapper-struct-ctor.rs b/src/test/ui/const-generics/array-wrapper-struct-ctor.rs
index 49fc53b32bd..390b6cc2049 100644
--- a/src/test/ui/const-generics/array-wrapper-struct-ctor.rs
+++ b/src/test/ui/const-generics/array-wrapper-struct-ctor.rs
@@ -1,7 +1,8 @@
 // run-pass
-
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 #![allow(dead_code)]
 
diff --git a/src/test/ui/const-generics/array-wrapper-struct-ctor.stderr b/src/test/ui/const-generics/array-wrapper-struct-ctor.stderr
deleted file mode 100644
index e6eb2a0a783..00000000000
--- a/src/test/ui/const-generics/array-wrapper-struct-ctor.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/array-wrapper-struct-ctor.rs:3:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs b/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs
index aac5d195f76..931f6ade7f1 100644
--- a/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs
+++ b/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs
@@ -1,6 +1,8 @@
 // check-pass
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 // This test confirms that the types can be inferred correctly for this example with const
 // generics. Previously this would ICE, and more recently error.
diff --git a/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr b/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr
deleted file mode 100644
index c5c48d7be46..00000000000
--- a/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/cannot-infer-type-for-const-param.rs:2:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/const-generics/const-arg-type-arg-misordered.stderr b/src/test/ui/const-generics/const-arg-type-arg-misordered.full.stderr
index 2e2bfed51fb..3827002ff4b 100644
--- a/src/test/ui/const-generics/const-arg-type-arg-misordered.stderr
+++ b/src/test/ui/const-generics/const-arg-type-arg-misordered.full.stderr
@@ -1,5 +1,5 @@
 error[E0747]: constant provided when a type was expected
-  --> $DIR/const-arg-type-arg-misordered.rs:6:35
+  --> $DIR/const-arg-type-arg-misordered.rs:8:35
    |
 LL | fn foo<const N: usize>() -> Array<N, ()> {
    |                                   ^
diff --git a/src/test/ui/const-generics/const-arg-type-arg-misordered.min.stderr b/src/test/ui/const-generics/const-arg-type-arg-misordered.min.stderr
new file mode 100644
index 00000000000..2c5fc8dcc01
--- /dev/null
+++ b/src/test/ui/const-generics/const-arg-type-arg-misordered.min.stderr
@@ -0,0 +1,12 @@
+error[E0747]: constant provided when a type was expected
+  --> $DIR/const-arg-type-arg-misordered.rs:8:35
+   |
+LL | fn foo<const N: usize>() -> Array<N, ()> {
+   |                                   ^
+   |
+   = note: type arguments must be provided before constant arguments
+   = help: reorder the arguments: types, then consts: `<T, N>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0747`.
diff --git a/src/test/ui/const-generics/const-arg-type-arg-misordered.rs b/src/test/ui/const-generics/const-arg-type-arg-misordered.rs
index 13ca56ad3e6..6680f772fa3 100644
--- a/src/test/ui/const-generics/const-arg-type-arg-misordered.rs
+++ b/src/test/ui/const-generics/const-arg-type-arg-misordered.rs
@@ -1,9 +1,12 @@
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 type Array<T, const N: usize> = [T; N];
 
-fn foo<const N: usize>() -> Array<N, ()> { //~ ERROR constant provided when a type was expected
+fn foo<const N: usize>() -> Array<N, ()> {
+    //~^ ERROR constant provided when a type was expected
     unimplemented!()
 }
 
diff --git a/src/test/ui/const-generics/const-param-before-other-params.stderr b/src/test/ui/const-generics/const-param-before-other-params.full.stderr
index 1194dd30f61..c2acaabbd88 100644
--- a/src/test/ui/const-generics/const-param-before-other-params.stderr
+++ b/src/test/ui/const-generics/const-param-before-other-params.full.stderr
@@ -1,5 +1,5 @@
 error: lifetime parameters must be declared prior to const parameters
-  --> $DIR/const-param-before-other-params.rs:4:21
+  --> $DIR/const-param-before-other-params.rs:6:21
    |
 LL | fn bar<const X: (), 'a>(_: &'a ()) {
    |       --------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const X: ()>`
diff --git a/src/test/ui/const-generics/const-param-before-other-params.min.stderr b/src/test/ui/const-generics/const-param-before-other-params.min.stderr
new file mode 100644
index 00000000000..c7e6d1be421
--- /dev/null
+++ b/src/test/ui/const-generics/const-param-before-other-params.min.stderr
@@ -0,0 +1,32 @@
+error: lifetime parameters must be declared prior to const parameters
+  --> $DIR/const-param-before-other-params.rs:6:21
+   |
+LL | fn bar<const X: (), 'a>(_: &'a ()) {
+   |       --------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const X: ()>`
+
+error: type parameters must be declared prior to const parameters
+  --> $DIR/const-param-before-other-params.rs:11:21
+   |
+LL | fn foo<const X: (), T>(_: &T) {}
+   |       --------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const X: ()>`
+
+error: `()` is forbidden as the type of a const generic parameter
+  --> $DIR/const-param-before-other-params.rs:6:17
+   |
+LL | fn bar<const X: (), 'a>(_: &'a ()) {
+   |                 ^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: `()` is forbidden as the type of a const generic parameter
+  --> $DIR/const-param-before-other-params.rs:11:17
+   |
+LL | fn foo<const X: (), T>(_: &T) {}
+   |                 ^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/const-generics/const-param-before-other-params.rs b/src/test/ui/const-generics/const-param-before-other-params.rs
index 0d787d9a67b..f1be90cf2e4 100644
--- a/src/test/ui/const-generics/const-param-before-other-params.rs
+++ b/src/test/ui/const-generics/const-param-before-other-params.rs
@@ -1,10 +1,15 @@
-#![allow(incomplete_features)]
-#![feature(const_generics)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 fn bar<const X: (), 'a>(_: &'a ()) {
     //~^ ERROR lifetime parameters must be declared prior to const parameters
+    //[min]~^^ ERROR `()` is forbidden as the type of a const generic parameter
 }
 
 fn foo<const X: (), T>(_: &T) {}
+//[min]~^ ERROR type parameters must be declared prior to const parameters
+//[min]~^^ ERROR `()` is forbidden as the type of a const generic parameter
 
 fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr
new file mode 100644
index 00000000000..a20c7264acf
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr
@@ -0,0 +1,9 @@
+error[E0741]: `&'static (dyn A + 'static)` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
+  --> $DIR/issue-63322-forbid-dyn.rs:10:18
+   |
+LL | fn test<const T: &'static dyn A>() {
+   |                  ^^^^^^^^^^^^^^ `&'static (dyn A + 'static)` doesn't derive both `PartialEq` and `Eq`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0741`.
diff --git a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr
new file mode 100644
index 00000000000..e6d9fb7a246
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr
@@ -0,0 +1,18 @@
+error: `&'static (dyn A + 'static)` is forbidden as the type of a const generic parameter
+  --> $DIR/issue-63322-forbid-dyn.rs:10:18
+   |
+LL | fn test<const T: &'static dyn A>() {
+   |                  ^^^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error[E0741]: `&'static (dyn A + 'static)` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
+  --> $DIR/issue-63322-forbid-dyn.rs:10:18
+   |
+LL | fn test<const T: &'static dyn A>() {
+   |                  ^^^^^^^^^^^^^^ `&'static (dyn A + 'static)` doesn't derive both `PartialEq` and `Eq`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0741`.
diff --git a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs
index 2bcaa27b4d2..2194eb97a41 100644
--- a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs
+++ b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs
@@ -1,5 +1,7 @@
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 trait A {}
 struct B;
@@ -7,6 +9,7 @@ impl A for B {}
 
 fn test<const T: &'static dyn A>() {
     //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` to be used
+    //[min]~^^ ERROR `&'static (dyn A + 'static)` is forbidden
     unimplemented!()
 }
 
diff --git a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr
deleted file mode 100644
index 32054e43716..00000000000
--- a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-63322-forbid-dyn.rs:1:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-
-error[E0741]: `&'static (dyn A + 'static)` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
-  --> $DIR/issue-63322-forbid-dyn.rs:8:18
-   |
-LL | fn test<const T: &'static dyn A>() {
-   |                  ^^^^^^^^^^^^^^ `&'static (dyn A + 'static)` doesn't derive both `PartialEq` and `Eq`
-
-error: aborting due to previous error; 1 warning emitted
-
-For more information about this error, try `rustc --explain E0741`.
diff --git a/src/test/ui/const-generics/issues/issue-64494.stderr b/src/test/ui/const-generics/issues/issue-64494.full.stderr
index 30dca169643..a97ec9308f8 100644
--- a/src/test/ui/const-generics/issues/issue-64494.stderr
+++ b/src/test/ui/const-generics/issues/issue-64494.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-64494.rs:14:53
+  --> $DIR/issue-64494.rs:16:53
    |
 LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {}
    |                                                     ^^^^
@@ -7,7 +7,7 @@ LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {}
    = note: this may fail depending on what value the parameter takes
 
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-64494.rs:16:53
+  --> $DIR/issue-64494.rs:19:53
    |
 LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {}
    |                                                     ^^^^
diff --git a/src/test/ui/const-generics/issues/issue-64494.min.stderr b/src/test/ui/const-generics/issues/issue-64494.min.stderr
new file mode 100644
index 00000000000..69fe0974a79
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-64494.min.stderr
@@ -0,0 +1,28 @@
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/issue-64494.rs:16:38
+   |
+LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {}
+   |                                      ^^^^^^ non-trivial anonymous constants must not depend on the parameter `T`
+   |
+   = help: it is currently only allowed to use either `T` or `{ T }` as generic constants
+
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/issue-64494.rs:19:38
+   |
+LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {}
+   |                                      ^^^^^^ non-trivial anonymous constants must not depend on the parameter `T`
+   |
+   = help: it is currently only allowed to use either `T` or `{ T }` as generic constants
+
+error[E0119]: conflicting implementations of trait `MyTrait`:
+  --> $DIR/issue-64494.rs:19:1
+   |
+LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {}
+   | ------------------------------------ first implementation here
+...
+LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/const-generics/issues/issue-64494.rs b/src/test/ui/const-generics/issues/issue-64494.rs
index 4c755530b99..3b598a41522 100644
--- a/src/test/ui/const-generics/issues/issue-64494.rs
+++ b/src/test/ui/const-generics/issues/issue-64494.rs
@@ -1,5 +1,7 @@
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 trait Foo {
     const VAL: usize;
@@ -12,8 +14,11 @@ struct Is<const T: bool>;
 impl True for Is<{true}> {}
 
 impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {}
-//~^ ERROR constant expression depends on a generic parameter
+//[full]~^ ERROR constant expression depends on a generic parameter
+//[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
 impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {}
-//~^ ERROR constant expression depends on a generic parameter
+//[full]~^ ERROR constant expression depends on a generic parameter
+//[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
+//[min]~| ERROR conflicting implementations of trait `MyTrait`
 
 fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-64519.rs b/src/test/ui/const-generics/issues/issue-64519.rs
index e9391096b04..1ca709d0975 100644
--- a/src/test/ui/const-generics/issues/issue-64519.rs
+++ b/src/test/ui/const-generics/issues/issue-64519.rs
@@ -1,7 +1,8 @@
 // check-pass
-
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 struct Foo<const D: usize> {
     state: Option<[u8; D]>,
diff --git a/src/test/ui/const-generics/issues/issue-66205.full.stderr b/src/test/ui/const-generics/issues/issue-66205.full.stderr
new file mode 100644
index 00000000000..a1520912e4e
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-66205.full.stderr
@@ -0,0 +1,10 @@
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-66205.rs:8:12
+   |
+LL |     fact::<{ N - 1 }>();
+   |            ^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-66205.min.stderr b/src/test/ui/const-generics/issues/issue-66205.min.stderr
new file mode 100644
index 00000000000..86709c389b6
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-66205.min.stderr
@@ -0,0 +1,10 @@
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/issue-66205.rs:8:14
+   |
+LL |     fact::<{ N - 1 }>();
+   |              ^ non-trivial anonymous constants must not depend on the parameter `N`
+   |
+   = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-66205.rs b/src/test/ui/const-generics/issues/issue-66205.rs
index 7cedf51ca04..e115eff356a 100644
--- a/src/test/ui/const-generics/issues/issue-66205.rs
+++ b/src/test/ui/const-generics/issues/issue-66205.rs
@@ -1,10 +1,13 @@
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 #![allow(dead_code, unconditional_recursion)]
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
 
 fn fact<const N: usize>() {
     fact::<{ N - 1 }>();
-    //~^ ERROR constant expression depends on a generic parameter
+    //[full]~^ ERROR constant expression depends on a generic parameter
+    //[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
 }
 
 fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-66205.stderr b/src/test/ui/const-generics/issues/issue-66205.stderr
deleted file mode 100644
index 1e9c0f2f3d9..00000000000
--- a/src/test/ui/const-generics/issues/issue-66205.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-66205.rs:2:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-
-error: constant expression depends on a generic parameter
-  --> $DIR/issue-66205.rs:6:12
-   |
-LL |     fact::<{ N - 1 }>();
-   |            ^^^^^^^^^
-   |
-   = note: this may fail depending on what value the parameter takes
-
-error: aborting due to previous error; 1 warning emitted
-
diff --git a/src/test/ui/const-generics/issues/issue-66906.rs b/src/test/ui/const-generics/issues/issue-66906.rs
index 486c72d8a34..3e048593c9b 100644
--- a/src/test/ui/const-generics/issues/issue-66906.rs
+++ b/src/test/ui/const-generics/issues/issue-66906.rs
@@ -1,7 +1,8 @@
 // check-pass
-
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 pub struct Tuple;
 
diff --git a/src/test/ui/const-generics/issues/issue-66906.stderr b/src/test/ui/const-generics/issues/issue-66906.stderr
deleted file mode 100644
index 8e8b552f90e..00000000000
--- a/src/test/ui/const-generics/issues/issue-66906.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-66906.rs:3:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/const-generics/issues/issue-67185-1.rs b/src/test/ui/const-generics/issues/issue-67185-1.rs
index b08057851a1..09d88ef89a3 100644
--- a/src/test/ui/const-generics/issues/issue-67185-1.rs
+++ b/src/test/ui/const-generics/issues/issue-67185-1.rs
@@ -1,7 +1,8 @@
 // check-pass
-
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 trait Baz {
     type Quaks;
diff --git a/src/test/ui/const-generics/issues/issue-67185-1.stderr b/src/test/ui/const-generics/issues/issue-67185-1.stderr
deleted file mode 100644
index 9cc797d6d8a..00000000000
--- a/src/test/ui/const-generics/issues/issue-67185-1.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-67185-1.rs:3:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/const-generics/issues/issue-68596.rs b/src/test/ui/const-generics/issues/issue-68596.rs
index 1f96e7d3b41..3b27d4d68c5 100644
--- a/src/test/ui/const-generics/issues/issue-68596.rs
+++ b/src/test/ui/const-generics/issues/issue-68596.rs
@@ -1,6 +1,8 @@
 // check-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 pub struct S(u8);
 
diff --git a/src/test/ui/const-generics/issues/issue-68615-adt.min.stderr b/src/test/ui/const-generics/issues/issue-68615-adt.min.stderr
new file mode 100644
index 00000000000..81c8f4392c7
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-68615-adt.min.stderr
@@ -0,0 +1,11 @@
+error: `[usize; 0]` is forbidden as the type of a const generic parameter
+  --> $DIR/issue-68615-adt.rs:7:23
+   |
+LL | struct Const<const V: [usize; 0]> {}
+   |                       ^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-68615-adt.rs b/src/test/ui/const-generics/issues/issue-68615-adt.rs
index 140bb28ec5a..d616f3ab95a 100644
--- a/src/test/ui/const-generics/issues/issue-68615-adt.rs
+++ b/src/test/ui/const-generics/issues/issue-68615-adt.rs
@@ -1,8 +1,11 @@
-// check-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// [full] check-pass
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 struct Const<const V: [usize; 0]> {}
+//[min]~^ ERROR `[usize; 0]` is forbidden as the type of a const generic parameter
 type MyConst = Const<{ [] }>;
 
 fn main() {
diff --git a/src/test/ui/const-generics/issues/issue-68615-array.min.stderr b/src/test/ui/const-generics/issues/issue-68615-array.min.stderr
new file mode 100644
index 00000000000..8f55a92fce9
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-68615-array.min.stderr
@@ -0,0 +1,11 @@
+error: `[usize; 0]` is forbidden as the type of a const generic parameter
+  --> $DIR/issue-68615-array.rs:7:21
+   |
+LL | struct Foo<const V: [usize; 0] > {}
+   |                     ^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-68615-array.rs b/src/test/ui/const-generics/issues/issue-68615-array.rs
index c384bc1e36d..24c9a59a185 100644
--- a/src/test/ui/const-generics/issues/issue-68615-array.rs
+++ b/src/test/ui/const-generics/issues/issue-68615-array.rs
@@ -1,8 +1,11 @@
-// check-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// [full] check-pass
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 struct Foo<const V: [usize; 0] > {}
+//[min]~^ ERROR `[usize; 0]` is forbidden as the type of a const generic parameter
 
 type MyFoo = Foo<{ [] }>;
 
diff --git a/src/test/ui/const-generics/issues/issue-68977.full.stderr b/src/test/ui/const-generics/issues/issue-68977.full.stderr
new file mode 100644
index 00000000000..3690bac3eb3
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-68977.full.stderr
@@ -0,0 +1,10 @@
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-68977.rs:35:44
+   |
+LL |     FxpStorageHelper<INT_BITS, FRAC_BITS>: FxpStorage,
+   |                                            ^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-68977.min.stderr b/src/test/ui/const-generics/issues/issue-68977.min.stderr
new file mode 100644
index 00000000000..5b2137b244c
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-68977.min.stderr
@@ -0,0 +1,18 @@
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/issue-68977.rs:29:17
+   |
+LL |     PhantomU8<{(INT_BITS + FRAC_BITS + 7) / 8}>;
+   |                 ^^^^^^^^ non-trivial anonymous constants must not depend on the parameter `INT_BITS`
+   |
+   = help: it is currently only allowed to use either `INT_BITS` or `{ INT_BITS }` as generic constants
+
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/issue-68977.rs:29:28
+   |
+LL |     PhantomU8<{(INT_BITS + FRAC_BITS + 7) / 8}>;
+   |                            ^^^^^^^^^ non-trivial anonymous constants must not depend on the parameter `FRAC_BITS`
+   |
+   = help: it is currently only allowed to use either `FRAC_BITS` or `{ FRAC_BITS }` as generic constants
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/const-generics/issues/issue-68977.rs b/src/test/ui/const-generics/issues/issue-68977.rs
index 346ea3c2042..02e634efec3 100644
--- a/src/test/ui/const-generics/issues/issue-68977.rs
+++ b/src/test/ui/const-generics/issues/issue-68977.rs
@@ -1,5 +1,7 @@
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 struct PhantomU8<const X: u8>;
 
@@ -25,11 +27,13 @@ fxp_storage_impls! {
 
 type FxpStorageHelper<const INT_BITS: u8, const FRAC_BITS: u8> =
     PhantomU8<{(INT_BITS + FRAC_BITS + 7) / 8}>;
+    //[min]~^ ERROR generic parameters must not be used inside of non trivial constant values
+    //[min]~| ERROR generic parameters must not be used inside of non trivial constant values
 
 struct Fxp<const INT_BITS: u8, const FRAC_BITS: u8>
 where
     FxpStorageHelper<INT_BITS, FRAC_BITS>: FxpStorage,
-    //~^ ERROR constant expression depends on a generic parameter
+    //[full]~^ ERROR constant expression depends on a generic parameter
 {
     storage: <FxpStorageHelper<INT_BITS, FRAC_BITS> as FxpStorage>::SInt,
 }
diff --git a/src/test/ui/const-generics/issues/issue-68977.stderr b/src/test/ui/const-generics/issues/issue-68977.stderr
deleted file mode 100644
index e1190d9026d..00000000000
--- a/src/test/ui/const-generics/issues/issue-68977.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-68977.rs:1:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-
-error: constant expression depends on a generic parameter
-  --> $DIR/issue-68977.rs:31:44
-   |
-LL |     FxpStorageHelper<INT_BITS, FRAC_BITS>: FxpStorage,
-   |                                            ^^^^^^^^^^
-   |
-   = note: this may fail depending on what value the parameter takes
-
-error: aborting due to previous error; 1 warning emitted
-
diff --git a/src/test/ui/const-generics/issues/issue-70125-1.rs b/src/test/ui/const-generics/issues/issue-70125-1.rs
index 08a8309d431..04175089dc0 100644
--- a/src/test/ui/const-generics/issues/issue-70125-1.rs
+++ b/src/test/ui/const-generics/issues/issue-70125-1.rs
@@ -1,6 +1,8 @@
 // run-pass
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 const L: usize = 4;
 
diff --git a/src/test/ui/const-generics/issues/issue-70125-1.stderr b/src/test/ui/const-generics/issues/issue-70125-1.stderr
deleted file mode 100644
index 8ad4b25ae5b..00000000000
--- a/src/test/ui/const-generics/issues/issue-70125-1.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-70125-1.rs:2:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-
-warning: 1 warning emitted
-
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 fb7d4886a7c..ceefc2dcb32 100644
--- a/src/test/ui/const-generics/issues/issue-70125-2.rs
+++ b/src/test/ui/const-generics/issues/issue-70125-2.rs
@@ -1,7 +1,8 @@
 // run-pass
-
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 fn main() {
     <()>::foo();
diff --git a/src/test/ui/const-generics/issues/issue-70125-2.stderr b/src/test/ui/const-generics/issues/issue-70125-2.stderr
deleted file mode 100644
index c1f9634810e..00000000000
--- a/src/test/ui/const-generics/issues/issue-70125-2.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-70125-2.rs:3:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/const-generics/issues/issue-70167.rs b/src/test/ui/const-generics/issues/issue-70167.rs
index b53cec80071..04c76a4dcaf 100644
--- a/src/test/ui/const-generics/issues/issue-70167.rs
+++ b/src/test/ui/const-generics/issues/issue-70167.rs
@@ -1,7 +1,8 @@
 // check-pass
-
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 pub trait Trait<const N: usize>: From<<Self as Trait<N>>::Item> {
   type Item;
diff --git a/src/test/ui/const-generics/issues/issue-70167.stderr b/src/test/ui/const-generics/issues/issue-70167.stderr
deleted file mode 100644
index 5d647e933c4..00000000000
--- a/src/test/ui/const-generics/issues/issue-70167.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-70167.rs:3:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/const-generics/issues/issue-71169.stderr b/src/test/ui/const-generics/issues/issue-71169.full.stderr
index 6d4cf4027c1..b87825d20ce 100644
--- a/src/test/ui/const-generics/issues/issue-71169.stderr
+++ b/src/test/ui/const-generics/issues/issue-71169.full.stderr
@@ -1,11 +1,11 @@
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/issue-71169.rs:4:43
+  --> $DIR/issue-71169.rs:6:43
    |
 LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
    |                                           ^^^ the type must not depend on the parameter `LEN`
 
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-71169.rs:8:14
+  --> $DIR/issue-71169.rs:11:14
    |
 LL |     foo::<4, DATA>();
    |              ^^^^
diff --git a/src/test/ui/const-generics/issues/issue-71169.min.stderr b/src/test/ui/const-generics/issues/issue-71169.min.stderr
new file mode 100644
index 00000000000..79d63443351
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-71169.min.stderr
@@ -0,0 +1,18 @@
+error[E0770]: the type of const parameters must not depend on other generic parameters
+  --> $DIR/issue-71169.rs:6:43
+   |
+LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
+   |                                           ^^^ the type must not depend on the parameter `LEN`
+
+error: `[u8; _]` is forbidden as the type of a const generic parameter
+  --> $DIR/issue-71169.rs:6:38
+   |
+LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
+   |                                      ^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0770`.
diff --git a/src/test/ui/const-generics/issues/issue-71169.rs b/src/test/ui/const-generics/issues/issue-71169.rs
index 943a16cfcd6..7007ec222ca 100644
--- a/src/test/ui/const-generics/issues/issue-71169.rs
+++ b/src/test/ui/const-generics/issues/issue-71169.rs
@@ -1,10 +1,13 @@
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
 //~^ ERROR the type of const parameters must not
+//[min]~^^ ERROR `[u8; _]` is forbidden as the type of a const generic parameter
 fn main() {
     const DATA: [u8; 4] = *b"ABCD";
     foo::<4, DATA>();
-    //~^ ERROR constant expression depends on
+    //[full]~^ ERROR constant expression depends on
 }
diff --git a/src/test/ui/const-generics/issues/issue-71381.stderr b/src/test/ui/const-generics/issues/issue-71381.full.stderr
index fd4ebe3dead..453ef00e6dc 100644
--- a/src/test/ui/const-generics/issues/issue-71381.stderr
+++ b/src/test/ui/const-generics/issues/issue-71381.full.stderr
@@ -1,23 +1,23 @@
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/issue-71381.rs:13:82
+  --> $DIR/issue-71381.rs:15:82
    |
 LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
    |                                                                                  ^^^^ the type must not depend on the parameter `Args`
 
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/issue-71381.rs:22:40
+  --> $DIR/issue-71381.rs:24:40
    |
 LL |         const FN: unsafe extern "C" fn(Args),
    |                                        ^^^^ the type must not depend on the parameter `Args`
 
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71381.rs:13:61
+  --> $DIR/issue-71381.rs:15:61
    |
 LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
    |                                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71381.rs:22:19
+  --> $DIR/issue-71381.rs:24:19
    |
 LL |         const FN: unsafe extern "C" fn(Args),
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-71381.min.stderr b/src/test/ui/const-generics/issues/issue-71381.min.stderr
new file mode 100644
index 00000000000..453ef00e6dc
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-71381.min.stderr
@@ -0,0 +1,27 @@
+error[E0770]: the type of const parameters must not depend on other generic parameters
+  --> $DIR/issue-71381.rs:15:82
+   |
+LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
+   |                                                                                  ^^^^ the type must not depend on the parameter `Args`
+
+error[E0770]: the type of const parameters must not depend on other generic parameters
+  --> $DIR/issue-71381.rs:24:40
+   |
+LL |         const FN: unsafe extern "C" fn(Args),
+   |                                        ^^^^ the type must not depend on the parameter `Args`
+
+error: using function pointers as const generic parameters is forbidden
+  --> $DIR/issue-71381.rs:15:61
+   |
+LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
+   |                                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: using function pointers as const generic parameters is forbidden
+  --> $DIR/issue-71381.rs:24:19
+   |
+LL |         const FN: unsafe extern "C" fn(Args),
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0770`.
diff --git a/src/test/ui/const-generics/issues/issue-71381.rs b/src/test/ui/const-generics/issues/issue-71381.rs
index 08f94823942..65d88e553b9 100644
--- a/src/test/ui/const-generics/issues/issue-71381.rs
+++ b/src/test/ui/const-generics/issues/issue-71381.rs
@@ -1,5 +1,7 @@
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 struct Test(*const usize);
 
diff --git a/src/test/ui/const-generics/issues/issue-71382.stderr b/src/test/ui/const-generics/issues/issue-71382.full.stderr
index 1652b0bdfa8..3da85ee040d 100644
--- a/src/test/ui/const-generics/issues/issue-71382.stderr
+++ b/src/test/ui/const-generics/issues/issue-71382.full.stderr
@@ -1,5 +1,5 @@
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71382.rs:15:23
+  --> $DIR/issue-71382.rs:17:23
    |
 LL |     fn test<const FN: fn()>(&self) {
    |                       ^^^^
diff --git a/src/test/ui/const-generics/issues/issue-71382.min.stderr b/src/test/ui/const-generics/issues/issue-71382.min.stderr
new file mode 100644
index 00000000000..3da85ee040d
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-71382.min.stderr
@@ -0,0 +1,8 @@
+error: using function pointers as const generic parameters is forbidden
+  --> $DIR/issue-71382.rs:17:23
+   |
+LL |     fn test<const FN: fn()>(&self) {
+   |                       ^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-71382.rs b/src/test/ui/const-generics/issues/issue-71382.rs
index e0cf9812d95..12a7d08382a 100644
--- a/src/test/ui/const-generics/issues/issue-71382.rs
+++ b/src/test/ui/const-generics/issues/issue-71382.rs
@@ -1,5 +1,7 @@
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 struct Test();
 
diff --git a/src/test/ui/const-generics/issues/issue-71611.stderr b/src/test/ui/const-generics/issues/issue-71611.full.stderr
index e2c9f22361e..48d4bb361a1 100644
--- a/src/test/ui/const-generics/issues/issue-71611.stderr
+++ b/src/test/ui/const-generics/issues/issue-71611.full.stderr
@@ -1,11 +1,11 @@
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/issue-71611.rs:4:31
+  --> $DIR/issue-71611.rs:6:31
    |
 LL | fn func<A, const F: fn(inner: A)>(outer: A) {
    |                               ^ the type must not depend on the parameter `A`
 
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71611.rs:4:21
+  --> $DIR/issue-71611.rs:6:21
    |
 LL | fn func<A, const F: fn(inner: A)>(outer: A) {
    |                     ^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-71611.min.stderr b/src/test/ui/const-generics/issues/issue-71611.min.stderr
new file mode 100644
index 00000000000..48d4bb361a1
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-71611.min.stderr
@@ -0,0 +1,15 @@
+error[E0770]: the type of const parameters must not depend on other generic parameters
+  --> $DIR/issue-71611.rs:6:31
+   |
+LL | fn func<A, const F: fn(inner: A)>(outer: A) {
+   |                               ^ the type must not depend on the parameter `A`
+
+error: using function pointers as const generic parameters is forbidden
+  --> $DIR/issue-71611.rs:6:21
+   |
+LL | fn func<A, const F: fn(inner: A)>(outer: A) {
+   |                     ^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0770`.
diff --git a/src/test/ui/const-generics/issues/issue-71611.rs b/src/test/ui/const-generics/issues/issue-71611.rs
index 06ff38dec66..9b8e8be6bc6 100644
--- a/src/test/ui/const-generics/issues/issue-71611.rs
+++ b/src/test/ui/const-generics/issues/issue-71611.rs
@@ -1,5 +1,7 @@
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 fn func<A, const F: fn(inner: A)>(outer: A) {
     //~^ ERROR: using function pointers as const generic parameters is forbidden
diff --git a/src/test/ui/const-generics/issues/issue-72352.stderr b/src/test/ui/const-generics/issues/issue-72352.full.stderr
index bc48da10393..51f94678467 100644
--- a/src/test/ui/const-generics/issues/issue-72352.stderr
+++ b/src/test/ui/const-generics/issues/issue-72352.full.stderr
@@ -1,5 +1,5 @@
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-72352.rs:6:42
+  --> $DIR/issue-72352.rs:8:42
    |
 LL | unsafe fn unsafely_do_the_thing<const F: fn(&CStr) -> usize>(ptr: *const i8) -> usize {
    |                                          ^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-72352.min.stderr b/src/test/ui/const-generics/issues/issue-72352.min.stderr
new file mode 100644
index 00000000000..51f94678467
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-72352.min.stderr
@@ -0,0 +1,8 @@
+error: using function pointers as const generic parameters is forbidden
+  --> $DIR/issue-72352.rs:8:42
+   |
+LL | unsafe fn unsafely_do_the_thing<const F: fn(&CStr) -> usize>(ptr: *const i8) -> usize {
+   |                                          ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-72352.rs b/src/test/ui/const-generics/issues/issue-72352.rs
index e977af8deb7..1517f3dae4f 100644
--- a/src/test/ui/const-generics/issues/issue-72352.rs
+++ b/src/test/ui/const-generics/issues/issue-72352.rs
@@ -1,5 +1,7 @@
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 use std::ffi::{CStr, CString};
 
diff --git a/src/test/ui/const-generics/issues/issue-73491.min.stderr b/src/test/ui/const-generics/issues/issue-73491.min.stderr
new file mode 100644
index 00000000000..5bf3671d38b
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-73491.min.stderr
@@ -0,0 +1,11 @@
+error: `[u32; _]` is forbidden as the type of a const generic parameter
+  --> $DIR/issue-73491.rs:9:19
+   |
+LL | fn hoge<const IN: [u32; LEN]>() {}
+   |                   ^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-73491.rs b/src/test/ui/const-generics/issues/issue-73491.rs
index 05e1513bb75..4f6c44ad2cd 100644
--- a/src/test/ui/const-generics/issues/issue-73491.rs
+++ b/src/test/ui/const-generics/issues/issue-73491.rs
@@ -1,9 +1,12 @@
-// check-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// [full] check-pass
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 const LEN: usize = 1024;
 
 fn hoge<const IN: [u32; LEN]>() {}
+//[min]~^ ERROR `[u32; _]` is forbidden as the type of a const generic parameter
 
 fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-73508.full.stderr b/src/test/ui/const-generics/issues/issue-73508.full.stderr
new file mode 100644
index 00000000000..0816bad35b2
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-73508.full.stderr
@@ -0,0 +1,8 @@
+error: using raw pointers as const generic parameters is forbidden
+  --> $DIR/issue-73508.rs:6:33
+   |
+LL | pub const fn func_name<const X: *const u32>() {}
+   |                                 ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-73508.min.stderr b/src/test/ui/const-generics/issues/issue-73508.min.stderr
new file mode 100644
index 00000000000..0816bad35b2
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-73508.min.stderr
@@ -0,0 +1,8 @@
+error: using raw pointers as const generic parameters is forbidden
+  --> $DIR/issue-73508.rs:6:33
+   |
+LL | pub const fn func_name<const X: *const u32>() {}
+   |                                 ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-73508.rs b/src/test/ui/const-generics/issues/issue-73508.rs
index ba2e2a38e74..21b87f7f901 100644
--- a/src/test/ui/const-generics/issues/issue-73508.rs
+++ b/src/test/ui/const-generics/issues/issue-73508.rs
@@ -1,4 +1,7 @@
-#![feature(const_generics)] //~ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 pub const fn func_name<const X: *const u32>() {}
 //~^ ERROR using raw pointers
diff --git a/src/test/ui/const-generics/issues/issue-73508.stderr b/src/test/ui/const-generics/issues/issue-73508.stderr
deleted file mode 100644
index 23ad1818b6f..00000000000
--- a/src/test/ui/const-generics/issues/issue-73508.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-73508.rs:1:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-
-error: using raw pointers as const generic parameters is forbidden
-  --> $DIR/issue-73508.rs:3:33
-   |
-LL | pub const fn func_name<const X: *const u32>() {}
-   |                                 ^^^^^^^^^^
-
-error: aborting due to previous error; 1 warning emitted
-
diff --git a/src/test/ui/const-generics/issues/issue-74101.min.stderr b/src/test/ui/const-generics/issues/issue-74101.min.stderr
new file mode 100644
index 00000000000..8062faefbe6
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-74101.min.stderr
@@ -0,0 +1,20 @@
+error: `[u8; _]` is forbidden as the type of a const generic parameter
+  --> $DIR/issue-74101.rs:7:18
+   |
+LL | fn test<const N: [u8; 1 + 2]>() {}
+   |                  ^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: `[u8; _]` is forbidden as the type of a const generic parameter
+  --> $DIR/issue-74101.rs:10:21
+   |
+LL | struct Foo<const N: [u8; 1 + 2]>;
+   |                     ^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/const-generics/issues/issue-74101.rs b/src/test/ui/const-generics/issues/issue-74101.rs
index 2f427ef3a27..2a7d31ac8dd 100644
--- a/src/test/ui/const-generics/issues/issue-74101.rs
+++ b/src/test/ui/const-generics/issues/issue-74101.rs
@@ -1,9 +1,13 @@
-// check-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// [full] check-pass
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 fn test<const N: [u8; 1 + 2]>() {}
+//[min]~^ ERROR `[u8; _]` is forbidden as the type of a const generic parameter
 
 struct Foo<const N: [u8; 1 + 2]>;
+//[min]~^ ERROR `[u8; _]` is forbidden as the type of a const generic parameter
 
 fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-74255.min.stderr b/src/test/ui/const-generics/issues/issue-74255.min.stderr
new file mode 100644
index 00000000000..86937d715c9
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-74255.min.stderr
@@ -0,0 +1,11 @@
+error: `IceEnum` is forbidden as the type of a const generic parameter
+  --> $DIR/issue-74255.rs:15:31
+   |
+LL |     fn ice_struct_fn<const I: IceEnum>() {}
+   |                               ^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-74255.rs b/src/test/ui/const-generics/issues/issue-74255.rs
index 55ccf57dc99..b277c273461 100644
--- a/src/test/ui/const-generics/issues/issue-74255.rs
+++ b/src/test/ui/const-generics/issues/issue-74255.rs
@@ -1,6 +1,8 @@
-// check-pass
-#![feature(const_generics)]
-#![allow(dead_code, incomplete_features)]
+// [full] check-pass
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 #[derive(PartialEq, Eq)]
 enum IceEnum {
@@ -11,6 +13,7 @@ struct IceStruct;
 
 impl IceStruct {
     fn ice_struct_fn<const I: IceEnum>() {}
+    //[min]~^ ERROR `IceEnum` is forbidden as the type of a const generic parameter
 }
 
 fn main() {
diff --git a/src/test/ui/const-generics/issues/issue-75047.min.stderr b/src/test/ui/const-generics/issues/issue-75047.min.stderr
new file mode 100644
index 00000000000..edc54b082db
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-75047.min.stderr
@@ -0,0 +1,11 @@
+error: `[u8; _]` is forbidden as the type of a const generic parameter
+  --> $DIR/issue-75047.rs:15:21
+   |
+LL | struct Foo<const N: [u8; Bar::<u32>::value()]>;
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-75047.rs b/src/test/ui/const-generics/issues/issue-75047.rs
index 5d068d851c1..7bab7cdd098 100644
--- a/src/test/ui/const-generics/issues/issue-75047.rs
+++ b/src/test/ui/const-generics/issues/issue-75047.rs
@@ -1,6 +1,8 @@
-// check-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// [full] check-pass
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 struct Bar<T>(T);
 
@@ -11,5 +13,6 @@ impl<T> Bar<T> {
 }
 
 struct Foo<const N: [u8; Bar::<u32>::value()]>;
+//[min]~^ ERROR `[u8; _]` is forbidden as the type of a const generic parameter
 
 fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue70273-assoc-fn.rs b/src/test/ui/const-generics/issues/issue70273-assoc-fn.rs
index c22e61d0ce3..28f80702dcf 100644
--- a/src/test/ui/const-generics/issues/issue70273-assoc-fn.rs
+++ b/src/test/ui/const-generics/issues/issue70273-assoc-fn.rs
@@ -1,7 +1,8 @@
 // check-pass
-
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 trait T<const A: usize> {
     fn f();
diff --git a/src/test/ui/const-generics/issues/issue70273-assoc-fn.stderr b/src/test/ui/const-generics/issues/issue70273-assoc-fn.stderr
deleted file mode 100644
index 931701b64b4..00000000000
--- a/src/test/ui/const-generics/issues/issue70273-assoc-fn.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue70273-assoc-fn.rs:3:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/const-generics/std/const-generics-range.min.stderr b/src/test/ui/const-generics/std/const-generics-range.min.stderr
new file mode 100644
index 00000000000..a71e7442021
--- /dev/null
+++ b/src/test/ui/const-generics/std/const-generics-range.min.stderr
@@ -0,0 +1,56 @@
+error: `std::ops::Range<usize>` is forbidden as the type of a const generic parameter
+  --> $DIR/const-generics-range.rs:8:24
+   |
+LL | struct _Range<const R: std::ops::Range<usize>>;
+   |                        ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: `std::ops::RangeFrom<usize>` is forbidden as the type of a const generic parameter
+  --> $DIR/const-generics-range.rs:13:28
+   |
+LL | struct _RangeFrom<const R: std::ops::RangeFrom<usize>>;
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: `std::ops::RangeFull` is forbidden as the type of a const generic parameter
+  --> $DIR/const-generics-range.rs:18:28
+   |
+LL | struct _RangeFull<const R: std::ops::RangeFull>;
+   |                            ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: `std::ops::RangeInclusive<usize>` is forbidden as the type of a const generic parameter
+  --> $DIR/const-generics-range.rs:24:33
+   |
+LL | struct _RangeInclusive<const R: std::ops::RangeInclusive<usize>>;
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: `std::ops::RangeTo<usize>` is forbidden as the type of a const generic parameter
+  --> $DIR/const-generics-range.rs:29:26
+   |
+LL | struct _RangeTo<const R: std::ops::RangeTo<usize>>;
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: `std::ops::RangeToInclusive<usize>` is forbidden as the type of a const generic parameter
+  --> $DIR/const-generics-range.rs:34:35
+   |
+LL | struct _RangeToInclusive<const R: std::ops::RangeToInclusive<usize>>;
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/const-generics/std/const-generics-range.rs b/src/test/ui/const-generics/std/const-generics-range.rs
index 6d56fe0d7b8..c04f4a3acfb 100644
--- a/src/test/ui/const-generics/std/const-generics-range.rs
+++ b/src/test/ui/const-generics/std/const-generics-range.rs
@@ -1,30 +1,38 @@
-// check-pass
-#![allow(incomplete_features)]
-#![feature(const_generics)]
+// [full] check-pass
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 // `Range` should be usable within const generics:
 struct _Range<const R: std::ops::Range<usize>>;
+//[min]~^ ERROR `std::ops::Range<usize>` is forbidden
 const RANGE : _Range<{ 0 .. 1000 }> = _Range;
 
 // `RangeFrom` should be usable within const generics:
 struct _RangeFrom<const R: std::ops::RangeFrom<usize>>;
+//[min]~^ ERROR `std::ops::RangeFrom<usize>` is forbidden
 const RANGE_FROM : _RangeFrom<{ 0 .. }> = _RangeFrom;
 
 // `RangeFull` should be usable within const generics:
 struct _RangeFull<const R: std::ops::RangeFull>;
+//[min]~^ ERROR `std::ops::RangeFull` is forbidden
 const RANGE_FULL : _RangeFull<{ .. }> = _RangeFull;
 
 // Regression test for #70155
 // `RangeInclusive` should be usable within const generics:
 struct _RangeInclusive<const R: std::ops::RangeInclusive<usize>>;
+//[min]~^ ERROR `std::ops::RangeInclusive<usize>` is forbidden
 const RANGE_INCLUSIVE : _RangeInclusive<{ 0 ..= 999 }> = _RangeInclusive;
 
 // `RangeTo` should be usable within const generics:
 struct _RangeTo<const R: std::ops::RangeTo<usize>>;
+//[min]~^ ERROR `std::ops::RangeTo<usize>` is forbidden
 const RANGE_TO : _RangeTo<{ .. 1000 }> = _RangeTo;
 
 // `RangeToInclusive` should be usable within const generics:
 struct _RangeToInclusive<const R: std::ops::RangeToInclusive<usize>>;
+//[min]~^ ERROR `std::ops::RangeToInclusive<usize>` is forbidden
 const RANGE_TO_INCLUSIVE : _RangeToInclusive<{ ..= 999 }> = _RangeToInclusive;
 
 pub fn main() {}
diff --git a/src/test/ui/const-generics/type-after-const-ok.min.stderr b/src/test/ui/const-generics/type-after-const-ok.min.stderr
new file mode 100644
index 00000000000..67a44d2c5b4
--- /dev/null
+++ b/src/test/ui/const-generics/type-after-const-ok.min.stderr
@@ -0,0 +1,8 @@
+error: type parameters must be declared prior to const parameters
+  --> $DIR/type-after-const-ok.rs:9:26
+   |
+LL | struct A<const N: usize, T>(T);
+   |         -----------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const N: usize>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/type-after-const-ok.rs b/src/test/ui/const-generics/type-after-const-ok.rs
index fc977d6617c..69227cdf19c 100644
--- a/src/test/ui/const-generics/type-after-const-ok.rs
+++ b/src/test/ui/const-generics/type-after-const-ok.rs
@@ -1,10 +1,12 @@
-// run-pass
+// [full] run-pass
+// revisions: full min
 // Verifies that having generic parameters after constants is permitted
-
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 #[allow(dead_code)]
 struct A<const N: usize, T>(T);
+//[min]~^ ERROR type parameters must be declared prior to const parameters
 
 fn main() {}
diff --git a/src/test/ui/const-generics/type-dependent/issue-61936.rs b/src/test/ui/const-generics/type-dependent/issue-61936.rs
index a7a923c6a59..1d42afa3f84 100644
--- a/src/test/ui/const-generics/type-dependent/issue-61936.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-61936.rs
@@ -1,6 +1,8 @@
 // run-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 trait SliceExt<T: Clone> {
     fn array_windows<'a, const N: usize>(&'a self) -> ArrayWindows<'a, T, N>;
diff --git a/src/test/ui/const-generics/type-dependent/issue-63695.rs b/src/test/ui/const-generics/type-dependent/issue-63695.rs
index f3c2e177594..465b66b09ce 100644
--- a/src/test/ui/const-generics/type-dependent/issue-63695.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-63695.rs
@@ -1,6 +1,8 @@
 // run-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 trait T {
     fn test<const A: i32>(&self) -> i32 { A }
diff --git a/src/test/ui/const-generics/type-dependent/issue-67144-1.rs b/src/test/ui/const-generics/type-dependent/issue-67144-1.rs
index a3d05959198..3d4910e9e4b 100644
--- a/src/test/ui/const-generics/type-dependent/issue-67144-1.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-67144-1.rs
@@ -1,6 +1,8 @@
 // check-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 struct X;
 
diff --git a/src/test/ui/const-generics/type-dependent/issue-67144-2.rs b/src/test/ui/const-generics/type-dependent/issue-67144-2.rs
index c53a149fa8d..0868d309b33 100644
--- a/src/test/ui/const-generics/type-dependent/issue-67144-2.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-67144-2.rs
@@ -1,6 +1,8 @@
 // check-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 struct A<const N: usize>;
 
diff --git a/src/test/ui/const-generics/type-dependent/issue-69816.rs b/src/test/ui/const-generics/type-dependent/issue-69816.rs
index cbe86cef323..4a374dc1db6 100644
--- a/src/test/ui/const-generics/type-dependent/issue-69816.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-69816.rs
@@ -1,6 +1,8 @@
 // run-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 trait IterExt: Sized + Iterator {
     fn default_for_size<const N: usize>(self) -> [Self::Item; N]
diff --git a/src/test/ui/const-generics/type-dependent/issue-70217.rs b/src/test/ui/const-generics/type-dependent/issue-70217.rs
index caa611cbd79..ba5a42e47e9 100644
--- a/src/test/ui/const-generics/type-dependent/issue-70217.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-70217.rs
@@ -1,6 +1,9 @@
 // check-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 struct Struct<const N: usize>;
 
diff --git a/src/test/ui/const-generics/type-dependent/issue-70507.rs b/src/test/ui/const-generics/type-dependent/issue-70507.rs
index 6fcf4116d43..234c09e04ae 100644
--- a/src/test/ui/const-generics/type-dependent/issue-70507.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-70507.rs
@@ -1,6 +1,8 @@
 // run-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 trait ConstChunksExactTrait<T> {
     fn const_chunks_exact<const N: usize>(&self) -> ConstChunksExact<'_, T, {N}>;
diff --git a/src/test/ui/const-generics/type-dependent/issue-70586.rs b/src/test/ui/const-generics/type-dependent/issue-70586.rs
index 5a0888506eb..fd52373cee2 100644
--- a/src/test/ui/const-generics/type-dependent/issue-70586.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-70586.rs
@@ -1,6 +1,8 @@
 // check-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 use std::marker::PhantomData;
 
diff --git a/src/test/ui/const-generics/type-dependent/issue-71348.min.stderr b/src/test/ui/const-generics/type-dependent/issue-71348.min.stderr
new file mode 100644
index 00000000000..8656239605d
--- /dev/null
+++ b/src/test/ui/const-generics/type-dependent/issue-71348.min.stderr
@@ -0,0 +1,20 @@
+error: `&'static str` is forbidden as the type of a const generic parameter
+  --> $DIR/issue-71348.rs:11:24
+   |
+LL | trait Get<'a, const N: &'static str> {
+   |                        ^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: `&'static str` is forbidden as the type of a const generic parameter
+  --> $DIR/issue-71348.rs:19:25
+   |
+LL |     fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Target
+   |                         ^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/const-generics/type-dependent/issue-71348.rs b/src/test/ui/const-generics/type-dependent/issue-71348.rs
index ec22dcdf60b..772e179746d 100644
--- a/src/test/ui/const-generics/type-dependent/issue-71348.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-71348.rs
@@ -1,12 +1,15 @@
-// run-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// [full] run-pass
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 struct Foo {
     i: i32,
 }
 
 trait Get<'a, const N: &'static str> {
+    //[min]~^ ERROR `&'static str` is forbidden as the type of a const generic parameter
     type Target: 'a;
 
     fn get(&'a self) -> &'a Self::Target;
@@ -14,6 +17,7 @@ trait Get<'a, const N: &'static str> {
 
 impl Foo {
     fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Target
+    //[min]~^ ERROR `&'static str` is forbidden as the type of a const generic parameter
     where
         Self: Get<'a, N>,
     {
diff --git a/src/test/ui/const-generics/type-dependent/issue-71382.full.stderr b/src/test/ui/const-generics/type-dependent/issue-71382.full.stderr
new file mode 100644
index 00000000000..da1d3270b7c
--- /dev/null
+++ b/src/test/ui/const-generics/type-dependent/issue-71382.full.stderr
@@ -0,0 +1,8 @@
+error: using function pointers as const generic parameters is forbidden
+  --> $DIR/issue-71382.rs:17:23
+   |
+LL |     fn test<const FN: fn() -> u8>(&self) -> u8 {
+   |                       ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/type-dependent/issue-71382.min.stderr b/src/test/ui/const-generics/type-dependent/issue-71382.min.stderr
new file mode 100644
index 00000000000..da1d3270b7c
--- /dev/null
+++ b/src/test/ui/const-generics/type-dependent/issue-71382.min.stderr
@@ -0,0 +1,8 @@
+error: using function pointers as const generic parameters is forbidden
+  --> $DIR/issue-71382.rs:17:23
+   |
+LL |     fn test<const FN: fn() -> u8>(&self) -> u8 {
+   |                       ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/type-dependent/issue-71382.rs b/src/test/ui/const-generics/type-dependent/issue-71382.rs
index 05abd488816..497fd1381de 100644
--- a/src/test/ui/const-generics/type-dependent/issue-71382.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-71382.rs
@@ -1,5 +1,7 @@
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 struct Test;
 
diff --git a/src/test/ui/const-generics/type-dependent/issue-71382.stderr b/src/test/ui/const-generics/type-dependent/issue-71382.stderr
deleted file mode 100644
index f441b71031e..00000000000
--- a/src/test/ui/const-generics/type-dependent/issue-71382.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-71382.rs:1:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-
-error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71382.rs:15:23
-   |
-LL |     fn test<const FN: fn() -> u8>(&self) -> u8 {
-   |                       ^^^^^^^^^^
-
-error: aborting due to previous error; 1 warning emitted
-
diff --git a/src/test/ui/const-generics/type-dependent/issue-71805.rs b/src/test/ui/const-generics/type-dependent/issue-71805.rs
index 6823d780aef..2aaf12cea4f 100644
--- a/src/test/ui/const-generics/type-dependent/issue-71805.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-71805.rs
@@ -1,6 +1,8 @@
 // run-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 use std::mem::MaybeUninit;
 
diff --git a/src/test/ui/const-generics/type-dependent/issue-73730.rs b/src/test/ui/const-generics/type-dependent/issue-73730.rs
index d90cc50ddc4..3e53190ee48 100644
--- a/src/test/ui/const-generics/type-dependent/issue-73730.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-73730.rs
@@ -1,6 +1,8 @@
 // check-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 trait Foo<'a, A>: Iterator<Item=A> {
     fn bar<const N: usize>(&mut self) -> *const [A; N];
diff --git a/src/test/ui/const-generics/type-dependent/non-local.rs b/src/test/ui/const-generics/type-dependent/non-local.rs
index e6f3eb075f1..747664a0962 100644
--- a/src/test/ui/const-generics/type-dependent/non-local.rs
+++ b/src/test/ui/const-generics/type-dependent/non-local.rs
@@ -1,7 +1,9 @@
 // aux-build:type_dependent_lib.rs
 // run-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 extern crate type_dependent_lib;
 
diff --git a/src/test/ui/const-generics/type-dependent/qpath.rs b/src/test/ui/const-generics/type-dependent/qpath.rs
index f3f98e5faf5..ec23ff1d221 100644
--- a/src/test/ui/const-generics/type-dependent/qpath.rs
+++ b/src/test/ui/const-generics/type-dependent/qpath.rs
@@ -1,6 +1,8 @@
 // run-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 struct A;
 impl A {
diff --git a/src/test/ui/const-generics/type-dependent/simple.rs b/src/test/ui/const-generics/type-dependent/simple.rs
index cc7c50d8fd8..70af6550923 100644
--- a/src/test/ui/const-generics/type-dependent/simple.rs
+++ b/src/test/ui/const-generics/type-dependent/simple.rs
@@ -1,6 +1,8 @@
 // run-pass
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 struct R;
 
diff --git a/src/test/ui/const-generics/type-dependent/type-mismatch.full.stderr b/src/test/ui/const-generics/type-dependent/type-mismatch.full.stderr
new file mode 100644
index 00000000000..a530e63449d
--- /dev/null
+++ b/src/test/ui/const-generics/type-dependent/type-mismatch.full.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/type-mismatch.rs:12:27
+   |
+LL |     assert_eq!(R.method::<1u16>(), 1);
+   |                           ^^^^ expected `u8`, found `u16`
+   |
+help: change the type of the numeric literal from `u16` to `u8`
+   |
+LL |     assert_eq!(R.method::<1u8>(), 1);
+   |                           ^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/type-dependent/type-mismatch.min.stderr b/src/test/ui/const-generics/type-dependent/type-mismatch.min.stderr
new file mode 100644
index 00000000000..a530e63449d
--- /dev/null
+++ b/src/test/ui/const-generics/type-dependent/type-mismatch.min.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/type-mismatch.rs:12:27
+   |
+LL |     assert_eq!(R.method::<1u16>(), 1);
+   |                           ^^^^ expected `u8`, found `u16`
+   |
+help: change the type of the numeric literal from `u16` to `u8`
+   |
+LL |     assert_eq!(R.method::<1u8>(), 1);
+   |                           ^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/type-dependent/type-mismatch.rs b/src/test/ui/const-generics/type-dependent/type-mismatch.rs
index 0c71f338bd2..67d80973f03 100644
--- a/src/test/ui/const-generics/type-dependent/type-mismatch.rs
+++ b/src/test/ui/const-generics/type-dependent/type-mismatch.rs
@@ -1,5 +1,7 @@
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 struct R;
 
diff --git a/src/test/ui/const-generics/type-dependent/type-mismatch.stderr b/src/test/ui/const-generics/type-dependent/type-mismatch.stderr
deleted file mode 100644
index 5bb7c5b0ea9..00000000000
--- a/src/test/ui/const-generics/type-dependent/type-mismatch.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/type-mismatch.rs:1:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-
-error[E0308]: mismatched types
-  --> $DIR/type-mismatch.rs:10:27
-   |
-LL |     assert_eq!(R.method::<1u16>(), 1);
-   |                           ^^^^ expected `u8`, found `u16`
-   |
-help: change the type of the numeric literal from `u16` to `u8`
-   |
-LL |     assert_eq!(R.method::<1u8>(), 1);
-   |                           ^^^
-
-error: aborting due to previous error; 1 warning emitted
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/types-mismatch-const-args.stderr b/src/test/ui/const-generics/types-mismatch-const-args.full.stderr
index 49530c9d240..265e9ee618b 100644
--- a/src/test/ui/const-generics/types-mismatch-const-args.stderr
+++ b/src/test/ui/const-generics/types-mismatch-const-args.full.stderr
@@ -1,14 +1,5 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/types-mismatch-const-args.rs:1:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-
 error[E0308]: mismatched types
-  --> $DIR/types-mismatch-const-args.rs:13:41
+  --> $DIR/types-mismatch-const-args.rs:15:41
    |
 LL |     let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {4u32}, {3u32}> { data: PhantomData };
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2_u32`, found `4_u32`
@@ -17,7 +8,7 @@ LL |     let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {4u32}, {3u32}> { data
               found type `4_u32`
 
 error[E0308]: mismatched types
-  --> $DIR/types-mismatch-const-args.rs:15:41
+  --> $DIR/types-mismatch-const-args.rs:17:41
    |
 LL |     let _: A<'a, u16, {2u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data: PhantomData };
    |            --------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u16`, found `u32`
@@ -27,6 +18,6 @@ LL |     let _: A<'a, u16, {2u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data
    = note: expected struct `A<'a, u16, {2u32}, {3u32}>`
               found struct `A<'b, u32, {2u32}, {3u32}>`
 
-error: aborting due to 2 previous errors; 1 warning emitted
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/types-mismatch-const-args.min.stderr b/src/test/ui/const-generics/types-mismatch-const-args.min.stderr
new file mode 100644
index 00000000000..27277f0c0be
--- /dev/null
+++ b/src/test/ui/const-generics/types-mismatch-const-args.min.stderr
@@ -0,0 +1,25 @@
+error[E0308]: mismatched types
+  --> $DIR/types-mismatch-const-args.rs:15:41
+   |
+LL |     let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {4u32}, {3u32}> { data: PhantomData };
+   |            --------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2_u32`, found `4_u32`
+   |            |
+   |            expected due to this
+   |
+   = note: expected struct `A<'_, _, 2_u32, _>`
+              found struct `A<'_, _, 4_u32, _>`
+
+error[E0308]: mismatched types
+  --> $DIR/types-mismatch-const-args.rs:17:41
+   |
+LL |     let _: A<'a, u16, {2u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data: PhantomData };
+   |            --------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u16`, found `u32`
+   |            |
+   |            expected due to this
+   |
+   = note: expected struct `A<'a, u16, _, _>`
+              found struct `A<'b, u32, _, _>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/types-mismatch-const-args.rs b/src/test/ui/const-generics/types-mismatch-const-args.rs
index bf517c11262..34b85304cc4 100644
--- a/src/test/ui/const-generics/types-mismatch-const-args.rs
+++ b/src/test/ui/const-generics/types-mismatch-const-args.rs
@@ -1,5 +1,7 @@
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 // tests the diagnostic output of type mismatches for types that have const generics arguments.
 
diff --git a/src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs b/src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs
index 7473718351e..45afbdc9ab1 100644
--- a/src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs
+++ b/src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs
@@ -1,7 +1,8 @@
 // run-pass
-
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 use std::fmt;
 
diff --git a/src/test/ui/const-generics/uninferred-consts-during-codegen-1.stderr b/src/test/ui/const-generics/uninferred-consts-during-codegen-1.stderr
deleted file mode 100644
index f41628d5d8e..00000000000
--- a/src/test/ui/const-generics/uninferred-consts-during-codegen-1.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/uninferred-consts-during-codegen-1.rs:3:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs b/src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs
index 8b95a010473..65ae05e1198 100644
--- a/src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs
+++ b/src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs
@@ -1,7 +1,8 @@
 // run-pass
-
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 use std::fmt;
 
diff --git a/src/test/ui/const-generics/uninferred-consts-during-codegen-2.stderr b/src/test/ui/const-generics/uninferred-consts-during-codegen-2.stderr
deleted file mode 100644
index f1703bc3a2f..00000000000
--- a/src/test/ui/const-generics/uninferred-consts-during-codegen-2.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/uninferred-consts-during-codegen-2.rs:3:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/consts/cow-is-borrowed.rs b/src/test/ui/consts/cow-is-borrowed.rs
new file mode 100644
index 00000000000..adebe20f5a2
--- /dev/null
+++ b/src/test/ui/consts/cow-is-borrowed.rs
@@ -0,0 +1,15 @@
+// run-pass
+
+#![feature(cow_is_borrowed)]
+
+use std::borrow::Cow;
+
+fn main() {
+    const COW: Cow<str> = Cow::Borrowed("moo");
+
+    const IS_BORROWED: bool = COW.is_borrowed();
+    assert!(IS_BORROWED);
+
+    const IS_OWNED: bool = COW.is_owned();
+    assert!(!IS_OWNED);
+}
diff --git a/src/test/ui/consts/std/net/ipv4.rs b/src/test/ui/consts/std/net/ipv4.rs
new file mode 100644
index 00000000000..8c676999ae7
--- /dev/null
+++ b/src/test/ui/consts/std/net/ipv4.rs
@@ -0,0 +1,58 @@
+// run-pass
+
+#![feature(ip)]
+#![feature(const_ipv4)]
+
+use std::net::{Ipv4Addr, Ipv6Addr};
+
+fn main() {
+    const IP_ADDRESS: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1);
+    assert_eq!(IP_ADDRESS, Ipv4Addr::LOCALHOST);
+
+    const OCTETS: [u8; 4] = IP_ADDRESS.octets();
+    assert_eq!(OCTETS, [127, 0, 0, 1]);
+
+    const IS_UNSPECIFIED : bool = IP_ADDRESS.is_unspecified();
+    assert!(!IS_UNSPECIFIED);
+
+    const IS_LOOPBACK : bool = IP_ADDRESS.is_loopback();
+    assert!(IS_LOOPBACK);
+
+    const IS_PRIVATE : bool = IP_ADDRESS.is_private();
+    assert!(!IS_PRIVATE);
+
+    const IS_LINK_LOCAL : bool = IP_ADDRESS.is_link_local();
+    assert!(!IS_LINK_LOCAL);
+
+    const IS_GLOBAL : bool = IP_ADDRESS.is_global();
+    assert!(!IS_GLOBAL);
+
+    const IS_SHARED : bool = IP_ADDRESS.is_shared();
+    assert!(!IS_SHARED);
+
+    const IS_IETF_PROTOCOL_ASSIGNMENT : bool = IP_ADDRESS.is_ietf_protocol_assignment();
+    assert!(!IS_IETF_PROTOCOL_ASSIGNMENT);
+
+    const IS_BENCHMARKING : bool = IP_ADDRESS.is_benchmarking();
+    assert!(!IS_BENCHMARKING);
+
+    const IS_RESERVED : bool = IP_ADDRESS.is_reserved();
+    assert!(!IS_RESERVED);
+
+    const IS_MULTICAST : bool = IP_ADDRESS.is_multicast();
+    assert!(!IS_MULTICAST);
+
+    const IS_BROADCAST : bool = IP_ADDRESS.is_broadcast();
+    assert!(!IS_BROADCAST);
+
+    const IS_DOCUMENTATION : bool = IP_ADDRESS.is_documentation();
+    assert!(!IS_DOCUMENTATION);
+
+    const IP_V6_COMPATIBLE : Ipv6Addr = IP_ADDRESS.to_ipv6_compatible();
+    assert_eq!(IP_V6_COMPATIBLE,
+        Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 1]));
+
+    const IP_V6_MAPPED : Ipv6Addr = IP_ADDRESS.to_ipv6_mapped();
+    assert_eq!(IP_V6_MAPPED,
+        Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 0, 0, 1]));
+}
diff --git a/src/test/ui/consts/std/net/ipv6.rs b/src/test/ui/consts/std/net/ipv6.rs
new file mode 100644
index 00000000000..e3841c38c22
--- /dev/null
+++ b/src/test/ui/consts/std/net/ipv6.rs
@@ -0,0 +1,53 @@
+// run-pass
+
+#![feature(ip)]
+#![feature(const_ipv6)]
+
+use std::net::{Ipv4Addr, Ipv6Addr, Ipv6MulticastScope};
+
+fn main() {
+    const IP_ADDRESS : Ipv6Addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
+    assert_eq!(IP_ADDRESS, Ipv6Addr::LOCALHOST);
+
+    const SEGMENTS : [u16; 8] = IP_ADDRESS.segments();
+    assert_eq!(SEGMENTS, [0 ,0 ,0 ,0 ,0 ,0 ,0, 1]);
+
+    const OCTETS : [u8; 16] = IP_ADDRESS.octets();
+    assert_eq!(OCTETS, [0 ,0 ,0 ,0 ,0 ,0 ,0, 0 ,0 ,0 ,0 ,0 ,0 ,0, 0, 1]);
+
+    const IS_UNSPECIFIED : bool = IP_ADDRESS.is_unspecified();
+    assert!(!IS_UNSPECIFIED);
+
+    const IS_LOOPBACK : bool = IP_ADDRESS.is_loopback();
+    assert!(IS_LOOPBACK);
+
+    const IS_GLOBAL : bool = IP_ADDRESS.is_global();
+    assert!(!IS_GLOBAL);
+
+    const IS_UNIQUE_LOCAL : bool = IP_ADDRESS.is_unique_local();
+    assert!(!IS_UNIQUE_LOCAL);
+
+    const IS_UNICAST_LINK_LOCAL_STRICT : bool = IP_ADDRESS.is_unicast_link_local_strict();
+    assert!(!IS_UNICAST_LINK_LOCAL_STRICT);
+
+    const IS_UNICAST_LINK_LOCAL : bool = IP_ADDRESS.is_unicast_link_local();
+    assert!(!IS_UNICAST_LINK_LOCAL);
+
+    const IS_UNICAST_SITE_LOCAL : bool = IP_ADDRESS.is_unicast_site_local();
+    assert!(!IS_UNICAST_SITE_LOCAL);
+
+    const IS_DOCUMENTATION : bool = IP_ADDRESS.is_documentation();
+    assert!(!IS_DOCUMENTATION);
+
+    const IS_UNICAST_GLOBAL : bool = IP_ADDRESS.is_unicast_global();
+    assert!(!IS_UNICAST_GLOBAL);
+
+    const MULTICAST_SCOPE : Option<Ipv6MulticastScope> = IP_ADDRESS.multicast_scope();
+    assert_eq!(MULTICAST_SCOPE, None);
+
+    const IS_MULTICAST : bool = IP_ADDRESS.is_multicast();
+    assert!(!IS_MULTICAST);
+
+    const IP_V4 : Option<Ipv4Addr> = IP_ADDRESS.to_ipv4();
+    assert_eq!(IP_V4.unwrap(), Ipv4Addr::new(0, 0, 0, 1));
+}
diff --git a/src/test/ui/error-codes/E0070.stderr b/src/test/ui/error-codes/E0070.stderr
index d809bb18dee..e24d498e352 100644
--- a/src/test/ui/error-codes/E0070.stderr
+++ b/src/test/ui/error-codes/E0070.stderr
@@ -14,12 +14,6 @@ LL |     1 = 3;
    |     |
    |     cannot assign to this expression
 
-error[E0308]: mismatched types
-  --> $DIR/E0070.rs:8:25
-   |
-LL |     some_other_func() = 4;
-   |                         ^ expected `()`, found integer
-
 error[E0070]: invalid left-hand side of assignment
   --> $DIR/E0070.rs:8:23
    |
@@ -28,6 +22,12 @@ LL |     some_other_func() = 4;
    |     |
    |     cannot assign to this expression
 
+error[E0308]: mismatched types
+  --> $DIR/E0070.rs:8:25
+   |
+LL |     some_other_func() = 4;
+   |                         ^ expected `()`, found integer
+
 error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0070, E0308.
diff --git a/src/test/ui/fmt/incorrect-separator.rs b/src/test/ui/fmt/incorrect-separator.rs
new file mode 100644
index 00000000000..b8d2e4a3473
--- /dev/null
+++ b/src/test/ui/fmt/incorrect-separator.rs
@@ -0,0 +1,29 @@
+// Allows to track issue #75492:
+// https://github.com/rust-lang/rust/issues/75492
+
+use std::iter;
+
+fn main() {
+    format!("A number: {}". iter::once(42).next().unwrap());
+    //~^ ERROR expected `,`, found `.`
+
+    // Other kind of types are also checked:
+
+    format!("A number: {}" / iter::once(42).next().unwrap());
+    //~^ ERROR expected `,`, found `/`
+
+    format!("A number: {}"; iter::once(42).next().unwrap());
+    //~^ ERROR expected `,`, found `;`
+
+    // Note: this character is an COMBINING COMMA BELOW unicode char
+    format!("A number: {}" ̦ iter::once(42).next().unwrap());
+    //~^ ERROR expected `,`, found `iter`
+    //~^^ ERROR unknown start of token: \u{326}
+
+    // Here recovery is tested.
+    // If the `compile_error!` is emitted, then the parser is able to recover
+    // from the incorrect first separator.
+    format!("{}". compile_error!("fail"));
+    //~^ ERROR expected `,`, found `.`
+    //~^^ ERROR fail
+}
diff --git a/src/test/ui/fmt/incorrect-separator.stderr b/src/test/ui/fmt/incorrect-separator.stderr
new file mode 100644
index 00000000000..5a3e5515bb9
--- /dev/null
+++ b/src/test/ui/fmt/incorrect-separator.stderr
@@ -0,0 +1,44 @@
+error: unknown start of token: \u{326}
+  --> $DIR/incorrect-separator.rs:19:28
+   |
+LL |     format!("A number: {}" ̦ iter::once(42).next().unwrap());
+   |                            ^
+
+error: expected `,`, found `.`
+  --> $DIR/incorrect-separator.rs:7:27
+   |
+LL |     format!("A number: {}". iter::once(42).next().unwrap());
+   |                           ^ expected `,`
+
+error: expected `,`, found `/`
+  --> $DIR/incorrect-separator.rs:12:28
+   |
+LL |     format!("A number: {}" / iter::once(42).next().unwrap());
+   |                            ^ expected `,`
+
+error: expected `,`, found `;`
+  --> $DIR/incorrect-separator.rs:15:27
+   |
+LL |     format!("A number: {}"; iter::once(42).next().unwrap());
+   |                           ^ expected `,`
+
+error: expected `,`, found `iter`
+  --> $DIR/incorrect-separator.rs:19:30
+   |
+LL |     format!("A number: {}" ̦ iter::once(42).next().unwrap());
+   |                             ^^^^ expected `,`
+
+error: expected `,`, found `.`
+  --> $DIR/incorrect-separator.rs:26:17
+   |
+LL |     format!("{}". compile_error!("fail"));
+   |                 ^ expected `,`
+
+error: fail
+  --> $DIR/incorrect-separator.rs:26:19
+   |
+LL |     format!("{}". compile_error!("fail"));
+   |                   ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 7 previous errors
+
diff --git a/src/test/ui/issues/issue-13407.stderr b/src/test/ui/issues/issue-13407.stderr
index f30b6cdeaf0..5352066bf77 100644
--- a/src/test/ui/issues/issue-13407.stderr
+++ b/src/test/ui/issues/issue-13407.stderr
@@ -10,12 +10,6 @@ note: the unit struct `C` is defined here
 LL |     struct C;
    |     ^^^^^^^^^
 
-error[E0308]: mismatched types
-  --> $DIR/issue-13407.rs:6:12
-   |
-LL |     A::C = 1;
-   |            ^ expected struct `A::C`, found integer
-
 error[E0070]: invalid left-hand side of assignment
   --> $DIR/issue-13407.rs:6:10
    |
@@ -24,6 +18,12 @@ LL |     A::C = 1;
    |     |
    |     cannot assign to this expression
 
+error[E0308]: mismatched types
+  --> $DIR/issue-13407.rs:6:12
+   |
+LL |     A::C = 1;
+   |            ^ expected struct `A::C`, found integer
+
 error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0070, E0308, E0603.
diff --git a/src/test/ui/macros/duplicate-builtin.rs b/src/test/ui/macros/duplicate-builtin.rs
new file mode 100644
index 00000000000..35f0f429059
--- /dev/null
+++ b/src/test/ui/macros/duplicate-builtin.rs
@@ -0,0 +1,17 @@
+// compile-flags:--crate-type lib
+#![feature(decl_macro)]
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+pub macro test($item:item) {
+//~^ NOTE previously defined
+    /* compiler built-in */
+}
+
+mod inner {
+    #[rustc_builtin_macro]
+    pub macro test($item:item) {
+    //~^ ERROR attempted to define built-in macro more than once [E0773]
+        /* compiler built-in */
+    }
+}
diff --git a/src/test/ui/macros/duplicate-builtin.stderr b/src/test/ui/macros/duplicate-builtin.stderr
new file mode 100644
index 00000000000..58accea27bb
--- /dev/null
+++ b/src/test/ui/macros/duplicate-builtin.stderr
@@ -0,0 +1,21 @@
+error[E0773]: attempted to define built-in macro more than once
+  --> $DIR/duplicate-builtin.rs:13:5
+   |
+LL | /     pub macro test($item:item) {
+LL | |
+LL | |         /* compiler built-in */
+LL | |     }
+   | |_____^
+   |
+note: previously defined here
+  --> $DIR/duplicate-builtin.rs:6:1
+   |
+LL | / pub macro test($item:item) {
+LL | |
+LL | |     /* compiler built-in */
+LL | | }
+   | |_^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0773`.
diff --git a/src/test/ui/macros/missing-comma.rs b/src/test/ui/macros/missing-comma.rs
index 2002fed6c93..92f8a779505 100644
--- a/src/test/ui/macros/missing-comma.rs
+++ b/src/test/ui/macros/missing-comma.rs
@@ -17,7 +17,7 @@ macro_rules! check {
 
 fn main() {
     println!("{}" a);
-    //~^ ERROR expected token: `,`
+    //~^ ERROR expected `,`, found `a`
     foo!(a b);
     //~^ ERROR no rules expected the token `b`
     foo!(a, b, c, d e);
diff --git a/src/test/ui/macros/missing-comma.stderr b/src/test/ui/macros/missing-comma.stderr
index f96848f8239..6da92bdea19 100644
--- a/src/test/ui/macros/missing-comma.stderr
+++ b/src/test/ui/macros/missing-comma.stderr
@@ -1,4 +1,4 @@
-error: expected token: `,`
+error: expected `,`, found `a`
   --> $DIR/missing-comma.rs:19:19
    |
 LL |     println!("{}" a);
diff --git a/src/test/ui/macros/unknown-builtin.rs b/src/test/ui/macros/unknown-builtin.rs
index a96b99ae4ff..16f9139e647 100644
--- a/src/test/ui/macros/unknown-builtin.rs
+++ b/src/test/ui/macros/unknown-builtin.rs
@@ -1,4 +1,4 @@
-// error-pattern: cannot find a built-in macro with name `line`
+// error-pattern: attempted to define built-in macro more than once
 
 #![feature(rustc_attrs)]
 
@@ -6,7 +6,7 @@
 macro_rules! unknown { () => () } //~ ERROR cannot find a built-in macro with name `unknown`
 
 #[rustc_builtin_macro]
-macro_rules! line { () => () }
+macro_rules! line { () => () } //~ NOTE previously defined here
 
 fn main() {
     line!();
diff --git a/src/test/ui/macros/unknown-builtin.stderr b/src/test/ui/macros/unknown-builtin.stderr
index 4b650b2c475..7b04e05293e 100644
--- a/src/test/ui/macros/unknown-builtin.stderr
+++ b/src/test/ui/macros/unknown-builtin.stderr
@@ -4,7 +4,7 @@ error: cannot find a built-in macro with name `unknown`
 LL | macro_rules! unknown { () => () }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: cannot find a built-in macro with name `line`
+error[E0773]: attempted to define built-in macro more than once
   --> $SRC_DIR/core/src/macros/mod.rs:LL:COL
    |
 LL | /     macro_rules! line {
@@ -13,6 +13,13 @@ LL | |             /* compiler built-in */
 LL | |         };
 LL | |     }
    | |_____^
+   |
+note: previously defined here
+  --> $DIR/unknown-builtin.rs:9:1
+   |
+LL | macro_rules! line { () => () }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0773`.
diff --git a/src/test/ui/parser/shebang/shebang-doc-comment.rs b/src/test/ui/parser/shebang/shebang-doc-comment.rs
index 7dbb9eebc75..72866753e0e 100644
--- a/src/test/ui/parser/shebang/shebang-doc-comment.rs
+++ b/src/test/ui/parser/shebang/shebang-doc-comment.rs
@@ -1,6 +1,3 @@
 #!///bin/bash
 [allow(unused_variables)]
-//~^^ ERROR expected `[`, found doc comment
-
-// Doc comment is misinterpreted as a whitespace (regular comment) during shebang detection.
-// Even if it wasn't, it would still result in an error, just a different one.
+//~^ ERROR expected item, found `[`
diff --git a/src/test/ui/parser/shebang/shebang-doc-comment.stderr b/src/test/ui/parser/shebang/shebang-doc-comment.stderr
index f524f556837..2227d45ec5a 100644
--- a/src/test/ui/parser/shebang/shebang-doc-comment.stderr
+++ b/src/test/ui/parser/shebang/shebang-doc-comment.stderr
@@ -1,8 +1,8 @@
-error: expected `[`, found doc comment `///bin/bash`
-  --> $DIR/shebang-doc-comment.rs:1:3
+error: expected item, found `[`
+  --> $DIR/shebang-doc-comment.rs:2:1
    |
-LL | #!///bin/bash
-   |   ^^^^^^^^^^^ expected `[`
+LL | [allow(unused_variables)]
+   | ^ expected item
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/unicode-quote-chars.rs b/src/test/ui/parser/unicode-quote-chars.rs
index 1812dad81af..eeaea3628bb 100644
--- a/src/test/ui/parser/unicode-quote-chars.rs
+++ b/src/test/ui/parser/unicode-quote-chars.rs
@@ -6,5 +6,5 @@ fn main() {
     //~^^ HELP Unicode characters '“' (Left Double Quotation Mark) and '”' (Right Double Quotation Mark) look like '"' (Quotation Mark), but are not
     //~^^^ ERROR unknown start of token: \u{201d}
     //~^^^^ HELP Unicode character '”' (Right Double Quotation Mark) looks like '"' (Quotation Mark), but it is not
-    //~^^^^^ ERROR expected token: `,`
+    //~^^^^^ ERROR expected `,`, found `world`
 }
diff --git a/src/test/ui/parser/unicode-quote-chars.stderr b/src/test/ui/parser/unicode-quote-chars.stderr
index 4b0cb96ed21..d9ec92b3f8a 100644
--- a/src/test/ui/parser/unicode-quote-chars.stderr
+++ b/src/test/ui/parser/unicode-quote-chars.stderr
@@ -20,7 +20,7 @@ help: Unicode character '”' (Right Double Quotation Mark) looks like '"' (Quot
 LL |     println!(“hello world");
    |                          ^
 
-error: expected token: `,`
+error: expected `,`, found `world`
   --> $DIR/unicode-quote-chars.rs:4:21
    |
 LL |     println!(“hello world”);
diff --git a/src/test/ui/pattern/const-pat-ice.stderr b/src/test/ui/pattern/const-pat-ice.stderr
index 2aa0824f301..6b42c0e0848 100644
--- a/src/test/ui/pattern/const-pat-ice.stderr
+++ b/src/test/ui/pattern/const-pat-ice.stderr
@@ -1,4 +1,4 @@
-thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir_build/thir/pattern/_match.rs:LL:CC
+thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', compiler/rustc_mir_build/src/thir/pattern/_match.rs:LL:CC
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
 error: internal compiler error: unexpected panic
diff --git a/src/test/ui/proc-macro/issue-75930-derive-cfg.rs b/src/test/ui/proc-macro/issue-75930-derive-cfg.rs
new file mode 100644
index 00000000000..e0f248c67e8
--- /dev/null
+++ b/src/test/ui/proc-macro/issue-75930-derive-cfg.rs
@@ -0,0 +1,30 @@
+// check-pass
+// compile-flags: -Z span-debug
+// aux-build:test-macros.rs
+
+// Regression test for issue #75930
+// Tests that we cfg-strip all targets before invoking
+// a derive macro
+
+#[macro_use]
+extern crate test_macros;
+
+#[derive(Print)]
+struct Foo<#[cfg(FALSE)] A, B> {
+    #[cfg(FALSE)] first: String,
+    second: bool,
+    third: [u8; {
+        #[cfg(FALSE)] struct Bar;
+        #[cfg(not(FALSE))] struct Inner;
+        #[cfg(FALSE)] let a = 25;
+        match true {
+            #[cfg(FALSE)] true => {},
+            false => {},
+            _ => {}
+        };
+        0
+    }],
+    fourth: B
+}
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout b/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout
new file mode 100644
index 00000000000..0371133a3f7
--- /dev/null
+++ b/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout
@@ -0,0 +1,221 @@
+PRINT-DERIVE INPUT (DISPLAY): struct Foo < B >
+{
+    second : bool, third :
+    [u8 ;
+     {
+         #[cfg(not(FALSE))] struct Inner ; match true
+         { false => { } _ => { } } ; 0
+     }], fourth : B,
+}
+PRINT-DERIVE INPUT (DEBUG): TokenStream [
+    Ident {
+        ident: "struct",
+        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+    },
+    Ident {
+        ident: "Foo",
+        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+    },
+    Punct {
+        ch: '<',
+        spacing: Alone,
+        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+    },
+    Ident {
+        ident: "B",
+        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+    },
+    Punct {
+        ch: '>',
+        spacing: Alone,
+        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+    },
+    Group {
+        delimiter: Brace,
+        stream: TokenStream [
+            Ident {
+                ident: "second",
+                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+            },
+            Punct {
+                ch: ':',
+                spacing: Alone,
+                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+            },
+            Ident {
+                ident: "bool",
+                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+            },
+            Punct {
+                ch: ',',
+                spacing: Alone,
+                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+            },
+            Ident {
+                ident: "third",
+                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+            },
+            Punct {
+                ch: ':',
+                spacing: Alone,
+                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+            },
+            Group {
+                delimiter: Bracket,
+                stream: TokenStream [
+                    Ident {
+                        ident: "u8",
+                        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                    },
+                    Punct {
+                        ch: ';',
+                        spacing: Alone,
+                        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                    },
+                    Group {
+                        delimiter: Brace,
+                        stream: TokenStream [
+                            Punct {
+                                ch: '#',
+                                spacing: Alone,
+                                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                            },
+                            Group {
+                                delimiter: Bracket,
+                                stream: TokenStream [
+                                    Ident {
+                                        ident: "cfg",
+                                        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                                    },
+                                    Group {
+                                        delimiter: Parenthesis,
+                                        stream: TokenStream [
+                                            Ident {
+                                                ident: "not",
+                                                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                                            },
+                                            Group {
+                                                delimiter: Parenthesis,
+                                                stream: TokenStream [
+                                                    Ident {
+                                                        ident: "FALSE",
+                                                        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                                                    },
+                                                ],
+                                                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                                            },
+                                        ],
+                                        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                                    },
+                                ],
+                                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                            },
+                            Ident {
+                                ident: "struct",
+                                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                            },
+                            Ident {
+                                ident: "Inner",
+                                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                            },
+                            Punct {
+                                ch: ';',
+                                spacing: Alone,
+                                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                            },
+                            Ident {
+                                ident: "match",
+                                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                            },
+                            Ident {
+                                ident: "true",
+                                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                            },
+                            Group {
+                                delimiter: Brace,
+                                stream: TokenStream [
+                                    Ident {
+                                        ident: "false",
+                                        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                                    },
+                                    Punct {
+                                        ch: '=',
+                                        spacing: Joint,
+                                        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                                    },
+                                    Punct {
+                                        ch: '>',
+                                        spacing: Alone,
+                                        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                                    },
+                                    Group {
+                                        delimiter: Brace,
+                                        stream: TokenStream [],
+                                        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                                    },
+                                    Ident {
+                                        ident: "_",
+                                        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                                    },
+                                    Punct {
+                                        ch: '=',
+                                        spacing: Joint,
+                                        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                                    },
+                                    Punct {
+                                        ch: '>',
+                                        spacing: Alone,
+                                        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                                    },
+                                    Group {
+                                        delimiter: Brace,
+                                        stream: TokenStream [],
+                                        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                                    },
+                                ],
+                                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                            },
+                            Punct {
+                                ch: ';',
+                                spacing: Alone,
+                                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                            },
+                            Literal {
+                                kind: Integer,
+                                symbol: "0",
+                                suffix: None,
+                                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                            },
+                        ],
+                        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+                    },
+                ],
+                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+            },
+            Punct {
+                ch: ',',
+                spacing: Alone,
+                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+            },
+            Ident {
+                ident: "fourth",
+                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+            },
+            Punct {
+                ch: ':',
+                spacing: Alone,
+                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+            },
+            Ident {
+                ident: "B",
+                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+            },
+            Punct {
+                ch: ',',
+                spacing: Alone,
+                span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+            },
+        ],
+        span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0),
+    },
+]
diff --git a/src/test/ui/proc-macro/load-panic-backtrace.rs b/src/test/ui/proc-macro/load-panic-backtrace.rs
new file mode 100644
index 00000000000..90fe109abb8
--- /dev/null
+++ b/src/test/ui/proc-macro/load-panic-backtrace.rs
@@ -0,0 +1,21 @@
+// aux-build:test-macros.rs
+// compile-flags: -Z proc-macro-backtrace
+// rustc-env:RUST_BACKTRACE=0
+
+// FIXME https://github.com/rust-lang/rust/issues/59998
+// normalize-stderr-test "thread '.*' panicked " -> ""
+// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
+// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> ""
+// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
+// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
+// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
+// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
+
+#[macro_use]
+extern crate test_macros;
+
+#[derive(Panic)]
+//~^ ERROR: proc-macro derive panicked
+struct Foo;
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/load-panic-backtrace.stderr b/src/test/ui/proc-macro/load-panic-backtrace.stderr
new file mode 100644
index 00000000000..63378b5735a
--- /dev/null
+++ b/src/test/ui/proc-macro/load-panic-backtrace.stderr
@@ -0,0 +1,11 @@
+at 'panic-derive', $DIR/auxiliary/test-macros.rs:43:5
+error: proc-macro derive panicked
+  --> $DIR/load-panic-backtrace.rs:17:10
+   |
+LL | #[derive(Panic)]
+   |          ^^^^^
+   |
+   = help: message: panic-derive
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
index 7f343d1a853..3372495d0fe 100644
--- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
@@ -568,10 +568,12 @@ error[E0308]: mismatched types
   --> $DIR/disallowed-positions.rs:56:8
    |
 LL |     if x = let 0 = 0 {}
-   |        ^^^^^^^^^^^^^
-   |        |
-   |        expected `bool`, found `()`
-   |        help: try comparing for equality: `x == let 0 = 0`
+   |        ^^^^^^^^^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to compare for equality
+   |
+LL |     if x == let 0 = 0 {}
+   |          ^^
 
 error[E0308]: mismatched types
   --> $DIR/disallowed-positions.rs:59:8
@@ -754,10 +756,12 @@ error[E0308]: mismatched types
   --> $DIR/disallowed-positions.rs:120:11
    |
 LL |     while x = let 0 = 0 {}
-   |           ^^^^^^^^^^^^^
-   |           |
-   |           expected `bool`, found `()`
-   |           help: try comparing for equality: `x == let 0 = 0`
+   |           ^^^^^^^^^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to compare for equality
+   |
+LL |     while x == let 0 = 0 {}
+   |             ^^
 
 error[E0308]: mismatched types
   --> $DIR/disallowed-positions.rs:123:11
diff --git a/src/test/ui/suggestions/if-let-typo.rs b/src/test/ui/suggestions/if-let-typo.rs
new file mode 100644
index 00000000000..c1e417b97f6
--- /dev/null
+++ b/src/test/ui/suggestions/if-let-typo.rs
@@ -0,0 +1,9 @@
+fn main() {
+    let foo = Some(0);
+    let bar = None;
+    if Some(x) = foo {} //~ ERROR cannot find value `x` in this scope
+    if Some(foo) = bar {} //~ ERROR mismatched types
+    if 3 = foo {} //~ ERROR mismatched types
+    //~^ ERROR mismatched types
+    if Some(3) = foo {} //~ ERROR mismatched types
+}
diff --git a/src/test/ui/suggestions/if-let-typo.stderr b/src/test/ui/suggestions/if-let-typo.stderr
new file mode 100644
index 00000000000..09db8e01469
--- /dev/null
+++ b/src/test/ui/suggestions/if-let-typo.stderr
@@ -0,0 +1,60 @@
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/if-let-typo.rs:4:13
+   |
+LL |     if Some(x) = foo {}
+   |             ^ not found in this scope
+   |
+help: you might have meant to use pattern matching
+   |
+LL |     if let Some(x) = foo {}
+   |        ^^^
+
+error[E0308]: mismatched types
+  --> $DIR/if-let-typo.rs:5:8
+   |
+LL |     if Some(foo) = bar {}
+   |        ^^^^^^^^^^^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to use pattern matching
+   |
+LL |     if let Some(foo) = bar {}
+   |        ^^^
+help: you might have meant to compare for equality
+   |
+LL |     if Some(foo) == bar {}
+   |                  ^^
+
+error[E0308]: mismatched types
+  --> $DIR/if-let-typo.rs:6:12
+   |
+LL |     if 3 = foo {}
+   |            ^^^ expected integer, found enum `std::option::Option`
+   |
+   = note: expected type `{integer}`
+              found enum `std::option::Option<{integer}>`
+
+error[E0308]: mismatched types
+  --> $DIR/if-let-typo.rs:6:8
+   |
+LL |     if 3 = foo {}
+   |        ^^^^^^^ expected `bool`, found `()`
+
+error[E0308]: mismatched types
+  --> $DIR/if-let-typo.rs:8:8
+   |
+LL |     if Some(3) = foo {}
+   |        ^^^^^^^^^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to use pattern matching
+   |
+LL |     if let Some(3) = foo {}
+   |        ^^^
+help: you might have meant to compare for equality
+   |
+LL |     if Some(3) == foo {}
+   |                ^^
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0308, E0425.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs
index bc2bf9eca93..01769f71153 100644
--- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs
@@ -4,7 +4,7 @@
 // Currently, the `type_alias_impl_trait` feature implicitly
 // depends on `impl_trait_in_bindings` in order to work properly.
 // Specifically, this line requires `impl_trait_in_bindings` to be enabled:
-// https://github.com/rust-lang/rust/blob/481068a707679257e2a738b40987246e0420e787/src/librustc_typeck/check/mod.rs#L856
+// https://github.com/rust-lang/rust/blob/481068a707679257e2a738b40987246e0420e787/compiler/rustc_typeck/check/mod.rs#L856
 #![feature(impl_trait_in_bindings)]
 //~^ WARN the feature `impl_trait_in_bindings` is incomplete
 
diff --git a/src/test/ui/type/type-check/assignment-expected-bool.stderr b/src/test/ui/type/type-check/assignment-expected-bool.stderr
index 3f1caddf728..d1c13a33f7f 100644
--- a/src/test/ui/type/type-check/assignment-expected-bool.stderr
+++ b/src/test/ui/type/type-check/assignment-expected-bool.stderr
@@ -2,100 +2,126 @@ error[E0308]: mismatched types
   --> $DIR/assignment-expected-bool.rs:6:19
    |
 LL |     let _: bool = 0 = 0;
-   |                   ^^^^^
-   |                   |
-   |                   expected `bool`, found `()`
-   |                   help: try comparing for equality: `0 == 0`
+   |                   ^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to compare for equality
+   |
+LL |     let _: bool = 0 == 0;
+   |                     ^^
 
 error[E0308]: mismatched types
   --> $DIR/assignment-expected-bool.rs:9:14
    |
 LL |         0 => 0 = 0,
-   |              ^^^^^
-   |              |
-   |              expected `bool`, found `()`
-   |              help: try comparing for equality: `0 == 0`
+   |              ^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to compare for equality
+   |
+LL |         0 => 0 == 0,
+   |                ^^
 
 error[E0308]: mismatched types
   --> $DIR/assignment-expected-bool.rs:10:14
    |
 LL |         _ => 0 = 0,
-   |              ^^^^^
-   |              |
-   |              expected `bool`, found `()`
-   |              help: try comparing for equality: `0 == 0`
+   |              ^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to compare for equality
+   |
+LL |         _ => 0 == 0,
+   |                ^^
 
 error[E0308]: mismatched types
   --> $DIR/assignment-expected-bool.rs:14:17
    |
 LL |         true => 0 = 0,
-   |                 ^^^^^
-   |                 |
-   |                 expected `bool`, found `()`
-   |                 help: try comparing for equality: `0 == 0`
+   |                 ^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to compare for equality
+   |
+LL |         true => 0 == 0,
+   |                   ^^
 
 error[E0308]: mismatched types
   --> $DIR/assignment-expected-bool.rs:18:8
    |
 LL |     if 0 = 0 {}
-   |        ^^^^^
-   |        |
-   |        expected `bool`, found `()`
-   |        help: try comparing for equality: `0 == 0`
+   |        ^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to use pattern matching
+   |
+LL |     if let 0 = 0 {}
+   |        ^^^
+help: you might have meant to compare for equality
+   |
+LL |     if 0 == 0 {}
+   |          ^^
 
 error[E0308]: mismatched types
   --> $DIR/assignment-expected-bool.rs:20:24
    |
 LL |     let _: bool = if { 0 = 0 } {
-   |                        ^^^^^
-   |                        |
-   |                        expected `bool`, found `()`
-   |                        help: try comparing for equality: `0 == 0`
+   |                        ^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to compare for equality
+   |
+LL |     let _: bool = if { 0 == 0 } {
+   |                          ^^
 
 error[E0308]: mismatched types
   --> $DIR/assignment-expected-bool.rs:21:9
    |
 LL |         0 = 0
-   |         ^^^^^
-   |         |
-   |         expected `bool`, found `()`
-   |         help: try comparing for equality: `0 == 0`
+   |         ^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to compare for equality
+   |
+LL |         0 == 0
+   |           ^^
 
 error[E0308]: mismatched types
   --> $DIR/assignment-expected-bool.rs:23:9
    |
 LL |         0 = 0
-   |         ^^^^^
-   |         |
-   |         expected `bool`, found `()`
-   |         help: try comparing for equality: `0 == 0`
+   |         ^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to compare for equality
+   |
+LL |         0 == 0
+   |           ^^
 
 error[E0308]: mismatched types
   --> $DIR/assignment-expected-bool.rs:26:13
    |
 LL |     let _ = (0 = 0)
-   |             ^^^^^^^
-   |             |
-   |             expected `bool`, found `()`
-   |             help: try comparing for equality: `0 == 0`
+   |             ^^^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to compare for equality
+   |
+LL |     let _ = (0 == 0)
+   |                ^^
 
 error[E0308]: mismatched types
   --> $DIR/assignment-expected-bool.rs:27:14
    |
 LL |         && { 0 = 0 }
-   |              ^^^^^
-   |              |
-   |              expected `bool`, found `()`
-   |              help: try comparing for equality: `0 == 0`
+   |              ^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to compare for equality
+   |
+LL |         && { 0 == 0 }
+   |                ^^
 
 error[E0308]: mismatched types
   --> $DIR/assignment-expected-bool.rs:28:12
    |
 LL |         || (0 = 0);
-   |            ^^^^^^^
-   |            |
-   |            expected `bool`, found `()`
-   |            help: try comparing for equality: `0 == 0`
+   |            ^^^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to compare for equality
+   |
+LL |         || (0 == 0);
+   |               ^^
 
 error[E0070]: invalid left-hand side of assignment
   --> $DIR/assignment-expected-bool.rs:31:22
diff --git a/src/test/ui/type/type-check/assignment-in-if.stderr b/src/test/ui/type/type-check/assignment-in-if.stderr
index 0957dcb986b..f5306a12264 100644
--- a/src/test/ui/type/type-check/assignment-in-if.stderr
+++ b/src/test/ui/type/type-check/assignment-in-if.stderr
@@ -2,55 +2,71 @@ error[E0308]: mismatched types
   --> $DIR/assignment-in-if.rs:15:8
    |
 LL |     if x = x {
-   |        ^^^^^
-   |        |
-   |        expected `bool`, found `()`
-   |        help: try comparing for equality: `x == x`
+   |        ^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to compare for equality
+   |
+LL |     if x == x {
+   |          ^^
 
 error[E0308]: mismatched types
   --> $DIR/assignment-in-if.rs:20:8
    |
 LL |     if (x = x) {
-   |        ^^^^^^^
-   |        |
-   |        expected `bool`, found `()`
-   |        help: try comparing for equality: `x == x`
+   |        ^^^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to compare for equality
+   |
+LL |     if (x == x) {
+   |           ^^
 
 error[E0308]: mismatched types
   --> $DIR/assignment-in-if.rs:25:8
    |
 LL |     if y = (Foo { foo: x }) {
-   |        ^^^^^^^^^^^^^^^^^^^^
-   |        |
-   |        expected `bool`, found `()`
-   |        help: try comparing for equality: `y == (Foo { foo: x })`
+   |        ^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to compare for equality
+   |
+LL |     if y == (Foo { foo: x }) {
+   |          ^^
 
 error[E0308]: mismatched types
   --> $DIR/assignment-in-if.rs:30:8
    |
 LL |     if 3 = x {
-   |        ^^^^^
-   |        |
-   |        expected `bool`, found `()`
-   |        help: try comparing for equality: `3 == x`
+   |        ^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to use pattern matching
+   |
+LL |     if let 3 = x {
+   |        ^^^
+help: you might have meant to compare for equality
+   |
+LL |     if 3 == x {
+   |          ^^
 
 error[E0308]: mismatched types
   --> $DIR/assignment-in-if.rs:36:13
    |
 LL |             x = 4
-   |             ^^^^^
-   |             |
-   |             expected `bool`, found `()`
-   |             help: try comparing for equality: `x == 4`
+   |             ^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to compare for equality
+   |
+LL |             x == 4
+   |               ^^
 
 error[E0308]: mismatched types
   --> $DIR/assignment-in-if.rs:38:13
    |
 LL |             x = 5
-   |             ^^^^^
-   |             |
-   |             expected `bool`, found `()`
-   |             help: try comparing for equality: `x == 5`
+   |             ^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to compare for equality
+   |
+LL |             x == 5
+   |               ^^
 
 error: aborting due to 6 previous errors
 
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 51b66125ba97d2906f461b3f4e0408f206299bb
+Subproject 126907a7cfccbe93778530e6a6bbaa3adb6c515
diff --git a/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs b/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs
index 7b419431c0f..3c3f8b26e3a 100644
--- a/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs
@@ -191,7 +191,7 @@ pub fn eq_stmt(l: &Stmt, r: &Stmt) -> bool {
         (Item(l), Item(r)) => eq_item(l, r, eq_item_kind),
         (Expr(l), Expr(r)) | (Semi(l), Semi(r)) => eq_expr(l, r),
         (Empty, Empty) => true,
-        (MacCall(l), MacCall(r)) => l.1 == r.1 && eq_mac_call(&l.0, &r.0) && over(&l.2, &r.2, |l, r| eq_attr(l, r)),
+        (MacCall(l), MacCall(r)) => l.style == r.style && eq_mac_call(&l.mac, &r.mac) && over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r)),
         _ => false,
     }
 }
diff --git a/src/tools/clippy/tests/ui/issue-3145.rs b/src/tools/clippy/tests/ui/issue-3145.rs
index f497d5550af..586d13647d1 100644
--- a/src/tools/clippy/tests/ui/issue-3145.rs
+++ b/src/tools/clippy/tests/ui/issue-3145.rs
@@ -1,3 +1,3 @@
 fn main() {
-    println!("{}" a); //~ERROR expected token: `,`
+    println!("{}" a); //~ERROR expected `,`, found `a`
 }
diff --git a/src/tools/clippy/tests/ui/issue-3145.stderr b/src/tools/clippy/tests/ui/issue-3145.stderr
index cb0d95f5e26..a35032aa150 100644
--- a/src/tools/clippy/tests/ui/issue-3145.stderr
+++ b/src/tools/clippy/tests/ui/issue-3145.stderr
@@ -1,7 +1,7 @@
-error: expected token: `,`
+error: expected `,`, found `a`
   --> $DIR/issue-3145.rs:2:19
    |
-LL |     println!("{}" a); //~ERROR expected token: `,`
+LL |     println!("{}" a); //~ERROR expected `,`, found `a`
    |                   ^ expected `,`
 
 error: aborting due to previous error
diff --git a/src/tools/error_index_generator/build.rs b/src/tools/error_index_generator/build.rs
index efa4177d1d8..caae8c61178 100644
--- a/src/tools/error_index_generator/build.rs
+++ b/src/tools/error_index_generator/build.rs
@@ -9,7 +9,7 @@ fn main() {
     let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
     let dest = out_dir.join("error_codes.rs");
 
-    let error_codes_path = "../../../src/librustc_error_codes/error_codes.rs";
+    let error_codes_path = "../../../compiler/rustc_error_codes/src/error_codes.rs";
 
     println!("cargo:rerun-if-changed={}", error_codes_path);
     let file = fs::read_to_string(error_codes_path)
@@ -19,7 +19,7 @@ fn main() {
     fs::write(&out_dir.join("all_error_codes.rs"), &contents).unwrap();
 
     // We copy the md files as well to the target directory.
-    for entry in WalkDir::new("../../../src/librustc_error_codes/error_codes") {
+    for entry in WalkDir::new("../../../compiler/rustc_error_codes/src/error_codes") {
         let entry = entry.unwrap();
         match entry.path().extension() {
             Some(s) if s == "md" => {}
diff --git a/src/tools/miri b/src/tools/miri
-Subproject c2a2e25d0b050d70d6a355f9b7545a991fc8783
+Subproject c28a8eeb742d7104bc407e12212c5143439963f
diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer
-Subproject e65d48d1fb3d4d91d9dc1148a7a836ff5c9a3c8
+Subproject ac4b134c6be27642dbe915f32a41f9a21bd0c1c
diff --git a/src/tools/tidy/src/debug_artifacts.rs b/src/tools/tidy/src/debug_artifacts.rs
index 408be83b926..ab87230f888 100644
--- a/src/tools/tidy/src/debug_artifacts.rs
+++ b/src/tools/tidy/src/debug_artifacts.rs
@@ -1,4 +1,4 @@
-//! Tidy check to prevent creation of unnecessary debug artifacts.
+//! Tidy check to prevent creation of unnecessary debug artifacts while running tests.
 
 use std::path::{Path, PathBuf};
 
diff --git a/src/tools/tidy/src/edition.rs b/src/tools/tidy/src/edition.rs
index 4a2e49fd1c3..7761ae64ee0 100644
--- a/src/tools/tidy/src/edition.rs
+++ b/src/tools/tidy/src/edition.rs
@@ -1,5 +1,4 @@
 //! Tidy check to ensure that crate `edition` is '2018'
-//!
 
 use std::path::Path;
 
diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index 678e346bd4f..d8029ea04f0 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -71,8 +71,14 @@ pub fn collect_lib_features(base_src_path: &Path) -> Features {
     lib_features
 }
 
-pub fn check(src_path: &Path, lib_path: &Path, bad: &mut bool, verbose: bool) -> CollectedFeatures {
-    let mut features = collect_lang_features(src_path, bad);
+pub fn check(
+    src_path: &Path,
+    compiler_path: &Path,
+    lib_path: &Path,
+    bad: &mut bool,
+    verbose: bool,
+) -> CollectedFeatures {
+    let mut features = collect_lang_features(compiler_path, bad);
     assert!(!features.is_empty());
 
     let lib_features = get_and_check_lib_features(lib_path, bad, &features);
@@ -225,15 +231,15 @@ fn test_filen_gate(filen_underscore: &str, features: &mut Features) -> bool {
     false
 }
 
-pub fn collect_lang_features(base_src_path: &Path, bad: &mut bool) -> Features {
-    let mut all = collect_lang_features_in(base_src_path, "active.rs", bad);
-    all.extend(collect_lang_features_in(base_src_path, "accepted.rs", bad));
-    all.extend(collect_lang_features_in(base_src_path, "removed.rs", bad));
+pub fn collect_lang_features(base_compiler_path: &Path, bad: &mut bool) -> Features {
+    let mut all = collect_lang_features_in(base_compiler_path, "active.rs", bad);
+    all.extend(collect_lang_features_in(base_compiler_path, "accepted.rs", bad));
+    all.extend(collect_lang_features_in(base_compiler_path, "removed.rs", bad));
     all
 }
 
 fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features {
-    let path = base.join("librustc_feature").join(file);
+    let path = base.join("rustc_feature").join("src").join(file);
     let contents = t!(fs::read_to_string(&path));
 
     // We allow rustc-internal features to omit a tracking issue.
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index 43105188ec4..36c9e58eb9a 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -11,44 +11,53 @@ use std::path::PathBuf;
 use std::process;
 
 fn main() {
-    let path: PathBuf = env::args_os().nth(1).expect("need path to src").into();
+    let root_path: PathBuf = env::args_os().nth(1).expect("need path to root of repo").into();
     let cargo: PathBuf = env::args_os().nth(2).expect("need path to cargo").into();
 
-    let library_path: PathBuf = path
-        .join("..")
-        .join("library")
-        .canonicalize()
-        .expect("unable to canonicalize path to library/");
+    let src_path = root_path.join("src");
+    let library_path = root_path.join("library");
+    let compiler_path = root_path.join("compiler");
 
     let args: Vec<String> = env::args().skip(1).collect();
 
     let mut bad = false;
     let verbose = args.iter().any(|s| *s == "--verbose");
 
+    // Checks over tests.
+    debug_artifacts::check(&src_path, &mut bad);
+    ui_tests::check(&src_path, &mut bad);
+
     // Checks that only make sense for the compiler.
-    debug_artifacts::check(&path, &mut bad);
-    errors::check(&path, &mut bad);
-    ui_tests::check(&path, &mut bad);
-    error_codes_check::check(&path, &mut bad);
+    errors::check(&compiler_path, &mut bad);
+    error_codes_check::check(&src_path, &mut bad);
 
     // Checks that only make sense for the std libs.
     pal::check(&library_path, &mut bad);
     unit_tests::check(&library_path, &mut bad);
 
-    // Check that need to be done for both the compiler and std libraries.
-    bins::check(&path, &mut bad);
+    // Checks that need to be done for both the compiler and std libraries.
+    bins::check(&src_path, &mut bad);
+    bins::check(&compiler_path, &mut bad);
     bins::check(&library_path, &mut bad);
-    style::check(&path, &mut bad);
+
+    style::check(&src_path, &mut bad);
+    style::check(&compiler_path, &mut bad);
     style::check(&library_path, &mut bad);
-    cargo::check(&path, &mut bad);
+
+    cargo::check(&src_path, &mut bad);
+    cargo::check(&compiler_path, &mut bad);
     cargo::check(&library_path, &mut bad);
-    edition::check(&path, &mut bad);
+
+    edition::check(&src_path, &mut bad);
+    edition::check(&compiler_path, &mut bad);
     edition::check(&library_path, &mut bad);
 
-    let collected = features::check(&path, &library_path, &mut bad, verbose);
-    unstable_book::check(&path, collected, &mut bad);
-    deps::check(&path.parent().unwrap(), &cargo, &mut bad);
-    extdeps::check(&path.parent().unwrap(), &mut bad);
+    let collected = features::check(&src_path, &compiler_path, &library_path, &mut bad, verbose);
+    unstable_book::check(&src_path, collected, &mut bad);
+
+    // Checks that are done on the cargo workspace.
+    deps::check(&root_path, &cargo, &mut bad);
+    extdeps::check(&root_path, &mut bad);
 
     if bad {
         eprintln!("some tidy checks failed");
diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs
index 8f9d6915790..1dba6b73b93 100644
--- a/src/tools/tidy/src/pal.rs
+++ b/src/tools/tidy/src/pal.rs
@@ -56,9 +56,14 @@ const EXCEPTION_PATHS: &[&str] = &[
     // Integration test for platform-specific run-time feature detection:
     "library/std/tests/run-time-detect.rs",
     "library/std/src/net/test.rs",
+    "library/std/src/net/addr",
+    "library/std/src/net/udp",
     "library/std/src/sys_common/mod.rs",
     "library/std/src/sys_common/net.rs",
     "library/std/src/sys_common/backtrace.rs",
+    "library/std/src/sys_common/remutex.rs",
+    "library/std/src/sync/mutex.rs",
+    "library/std/src/sync/rwlock.rs",
     // panic_unwind shims
     "library/std/src/panicking.rs",
     "library/term", // Not sure how to make this crate portable, but test crate needs it.
diff --git a/src/tools/tidy/src/unit_tests.rs b/src/tools/tidy/src/unit_tests.rs
index c6d67844a2b..04f2bbaa0d9 100644
--- a/src/tools/tidy/src/unit_tests.rs
+++ b/src/tools/tidy/src/unit_tests.rs
@@ -20,15 +20,19 @@ pub fn check(root_path: &Path, bad: &mut bool) {
     let mut skip = |path: &Path| {
         let file_name = path.file_name().unwrap_or_default();
         if path.is_dir() {
-            super::filter_dirs(path) ||
-            path.ends_with("src/test") ||
-            path.ends_with("src/doc") ||
-            path.ends_with("library/std") || // FIXME?
-            (file_name == "tests" || file_name == "benches") && !is_core(path)
+            super::filter_dirs(path)
+                || path.ends_with("src/test")
+                || path.ends_with("src/doc")
+                || (file_name == "tests" || file_name == "benches") && !is_core(path)
         } else {
             let extension = path.extension().unwrap_or_default();
             extension != "rs"
                 || (file_name == "tests.rs" || file_name == "benches.rs") && !is_core(path)
+                // UI tests with different names
+                || path.ends_with("src/thread/local/dynamic_tests.rs")
+                || path.ends_with("src/sync/mpsc/sync_tests.rs")
+                // Has copyright banner
+                || path.ends_with("src/sys/cloudabi/abi/cloudabi.rs")
         }
     };
 
diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs
index 5d277e1c41f..387b2acd106 100644
--- a/src/tools/unstable-book-gen/src/main.rs
+++ b/src/tools/unstable-book-gen/src/main.rs
@@ -94,14 +94,16 @@ fn copy_recursive(from: &Path, to: &Path) {
 }
 
 fn main() {
-    let library_path_str = env::args_os().nth(1).expect("library path required");
-    let src_path_str = env::args_os().nth(2).expect("source path required");
-    let dest_path_str = env::args_os().nth(3).expect("destination path required");
+    let library_path_str = env::args_os().nth(1).expect("library/ path required");
+    let compiler_path_str = env::args_os().nth(2).expect("compiler/ path required");
+    let src_path_str = env::args_os().nth(3).expect("src/ path required");
+    let dest_path_str = env::args_os().nth(4).expect("destination path required");
     let library_path = Path::new(&library_path_str);
+    let compiler_path = Path::new(&compiler_path_str);
     let src_path = Path::new(&src_path_str);
     let dest_path = Path::new(&dest_path_str);
 
-    let lang_features = collect_lang_features(src_path, &mut false);
+    let lang_features = collect_lang_features(compiler_path, &mut false);
     let lib_features = collect_lib_features(library_path)
         .into_iter()
         .filter(|&(ref name, _)| !lang_features.contains_key(name))