about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock6
-rw-r--r--RELEASES.md3
-rw-r--r--appveyor.yml4
-rw-r--r--src/bootstrap/bin/rustdoc.rs10
-rw-r--r--src/bootstrap/builder.rs4
-rw-r--r--src/bootstrap/lib.rs6
-rw-r--r--src/bootstrap/mk/Makefile.in1
-rw-r--r--src/bootstrap/native.rs22
-rw-r--r--src/bootstrap/test.rs12
-rw-r--r--src/ci/docker/dist-x86_64-musl/Dockerfile23
-rw-r--r--src/ci/docker/scripts/musl-toolchain.sh70
-rw-r--r--src/ci/docker/test-various/Dockerfile17
-rw-r--r--src/liballoc/prelude.rs19
-rw-r--r--src/liballoc/prelude/mod.rs16
-rw-r--r--src/liballoc/prelude/v1.rs11
-rw-r--r--src/liballoc/tests/binary_heap.rs2
-rw-r--r--src/liballoc/tests/btree/map.rs5
-rw-r--r--src/liballoc/tests/slice.rs20
-rw-r--r--src/liballoc/tests/str.rs13
-rw-r--r--src/liballoc/tests/string.rs9
-rw-r--r--src/liballoc/tests/vec.rs12
-rw-r--r--src/liballoc/tests/vec_deque.rs1
-rw-r--r--src/libcore/cmp.rs26
-rw-r--r--src/libcore/ffi.rs14
-rw-r--r--src/libcore/iter/adapters/mod.rs4
-rw-r--r--src/libcore/iter/sources.rs6
-rw-r--r--src/libcore/mem.rs9
-rw-r--r--src/libcore/num/dec2flt/algorithm.rs2
-rw-r--r--src/libcore/num/dec2flt/mod.rs6
-rw-r--r--src/libcore/num/dec2flt/parse.rs2
-rw-r--r--src/libcore/num/flt2dec/decoder.rs2
-rw-r--r--src/libcore/num/flt2dec/mod.rs14
-rw-r--r--src/libcore/ops/range.rs49
-rw-r--r--src/libcore/option.rs12
-rw-r--r--src/libcore/pin.rs2
-rw-r--r--src/libcore/result.rs4
-rw-r--r--src/libcore/str/mod.rs8
-rw-r--r--src/libcore/task/wake.rs2
-rw-r--r--src/libcore/tests/cell.rs15
-rw-r--r--src/libcore/tests/iter.rs2
-rw-r--r--src/libcore/tests/lib.rs1
-rw-r--r--src/libcore/tests/num/bignum.rs14
-rw-r--r--src/libcore/tests/num/int_macros.rs48
-rw-r--r--src/libcore/tests/ops.rs8
-rw-r--r--src/libcore/tests/option.rs3
-rw-r--r--src/libcore/tests/result.rs3
-rw-r--r--src/libcore/tests/slice.rs7
-rw-r--r--src/libcore/tests/time.rs2
-rw-r--r--src/libcore/time.rs140
-rw-r--r--src/librustc/dep_graph/dep_node.rs4
-rw-r--r--src/librustc/hir/def_id.rs2
-rw-r--r--src/librustc/hir/map/definitions.rs6
-rw-r--r--src/librustc/hir/map/mod.rs10
-rw-r--r--src/librustc/infer/error_reporting/mod.rs129
-rw-r--r--src/librustc/infer/error_reporting/need_type_info.rs24
-rw-r--r--src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs233
-rw-r--r--src/librustc/infer/error_reporting/nice_region_error/util.rs4
-rw-r--r--src/librustc/infer/outlives/free_region_map.rs2
-rw-r--r--src/librustc/lib.rs3
-rw-r--r--src/librustc/lint/levels.rs7
-rw-r--r--src/librustc/lint/mod.rs21
-rw-r--r--src/librustc/middle/dead.rs4
-rw-r--r--src/librustc/middle/mem_categorization.rs23
-rw-r--r--src/librustc/middle/region.rs6
-rw-r--r--src/librustc/middle/resolve_lifetime.rs46
-rw-r--r--src/librustc/middle/stability.rs4
-rw-r--r--src/librustc/mir/interpret/allocation.rs76
-rw-r--r--src/librustc/mir/mod.rs25
-rw-r--r--src/librustc/session/config.rs19
-rw-r--r--src/librustc/traits/error_reporting.rs17
-rw-r--r--src/librustc/traits/mod.rs8
-rw-r--r--src/librustc/traits/object_safety.rs2
-rw-r--r--src/librustc/traits/on_unimplemented.rs2
-rw-r--r--src/librustc/traits/project.rs2
-rw-r--r--src/librustc/traits/specialize/mod.rs2
-rw-r--r--src/librustc/traits/structural_impls.rs5
-rw-r--r--src/librustc/ty/context.rs64
-rw-r--r--src/librustc/ty/error.rs33
-rw-r--r--src/librustc/ty/instance.rs11
-rw-r--r--src/librustc/ty/item_path.rs573
-rw-r--r--src/librustc/ty/mod.rs12
-rw-r--r--src/librustc/ty/print/mod.rs327
-rw-r--r--src/librustc/ty/print/pretty.rs1621
-rw-r--r--src/librustc/ty/query/config.rs32
-rw-r--r--src/librustc/ty/query/plumbing.rs5
-rw-r--r--src/librustc/ty/relate.rs6
-rw-r--r--src/librustc/ty/structural_impls.rs300
-rw-r--r--src/librustc/ty/sty.rs12
-rw-r--r--src/librustc/ty/subst.rs38
-rw-r--r--src/librustc/ty/util.rs4
-rw-r--r--src/librustc/util/ppaux.rs1667
-rw-r--r--src/librustc/util/profiling.rs31
-rw-r--r--src/librustc/util/time_graph.rs268
-rw-r--r--src/librustc_borrowck/borrowck/mod.rs8
-rw-r--r--src/librustc_codegen_llvm/back/lto.rs44
-rw-r--r--src/librustc_codegen_llvm/back/write.rs58
-rw-r--r--src/librustc_codegen_llvm/intrinsic.rs25
-rw-r--r--src/librustc_codegen_llvm/lib.rs22
-rw-r--r--src/librustc_codegen_ssa/back/linker.rs15
-rw-r--r--src/librustc_codegen_ssa/back/lto.rs5
-rw-r--r--src/librustc_codegen_ssa/back/write.rs113
-rw-r--r--src/librustc_codegen_ssa/base.rs27
-rw-r--r--src/librustc_codegen_ssa/lib.rs1
-rw-r--r--src/librustc_codegen_ssa/mir/constant.rs2
-rw-r--r--src/librustc_codegen_ssa/traits/type_.rs2
-rw-r--r--src/librustc_codegen_ssa/traits/write.rs6
-rw-r--r--src/librustc_codegen_utils/lib.rs1
-rw-r--r--src/librustc_codegen_utils/symbol_names.rs364
-rw-r--r--src/librustc_codegen_utils/symbol_names_test.rs12
-rw-r--r--src/librustc_driver/pretty.rs2
-rw-r--r--src/librustc_errors/lib.rs1
-rw-r--r--src/librustc_incremental/assert_dep_graph.rs2
-rw-r--r--src/librustc_incremental/persist/dirty_clean.rs2
-rw-r--r--src/librustc_interface/passes.rs13
-rw-r--r--src/librustc_lint/unused.rs2
-rw-r--r--src/librustc_mir/borrow_check/error_reporting.rs71
-rw-r--r--src/librustc_mir/borrow_check/mod.rs2
-rw-r--r--src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs2
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs14
-rw-r--r--src/librustc_mir/build/matches/simplify.rs2
-rw-r--r--src/librustc_mir/build/scope.rs30
-rw-r--r--src/librustc_mir/const_eval.rs45
-rw-r--r--src/librustc_mir/hair/cx/block.rs2
-rw-r--r--src/librustc_mir/hair/cx/expr.rs7
-rw-r--r--src/librustc_mir/hair/cx/mod.rs41
-rw-r--r--src/librustc_mir/hair/pattern/_match.rs10
-rw-r--r--src/librustc_mir/hair/pattern/check_match.rs2
-rw-r--r--src/librustc_mir/hair/pattern/mod.rs18
-rw-r--r--src/librustc_mir/hair/util.rs10
-rw-r--r--src/librustc_mir/interpret/cast.rs6
-rw-r--r--src/librustc_mir/interpret/eval_context.rs14
-rw-r--r--src/librustc_mir/interpret/memory.rs102
-rw-r--r--src/librustc_mir/interpret/operator.rs2
-rw-r--r--src/librustc_mir/interpret/place.rs2
-rw-r--r--src/librustc_mir/lib.rs1
-rw-r--r--src/librustc_mir/monomorphize/collector.rs40
-rw-r--r--src/librustc_mir/monomorphize/item.rs5
-rw-r--r--src/librustc_mir/monomorphize/partitioning.rs2
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs2
-rw-r--r--src/librustc_mir/transform/rustc_peek.rs4
-rw-r--r--src/librustc_mir/util/graphviz.rs4
-rw-r--r--src/librustc_mir/util/liveness.rs6
-rw-r--r--src/librustc_mir/util/pretty.rs19
-rw-r--r--src/librustc_privacy/lib.rs4
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs27
-rw-r--r--src/librustc_save_analysis/lib.rs30
-rw-r--r--src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs23
-rw-r--r--src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs24
-rw-r--r--src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs24
-rw-r--r--src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs24
-rw-r--r--src/librustc_target/spec/mod.rs4
-rw-r--r--src/librustc_target/spec/uefi_base.rs2
-rw-r--r--src/librustc_typeck/astconv.rs16
-rw-r--r--src/librustc_typeck/check/_match.rs8
-rw-r--r--src/librustc_typeck/check/compare_method.rs2
-rw-r--r--src/librustc_typeck/check/demand.rs2
-rw-r--r--src/librustc_typeck/check/method/probe.rs4
-rw-r--r--src/librustc_typeck/check/method/suggest.rs18
-rw-r--r--src/librustc_typeck/check/mod.rs129
-rw-r--r--src/librustc_typeck/check/upvar.rs7
-rw-r--r--src/librustc_typeck/check/wfcheck.rs6
-rw-r--r--src/librustc_typeck/check/writeback.rs2
-rw-r--r--src/librustc_typeck/coherence/builtin.rs8
-rw-r--r--src/librustc_typeck/coherence/mod.rs6
-rw-r--r--src/librustc_typeck/coherence/orphan.rs4
-rw-r--r--src/librustc_typeck/lib.rs4
-rw-r--r--src/librustc_typeck/variance/constraints.rs2
-rw-r--r--src/librustdoc/clean/mod.rs118
-rw-r--r--src/librustdoc/html/render.rs6
-rw-r--r--src/librustdoc/html/static/main.js69
-rw-r--r--src/librustdoc/lib.rs3
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs6
-rw-r--r--src/libstd/collections/hash/map.rs2
-rw-r--r--src/libstd/collections/hash/set.rs2
-rw-r--r--src/libstd/f32.rs21
-rw-r--r--src/libstd/f64.rs21
-rw-r--r--src/libstd/fs.rs25
-rw-r--r--src/libstd/io/mod.rs40
-rw-r--r--src/libstd/lib.rs3
-rw-r--r--src/libstd/os/fortanix_sgx/mod.rs5
-rw-r--r--src/libstd/process.rs2
-rw-r--r--src/libstd/sync/condvar.rs12
-rw-r--r--src/libstd/sys/redox/net/tcp.rs10
-rw-r--r--src/libstd/sys/sgx/abi/thread.rs1
-rw-r--r--src/libstd/sys/sgx/net.rs16
-rw-r--r--src/libstd/sys/unix/fs.rs87
-rw-r--r--src/libstd/sys/wasm/alloc.rs95
-rw-r--r--src/libstd/sys/windows/pipe.rs6
-rw-r--r--src/libstd/time.rs11
-rw-r--r--src/libsyntax/config.rs6
-rw-r--r--src/libsyntax/diagnostic_list.rs15
-rw-r--r--src/libsyntax/feature_gate.rs13
-rw-r--r--src/libsyntax/parse/parser.rs45
m---------src/llvm-project0
-rw-r--r--src/test/debuginfo/auxiliary/issue-13213-aux.rs (renamed from src/test/debuginfo/auxiliary/issue13213aux.rs)0
-rw-r--r--src/test/debuginfo/issue-13213.rs6
-rw-r--r--src/test/incremental/auxiliary/issue-49482-macro-def.rs (renamed from src/test/incremental/auxiliary/issue_49482_macro_def.rs)0
-rw-r--r--src/test/incremental/auxiliary/issue-49482-reexport.rs (renamed from src/test/incremental/auxiliary/issue_49482_reexport.rs)0
-rw-r--r--src/test/incremental/auxiliary/issue-54059.rs (renamed from src/test/incremental/auxiliary/issue_54059.rs)0
-rw-r--r--src/test/incremental/issue-49482.rs4
-rw-r--r--src/test/incremental/issue-49595/issue-49595.rs (renamed from src/test/incremental/issue-49595/issue_49595.rs)0
-rw-r--r--src/test/incremental/issue-54059.rs2
-rw-r--r--src/test/mir-opt/basic_assignment.rs2
-rw-r--r--src/test/mir-opt/issue-41697.rs2
-rw-r--r--src/test/mir-opt/match_false_edges.rs6
-rw-r--r--src/test/mir-opt/retag.rs2
-rw-r--r--src/test/mir-opt/storage_ranges.rs2
-rw-r--r--src/test/mir-opt/unusual-item-types.rs18
-rw-r--r--src/test/pretty/issue-12590-a.rs (renamed from src/test/pretty/issue_12590_a.rs)1
-rw-r--r--src/test/pretty/issue-12590-b.rs5
-rw-r--r--src/test/pretty/issue-12590-c.pp (renamed from src/test/pretty/issue_12590_c.pp)3
-rw-r--r--src/test/pretty/issue-12590-c.rs (renamed from src/test/pretty/issue_12590_c.rs)3
-rw-r--r--src/test/pretty/issue-4264.pp34
-rw-r--r--src/test/pretty/issue_12590_b.rs4
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/custom-derive-partial-eq.rs (renamed from src/test/run-pass-fulldeps/auxiliary/custom_derive_partial_eq.rs)0
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs (renamed from src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin_attr.rs)0
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin.rs (renamed from src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin.rs)0
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/issue-24106.rs (renamed from src/test/run-pass-fulldeps/auxiliary/issue_24106.rs)0
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs (renamed from src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs)0
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/llvm-pass-plugin.rs (renamed from src/test/run-pass-fulldeps/auxiliary/llvm_pass_plugin.rs)0
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/macro-crate-test.rs (renamed from src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs)0
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/plugin-args.rs (renamed from src/test/run-pass-fulldeps/auxiliary/plugin_args.rs)0
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/roman-numerals.rs (renamed from src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs)0
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/syntax-extension-with-dll-deps-1.rs (renamed from src/test/run-pass-fulldeps/auxiliary/syntax_extension_with_dll_deps_1.rs)0
-rw-r--r--src/test/run-pass-fulldeps/custom-derive-partial-eq.rs2
-rw-r--r--src/test/run-pass-fulldeps/derive-totalsum-attr.rs2
-rw-r--r--src/test/run-pass-fulldeps/derive-totalsum.rs2
-rw-r--r--src/test/run-pass-fulldeps/issue-15778-pass.rs2
-rw-r--r--src/test/run-pass-fulldeps/issue-24106.rs (renamed from src/test/run-pass-fulldeps/issue_24106.rs)2
-rw-r--r--src/test/run-pass-fulldeps/issue-40663.rs2
-rw-r--r--src/test/run-pass-fulldeps/llvm-pass-plugin.rs2
-rw-r--r--src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs2
-rw-r--r--src/test/run-pass-fulldeps/plugin-args-1.rs2
-rw-r--r--src/test/run-pass-fulldeps/plugin-args-2.rs2
-rw-r--r--src/test/run-pass-fulldeps/plugin-args-3.rs2
-rw-r--r--src/test/run-pass-fulldeps/roman-numerals-macro.rs2
-rw-r--r--src/test/run-pass-fulldeps/undef_mask.rs26
-rw-r--r--src/test/run-pass/array-slice-vec/estr-slice.rs8
-rw-r--r--src/test/run-pass/auxiliary/rmeta-rlib.rs (renamed from src/test/run-pass/auxiliary/rmeta_rlib.rs)0
-rw-r--r--src/test/run-pass/auxiliary/rmeta-rmeta.rs (renamed from src/test/run-pass/auxiliary/rmeta_rmeta.rs)0
-rw-r--r--src/test/run-pass/issue-55809.rs30
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-10031-aux.rs (renamed from src/test/run-pass/issues/auxiliary/issue_10031_aux.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-12612-1.rs (renamed from src/test/run-pass/issues/auxiliary/issue_12612_1.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-12612-2.rs (renamed from src/test/run-pass/issues/auxiliary/issue_12612_2.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-13507.rs (renamed from src/test/run-pass/issues/auxiliary/issue13507.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-19293.rs (renamed from src/test/run-pass/issues/auxiliary/issue_19293.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-20389.rs (renamed from src/test/run-pass/issues/auxiliary/issue_20389.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-2170-lib.rs (renamed from src/test/run-pass/issues/auxiliary/issue2170lib.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-2316-a.rs (renamed from src/test/run-pass/issues/auxiliary/issue_2316_a.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-2316-b.rs (renamed from src/test/run-pass/issues/auxiliary/issue_2316_b.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-2472-b.rs (renamed from src/test/run-pass/issues/auxiliary/issue_2472_b.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-2723-a.rs (renamed from src/test/run-pass/issues/auxiliary/issue_2723_a.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-3136-a.rc (renamed from src/test/run-pass/issues/auxiliary/issue_3136_a.rc)1
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-3136-a.rs (renamed from src/test/run-pass/issues/auxiliary/issue_3136_a.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-34796-aux.rs (renamed from src/test/run-pass/issues/auxiliary/issue34796aux.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-38190.rs (renamed from src/test/run-pass/issues/auxiliary/issue_38190.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-38226-aux.rs (renamed from src/test/run-pass/issues/auxiliary/issue_38226_aux.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-38715-modern.rs (renamed from src/test/run-pass/issues/auxiliary/issue_38715-modern.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-38715.rs (renamed from src/test/run-pass/issues/auxiliary/issue_38715.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-3979-traits.rs (renamed from src/test/run-pass/issues/auxiliary/issue_3979_traits.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-39823.rs (renamed from src/test/run-pass/issues/auxiliary/issue_39823.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-40469.rs (renamed from src/test/run-pass/issues/auxiliary/issue_40469.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-41053.rs (renamed from src/test/run-pass/issues/auxiliary/issue_41053.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-42007-s.rs (renamed from src/test/run-pass/issues/auxiliary/issue_42007_s.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-8401.rs (renamed from src/test/run-pass/issues/auxiliary/issue_8401.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-9123.rs (renamed from src/test/run-pass/issues/auxiliary/issue_9123.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-9155.rs (renamed from src/test/run-pass/issues/auxiliary/issue_9155.rs)0
-rw-r--r--src/test/run-pass/issues/auxiliary/issue-9188.rs (renamed from src/test/run-pass/issues/auxiliary/issue_9188.rs)0
-rw-r--r--src/test/run-pass/issues/issue-10031.rs2
-rw-r--r--src/test/run-pass/issues/issue-12612.rs4
-rw-r--r--src/test/run-pass/issues/issue-13507-2.rs10
-rw-r--r--src/test/run-pass/issues/issue-18952.rs (renamed from src/test/run-pass/issue-18952.rs)0
-rw-r--r--src/test/run-pass/issues/issue-19293.rs2
-rw-r--r--src/test/run-pass/issues/issue-20389.rs2
-rw-r--r--src/test/run-pass/issues/issue-2170-exe.rs9
-rw-r--r--src/test/run-pass/issues/issue-2316-c.rs4
-rw-r--r--src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs (renamed from src/test/run-pass/issues/issue24687-embed-debuginfo/auxiliary/issue24687_lib.rs)5
-rw-r--r--src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs (renamed from src/test/run-pass/issues/issue24687-embed-debuginfo/auxiliary/issue24687_mbcs_in_comments.rs)0
-rw-r--r--src/test/run-pass/issues/issue-24687-embed-debuginfo/main.rs (renamed from src/test/run-pass/issues/issue24687-embed-debuginfo/main.rs)6
-rw-r--r--src/test/run-pass/issues/issue-2472.rs2
-rw-r--r--src/test/run-pass/issues/issue-26873-multifile.rs3
-rw-r--r--src/test/run-pass/issues/issue-26873-multifile/A/B.rs (renamed from src/test/run-pass/issues/issue_26873_multifile/A/B.rs)0
-rw-r--r--src/test/run-pass/issues/issue-26873-multifile/A/C.rs (renamed from src/test/run-pass/issues/issue_26873_multifile/A/C.rs)0
-rw-r--r--src/test/run-pass/issues/issue-26873-multifile/A/mod.rs (renamed from src/test/run-pass/issues/issue_26873_multifile/A/mod.rs)0
-rw-r--r--src/test/run-pass/issues/issue-26873-multifile/compiletest-ignore-dir (renamed from src/test/run-pass/issues/issue_26873_multifile/compiletest-ignore-dir)0
-rw-r--r--src/test/run-pass/issues/issue-26873-multifile/mod.rs (renamed from src/test/run-pass/issues/issue_26873_multifile/mod.rs)0
-rw-r--r--src/test/run-pass/issues/issue-2723-b.rs2
-rw-r--r--src/test/run-pass/issues/issue-28498-must-work-ex1.rs (renamed from src/test/run-pass/issues/issue28498-must-work-ex1.rs)0
-rw-r--r--src/test/run-pass/issues/issue-28498-must-work-ex2.rs (renamed from src/test/run-pass/issues/issue28498-must-work-ex2.rs)0
-rw-r--r--src/test/run-pass/issues/issue-28498-ugeh-ex1.rs (renamed from src/test/run-pass/issues/issue28498-ugeh-ex1.rs)0
-rw-r--r--src/test/run-pass/issues/issue-28498-ugeh-with-lifetime-param.rs (renamed from src/test/run-pass/issues/issue28498-ugeh-with-lifetime-param.rs)0
-rw-r--r--src/test/run-pass/issues/issue-28498-ugeh-with-passed-to-fn.rs (renamed from src/test/run-pass/issues/issue28498-ugeh-with-passed-to-fn.rs)0
-rw-r--r--src/test/run-pass/issues/issue-28498-ugeh-with-trait-bound.rs (renamed from src/test/run-pass/issues/issue28498-ugeh-with-trait-bound.rs)0
-rw-r--r--src/test/run-pass/issues/issue-29927-1.rs (renamed from src/test/run-pass/issues/issue29927-1.rs)0
-rw-r--r--src/test/run-pass/issues/issue-3136-b.rs (renamed from src/test/run-pass/issues/issue_3136_b.rs)3
-rw-r--r--src/test/run-pass/issues/issue-34796.rs6
-rw-r--r--src/test/run-pass/issues/issue-38190.rs7
-rw-r--r--src/test/run-pass/issues/issue-38226.rs2
-rw-r--r--src/test/run-pass/issues/issue-38715.rs4
-rw-r--r--src/test/run-pass/issues/issue-3979-xcrate.rs2
-rw-r--r--src/test/run-pass/issues/issue-39823.rs2
-rw-r--r--src/test/run-pass/issues/issue-40469.rs2
-rw-r--r--src/test/run-pass/issues/issue-41053.rs2
-rw-r--r--src/test/run-pass/issues/issue-42007.rs2
-rw-r--r--src/test/run-pass/issues/issue-45510.rs (renamed from src/test/run-pass/issue-45510.rs)0
-rw-r--r--src/test/run-pass/issues/issue-48006.rs (renamed from src/test/run-pass/issue-48006.rs)0
-rw-r--r--src/test/run-pass/issues/issue-53728.rs (renamed from src/test/run-pass/issue-53728.rs)0
-rw-r--r--src/test/run-pass/issues/issue-53843.rs (renamed from src/test/run-pass/issue-53843.rs)0
-rw-r--r--src/test/run-pass/issues/issue-54462-mutable-noalias-correctness.rs (renamed from src/test/run-pass/issue-54462-mutable-noalias-correctness.rs)0
-rw-r--r--src/test/run-pass/issues/issue-54467.rs (renamed from src/test/run-pass/issue-54467.rs)0
-rw-r--r--src/test/run-pass/issues/issue-55376.rs (renamed from src/test/run-pass/issue-55376.rs)0
-rw-r--r--src/test/run-pass/issues/issue-55380.rs (renamed from src/test/run-pass/issue-55380.rs)0
-rw-r--r--src/test/run-pass/issues/issue-56237.rs (renamed from src/test/run-pass/issue-56237.rs)0
-rw-r--r--src/test/run-pass/issues/issue-57924.rs9
-rw-r--r--src/test/run-pass/issues/issue-8401.rs2
-rw-r--r--src/test/run-pass/issues/issue-9123.rs2
-rw-r--r--src/test/run-pass/issues/issue-9155.rs (renamed from src/test/run-pass/issues/issue_9155.rs)2
-rw-r--r--src/test/run-pass/issues/issue-9188.rs2
-rw-r--r--src/test/run-pass/issues/issue2170exe.rs9
-rw-r--r--src/test/run-pass/rmeta.rs4
-rw-r--r--src/test/run-pass/simd/simd-size-align.rs32
-rw-r--r--src/test/rustdoc/auxiliary/enum-primitive.rs (renamed from src/test/rustdoc/auxiliary/enum_primitive.rs)0
-rw-r--r--src/test/rustdoc/auxiliary/reexp-stripped.rs (renamed from src/test/rustdoc/auxiliary/reexp_stripped.rs)0
-rw-r--r--src/test/rustdoc/no-stack-overflow-25295.rs5
-rw-r--r--src/test/rustdoc/redirect.rs2
-rw-r--r--src/test/ui-fulldeps/auxiliary/attr-plugin-test.rs (renamed from src/test/ui-fulldeps/auxiliary/attr_plugin_test.rs)0
-rw-r--r--src/test/ui-fulldeps/auxiliary/lint-for-crate.rs (renamed from src/test/ui-fulldeps/auxiliary/lint_for_crate.rs)0
-rw-r--r--src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs (renamed from src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs)0
-rw-r--r--src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs (renamed from src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs)0
-rw-r--r--src/test/ui-fulldeps/auxiliary/lint-tool-test.rs (renamed from src/test/ui-fulldeps/auxiliary/lint_tool_test.rs)0
-rw-r--r--src/test/ui-fulldeps/auxiliary/rlib-crate-test.rs (renamed from src/test/ui-fulldeps/auxiliary/rlib_crate_test.rs)0
-rw-r--r--src/test/ui-fulldeps/dropck-tarena-cycle-checked.rs (renamed from src/test/ui-fulldeps/dropck_tarena_cycle_checked.rs)0
-rw-r--r--src/test/ui-fulldeps/dropck-tarena-cycle-checked.stderr (renamed from src/test/ui-fulldeps/dropck_tarena_cycle_checked.stderr)2
-rw-r--r--src/test/ui-fulldeps/dropck-tarena-unsound-drop.rs (renamed from src/test/ui-fulldeps/dropck_tarena_unsound_drop.rs)0
-rw-r--r--src/test/ui-fulldeps/dropck-tarena-unsound-drop.stderr (renamed from src/test/ui-fulldeps/dropck_tarena_unsound_drop.stderr)2
-rw-r--r--src/test/ui-fulldeps/gated-plugin.rs2
-rw-r--r--src/test/ui-fulldeps/issue-15778-fail.rs2
-rw-r--r--src/test/ui-fulldeps/lint-group-plugin-deny-cmdline.rs2
-rw-r--r--src/test/ui-fulldeps/lint-group-plugin.rs2
-rw-r--r--src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs2
-rw-r--r--src/test/ui-fulldeps/lint-plugin-cmdline-load.rs2
-rw-r--r--src/test/ui-fulldeps/lint-plugin-deny-attr.rs2
-rw-r--r--src/test/ui-fulldeps/lint-plugin-deny-cmdline.rs2
-rw-r--r--src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs2
-rw-r--r--src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs2
-rw-r--r--src/test/ui-fulldeps/lint-plugin.rs2
-rw-r--r--src/test/ui-fulldeps/lint-tool-cmdline-allow.rs (renamed from src/test/ui-fulldeps/lint_tool_cmdline_allow.rs)7
-rw-r--r--src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr (renamed from src/test/ui-fulldeps/lint_tool_cmdline_allow.stderr)12
-rw-r--r--src/test/ui-fulldeps/lint-tool-test.rs (renamed from src/test/ui-fulldeps/lint_tool_test.rs)2
-rw-r--r--src/test/ui-fulldeps/lint-tool-test.stderr (renamed from src/test/ui-fulldeps/lint_tool_test.stderr)18
-rw-r--r--src/test/ui-fulldeps/macro-crate-rlib.rs2
-rw-r--r--src/test/ui-fulldeps/plugin-as-extern-crate.rs2
-rw-r--r--src/test/ui-fulldeps/plugin-attr-register-deny.rs2
-rw-r--r--src/test/ui/associated-types/associated-types-eq-3.stderr2
-rw-r--r--src/test/ui/associated-types/associated-types-overridden-binding-2.stderr2
-rw-r--r--src/test/ui/auxiliary/default-ty-param-cross-crate-crate.rs (renamed from src/test/ui/auxiliary/default_ty_param_cross_crate_crate.rs)0
-rw-r--r--src/test/ui/auxiliary/define-macro.rs (renamed from src/test/ui/auxiliary/define_macro.rs)0
-rw-r--r--src/test/ui/auxiliary/orphan-check-diagnostics.rs (renamed from src/test/ui/auxiliary/orphan_check_diagnostics.rs)0
-rw-r--r--src/test/ui/auxiliary/pub-and-stability.rs (renamed from src/test/ui/auxiliary/pub_and_stability.rs)0
-rw-r--r--src/test/ui/auxiliary/rmeta-meta.rs (renamed from src/test/ui/auxiliary/rmeta_meta.rs)0
-rw-r--r--src/test/ui/auxiliary/rmeta-rlib.rs (renamed from src/test/ui/auxiliary/rmeta_rlib.rs)0
-rw-r--r--src/test/ui/auxiliary/stability-cfg2.rs (renamed from src/test/ui/auxiliary/stability_cfg2.rs)0
-rw-r--r--src/test/ui/auxiliary/xc-private-method-lib.rs (renamed from src/test/ui/auxiliary/xc_private_method_lib.rs)0
-rw-r--r--src/test/ui/bad/bad-sized.stderr2
-rw-r--r--src/test/ui/confuse-field-and-method/issue-2392.stderr2
-rw-r--r--src/test/ui/consts/const-size_of-cycle.stderr8
-rw-r--r--src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr2
-rw-r--r--src/test/ui/consts/union_constant.rs11
-rw-r--r--src/test/ui/deprecation/deprecation-lint.rs2
-rw-r--r--src/test/ui/deprecation/deprecation-lint.stderr2
-rw-r--r--src/test/ui/e0119/auxiliary/issue-23563-a.rs (renamed from src/test/ui/e0119/auxiliary/issue_23563_a.rs)0
-rw-r--r--src/test/ui/e0119/issue-23563.rs2
-rw-r--r--src/test/ui/enable-unstable-lib-feature.rs2
-rw-r--r--src/test/ui/explore-issue-38412.rs3
-rw-r--r--src/test/ui/feature-gate/allow-features-empty.rs10
-rw-r--r--src/test/ui/feature-gate/allow-features-empty.stderr21
-rw-r--r--src/test/ui/feature-gate/allow-features.rs10
-rw-r--r--src/test/ui/feature-gate/allow-features.stderr9
-rw-r--r--src/test/ui/impl-trait/auto-trait-leak.stderr12
-rw-r--r--src/test/ui/issues/issue-10536.rs2
-rw-r--r--src/test/ui/issues/issue-10536.stderr10
-rw-r--r--src/test/ui/issues/issue-17252.stderr2
-rw-r--r--src/test/ui/issues/issue-17651.stderr2
-rw-r--r--src/test/ui/issues/issue-17905-2.stderr4
-rw-r--r--src/test/ui/issues/issue-20605.stderr4
-rw-r--r--src/test/ui/issues/issue-20831-debruijn.stderr4
-rw-r--r--src/test/ui/issues/issue-22312.stderr2
-rw-r--r--src/test/ui/issues/issue-22638.stderr2
-rw-r--r--src/test/ui/issues/issue-23302-1.stderr6
-rw-r--r--src/test/ui/issues/issue-23302-2.stderr6
-rw-r--r--src/test/ui/issues/issue-36163.stderr6
-rw-r--r--src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr4
-rw-r--r--src/test/ui/issues/issue-42944.rs (renamed from src/test/ui/issue-42944.rs)0
-rw-r--r--src/test/ui/issues/issue-42944.stderr (renamed from src/test/ui/issue-42944.stderr)0
-rw-r--r--src/test/ui/issues/issue-44415.stderr8
-rw-r--r--src/test/ui/issues/issue-53787-inline-assembler-macro.rs (renamed from src/test/ui/issue-53787-inline-assembler-macro.rs)0
-rw-r--r--src/test/ui/issues/issue-53787-inline-assembler-macro.stderr (renamed from src/test/ui/issue-53787-inline-assembler-macro.stderr)0
-rw-r--r--src/test/ui/issues/issue-54943-1.rs (renamed from src/test/ui/issue-54943-1.rs)0
-rw-r--r--src/test/ui/issues/issue-54943-2.rs (renamed from src/test/ui/issue-54943-2.rs)0
-rw-r--r--src/test/ui/issues/issue-54943-3.rs (renamed from src/test/ui/issue-54943-3.rs)0
-rw-r--r--src/test/ui/issues/issue-54943.rs (renamed from src/test/ui/issue-54943.rs)0
-rw-r--r--src/test/ui/issues/issue-54943.stderr (renamed from src/test/ui/issue-54943.stderr)0
-rw-r--r--src/test/ui/issues/issue-55511.nll.stderr (renamed from src/test/ui/issue-55511.nll.stderr)0
-rw-r--r--src/test/ui/issues/issue-55511.rs (renamed from src/test/ui/issue-55511.rs)0
-rw-r--r--src/test/ui/issues/issue-55511.stderr (renamed from src/test/ui/issue-55511.stderr)0
-rw-r--r--src/test/ui/issues/issue-55796.stderr8
-rw-r--r--src/test/ui/issues/issue-55846.rs (renamed from src/test/ui/issue-55846.rs)0
-rw-r--r--src/test/ui/issues/issue-56411-aux.rs (renamed from src/test/ui/issues/issue_56411_aux.rs)0
-rw-r--r--src/test/ui/issues/issue-56411.rs5
-rw-r--r--src/test/ui/issues/issue-56411.stderr12
-rw-r--r--src/test/ui/issues/issue-59029-1.rs8
-rw-r--r--src/test/ui/issues/issue-59029-1.stderr9
-rw-r--r--src/test/ui/issues/issue-59029-2.rs8
-rw-r--r--src/test/ui/lint/auxiliary/stability-cfg2.rs5
-rw-r--r--src/test/ui/lint/lint-stability-deprecated.rs2
-rw-r--r--src/test/ui/lint/lint-stability.rs2
-rw-r--r--src/test/ui/namespace/namespace-mix.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument-callee.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr4
-rw-r--r--src/test/ui/orphan-check-diagnostics.rs5
-rw-r--r--src/test/ui/orphan-check-diagnostics.stderr2
-rw-r--r--src/test/ui/out-of-order-shadowing.rs2
-rw-r--r--src/test/ui/parser/macros-no-semicolon-items.rs11
-rw-r--r--src/test/ui/parser/macros-no-semicolon-items.stderr41
-rw-r--r--src/test/ui/privacy/private-inferred-type-3.rs2
-rw-r--r--src/test/ui/privacy/private-inferred-type-3.stderr2
-rw-r--r--src/test/ui/privacy/private-inferred-type.rs2
-rw-r--r--src/test/ui/privacy/private-inferred-type.stderr2
-rw-r--r--src/test/ui/proc-macro/auxiliary/issue-38586.rs (renamed from src/test/ui/proc-macro/auxiliary/issue_38586.rs)0
-rw-r--r--src/test/ui/proc-macro/auxiliary/issue-50493.rs (renamed from src/test/ui/proc-macro/auxiliary/issue_50493.rs)0
-rw-r--r--src/test/ui/proc-macro/issue-38586.rs2
-rw-r--r--src/test/ui/proc-macro/issue-50493.rs2
-rw-r--r--src/test/ui/regions/regions-addr-of-upvar-self.stderr2
-rw-r--r--src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr2
-rw-r--r--src/test/ui/resolve/auxiliary/issue-19452-aux.rs (renamed from src/test/ui/resolve/auxiliary/issue_19452_aux.rs)0
-rw-r--r--src/test/ui/resolve/auxiliary/issue-3907.rs (renamed from src/test/ui/resolve/auxiliary/issue_3907.rs)0
-rw-r--r--src/test/ui/resolve/issue-19452.rs3
-rw-r--r--src/test/ui/resolve/issue-19452.stderr4
-rw-r--r--src/test/ui/resolve/issue-3907-2.rs3
-rw-r--r--src/test/ui/resolve/issue-3907-2.stderr2
-rw-r--r--src/test/ui/resolve/issue-3907.rs3
-rw-r--r--src/test/ui/resolve/issue-3907.stderr2
-rw-r--r--src/test/ui/retslot-cast.stderr6
-rw-r--r--src/test/ui/rmeta-lib-pass.rs2
-rw-r--r--src/test/ui/rmeta-pass.rs2
-rw-r--r--src/test/ui/rmeta_lib.rs2
-rw-r--r--src/test/ui/rmeta_meta_main.rs2
-rw-r--r--src/test/ui/simd-type.rs3
-rw-r--r--src/test/ui/simd-type.stderr10
-rw-r--r--src/test/ui/substs-ppaux.rs2
-rw-r--r--src/test/ui/substs-ppaux.verbose.stderr2
-rw-r--r--src/test/ui/suggestions/return-without-lifetime.rs10
-rw-r--r--src/test/ui/suggestions/return-without-lifetime.stderr25
-rw-r--r--src/test/ui/symbol-names/basic.rs2
-rw-r--r--src/test/ui/symbol-names/basic.stderr6
-rw-r--r--src/test/ui/symbol-names/impl1.rs4
-rw-r--r--src/test/ui/symbol-names/impl1.stderr12
-rw-r--r--src/test/ui/type_length_limit.rs2
-rw-r--r--src/test/ui/type_length_limit.stderr8
-rw-r--r--src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr2
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr4
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr4
-rw-r--r--src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr4
-rw-r--r--src/test/ui/use/auxiliary/use-from-trait-xc.rs (renamed from src/test/ui/auxiliary/use_from_trait_xc.rs)0
-rw-r--r--src/test/ui/use/auxiliary/use_from_trait_xc.rs29
-rw-r--r--src/test/ui/use/issue-18986.rs (renamed from src/test/ui/issue-18986.rs)2
-rw-r--r--src/test/ui/use/issue-18986.stderr (renamed from src/test/ui/issue-18986.stderr)0
-rw-r--r--src/test/ui/use/use-from-trait-xc.rs2
-rw-r--r--src/test/ui/useless-comment.rs (renamed from src/test/ui/useless_comment.rs)0
-rw-r--r--src/test/ui/useless-comment.stderr (renamed from src/test/ui/useless_comment.stderr)22
-rw-r--r--src/test/ui/xc-private-method.rs2
-rw-r--r--src/test/ui/xc-private-method2.rs2
-rw-r--r--src/tools/build-manifest/src/main.rs9
m---------src/tools/cargo0
-rw-r--r--src/tools/compiletest/src/util.rs8
m---------src/tools/miri28
478 files changed, 5353 insertions, 4199 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 39ecc880097..27f7f59165b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -251,7 +251,7 @@ dependencies = [
  "fwdansi 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "git2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "git2-curl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "ignore 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1009,7 +1009,7 @@ dependencies = [
 
 [[package]]
 name = "glob"
-version = "0.2.11"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -4083,7 +4083,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "b900c08c1939860ce8b54dc6a89e26e00c04c380fd0e09796799bd7f12861e05"
 "checksum git2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7339329bfa14a00223244311560d11f8f489b453fb90092af97f267a6090ab0"
 "checksum git2-curl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d58551e903ed7e2d6fe3a2f3c7efa3a784ec29b19d0fbb035aaf0497c183fbdd"
-"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
+"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
 "checksum globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4743617a7464bbda3c8aec8558ff2f9429047e025771037df561d383337ff865"
 "checksum handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d89ec99d1594f285d4590fc32bac5f75cdab383f1123d504d27862c644a807dd"
 "checksum handlebars 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d82e5750d8027a97b9640e3fefa66bbaf852a35228e1c90790efd13c4b09c166"
diff --git a/RELEASES.md b/RELEASES.md
index 4cda02c5c2e..a49e072e9ea 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -110,8 +110,11 @@ Compatibility Notes
   methods instead.
 - The `Error::cause` method has been deprecated in favor of `Error::source` which supports
   downcasting.
+- [Libtest no longer creates a new thread for each test when
+  `--test-threads=1`.  It also runs the tests in deterministic order][56243]
 
 [55982]: https://github.com/rust-lang/rust/pull/55982/
+[56243]: https://github.com/rust-lang/rust/pull/56243
 [56303]: https://github.com/rust-lang/rust/pull/56303/
 [56351]: https://github.com/rust-lang/rust/pull/56351/
 [56362]: https://github.com/rust-lang/rust/pull/56362
diff --git a/appveyor.yml b/appveyor.yml
index d70ad54b1c8..2abf723de49 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,7 @@
 environment:
+  # This is required for at least an AArch64 compiler in one image, and is also
+  # going to soon be required for compiling LLVM.
+  APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 Preview
 
   # By default schannel checks revocation of certificates unlike some other SSL
   # backends, but we've historically had problems on CI where a revocation
@@ -81,7 +84,6 @@ environment:
     DIST_REQUIRE_ALL_TOOLS: 1
     DEPLOY: 1
     CI_JOB_NAME: dist-x86_64-msvc
-    APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 Preview
   - RUST_CONFIGURE_ARGS: >
       --build=i686-pc-windows-msvc
       --target=i586-pc-windows-msvc
diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs
index 36beec3a944..085f243785c 100644
--- a/src/bootstrap/bin/rustdoc.rs
+++ b/src/bootstrap/bin/rustdoc.rs
@@ -35,7 +35,7 @@ fn main() {
         .arg("--cfg")
         .arg("dox")
         .arg("--sysroot")
-        .arg(sysroot)
+        .arg(&sysroot)
         .env(bootstrap::util::dylib_path_var(),
              env::join_paths(&dylib_path).unwrap());
 
@@ -72,7 +72,13 @@ fn main() {
     }
 
     if verbose > 1 {
-        eprintln!("rustdoc command: {:?}", cmd);
+        eprintln!(
+            "rustdoc command: {:?}={:?} {:?}",
+            bootstrap::util::dylib_path_var(),
+            env::join_paths(&dylib_path).unwrap(),
+            cmd,
+        );
+        eprintln!("sysroot: {:?}", sysroot);
         eprintln!("libdir: {:?}", libdir);
     }
 
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 1a36cb45d26..fd5038ccb95 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -374,6 +374,7 @@ impl<'a> Builder<'a> {
                 test::MirOpt,
                 test::Codegen,
                 test::CodegenUnits,
+                test::Assembly,
                 test::Incremental,
                 test::Debuginfo,
                 test::UiFullDeps,
@@ -408,12 +409,11 @@ impl<'a> Builder<'a> {
                 test::RustdocJSStd,
                 test::RustdocJSNotStd,
                 test::RustdocTheme,
+                test::RustdocUi,
                 // Run bootstrap close to the end as it's unlikely to fail
                 test::Bootstrap,
                 // Run run-make last, since these won't pass without make on Windows
                 test::RunMake,
-                test::RustdocUi,
-                test::Assembly,
             ),
             Kind::Bench => describe!(test::Crate, test::CrateLibrustc),
             Kind::Doc => describe!(
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 9317a40545e..976b30a55c9 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -241,6 +241,8 @@ pub struct Build {
     clippy_info: channel::GitInfo,
     miri_info: channel::GitInfo,
     rustfmt_info: channel::GitInfo,
+    in_tree_llvm_info: channel::GitInfo,
+    emscripten_llvm_info: channel::GitInfo,
     local_rebuild: bool,
     fail_fast: bool,
     doc_tests: DocTests,
@@ -363,6 +365,8 @@ impl Build {
         let clippy_info = channel::GitInfo::new(&config, &src.join("src/tools/clippy"));
         let miri_info = channel::GitInfo::new(&config, &src.join("src/tools/miri"));
         let rustfmt_info = channel::GitInfo::new(&config, &src.join("src/tools/rustfmt"));
+        let in_tree_llvm_info = channel::GitInfo::new(&config, &src.join("src/llvm-project"));
+        let emscripten_llvm_info = channel::GitInfo::new(&config, &src.join("src/llvm-emscripten"));
 
         let mut build = Build {
             initial_rustc: config.initial_rustc.clone(),
@@ -386,6 +390,8 @@ impl Build {
             clippy_info,
             miri_info,
             rustfmt_info,
+            in_tree_llvm_info,
+            emscripten_llvm_info,
             cc: HashMap::new(),
             cxx: HashMap::new(),
             ar: HashMap::new(),
diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in
index 1c27cf3909b..07be27c2f5a 100644
--- a/src/bootstrap/mk/Makefile.in
+++ b/src/bootstrap/mk/Makefile.in
@@ -48,7 +48,6 @@ check:
 	$(Q)$(BOOTSTRAP) test $(BOOTSTRAP_ARGS)
 check-aux:
 	$(Q)$(BOOTSTRAP) test \
-		src/test/pretty \
 		src/test/run-pass/pretty \
 		src/test/run-fail/pretty \
 		src/test/run-pass-valgrind/pretty \
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index d78670cfe51..3babbc9e102 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -18,6 +18,7 @@ use build_helper::output;
 use cmake;
 use cc;
 
+use crate::channel;
 use crate::util::{self, exe};
 use build_helper::up_to_date;
 use crate::builder::{Builder, RunConfig, ShouldRun, Step};
@@ -231,7 +232,26 @@ impl Step for Llvm {
         }
 
         if let Some(ref suffix) = builder.config.llvm_version_suffix {
-            cfg.define("LLVM_VERSION_SUFFIX", suffix);
+            // Allow version-suffix="" to not define a version suffix at all.
+            if !suffix.is_empty() {
+                cfg.define("LLVM_VERSION_SUFFIX", suffix);
+            }
+        } else {
+            let mut default_suffix = format!(
+                "-rust-{}-{}",
+                channel::CFG_RELEASE_NUM,
+                builder.config.channel,
+            );
+            let llvm_info = if self.emscripten {
+                &builder.emscripten_llvm_info
+            } else {
+                &builder.in_tree_llvm_info
+            };
+            if let Some(sha) = llvm_info.sha_short() {
+                default_suffix.push_str("-");
+                default_suffix.push_str(sha);
+            }
+            cfg.define("LLVM_VERSION_SUFFIX", default_suffix);
         }
 
         if let Some(ref linker) = builder.config.llvm_use_linker {
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index cb66eb238b3..b348ed980f4 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -897,12 +897,10 @@ host_test!(Rustdoc {
     suite: "rustdoc"
 });
 
-test!(Pretty {
+host_test!(Pretty {
     path: "src/test/pretty",
     mode: "pretty",
-    suite: "pretty",
-    default: false,
-    host: true
+    suite: "pretty"
 });
 test!(RunPassPretty {
     path: "src/test/run-pass/pretty",
@@ -999,11 +997,7 @@ impl Step for Compiletest {
             });
         }
 
-        if suite.ends_with("fulldeps") ||
-            // FIXME: Does pretty need librustc compiled? Note that there are
-            // fulldeps test suites with mode = pretty as well.
-            mode == "pretty"
-        {
+        if suite.ends_with("fulldeps") {
             builder.ensure(compile::Rustc { compiler, target });
         }
 
diff --git a/src/ci/docker/dist-x86_64-musl/Dockerfile b/src/ci/docker/dist-x86_64-musl/Dockerfile
index 06f8a2fbba8..560df2f3a57 100644
--- a/src/ci/docker/dist-x86_64-musl/Dockerfile
+++ b/src/ci/docker/dist-x86_64-musl/Dockerfile
@@ -4,6 +4,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   g++ \
   make \
   file \
+  wget \
   curl \
   ca-certificates \
   python2.7 \
@@ -18,19 +19,17 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
 
 WORKDIR /build/
 
-COPY scripts/musl.sh /build/
+COPY scripts/musl-toolchain.sh /build/
 # We need to mitigate rust-lang/rust#34978 when compiling musl itself as well
-RUN CC=gcc \
-    CFLAGS="-Wa,-mrelax-relocations=no" \
-    CXX=g++ \
+RUN CFLAGS="-Wa,-mrelax-relocations=no" \
     CXXFLAGS="-Wa,-mrelax-relocations=no" \
-    bash musl.sh x86_64 && rm -rf /build
+    bash musl-toolchain.sh x86_64 && rm -rf build
 
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
 ENV RUST_CONFIGURE_ARGS \
-      --musl-root-x86_64=/musl-x86_64 \
+      --musl-root-x86_64=/usr/local/x86_64-linux-musl \
       --enable-extended \
       --disable-docs
 
@@ -41,6 +40,12 @@ ENV RUST_CONFIGURE_ARGS \
 # See: https://github.com/rust-lang/rust/issues/34978
 ENV CFLAGS_x86_64_unknown_linux_musl=-Wa,-mrelax-relocations=no
 
-ENV SCRIPT \
-      python2.7 ../x.py test --target x86_64-unknown-linux-musl && \
-      python2.7 ../x.py dist --target x86_64-unknown-linux-musl
+ENV HOSTS=x86_64-unknown-linux-musl \
+    CC_x86_64_unknown_linux_musl=x86_64-linux-musl-gcc \
+    CXX_x86_64_unknown_linux_musl=x86_64-linux-musl-g++
+
+# Musl defaults to static libs but we need them to be dynamic for host toolchain.
+# The toolchain will produce static libs by default.
+ENV RUSTFLAGS="-C target-feature=-crt-static"
+
+ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh
new file mode 100644
index 00000000000..95b7c2869c9
--- /dev/null
+++ b/src/ci/docker/scripts/musl-toolchain.sh
@@ -0,0 +1,70 @@
+# This script runs `musl-cross-make` to prepare C toolchain (Binutils, GCC, musl itself)
+# and builds static libunwind that we distribute for static target.
+#
+# Versions of the toolchain components are configurable in `musl-cross-make/Makefile` and
+# musl unlike GLIBC is forward compatible so upgrading it shouldn't break old distributions.
+# Right now we have: Binutils 2.27, GCC 6.3.0, musl 1.1.18
+set -ex
+
+hide_output() {
+  set +x
+  on_err="
+echo ERROR: An error was encountered with the build.
+cat /tmp/build.log
+exit 1
+"
+  trap "$on_err" ERR
+  bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
+  PING_LOOP_PID=$!
+  $@ &> /tmp/build.log
+  trap - ERR
+  kill $PING_LOOP_PID
+  rm /tmp/build.log
+  set -x
+}
+
+ARCH=$1
+TARGET=$ARCH-linux-musl
+
+OUTPUT=/usr/local
+shift
+
+git clone https://github.com/richfelker/musl-cross-make -b v0.9.7
+cd musl-cross-make
+
+hide_output make -j$(nproc) TARGET=$TARGET
+hide_output make install TARGET=$TARGET OUTPUT=$OUTPUT
+
+cd -
+
+# Install musl library to make binaries executable
+ln -s $OUTPUT/$TARGET/lib/libc.so /lib/ld-musl-$ARCH.so.1
+echo $OUTPUT/$TARGET/lib >> /etc/ld-musl-$ARCH.path
+
+
+export CC=$TARGET-gcc
+export CXX=$TARGET-g++
+
+LLVM=70
+
+# may have been downloaded in a previous run
+if [ ! -d libunwind-release_$LLVM ]; then
+  curl -L https://github.com/llvm-mirror/llvm/archive/release_$LLVM.tar.gz | tar xzf -
+  curl -L https://github.com/llvm-mirror/libunwind/archive/release_$LLVM.tar.gz | tar xzf -
+fi
+
+# fixme(mati865): Replace it with https://github.com/rust-lang/rust/pull/59089
+mkdir libunwind-build
+cd libunwind-build
+cmake ../libunwind-release_$LLVM \
+          -DLLVM_PATH=/build/llvm-release_$LLVM \
+          -DLIBUNWIND_ENABLE_SHARED=0 \
+          -DCMAKE_C_COMPILER=$CC \
+          -DCMAKE_CXX_COMPILER=$CXX \
+          -DCMAKE_C_FLAGS="$CFLAGS" \
+          -DCMAKE_CXX_FLAGS="$CXXFLAGS"
+
+hide_output make -j$(nproc)
+cp lib/libunwind.a $OUTPUT/$TARGET/lib
+cd - && rm -rf libunwind-build
+
diff --git a/src/ci/docker/test-various/Dockerfile b/src/ci/docker/test-various/Dockerfile
index 7891e9f625a..611a24a69bd 100644
--- a/src/ci/docker/test-various/Dockerfile
+++ b/src/ci/docker/test-various/Dockerfile
@@ -11,7 +11,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   cmake \
   sudo \
   gdb \
-  xz-utils
+  xz-utils \
+  wget \
+  patch
 
 # FIXME: build the `ptx-linker` instead.
 RUN curl -sL https://github.com/denzp/rust-ptx-linker/releases/download/v0.9.0-alpha.2/rust-ptx-linker.linux64.tar.gz | \
@@ -20,10 +22,16 @@ RUN curl -sL https://github.com/denzp/rust-ptx-linker/releases/download/v0.9.0-a
 RUN curl -sL https://nodejs.org/dist/v9.2.0/node-v9.2.0-linux-x64.tar.xz | \
   tar -xJ
 
+WORKDIR /build/
+COPY scripts/musl-toolchain.sh /build/
+RUN bash musl-toolchain.sh x86_64 && rm -rf build
+WORKDIR /
+
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
 ENV RUST_CONFIGURE_ARGS \
+  --musl-root-x86_64=/usr/local/x86_64-linux-musl \
   --set build.nodejs=/node-v9.2.0-linux-x64/bin/node \
   --set rust.lld
 
@@ -48,4 +56,9 @@ ENV NVPTX_SCRIPT python2.7 /checkout/x.py test --target $NVPTX_TARGETS \
   src/test/run-make \
   src/test/assembly
 
-ENV SCRIPT $WASM_SCRIPT && $NVPTX_SCRIPT
+ENV MUSL_TARGETS=x86_64-unknown-linux-musl \
+    CC_x86_64_unknown_linux_musl=x86_64-linux-musl-gcc \
+    CXX_x86_64_unknown_linux_musl=x86_64-linux-musl-g++
+ENV MUSL_SCRIPT python2.7 /checkout/x.py test --target $MUSL_TARGETS
+
+ENV SCRIPT $WASM_SCRIPT && $NVPTX_SCRIPT && $MUSL_SCRIPT
diff --git a/src/liballoc/prelude.rs b/src/liballoc/prelude.rs
deleted file mode 100644
index 6767cf89f73..00000000000
--- a/src/liballoc/prelude.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-//! The alloc Prelude
-//!
-//! The purpose of this module is to alleviate imports of commonly-used
-//! items of the `alloc` crate by adding a glob import to the top of modules:
-//!
-//! ```
-//! # #![allow(unused_imports)]
-//! # #![feature(alloc)]
-//! extern crate alloc;
-//! use alloc::prelude::*;
-//! ```
-
-#![unstable(feature = "alloc", issue = "27783")]
-
-#[unstable(feature = "alloc", issue = "27783")] pub use crate::borrow::ToOwned;
-#[unstable(feature = "alloc", issue = "27783")] pub use crate::boxed::Box;
-#[unstable(feature = "alloc", issue = "27783")] pub use crate::slice::SliceConcatExt;
-#[unstable(feature = "alloc", issue = "27783")] pub use crate::string::{String, ToString};
-#[unstable(feature = "alloc", issue = "27783")] pub use crate::vec::Vec;
diff --git a/src/liballoc/prelude/mod.rs b/src/liballoc/prelude/mod.rs
new file mode 100644
index 00000000000..33cc51d1732
--- /dev/null
+++ b/src/liballoc/prelude/mod.rs
@@ -0,0 +1,16 @@
+//! The alloc Prelude
+//!
+//! The purpose of this module is to alleviate imports of commonly-used
+//! items of the `alloc` crate by adding a glob import to the top of modules:
+//!
+//! ```
+//! # #![allow(unused_imports)]
+//! # #![feature(alloc)]
+//! #![feature(alloc_prelude)]
+//! extern crate alloc;
+//! use alloc::prelude::v1::*;
+//! ```
+
+#![unstable(feature = "alloc_prelude", issue = "58935")]
+
+pub mod v1;
diff --git a/src/liballoc/prelude/v1.rs b/src/liballoc/prelude/v1.rs
new file mode 100644
index 00000000000..b6b01395ad6
--- /dev/null
+++ b/src/liballoc/prelude/v1.rs
@@ -0,0 +1,11 @@
+//! The first version of the prelude of `alloc` crate.
+//!
+//! See the [module-level documentation](../index.html) for more.
+
+#![unstable(feature = "alloc_prelude", issue = "58935")]
+
+#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::borrow::ToOwned;
+#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::boxed::Box;
+#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::slice::SliceConcatExt;
+#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::string::{String, ToString};
+#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::vec::Vec;
diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs
index 1d4a3edc1ac..0930f8dacd4 100644
--- a/src/liballoc/tests/binary_heap.rs
+++ b/src/liballoc/tests/binary_heap.rs
@@ -282,7 +282,7 @@ fn assert_covariance() {
 //
 // Destructors must be called exactly once per element.
 #[test]
-#[cfg(not(miri))] // Miri does not support panics
+#[cfg(not(miri))] // Miri does not support panics nor entropy
 fn panic_safe() {
     static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
 
diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs
index f14750089c9..844afe87076 100644
--- a/src/liballoc/tests/btree/map.rs
+++ b/src/liballoc/tests/btree/map.rs
@@ -226,7 +226,6 @@ fn test_range_equal_empty_cases() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_range_equal_excluded() {
     let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
     map.range((Excluded(2), Excluded(2)));
@@ -234,7 +233,6 @@ fn test_range_equal_excluded() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_range_backwards_1() {
     let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
     map.range((Included(3), Included(2)));
@@ -242,7 +240,6 @@ fn test_range_backwards_1() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_range_backwards_2() {
     let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
     map.range((Included(3), Excluded(2)));
@@ -250,7 +247,6 @@ fn test_range_backwards_2() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_range_backwards_3() {
     let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
     map.range((Excluded(3), Included(2)));
@@ -258,7 +254,6 @@ fn test_range_backwards_3() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_range_backwards_4() {
     let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
     map.range((Excluded(3), Excluded(2)));
diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs
index feba46b0fad..b54c128a024 100644
--- a/src/liballoc/tests/slice.rs
+++ b/src/liballoc/tests/slice.rs
@@ -258,7 +258,6 @@ fn test_swap_remove() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_swap_remove_fail() {
     let mut v = vec![1];
     let _ = v.swap_remove(0);
@@ -632,7 +631,6 @@ fn test_insert() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_insert_oob() {
     let mut a = vec![1, 2, 3];
     a.insert(4, 5);
@@ -657,7 +655,6 @@ fn test_remove() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_remove_fail() {
     let mut a = vec![1];
     let _ = a.remove(0);
@@ -939,7 +936,6 @@ fn test_windowsator() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_windowsator_0() {
     let v = &[1, 2, 3, 4];
     let _it = v.windows(0);
@@ -964,7 +960,6 @@ fn test_chunksator() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_chunksator_0() {
     let v = &[1, 2, 3, 4];
     let _it = v.chunks(0);
@@ -989,7 +984,6 @@ fn test_chunks_exactator() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_chunks_exactator_0() {
     let v = &[1, 2, 3, 4];
     let _it = v.chunks_exact(0);
@@ -1014,7 +1008,6 @@ fn test_rchunksator() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_rchunksator_0() {
     let v = &[1, 2, 3, 4];
     let _it = v.rchunks(0);
@@ -1039,7 +1032,6 @@ fn test_rchunks_exactator() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_rchunks_exactator_0() {
     let v = &[1, 2, 3, 4];
     let _it = v.rchunks_exact(0);
@@ -1092,7 +1084,6 @@ fn test_vec_default() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_overflow_does_not_cause_segfault() {
     let mut v = vec![];
     v.reserve_exact(!0);
@@ -1102,7 +1093,6 @@ fn test_overflow_does_not_cause_segfault() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_overflow_does_not_cause_segfault_managed() {
     let mut v = vec![Rc::new(1)];
     v.reserve_exact(!0);
@@ -1278,7 +1268,6 @@ fn test_mut_chunks_rev() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_mut_chunks_0() {
     let mut v = [1, 2, 3, 4];
     let _it = v.chunks_mut(0);
@@ -1311,7 +1300,6 @@ fn test_mut_chunks_exact_rev() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_mut_chunks_exact_0() {
     let mut v = [1, 2, 3, 4];
     let _it = v.chunks_exact_mut(0);
@@ -1344,7 +1332,6 @@ fn test_mut_rchunks_rev() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_mut_rchunks_0() {
     let mut v = [1, 2, 3, 4];
     let _it = v.rchunks_mut(0);
@@ -1377,7 +1364,6 @@ fn test_mut_rchunks_exact_rev() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_mut_rchunks_exact_0() {
     let mut v = [1, 2, 3, 4];
     let _it = v.rchunks_exact_mut(0);
@@ -1411,7 +1397,7 @@ fn test_box_slice_clone() {
 #[test]
 #[allow(unused_must_use)] // here, we care about the side effects of `.clone()`
 #[cfg_attr(target_os = "emscripten", ignore)]
-#[cfg(not(miri))] // Miri does not support panics
+#[cfg(not(miri))] // Miri does not support threads nor entropy
 fn test_box_slice_clone_panics() {
     use std::sync::Arc;
     use std::sync::atomic::{AtomicUsize, Ordering};
@@ -1476,7 +1462,6 @@ fn test_copy_from_slice() {
 
 #[test]
 #[should_panic(expected = "destination and source slices have different lengths")]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_copy_from_slice_dst_longer() {
     let src = [0, 1, 2, 3];
     let mut dst = [0; 5];
@@ -1485,7 +1470,6 @@ fn test_copy_from_slice_dst_longer() {
 
 #[test]
 #[should_panic(expected = "destination and source slices have different lengths")]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_copy_from_slice_dst_shorter() {
     let src = [0, 1, 2, 3];
     let mut dst = [0; 3];
@@ -1605,7 +1589,7 @@ thread_local!(static SILENCE_PANIC: Cell<bool> = Cell::new(false));
 
 #[test]
 #[cfg_attr(target_os = "emscripten", ignore)] // no threads
-#[cfg(not(miri))] // Miri does not support panics
+#[cfg(not(miri))] // Miri does not support threads nor entropy
 fn panic_safe() {
     let prev = panic::take_hook();
     panic::set_hook(Box::new(move |info| {
diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs
index b33a5642188..b197516403f 100644
--- a/src/liballoc/tests/str.rs
+++ b/src/liballoc/tests/str.rs
@@ -7,7 +7,7 @@ fn test_le() {
     assert!("" <= "");
     assert!("" <= "foo");
     assert!("foo" <= "foo");
-    assert!("foo" != "bar");
+    assert_ne!("foo", "bar");
 }
 
 #[test]
@@ -351,7 +351,6 @@ mod slice_index {
     //  to be used in `should_panic`)
     #[test]
     #[should_panic(expected = "out of bounds")]
-    #[cfg(not(miri))] // Miri does not support panics
     fn assert_range_eq_can_fail_by_panic() {
         assert_range_eq!("abc", 0..5, "abc");
     }
@@ -361,7 +360,6 @@ mod slice_index {
     //  to be used in `should_panic`)
     #[test]
     #[should_panic(expected = "==")]
-    #[cfg(not(miri))] // Miri does not support panics
     fn assert_range_eq_can_fail_by_inequality() {
         assert_range_eq!("abc", 0..2, "abc");
     }
@@ -409,7 +407,6 @@ mod slice_index {
 
                 #[test]
                 #[should_panic(expected = $expect_msg)]
-                #[cfg(not(miri))] // Miri does not support panics
                 fn index_fail() {
                     let v: String = $data.into();
                     let v: &str = &v;
@@ -418,7 +415,6 @@ mod slice_index {
 
                 #[test]
                 #[should_panic(expected = $expect_msg)]
-                #[cfg(not(miri))] // Miri does not support panics
                 fn index_mut_fail() {
                     let mut v: String = $data.into();
                     let v: &mut str = &mut v;
@@ -514,7 +510,6 @@ mod slice_index {
 
     #[test]
     #[should_panic]
-    #[cfg(not(miri))] // Miri does not support panics
     fn test_slice_fail() {
         &"中华Việt Nam"[0..2];
     }
@@ -666,14 +661,12 @@ mod slice_index {
     // check the panic includes the prefix of the sliced string
     #[test]
     #[should_panic(expected="byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")]
-    #[cfg(not(miri))] // Miri does not support panics
     fn test_slice_fail_truncated_1() {
         &LOREM_PARAGRAPH[..1024];
     }
     // check the truncation in the panic message
     #[test]
     #[should_panic(expected="luctus, im`[...]")]
-    #[cfg(not(miri))] // Miri does not support panics
     fn test_slice_fail_truncated_2() {
         &LOREM_PARAGRAPH[..1024];
     }
@@ -688,7 +681,6 @@ fn test_str_slice_rangetoinclusive_ok() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_str_slice_rangetoinclusive_notok() {
     let s = "abcαβγ";
     &s[..=3];
@@ -704,7 +696,6 @@ fn test_str_slicemut_rangetoinclusive_ok() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_str_slicemut_rangetoinclusive_notok() {
     let mut s = "abcαβγ".to_owned();
     let s: &mut str = &mut s;
@@ -894,7 +885,6 @@ fn test_as_bytes() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_as_bytes_fail() {
     // Don't double free. (I'm not sure if this exercises the
     // original problem code path anymore.)
@@ -984,7 +974,6 @@ fn test_split_at_mut() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_split_at_boundscheck() {
     let s = "ศไทย中华Việt Nam";
     s.split_at(1);
diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs
index 7e93d84fe3b..7e75b8c4f28 100644
--- a/src/liballoc/tests/string.rs
+++ b/src/liballoc/tests/string.rs
@@ -231,7 +231,6 @@ fn test_split_off_empty() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_split_off_past_end() {
     let orig = "Hello, world!";
     let mut split = String::from(orig);
@@ -240,7 +239,6 @@ fn test_split_off_past_end() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_split_off_mid_char() {
     let mut orig = String::from("山");
     orig.split_off(1);
@@ -289,7 +287,6 @@ fn test_str_truncate_invalid_len() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_str_truncate_split_codepoint() {
     let mut s = String::from("\u{FC}"); // ü
     s.truncate(1);
@@ -324,7 +321,6 @@ fn remove() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn remove_bad() {
     "ศ".to_string().remove(1);
 }
@@ -360,13 +356,11 @@ fn insert() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn insert_bad1() {
     "".to_string().insert(1, 't');
 }
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn insert_bad2() {
     "ệ".to_string().insert(1, 't');
 }
@@ -447,7 +441,6 @@ fn test_replace_range() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_replace_range_char_boundary() {
     let mut s = "Hello, 世界!".to_owned();
     s.replace_range(..8, "");
@@ -464,7 +457,6 @@ fn test_replace_range_inclusive_range() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_replace_range_out_of_bounds() {
     let mut s = String::from("12345");
     s.replace_range(5..6, "789");
@@ -472,7 +464,6 @@ fn test_replace_range_out_of_bounds() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_replace_range_inclusive_out_of_bounds() {
     let mut s = String::from("12345");
     s.replace_range(5..=5, "789");
diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs
index 6e4ca1d90e6..545332bcd6a 100644
--- a/src/liballoc/tests/vec.rs
+++ b/src/liballoc/tests/vec.rs
@@ -368,7 +368,6 @@ fn test_vec_truncate_drop() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_vec_truncate_fail() {
     struct BadElem(i32);
     impl Drop for BadElem {
@@ -392,7 +391,6 @@ fn test_index() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_index_out_of_bounds() {
     let vec = vec![1, 2, 3];
     let _ = vec[3];
@@ -400,7 +398,6 @@ fn test_index_out_of_bounds() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_slice_out_of_bounds_1() {
     let x = vec![1, 2, 3, 4, 5];
     &x[!0..];
@@ -408,7 +405,6 @@ fn test_slice_out_of_bounds_1() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_slice_out_of_bounds_2() {
     let x = vec![1, 2, 3, 4, 5];
     &x[..6];
@@ -416,7 +412,6 @@ fn test_slice_out_of_bounds_2() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_slice_out_of_bounds_3() {
     let x = vec![1, 2, 3, 4, 5];
     &x[!0..4];
@@ -424,7 +419,6 @@ fn test_slice_out_of_bounds_3() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_slice_out_of_bounds_4() {
     let x = vec![1, 2, 3, 4, 5];
     &x[1..6];
@@ -432,7 +426,6 @@ fn test_slice_out_of_bounds_4() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_slice_out_of_bounds_5() {
     let x = vec![1, 2, 3, 4, 5];
     &x[3..2];
@@ -440,7 +433,6 @@ fn test_slice_out_of_bounds_5() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_swap_remove_empty() {
     let mut vec = Vec::<i32>::new();
     vec.swap_remove(0);
@@ -511,7 +503,6 @@ fn test_drain_items_zero_sized() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_drain_out_of_bounds() {
     let mut v = vec![1, 2, 3, 4, 5];
     v.drain(5..6);
@@ -585,7 +576,6 @@ fn test_drain_max_vec_size() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_drain_inclusive_out_of_bounds() {
     let mut v = vec![1, 2, 3, 4, 5];
     v.drain(5..=5);
@@ -615,7 +605,6 @@ fn test_splice_inclusive_range() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_splice_out_of_bounds() {
     let mut v = vec![1, 2, 3, 4, 5];
     let a = [10, 11, 12];
@@ -624,7 +613,6 @@ fn test_splice_out_of_bounds() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_splice_inclusive_out_of_bounds() {
     let mut v = vec![1, 2, 3, 4, 5];
     let a = [10, 11, 12];
diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs
index 16ddc1444fc..e0fe10a55f5 100644
--- a/src/liballoc/tests/vec_deque.rs
+++ b/src/liballoc/tests/vec_deque.rs
@@ -108,7 +108,6 @@ fn test_index() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_index_out_of_bounds() {
     let mut deq = VecDeque::new();
     for i in 1..4 {
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 94bed370836..7de94d25c76 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -567,6 +567,32 @@ pub trait Ord: Eq + PartialOrd<Self> {
     where Self: Sized {
         if self <= other { self } else { other }
     }
+
+    /// Returns max if self is greater than max, and min if self is less than min.
+    /// Otherwise this will return self.  Panics if min > max.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(clamp)]
+    ///
+    /// assert!((-3).clamp(-2, 1) == -2);
+    /// assert!(0.clamp(-2, 1) == 0);
+    /// assert!(2.clamp(-2, 1) == 1);
+    /// ```
+    #[unstable(feature = "clamp", issue = "44095")]
+    fn clamp(self, min: Self, max: Self) -> Self
+    where Self: Sized {
+        assert!(min <= max);
+        if self < min {
+            min
+        }
+        else if self > max {
+            max
+        } else {
+            self
+        }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs
index d88793f2801..5cc9c25c21e 100644
--- a/src/libcore/ffi.rs
+++ b/src/libcore/ffi.rs
@@ -79,9 +79,9 @@ impl fmt::Debug for VaListImpl {
                      all supported platforms",
            issue = "44930")]
 struct VaListImpl {
-    stack: *mut (),
-    gr_top: *mut (),
-    vr_top: *mut (),
+    stack: *mut c_void,
+    gr_top: *mut c_void,
+    vr_top: *mut c_void,
     gr_offs: i32,
     vr_offs: i32,
 }
@@ -98,8 +98,8 @@ struct VaListImpl {
     gpr: u8,
     fpr: u8,
     reserved: u16,
-    overflow_arg_area: *mut (),
-    reg_save_area: *mut (),
+    overflow_arg_area: *mut c_void,
+    reg_save_area: *mut c_void,
 }
 
 /// x86_64 ABI implementation of a `va_list`.
@@ -113,8 +113,8 @@ struct VaListImpl {
 struct VaListImpl {
     gp_offset: i32,
     fp_offset: i32,
-    overflow_arg_area: *mut (),
-    reg_save_area: *mut (),
+    overflow_arg_area: *mut c_void,
+    reg_save_area: *mut c_void,
 }
 
 /// A wrapper for a `va_list`
diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs
index d4ad22c16bb..cccd51b5779 100644
--- a/src/libcore/iter/adapters/mod.rs
+++ b/src/libcore/iter/adapters/mod.rs
@@ -1198,7 +1198,7 @@ impl<I: Iterator> Peekable<I> {
     }
 }
 
-/// An iterator that rejects elements while `predicate` is true.
+/// An iterator that rejects elements while `predicate` returns `true`.
 ///
 /// This `struct` is created by the [`skip_while`] method on [`Iterator`]. See its
 /// documentation for more.
@@ -1286,7 +1286,7 @@ impl<I: Iterator, P> Iterator for SkipWhile<I, P>
 impl<I, P> FusedIterator for SkipWhile<I, P>
     where I: FusedIterator, P: FnMut(&I::Item) -> bool {}
 
-/// An iterator that only accepts elements while `predicate` is true.
+/// An iterator that only accepts elements while `predicate` returns `true`.
 ///
 /// This `struct` is created by the [`take_while`] method on [`Iterator`]. See its
 /// documentation for more.
diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs
index 74ff7f41d76..ffc24df3ed4 100644
--- a/src/libcore/iter/sources.rs
+++ b/src/libcore/iter/sources.rs
@@ -39,8 +39,7 @@ unsafe impl<A: Clone> TrustedLen for Repeat<A> {}
 
 /// Creates a new iterator that endlessly repeats a single element.
 ///
-/// The `repeat()` function repeats a single value over and over and over and
-/// over and over and 🔁.
+/// The `repeat()` function repeats a single value over and over again.
 ///
 /// Infinite iterators like `repeat()` are often used with adapters like
 /// [`take`], in order to make them finite.
@@ -128,8 +127,7 @@ unsafe impl<A, F: FnMut() -> A> TrustedLen for RepeatWith<F> {}
 /// Creates a new iterator that repeats elements of type `A` endlessly by
 /// applying the provided closure, the repeater, `F: FnMut() -> A`.
 ///
-/// The `repeat_with()` function calls the repeater over and over and over and
-/// over and over and 🔁.
+/// The `repeat_with()` function calls the repeater over and over again.
 ///
 /// Infinite iterators like `repeat_with()` are often used with adapters like
 /// [`take`], in order to make them finite.
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs
index 90e84d0b28c..3d2fcdc9793 100644
--- a/src/libcore/mem.rs
+++ b/src/libcore/mem.rs
@@ -1111,11 +1111,12 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
 /// ```
 ///
 /// The compiler then knows to not make any incorrect assumptions or optimizations on this code.
+//
 // FIXME before stabilizing, explain how to initialize a struct field-by-field.
 #[allow(missing_debug_implementations)]
 #[unstable(feature = "maybe_uninit", issue = "53491")]
 #[derive(Copy)]
-// NOTE after stabilizing `MaybeUninit` proceed to deprecate `mem::uninitialized`.
+// NOTE: after stabilizing `MaybeUninit`, proceed to deprecate `mem::uninitialized`.
 pub union MaybeUninit<T> {
     uninit: (),
     value: ManuallyDrop<T>,
@@ -1125,13 +1126,13 @@ pub union MaybeUninit<T> {
 impl<T: Copy> Clone for MaybeUninit<T> {
     #[inline(always)]
     fn clone(&self) -> Self {
-        // Not calling T::clone(), we cannot know if we are initialized enough for that.
+        // Not calling `T::clone()`, we cannot know if we are initialized enough for that.
         *self
     }
 }
 
 impl<T> MaybeUninit<T> {
-    /// Create a new `MaybeUninit<T>` initialized with the given value.
+    /// Creates a new `MaybeUninit<T>` initialized with the given value.
     ///
     /// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
     /// It is your responsibility to make sure `T` gets dropped if it got initialized.
@@ -1239,6 +1240,7 @@ impl<T> MaybeUninit<T> {
     /// let x_vec = unsafe { &*x.as_ptr() };
     /// // We have created a reference to an uninitialized vector! This is undefined behavior.
     /// ```
+    ///
     /// (Notice that the rules around references to uninitialized data are not finalized yet, but
     /// until they are, it is advisable to avoid them.)
     #[unstable(feature = "maybe_uninit", issue = "53491")]
@@ -1277,6 +1279,7 @@ impl<T> MaybeUninit<T> {
     /// let x_vec = unsafe { &mut *x.as_mut_ptr() };
     /// // We have created a reference to an uninitialized vector! This is undefined behavior.
     /// ```
+    ///
     /// (Notice that the rules around references to uninitialized data are not finalized yet, but
     /// until they are, it is advisable to avoid them.)
     #[unstable(feature = "maybe_uninit", issue = "53491")]
diff --git a/src/libcore/num/dec2flt/algorithm.rs b/src/libcore/num/dec2flt/algorithm.rs
index 3b57bb7544b..a83134a6b2c 100644
--- a/src/libcore/num/dec2flt/algorithm.rs
+++ b/src/libcore/num/dec2flt/algorithm.rs
@@ -326,7 +326,7 @@ pub fn algorithm_m<T: RawFloat>(f: &Big, e: i16) -> T {
     round_by_remainder(v, rem, q, z)
 }
 
-/// Skip over most Algorithm M iterations by checking the bit length.
+/// Skips over most Algorithm M iterations by checking the bit length.
 fn quick_start<T: RawFloat>(u: &mut Big, v: &mut Big, k: &mut i16) {
     // The bit length is an estimate of the base two logarithm, and log(u / v) = log(u) - log(v).
     // The estimate is off by at most 1, but always an under-estimate, so the error on log(u)
diff --git a/src/libcore/num/dec2flt/mod.rs b/src/libcore/num/dec2flt/mod.rs
index 47ea5aa5ff0..d62cdae0688 100644
--- a/src/libcore/num/dec2flt/mod.rs
+++ b/src/libcore/num/dec2flt/mod.rs
@@ -304,8 +304,8 @@ fn simplify(decimal: &mut Decimal) {
     }
 }
 
-/// Quick and dirty upper bound on the size (log10) of the largest value that Algorithm R and
-/// Algorithm M will compute while working on the given decimal.
+/// Returns a quick-an-dirty upper bound on the size (log10) of the largest value that Algorithm R
+/// and Algorithm M will compute while working on the given decimal.
 fn bound_intermediate_digits(decimal: &Decimal, e: i64) -> u64 {
     // We don't need to worry too much about overflow here thanks to trivial_cases() and the
     // parser, which filter out the most extreme inputs for us.
@@ -324,7 +324,7 @@ fn bound_intermediate_digits(decimal: &Decimal, e: i64) -> u64 {
     }
 }
 
-/// Detect obvious overflows and underflows without even looking at the decimal digits.
+/// Detects obvious overflows and underflows without even looking at the decimal digits.
 fn trivial_cases<T: RawFloat>(decimal: &Decimal) -> Option<T> {
     // There were zeros but they were stripped by simplify()
     if decimal.integral.is_empty() && decimal.fractional.is_empty() {
diff --git a/src/libcore/num/dec2flt/parse.rs b/src/libcore/num/dec2flt/parse.rs
index 933f8c1d3f7..f970595452e 100644
--- a/src/libcore/num/dec2flt/parse.rs
+++ b/src/libcore/num/dec2flt/parse.rs
@@ -78,7 +78,7 @@ pub fn parse_decimal(s: &str) -> ParseResult {
     }
 }
 
-/// Carve off decimal digits up to the first non-digit character.
+/// Carves off decimal digits up to the first non-digit character.
 fn eat_digits(s: &[u8]) -> (&[u8], &[u8]) {
     let mut i = 0;
     while i < s.len() && b'0' <= s[i] && s[i] <= b'9' {
diff --git a/src/libcore/num/flt2dec/decoder.rs b/src/libcore/num/flt2dec/decoder.rs
index a3bf783976b..a8da31d3e48 100644
--- a/src/libcore/num/flt2dec/decoder.rs
+++ b/src/libcore/num/flt2dec/decoder.rs
@@ -10,7 +10,7 @@ use num::dec2flt::rawfp::RawFloat;
 ///
 /// - Any number from `(mant - minus) * 2^exp` to `(mant + plus) * 2^exp` will
 ///   round to the original value. The range is inclusive only when
-///   `inclusive` is true.
+///   `inclusive` is `true`.
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct Decoded {
     /// The scaled mantissa.
diff --git a/src/libcore/num/flt2dec/mod.rs b/src/libcore/num/flt2dec/mod.rs
index f9b46a12f7f..defd4247f4e 100644
--- a/src/libcore/num/flt2dec/mod.rs
+++ b/src/libcore/num/flt2dec/mod.rs
@@ -315,15 +315,15 @@ fn digits_to_dec_str<'a>(buf: &'a [u8], exp: i16, frac_digits: usize,
     }
 }
 
-/// Formats given decimal digits `0.<...buf...> * 10^exp` into the exponential form
-/// with at least given number of significant digits. When `upper` is true,
+/// Formats the given decimal digits `0.<...buf...> * 10^exp` into the exponential
+/// form with at least the given number of significant digits. When `upper` is `true`,
 /// the exponent will be prefixed by `E`; otherwise that's `e`. The result is
 /// stored to the supplied parts array and a slice of written parts is returned.
 ///
 /// `min_digits` can be less than the number of actual significant digits in `buf`;
 /// it will be ignored and full digits will be printed. It is only used to print
-/// additional zeroes after rendered digits. Thus `min_digits` of 0 means that
-/// it will only print given digits and nothing else.
+/// additional zeroes after rendered digits. Thus, `min_digits == 0` means that
+/// it will only print the given digits and nothing else.
 fn digits_to_exp_str<'a>(buf: &'a [u8], exp: i16, min_ndigits: usize, upper: bool,
                          parts: &'a mut [Part<'a>]) -> &'a [Part<'a>] {
     assert!(!buf.is_empty());
@@ -384,7 +384,7 @@ fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static
     }
 }
 
-/// Formats given floating point number into the decimal form with at least
+/// Formats the given floating point number into the decimal form with at least
 /// given number of fractional digits. The result is stored to the supplied parts
 /// array while utilizing given byte buffer as a scratch. `upper` is currently
 /// unused but left for the future decision to change the case of non-finite values,
@@ -438,7 +438,7 @@ pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T,
     }
 }
 
-/// Formats given floating point number into the decimal form or
+/// Formats the given floating point number into the decimal form or
 /// the exponential form, depending on the resulting exponent. The result is
 /// stored to the supplied parts array while utilizing given byte buffer
 /// as a scratch. `upper` is used to determine the case of non-finite values
@@ -497,7 +497,7 @@ pub fn to_shortest_exp_str<'a, T, F>(mut format_shortest: F, v: T,
     }
 }
 
-/// Returns rather crude approximation (upper bound) for the maximum buffer size
+/// Returns a rather crude approximation (upper bound) for the maximum buffer size
 /// calculated from the given decoded exponent.
 ///
 /// The exact limit is:
diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs
index 81a8d001dd9..4f71c8e7949 100644
--- a/src/libcore/ops/range.rs
+++ b/src/libcore/ops/range.rs
@@ -71,7 +71,7 @@ impl fmt::Debug for RangeFull {
 /// assert_eq!(arr[1..=3], [  1,2,3  ]);
 /// ```
 #[doc(alias = "..")]
-#[derive(Clone, PartialEq, Eq, Hash)]  // not Copy -- see #27186
+#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Range<Idx> {
     /// The lower bound of the range (inclusive).
@@ -95,8 +95,6 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(range_contains)]
-    ///
     /// use std::f32;
     ///
     /// assert!(!(3..5).contains(&2));
@@ -112,7 +110,7 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
     /// assert!(!(0.0..f32::NAN).contains(&0.5));
     /// assert!(!(f32::NAN..1.0).contains(&0.5));
     /// ```
-    #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
+    #[stable(feature = "range_contains", since = "1.35.0")]
     pub fn contains<U>(&self, item: &U) -> bool
     where
         Idx: PartialOrd<U>,
@@ -175,7 +173,7 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
 ///
 /// [`Iterator`]: ../iter/trait.IntoIterator.html
 #[doc(alias = "..")]
-#[derive(Clone, PartialEq, Eq, Hash)]  // not Copy -- see #27186
+#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RangeFrom<Idx> {
     /// The lower bound of the range (inclusive).
@@ -196,8 +194,6 @@ impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(range_contains)]
-    ///
     /// use std::f32;
     ///
     /// assert!(!(3..).contains(&2));
@@ -208,7 +204,7 @@ impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
     /// assert!(!(0.0..).contains(&f32::NAN));
     /// assert!(!(f32::NAN..).contains(&0.5));
     /// ```
-    #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
+    #[stable(feature = "range_contains", since = "1.35.0")]
     pub fn contains<U>(&self, item: &U) -> bool
     where
         Idx: PartialOrd<U>,
@@ -280,8 +276,6 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(range_contains)]
-    ///
     /// use std::f32;
     ///
     /// assert!( (..5).contains(&-1_000_000_000));
@@ -292,7 +286,7 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
     /// assert!(!(..1.0).contains(&f32::NAN));
     /// assert!(!(..f32::NAN).contains(&0.5));
     /// ```
-    #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
+    #[stable(feature = "range_contains", since = "1.35.0")]
     pub fn contains<U>(&self, item: &U) -> bool
     where
         Idx: PartialOrd<U>,
@@ -329,7 +323,7 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
 /// assert_eq!(arr[1..=3], [  1,2,3  ]);  // RangeInclusive
 /// ```
 #[doc(alias = "..=")]
-#[derive(Clone)]  // not Copy -- see #27186
+#[derive(Clone)] // not Copy -- see #27186
 #[stable(feature = "inclusive_range", since = "1.26.0")]
 pub struct RangeInclusive<Idx> {
     pub(crate) start: Idx,
@@ -365,7 +359,8 @@ impl<T: PartialOrd> RangeInclusiveEquality for T {
 impl<Idx: PartialEq> PartialEq for RangeInclusive<Idx> {
     #[inline]
     fn eq(&self, other: &Self) -> bool {
-        self.start == other.start && self.end == other.end
+        self.start == other.start
+            && self.end == other.end
             && RangeInclusiveEquality::canonicalized_is_empty(self)
                 == RangeInclusiveEquality::canonicalized_is_empty(other)
     }
@@ -397,7 +392,11 @@ impl<Idx> RangeInclusive<Idx> {
     #[inline]
     #[rustc_promotable]
     pub const fn new(start: Idx, end: Idx) -> Self {
-        Self { start, end, is_empty: None }
+        Self {
+            start,
+            end,
+            is_empty: None,
+        }
     }
 
     /// Returns the lower bound of the range (inclusive).
@@ -478,8 +477,6 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(range_contains)]
-    ///
     /// use std::f32;
     ///
     /// assert!(!(3..=5).contains(&2));
@@ -496,7 +493,7 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
     /// assert!(!(0.0..=f32::NAN).contains(&0.0));
     /// assert!(!(f32::NAN..=1.0).contains(&1.0));
     /// ```
-    #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
+    #[stable(feature = "range_contains", since = "1.35.0")]
     pub fn contains<U>(&self, item: &U) -> bool
     where
         Idx: PartialOrd<U>,
@@ -609,15 +606,12 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeToInclusive<Idx> {
     }
 }
 
-#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
 impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
     /// Returns `true` if `item` is contained in the range.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(range_contains)]
-    ///
     /// use std::f32;
     ///
     /// assert!( (..=5).contains(&-1_000_000_000));
@@ -628,7 +622,7 @@ impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
     /// assert!(!(..=1.0).contains(&f32::NAN));
     /// assert!(!(..=f32::NAN).contains(&0.5));
     /// ```
-    #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
+    #[stable(feature = "range_contains", since = "1.35.0")]
     pub fn contains<U>(&self, item: &U) -> bool
     where
         Idx: PartialOrd<U>,
@@ -730,14 +724,11 @@ pub trait RangeBounds<T: ?Sized> {
     #[stable(feature = "collections_range", since = "1.28.0")]
     fn end_bound(&self) -> Bound<&T>;
 
-
     /// Returns `true` if `item` is contained in the range.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(range_contains)]
-    ///
     /// use std::f32;
     ///
     /// assert!( (3..5).contains(&4));
@@ -747,7 +738,7 @@ pub trait RangeBounds<T: ?Sized> {
     /// assert!(!(0.0..1.0).contains(&f32::NAN));
     /// assert!(!(0.0..f32::NAN).contains(&0.5));
     /// assert!(!(f32::NAN..1.0).contains(&0.5));
-    #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
+    #[stable(feature = "range_contains", since = "1.35.0")]
     fn contains<U>(&self, item: &U) -> bool
     where
         T: PartialOrd<U>,
@@ -757,9 +748,7 @@ pub trait RangeBounds<T: ?Sized> {
             Included(ref start) => *start <= item,
             Excluded(ref start) => *start < item,
             Unbounded => true,
-        })
-        &&
-        (match self.end_bound() {
+        }) && (match self.end_bound() {
             Included(ref end) => item <= *end,
             Excluded(ref end) => item < *end,
             Unbounded => true,
@@ -835,7 +824,7 @@ impl<T> RangeBounds<T> for (Bound<T>, Bound<T>) {
         match *self {
             (Included(ref start), _) => Included(start),
             (Excluded(ref start), _) => Excluded(start),
-            (Unbounded, _)           => Unbounded,
+            (Unbounded, _) => Unbounded,
         }
     }
 
@@ -843,7 +832,7 @@ impl<T> RangeBounds<T> for (Bound<T>, Bound<T>) {
         match *self {
             (_, Included(ref end)) => Included(end),
             (_, Excluded(ref end)) => Excluded(end),
-            (_, Unbounded)         => Unbounded,
+            (_, Unbounded) => Unbounded,
         }
     }
 }
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 46dfe28da62..dfc388409a8 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -210,7 +210,7 @@ impl<T> Option<T> {
     // Adapter for working with references
     /////////////////////////////////////////////////////////////////////////
 
-    /// Converts from `Option<T>` to `Option<&T>`.
+    /// Converts from `&Option<T>` to `Option<&T>`.
     ///
     /// # Examples
     ///
@@ -239,7 +239,7 @@ impl<T> Option<T> {
         }
     }
 
-    /// Converts from `Option<T>` to `Option<&mut T>`.
+    /// Converts from `&mut Option<T>` to `Option<&mut T>`.
     ///
     /// # Examples
     ///
@@ -881,15 +881,13 @@ impl<T: Copy> Option<&T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(copied)]
-    ///
     /// let x = 12;
     /// let opt_x = Some(&x);
     /// assert_eq!(opt_x, Some(&12));
     /// let copied = opt_x.copied();
     /// assert_eq!(copied, Some(12));
     /// ```
-    #[unstable(feature = "copied", issue = "57126")]
+    #[stable(feature = "copied", since = "1.35.0")]
     pub fn copied(self) -> Option<T> {
         self.map(|&t| t)
     }
@@ -902,15 +900,13 @@ impl<T: Copy> Option<&mut T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(copied)]
-    ///
     /// let mut x = 12;
     /// let opt_x = Some(&mut x);
     /// assert_eq!(opt_x, Some(&mut 12));
     /// let copied = opt_x.copied();
     /// assert_eq!(copied, Some(12));
     /// ```
-    #[unstable(feature = "copied", issue = "57126")]
+    #[stable(feature = "copied", since = "1.35.0")]
     pub fn copied(self) -> Option<T> {
         self.map(|&mut t| t)
     }
diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs
index fb78f5e5a23..cf55b6c379d 100644
--- a/src/libcore/pin.rs
+++ b/src/libcore/pin.rs
@@ -1,4 +1,4 @@
-//! Types which pin data to its location in memory
+//! Types that pin data to its location in memory.
 //!
 //! It is sometimes useful to have objects that are guaranteed to not move,
 //! in the sense that their placement in memory does not change, and can thus be relied upon.
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 2bd6b536301..967f7e3e2fe 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -369,7 +369,7 @@ impl<T, E> Result<T, E> {
     // Adapter for working with references
     /////////////////////////////////////////////////////////////////////////
 
-    /// Converts from `Result<T, E>` to `Result<&T, &E>`.
+    /// Converts from `&Result<T, E>` to `Result<&T, &E>`.
     ///
     /// Produces a new `Result`, containing a reference
     /// into the original, leaving the original in place.
@@ -394,7 +394,7 @@ impl<T, E> Result<T, E> {
         }
     }
 
-    /// Converts from `Result<T, E>` to `Result<&mut T, &mut E>`.
+    /// Converts from `&mut Result<T, E>` to `Result<&mut T, &mut E>`.
     ///
     /// # Examples
     ///
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 53334adadb8..528281d317b 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -2968,7 +2968,7 @@ impl str {
     ///
     /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
     /// allows a reverse search and forward/reverse search yields the same
-    /// elements. This is true for, eg, [`char`] but not for `&str`.
+    /// elements. This is true for, e.g., [`char`], but not for `&str`.
     ///
     /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
     ///
@@ -3143,7 +3143,7 @@ impl str {
     ///
     /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
     /// allows a reverse search and forward/reverse search yields the same
-    /// elements. This is true for, eg, [`char`] but not for `&str`.
+    /// elements. This is true for, e.g., [`char`], but not for `&str`.
     ///
     /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
     ///
@@ -3326,7 +3326,7 @@ impl str {
     ///
     /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
     /// allows a reverse search and forward/reverse search yields the same
-    /// elements. This is true for, eg, [`char`] but not for `&str`.
+    /// elements. This is true for, e.g., [`char`], but not for `&str`.
     ///
     /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
     ///
@@ -3402,7 +3402,7 @@ impl str {
     ///
     /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
     /// allows a reverse search and forward/reverse search yields the same
-    /// elements. This is true for, eg, [`char`] but not for `&str`.
+    /// elements. This is true for, e.g., [`char`], but not for `&str`.
     ///
     /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
     ///
diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs
index 21f0a8cea41..12f812d3bed 100644
--- a/src/libcore/task/wake.rs
+++ b/src/libcore/task/wake.rs
@@ -108,7 +108,7 @@ impl Waker {
         unsafe { (self.waker.vtable.wake)(self.waker.data) }
     }
 
-    /// Returns whether or not this `Waker` and other `Waker` have awaken the same task.
+    /// Returns `true` if this `Waker` and another `Waker` have awoken the same task.
     ///
     /// This function works on a best-effort basis, and may return false even
     /// when the `Waker`s would awaken the same task. However, if this function
diff --git a/src/libcore/tests/cell.rs b/src/libcore/tests/cell.rs
index b16416022c0..7bd7d187410 100644
--- a/src/libcore/tests/cell.rs
+++ b/src/libcore/tests/cell.rs
@@ -5,15 +5,15 @@ use std::mem::drop;
 #[test]
 fn smoketest_cell() {
     let x = Cell::new(10);
-    assert!(x == Cell::new(10));
-    assert!(x.get() == 10);
+    assert_eq!(x, Cell::new(10));
+    assert_eq!(x.get(), 10);
     x.set(20);
-    assert!(x == Cell::new(20));
-    assert!(x.get() == 20);
+    assert_eq!(x, Cell::new(20));
+    assert_eq!(x.get(), 20);
 
     let y = Cell::new((30, 40));
-    assert!(y == Cell::new((30, 40)));
-    assert!(y.get() == (30, 40));
+    assert_eq!(y, Cell::new((30, 40)));
+    assert_eq!(y.get(), (30, 40));
 }
 
 #[test]
@@ -109,7 +109,6 @@ fn double_borrow_single_release_no_borrow_mut() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn discard_doesnt_unborrow() {
     let x = RefCell::new(0);
     let _b = x.borrow();
@@ -350,7 +349,6 @@ fn refcell_ref_coercion() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn refcell_swap_borrows() {
     let x = RefCell::new(0);
     let _b = x.borrow();
@@ -360,7 +358,6 @@ fn refcell_swap_borrows() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn refcell_replace_borrows() {
     let x = RefCell::new(0);
     let _b = x.borrow();
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index a9db9b35d8d..a3f0b02e2fe 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -253,7 +253,6 @@ fn test_iterator_step_by_nth_overflow() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_iterator_step_by_zero() {
     let mut it = (0..).step_by(0);
     it.next();
@@ -1442,7 +1441,6 @@ fn test_rposition() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_rposition_panic() {
     let v: [(Box<_>, Box<_>); 4] =
         [(box 0, box 0), (box 0, box 0),
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index d0021376389..a50310e195f 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -1,6 +1,5 @@
 #![feature(box_syntax)]
 #![feature(cell_update)]
-#![feature(copied)]
 #![feature(core_private_bignum)]
 #![feature(core_private_diy_float)]
 #![feature(dec2flt)]
diff --git a/src/libcore/tests/num/bignum.rs b/src/libcore/tests/num/bignum.rs
index 956c22c9982..b873f1dd065 100644
--- a/src/libcore/tests/num/bignum.rs
+++ b/src/libcore/tests/num/bignum.rs
@@ -3,7 +3,6 @@ use core::num::bignum::tests::Big8x3 as Big;
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_from_u64_overflow() {
     Big::from_u64(0x1000000);
 }
@@ -20,14 +19,12 @@ fn test_add() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_add_overflow_1() {
     Big::from_small(1).add(&Big::from_u64(0xffffff));
 }
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_add_overflow_2() {
     Big::from_u64(0xffffff).add(&Big::from_small(1));
 }
@@ -45,7 +42,6 @@ fn test_add_small() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_add_small_overflow() {
     Big::from_u64(0xffffff).add_small(1);
 }
@@ -61,14 +57,12 @@ fn test_sub() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_sub_underflow_1() {
     Big::from_u64(0x10665).sub(&Big::from_u64(0x10666));
 }
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_sub_underflow_2() {
     Big::from_small(0).sub(&Big::from_u64(0x123456));
 }
@@ -82,7 +76,6 @@ fn test_mul_small() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_mul_small_overflow() {
     Big::from_u64(0x800000).mul_small(2);
 }
@@ -101,14 +94,12 @@ fn test_mul_pow2() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_mul_pow2_overflow_1() {
     Big::from_u64(0x1).mul_pow2(24);
 }
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_mul_pow2_overflow_2() {
     Big::from_u64(0x123).mul_pow2(16);
 }
@@ -127,14 +118,12 @@ fn test_mul_pow5() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_mul_pow5_overflow_1() {
     Big::from_small(1).mul_pow5(12);
 }
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_mul_pow5_overflow_2() {
     Big::from_small(230).mul_pow5(8);
 }
@@ -152,14 +141,12 @@ fn test_mul_digits() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_mul_digits_overflow_1() {
     Big::from_u64(0x800000).mul_digits(&[2]);
 }
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_mul_digits_overflow_2() {
     Big::from_u64(0x1000).mul_digits(&[0, 0x10]);
 }
@@ -219,7 +206,6 @@ fn test_get_bit() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_get_bit_out_of_range() {
     Big::from_small(42).get_bit(24);
 }
diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs
index 5c6ee8f8ba0..4881f79ec24 100644
--- a/src/libcore/tests/num/int_macros.rs
+++ b/src/libcore/tests/num/int_macros.rs
@@ -12,7 +12,7 @@ mod tests {
     fn test_overflows() {
         assert!(MAX > 0);
         assert!(MIN <= 0);
-        assert!(MIN + MAX + 1 == 0);
+        assert_eq!(MIN + MAX + 1, 0);
     }
 
     #[test]
@@ -22,22 +22,22 @@ mod tests {
 
     #[test]
     fn test_rem_euclid() {
-        assert!((-1 as $T).rem_euclid(MIN) == MAX);
+        assert_eq!((-1 as $T).rem_euclid(MIN), MAX);
     }
 
     #[test]
     pub fn test_abs() {
-        assert!((1 as $T).abs() == 1 as $T);
-        assert!((0 as $T).abs() == 0 as $T);
-        assert!((-1 as $T).abs() == 1 as $T);
+        assert_eq!((1 as $T).abs(), 1 as $T);
+        assert_eq!((0 as $T).abs(), 0 as $T);
+        assert_eq!((-1 as $T).abs(), 1 as $T);
     }
 
     #[test]
     fn test_signum() {
-        assert!((1 as $T).signum() == 1 as $T);
-        assert!((0 as $T).signum() == 0 as $T);
-        assert!((-0 as $T).signum() == 0 as $T);
-        assert!((-1 as $T).signum() == -1 as $T);
+        assert_eq!((1 as $T).signum(), 1 as $T);
+        assert_eq!((0 as $T).signum(), 0 as $T);
+        assert_eq!((-0 as $T).signum(), 0 as $T);
+        assert_eq!((-1 as $T).signum(), -1 as $T);
     }
 
     #[test]
@@ -58,12 +58,12 @@ mod tests {
 
     #[test]
     fn test_bitwise_operators() {
-        assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T));
-        assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T));
-        assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T));
-        assert!(0b1110 as $T == (0b0111 as $T).shl(1));
-        assert!(0b0111 as $T == (0b1110 as $T).shr(1));
-        assert!(-(0b11 as $T) - (1 as $T) == (0b11 as $T).not());
+        assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(0b1010 as $T));
+        assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(0b1010 as $T));
+        assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(0b1010 as $T));
+        assert_eq!(0b1110 as $T, (0b0111 as $T).shl(1));
+        assert_eq!(0b0111 as $T, (0b1110 as $T).shr(1));
+        assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not());
     }
 
     const A: $T = 0b0101100;
@@ -75,17 +75,17 @@ mod tests {
 
     #[test]
     fn test_count_ones() {
-        assert!(A.count_ones() == 3);
-        assert!(B.count_ones() == 2);
-        assert!(C.count_ones() == 5);
+        assert_eq!(A.count_ones(), 3);
+        assert_eq!(B.count_ones(), 2);
+        assert_eq!(C.count_ones(), 5);
     }
 
     #[test]
     fn test_count_zeros() {
         let bits = mem::size_of::<$T>() * 8;
-        assert!(A.count_zeros() == bits as u32 - 3);
-        assert!(B.count_zeros() == bits as u32 - 2);
-        assert!(C.count_zeros() == bits as u32 - 5);
+        assert_eq!(A.count_zeros(), bits as u32 - 3);
+        assert_eq!(B.count_zeros(), bits as u32 - 2);
+        assert_eq!(C.count_zeros(), bits as u32 - 5);
     }
 
     #[test]
@@ -148,9 +148,9 @@ mod tests {
 
     #[test]
     fn test_signed_checked_div() {
-        assert!((10 as $T).checked_div(2) == Some(5));
-        assert!((5 as $T).checked_div(0) == None);
-        assert!(isize::MIN.checked_div(-1) == None);
+        assert_eq!((10 as $T).checked_div(2), Some(5));
+        assert_eq!((5 as $T).checked_div(0), None);
+        assert_eq!(isize::MIN.checked_div(-1), None);
     }
 
     #[test]
diff --git a/src/libcore/tests/ops.rs b/src/libcore/tests/ops.rs
index 401644e120d..78cf07119e7 100644
--- a/src/libcore/tests/ops.rs
+++ b/src/libcore/tests/ops.rs
@@ -7,11 +7,11 @@ fn test_range() {
     let r = Range { start: 2, end: 10 };
     let mut count = 0;
     for (i, ri) in r.enumerate() {
-        assert!(ri == i + 2);
+        assert_eq!(ri, i + 2);
         assert!(ri >= 2 && ri < 10);
         count += 1;
     }
-    assert!(count == 8);
+    assert_eq!(count, 8);
 }
 
 #[test]
@@ -19,11 +19,11 @@ fn test_range_from() {
     let r = RangeFrom { start: 2 };
     let mut count = 0;
     for (i, ri) in r.take(10).enumerate() {
-        assert!(ri == i + 2);
+        assert_eq!(ri, i + 2);
         assert!(ri >= 2 && ri < 12);
         count += 1;
     }
-    assert!(count == 10);
+    assert_eq!(count, 10);
 }
 
 #[test]
diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs
index 87ce2720c59..b059b134868 100644
--- a/src/libcore/tests/option.rs
+++ b/src/libcore/tests/option.rs
@@ -69,7 +69,6 @@ fn test_option_dance() {
 }
 
 #[test] #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_option_too_much_dance() {
     struct A;
     let mut y = Some(A);
@@ -130,7 +129,6 @@ fn test_unwrap() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_unwrap_panic1() {
     let x: Option<isize> = None;
     x.unwrap();
@@ -138,7 +136,6 @@ fn test_unwrap_panic1() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_unwrap_panic2() {
     let x: Option<String> = None;
     x.unwrap();
diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs
index bbc85685176..1fab07526a0 100644
--- a/src/libcore/tests/result.rs
+++ b/src/libcore/tests/result.rs
@@ -117,7 +117,6 @@ fn test_unwrap_or_else() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 pub fn test_unwrap_or_else_panic() {
     fn handler(msg: &'static str) -> isize {
         if msg == "I got this." {
@@ -139,7 +138,6 @@ pub fn test_expect_ok() {
 }
 #[test]
 #[should_panic(expected="Got expected error: \"All good\"")]
-#[cfg(not(miri))] // Miri does not support panics
 pub fn test_expect_err() {
     let err: Result<isize, &'static str> = Err("All good");
     err.expect("Got expected error");
@@ -153,7 +151,6 @@ pub fn test_expect_err_err() {
 }
 #[test]
 #[should_panic(expected="Got expected ok: \"All good\"")]
-#[cfg(not(miri))] // Miri does not support panics
 pub fn test_expect_err_ok() {
     let err: Result<&'static str, isize> = Ok("All good");
     err.expect_err("Got expected ok");
diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs
index 31d16e0e320..ac9c17a0f7c 100644
--- a/src/libcore/tests/slice.rs
+++ b/src/libcore/tests/slice.rs
@@ -782,7 +782,6 @@ mod slice_index {
     //  to be used in `should_panic`)
     #[test]
     #[should_panic(expected = "out of range")]
-    #[cfg(not(miri))] // Miri does not support panics
     fn assert_range_eq_can_fail_by_panic() {
         assert_range_eq!([0, 1, 2], 0..5, [0, 1, 2]);
     }
@@ -792,7 +791,6 @@ mod slice_index {
     //  to be used in `should_panic`)
     #[test]
     #[should_panic(expected = "==")]
-    #[cfg(not(miri))] // Miri does not support panics
     fn assert_range_eq_can_fail_by_inequality() {
         assert_range_eq!([0, 1, 2], 0..2, [0, 1, 2]);
     }
@@ -842,7 +840,6 @@ mod slice_index {
 
                 #[test]
                 #[should_panic(expected = $expect_msg)]
-                #[cfg(not(miri))] // Miri does not support panics
                 fn index_fail() {
                     let v = $data;
                     let v: &[_] = &v;
@@ -851,7 +848,6 @@ mod slice_index {
 
                 #[test]
                 #[should_panic(expected = $expect_msg)]
-                #[cfg(not(miri))] // Miri does not support panics
                 fn index_mut_fail() {
                     let mut v = $data;
                     let v: &mut [_] = &mut v;
@@ -1304,7 +1300,6 @@ fn test_copy_within() {
 
 #[test]
 #[should_panic(expected = "src is out of bounds")]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_copy_within_panics_src_too_long() {
     let mut bytes = *b"Hello, World!";
     // The length is only 13, so 14 is out of bounds.
@@ -1313,7 +1308,6 @@ fn test_copy_within_panics_src_too_long() {
 
 #[test]
 #[should_panic(expected = "dest is out of bounds")]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_copy_within_panics_dest_too_long() {
     let mut bytes = *b"Hello, World!";
     // The length is only 13, so a slice of length 4 starting at index 10 is out of bounds.
@@ -1321,7 +1315,6 @@ fn test_copy_within_panics_dest_too_long() {
 }
 #[test]
 #[should_panic(expected = "src end is before src start")]
-#[cfg(not(miri))] // Miri does not support panics
 fn test_copy_within_panics_src_inverted() {
     let mut bytes = *b"Hello, World!";
     // 2 is greater than 1, so this range is invalid.
diff --git a/src/libcore/tests/time.rs b/src/libcore/tests/time.rs
index 09aae458348..6efd22572dc 100644
--- a/src/libcore/tests/time.rs
+++ b/src/libcore/tests/time.rs
@@ -107,14 +107,12 @@ fn checked_sub() {
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn sub_bad1() {
     let _ = Duration::new(0, 0) - Duration::new(0, 1);
 }
 
 #[test]
 #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
 fn sub_bad2() {
     let _ = Duration::new(0, 0) - Duration::new(1, 0);
 }
diff --git a/src/libcore/time.rs b/src/libcore/time.rs
index 91161ca477e..ae6d8078fd2 100644
--- a/src/libcore/time.rs
+++ b/src/libcore/time.rs
@@ -21,7 +21,6 @@ const NANOS_PER_MILLI: u32 = 1_000_000;
 const NANOS_PER_MICRO: u32 = 1_000;
 const MILLIS_PER_SEC: u64 = 1_000;
 const MICROS_PER_SEC: u64 = 1_000_000;
-const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64;
 
 /// A `Duration` type to represent a span of time, typically used for system
 /// timeouts.
@@ -510,15 +509,34 @@ impl Duration {
     /// use std::time::Duration;
     ///
     /// let dur = Duration::new(2, 700_000_000);
-    /// assert_eq!(dur.as_float_secs(), 2.7);
+    /// assert_eq!(dur.as_secs_f64(), 2.7);
     /// ```
     #[unstable(feature = "duration_float", issue = "54361")]
     #[inline]
-    pub const fn as_float_secs(&self) -> f64 {
+    pub const fn as_secs_f64(&self) -> f64 {
         (self.secs as f64) + (self.nanos as f64) / (NANOS_PER_SEC as f64)
     }
 
-    /// Creates a new `Duration` from the specified number of seconds.
+    /// Returns the number of seconds contained by this `Duration` as `f32`.
+    ///
+    /// The returned value does include the fractional (nanosecond) part of the duration.
+    ///
+    /// # Examples
+    /// ```
+    /// #![feature(duration_float)]
+    /// use std::time::Duration;
+    ///
+    /// let dur = Duration::new(2, 700_000_000);
+    /// assert_eq!(dur.as_secs_f32(), 2.7);
+    /// ```
+    #[unstable(feature = "duration_float", issue = "54361")]
+    #[inline]
+    pub const fn as_secs_f32(&self) -> f32 {
+        (self.secs as f32) + (self.nanos as f32) / (NANOS_PER_SEC as f32)
+    }
+
+    /// Creates a new `Duration` from the specified number of seconds represented
+    /// as `f64`.
     ///
     /// # Panics
     /// This constructor will panic if `secs` is not finite, negative or overflows `Duration`.
@@ -528,12 +546,14 @@ impl Duration {
     /// #![feature(duration_float)]
     /// use std::time::Duration;
     ///
-    /// let dur = Duration::from_float_secs(2.7);
+    /// let dur = Duration::from_secs_f64(2.7);
     /// assert_eq!(dur, Duration::new(2, 700_000_000));
     /// ```
     #[unstable(feature = "duration_float", issue = "54361")]
     #[inline]
-    pub fn from_float_secs(secs: f64) -> Duration {
+    pub fn from_secs_f64(secs: f64) -> Duration {
+        const MAX_NANOS_F64: f64 =
+            ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64;
         let nanos =  secs * (NANOS_PER_SEC as f64);
         if !nanos.is_finite() {
             panic!("got non-finite value when converting float to duration");
@@ -551,6 +571,42 @@ impl Duration {
         }
     }
 
+    /// Creates a new `Duration` from the specified number of seconds represented
+    /// as `f32`.
+    ///
+    /// # Panics
+    /// This constructor will panic if `secs` is not finite, negative or overflows `Duration`.
+    ///
+    /// # Examples
+    /// ```
+    /// #![feature(duration_float)]
+    /// use std::time::Duration;
+    ///
+    /// let dur = Duration::from_secs_f32(2.7);
+    /// assert_eq!(dur, Duration::new(2, 700_000_000));
+    /// ```
+    #[unstable(feature = "duration_float", issue = "54361")]
+    #[inline]
+    pub fn from_secs_f32(secs: f32) -> Duration {
+        const MAX_NANOS_F32: f32 =
+            ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f32;
+        let nanos =  secs * (NANOS_PER_SEC as f32);
+        if !nanos.is_finite() {
+            panic!("got non-finite value when converting float to duration");
+        }
+        if nanos >= MAX_NANOS_F32 {
+            panic!("overflow when converting float to duration");
+        }
+        if nanos < 0.0 {
+            panic!("underflow when converting float to duration");
+        }
+        let nanos =  nanos as u128;
+        Duration {
+            secs: (nanos / (NANOS_PER_SEC as u128)) as u64,
+            nanos: (nanos % (NANOS_PER_SEC as u128)) as u32,
+        }
+    }
+
     /// Multiplies `Duration` by `f64`.
     ///
     /// # Panics
@@ -568,7 +624,29 @@ impl Duration {
     #[unstable(feature = "duration_float", issue = "54361")]
     #[inline]
     pub fn mul_f64(self, rhs: f64) -> Duration {
-        Duration::from_float_secs(rhs * self.as_float_secs())
+        Duration::from_secs_f64(rhs * self.as_secs_f64())
+    }
+
+    /// Multiplies `Duration` by `f32`.
+    ///
+    /// # Panics
+    /// This method will panic if result is not finite, negative or overflows `Duration`.
+    ///
+    /// # Examples
+    /// ```
+    /// #![feature(duration_float)]
+    /// use std::time::Duration;
+    ///
+    /// let dur = Duration::new(2, 700_000_000);
+    /// // note that due to rounding errors result is slightly different
+    /// // from 8.478 and 847800.0
+    /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640));
+    /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847799, 969_120_256));
+    /// ```
+    #[unstable(feature = "duration_float", issue = "54361")]
+    #[inline]
+    pub fn mul_f32(self, rhs: f32) -> Duration {
+        Duration::from_secs_f32(rhs * self.as_secs_f32())
     }
 
     /// Divide `Duration` by `f64`.
@@ -589,7 +667,30 @@ impl Duration {
     #[unstable(feature = "duration_float", issue = "54361")]
     #[inline]
     pub fn div_f64(self, rhs: f64) -> Duration {
-        Duration::from_float_secs(self.as_float_secs() / rhs)
+        Duration::from_secs_f64(self.as_secs_f64() / rhs)
+    }
+
+    /// Divide `Duration` by `f32`.
+    ///
+    /// # Panics
+    /// This method will panic if result is not finite, negative or overflows `Duration`.
+    ///
+    /// # Examples
+    /// ```
+    /// #![feature(duration_float)]
+    /// use std::time::Duration;
+    ///
+    /// let dur = Duration::new(2, 700_000_000);
+    /// // note that due to rounding errors result is slightly
+    /// // different from 0.859_872_611
+    /// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_576));
+    /// // note that truncation is used, not rounding
+    /// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_598));
+    /// ```
+    #[unstable(feature = "duration_float", issue = "54361")]
+    #[inline]
+    pub fn div_f32(self, rhs: f32) -> Duration {
+        Duration::from_secs_f32(self.as_secs_f32() / rhs)
     }
 
     /// Divide `Duration` by `Duration` and return `f64`.
@@ -601,12 +702,29 @@ impl Duration {
     ///
     /// let dur1 = Duration::new(2, 700_000_000);
     /// let dur2 = Duration::new(5, 400_000_000);
-    /// assert_eq!(dur1.div_duration(dur2), 0.5);
+    /// assert_eq!(dur1.div_duration_f64(dur2), 0.5);
+    /// ```
+    #[unstable(feature = "duration_float", issue = "54361")]
+    #[inline]
+    pub fn div_duration_f64(self, rhs: Duration) -> f64 {
+        self.as_secs_f64() / rhs.as_secs_f64()
+    }
+
+    /// Divide `Duration` by `Duration` and return `f32`.
+    ///
+    /// # Examples
+    /// ```
+    /// #![feature(duration_float)]
+    /// use std::time::Duration;
+    ///
+    /// let dur1 = Duration::new(2, 700_000_000);
+    /// let dur2 = Duration::new(5, 400_000_000);
+    /// assert_eq!(dur1.div_duration_f32(dur2), 0.5);
     /// ```
     #[unstable(feature = "duration_float", issue = "54361")]
     #[inline]
-    pub fn div_duration(self, rhs: Duration) -> f64 {
-        self.as_float_secs() / rhs.as_float_secs()
+    pub fn div_duration_f32(self, rhs: Duration) -> f32 {
+        self.as_secs_f32() / rhs.as_secs_f32()
     }
 }
 
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 41a4a803100..eb75e624d34 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -724,7 +724,7 @@ impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for DefId {
     }
 
     fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
-        tcx.item_path_str(*self)
+        tcx.def_path_str(*self)
     }
 }
 
@@ -736,7 +736,7 @@ impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for DefIndex {
     }
 
     fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
-        tcx.item_path_str(DefId::local(*self))
+        tcx.def_path_str(DefId::local(*self))
     }
 }
 
diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs
index ed1c15a73c2..397843fd75a 100644
--- a/src/librustc/hir/def_id.rs
+++ b/src/librustc/hir/def_id.rs
@@ -249,7 +249,7 @@ impl DefId {
         if self.is_local() && self.index == CRATE_DEF_INDEX {
             format!("top-level module")
         } else {
-            format!("module `{}`", tcx.item_path_str(*self))
+            format!("module `{}`", tcx.def_path_str(*self))
         }
     }
 }
diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs
index f454d691d41..dca4ce4aef8 100644
--- a/src/librustc/hir/map/definitions.rs
+++ b/src/librustc/hir/map/definitions.rs
@@ -679,13 +679,13 @@ impl DefPathData {
                 return name
             }
             // note that this does not show up in user printouts
-            CrateRoot => "{{root}}",
+            CrateRoot => "{{crate}}",
             Impl => "{{impl}}",
-            Misc => "{{?}}",
+            Misc => "{{misc}}",
             ClosureExpr => "{{closure}}",
             StructCtor => "{{constructor}}",
             AnonConst => "{{constant}}",
-            ImplTrait => "{{impl-Trait}}",
+            ImplTrait => "{{opaque}}",
         };
 
         Symbol::intern(s).as_interned_str()
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 86b6805cc9b..151c5413dcf 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -541,7 +541,8 @@ impl<'hir> Map<'hir> {
 
     pub fn ty_param_owner(&self, id: HirId) -> HirId {
         match self.get_by_hir_id(id) {
-            Node::Item(&Item { node: ItemKind::Trait(..), .. }) => id,
+            Node::Item(&Item { node: ItemKind::Trait(..), .. }) |
+            Node::Item(&Item { node: ItemKind::TraitAlias(..), .. }) => id,
             Node::GenericParam(_) => self.get_parent_node_by_hir_id(id),
             _ => bug!("ty_param_owner: {} not a type parameter", self.hir_to_string(id))
         }
@@ -549,7 +550,8 @@ impl<'hir> Map<'hir> {
 
     pub fn ty_param_name(&self, id: HirId) -> Name {
         match self.get_by_hir_id(id) {
-            Node::Item(&Item { node: ItemKind::Trait(..), .. }) => keywords::SelfUpper.name(),
+            Node::Item(&Item { node: ItemKind::Trait(..), .. }) |
+            Node::Item(&Item { node: ItemKind::TraitAlias(..), .. }) => keywords::SelfUpper.name(),
             Node::GenericParam(param) => param.name.ident().name,
             _ => bug!("ty_param_name: {} not a type parameter", self.hir_to_string(id)),
         }
@@ -1019,6 +1021,7 @@ impl<'hir> Map<'hir> {
     pub fn attrs(&self, id: NodeId) -> &'hir [ast::Attribute] {
         self.read(id); // reveals attributes on the node
         let attrs = match self.find(id) {
+            Some(Node::Local(l)) => Some(&l.attrs[..]),
             Some(Node::Item(i)) => Some(&i.attrs[..]),
             Some(Node::ForeignItem(fi)) => Some(&fi.attrs[..]),
             Some(Node::TraitItem(ref ti)) => Some(&ti.attrs[..]),
@@ -1350,7 +1353,8 @@ fn node_id_to_string(map: &Map<'_>, id: NodeId, include_id: bool) -> String {
         // the user-friendly path, otherwise fall back to stringifying DefPath.
         crate::ty::tls::with_opt(|tcx| {
             if let Some(tcx) = tcx {
-                tcx.node_path_str(id)
+                let def_id = map.local_def_id(id);
+                tcx.def_path_str(def_id)
             } else if let Some(path) = map.def_path_from_id(id) {
                 path.data.into_iter().map(|elem| {
                     elem.data.to_string()
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index c7936534aad..2810b5a8e6a 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -223,7 +223,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                     self.hir().span_by_hir_id(node),
                 ),
                 _ => (
-                    format!("the lifetime {} as defined on", fr.bound_region),
+                    format!("the lifetime {} as defined on", region),
                     cm.def_span(self.hir().span_by_hir_id(node)),
                 ),
             },
@@ -444,17 +444,109 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         terr: &TypeError<'tcx>,
         sp: Span,
     ) {
+        use hir::def_id::CrateNum;
+        use hir::map::DisambiguatedDefPathData;
+        use ty::print::Printer;
+        use ty::subst::Kind;
+
+        struct AbsolutePathPrinter<'a, 'gcx, 'tcx> {
+            tcx: TyCtxt<'a, 'gcx, 'tcx>,
+        }
+
+        struct NonTrivialPath;
+
+        impl<'gcx, 'tcx> Printer<'gcx, 'tcx> for AbsolutePathPrinter<'_, 'gcx, 'tcx> {
+            type Error = NonTrivialPath;
+
+            type Path = Vec<String>;
+            type Region = !;
+            type Type = !;
+            type DynExistential = !;
+
+            fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx> {
+                self.tcx
+            }
+
+            fn print_region(
+                self,
+                _region: ty::Region<'_>,
+            ) -> Result<Self::Region, Self::Error> {
+                Err(NonTrivialPath)
+            }
+
+            fn print_type(
+                self,
+                _ty: Ty<'tcx>,
+            ) -> Result<Self::Type, Self::Error> {
+                Err(NonTrivialPath)
+            }
+
+            fn print_dyn_existential(
+                self,
+                _predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
+            ) -> Result<Self::DynExistential, Self::Error> {
+                Err(NonTrivialPath)
+            }
+
+            fn path_crate(
+                self,
+                cnum: CrateNum,
+            ) -> Result<Self::Path, Self::Error> {
+                Ok(vec![self.tcx.original_crate_name(cnum).to_string()])
+            }
+            fn path_qualified(
+                self,
+                _self_ty: Ty<'tcx>,
+                _trait_ref: Option<ty::TraitRef<'tcx>>,
+            ) -> Result<Self::Path, Self::Error> {
+                Err(NonTrivialPath)
+            }
+
+            fn path_append_impl(
+                self,
+                _print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
+                _disambiguated_data: &DisambiguatedDefPathData,
+                _self_ty: Ty<'tcx>,
+                _trait_ref: Option<ty::TraitRef<'tcx>>,
+            ) -> Result<Self::Path, Self::Error> {
+                Err(NonTrivialPath)
+            }
+            fn path_append(
+                self,
+                print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
+                disambiguated_data: &DisambiguatedDefPathData,
+            ) -> Result<Self::Path, Self::Error> {
+                let mut path = print_prefix(self)?;
+                path.push(disambiguated_data.data.as_interned_str().to_string());
+                Ok(path)
+            }
+            fn path_generic_args(
+                self,
+                print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
+                _args: &[Kind<'tcx>],
+            ) -> Result<Self::Path, Self::Error> {
+                print_prefix(self)
+            }
+        }
+
         let report_path_match = |err: &mut DiagnosticBuilder<'_>, did1: DefId, did2: DefId| {
             // Only external crates, if either is from a local
             // module we could have false positives
             if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate {
-                let exp_path = self.tcx.item_path_str(did1);
-                let found_path = self.tcx.item_path_str(did2);
-                let exp_abs_path = self.tcx.absolute_item_path_str(did1);
-                let found_abs_path = self.tcx.absolute_item_path_str(did2);
+                let abs_path = |def_id| {
+                    AbsolutePathPrinter { tcx: self.tcx }
+                        .print_def_path(def_id, &[])
+                };
+
                 // We compare strings because DefPath can be different
                 // for imported and non-imported crates
-                if exp_path == found_path || exp_abs_path == found_abs_path {
+                let same_path = || -> Result<_, NonTrivialPath> {
+                    Ok(
+                        self.tcx.def_path_str(did1) == self.tcx.def_path_str(did2) ||
+                        abs_path(did1)? == abs_path(did2)?
+                    )
+                };
+                if same_path().unwrap_or(false) {
                     let crate_name = self.tcx.crate_name(did1.krate);
                     err.span_note(
                         sp,
@@ -658,7 +750,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 return Some(());
             }
             if let &ty::Adt(def, _) = &ta.sty {
-                let path_ = self.tcx.item_path_str(def.did.clone());
+                let path_ = self.tcx.def_path_str(def.did.clone());
                 if path_ == other_path {
                     self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, &other_ty);
                     return Some(());
@@ -683,7 +775,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     }
 
     /// For generic types with parameters with defaults, remove the parameters corresponding to
-    /// the defaults. This repeats a lot of the logic found in `PrintContext::parameterized`.
+    /// the defaults. This repeats a lot of the logic found in `ty::print::pretty`.
     fn strip_generic_default_params(
         &self,
         def_id: DefId,
@@ -742,11 +834,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             mutbl: hir::Mutability,
             s: &mut DiagnosticStyledString,
         ) {
-            let r = &r.to_string();
+            let mut r = r.to_string();
+            if r == "'_" {
+                r.clear();
+            } else {
+                r.push(' ');
+            }
             s.push_highlighted(format!(
-                "&{}{}{}",
+                "&{}{}",
                 r,
-                if r == "" { "" } else { " " },
                 if mutbl == hir::MutMutable { "mut " } else { "" }
             ));
             s.push_normal(ty.to_string());
@@ -757,8 +853,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 let sub_no_defaults_1 = self.strip_generic_default_params(def1.did, sub1);
                 let sub_no_defaults_2 = self.strip_generic_default_params(def2.did, sub2);
                 let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
-                let path1 = self.tcx.item_path_str(def1.did.clone());
-                let path2 = self.tcx.item_path_str(def2.did.clone());
+                let path1 = self.tcx.def_path_str(def1.did.clone());
+                let path2 = self.tcx.def_path_str(def2.did.clone());
                 if def1.did == def2.did {
                     // Easy case. Replace same types with `_` to shorten the output and highlight
                     // the differing ones.
@@ -1013,7 +1109,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                             if exp_is_struct && &exp_found.expected == ret_ty.skip_binder() {
                                 let message = format!(
                                     "did you mean `{}(/* fields */)`?",
-                                    self.tcx.item_path_str(def_id)
+                                    self.tcx.def_path_str(def_id)
                                 );
                                 diag.span_label(span, message);
                             }
@@ -1425,7 +1521,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         var_origin: RegionVariableOrigin,
     ) -> DiagnosticBuilder<'tcx> {
         let br_string = |br: ty::BoundRegion| {
-            let mut s = br.to_string();
+            let mut s = match br {
+                ty::BrNamed(_, name) => name.to_string(),
+                _ => String::new(),
+            };
             if !s.is_empty() {
                 s.push_str(" ");
             }
diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs
index 9e0e48e4741..0a83b839201 100644
--- a/src/librustc/infer/error_reporting/need_type_info.rs
+++ b/src/librustc/infer/error_reporting/need_type_info.rs
@@ -1,8 +1,10 @@
+use crate::hir::def::Namespace;
 use crate::hir::{self, Local, Pat, Body, HirId};
 use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use crate::infer::InferCtxt;
 use crate::infer::type_variable::TypeVariableOrigin;
 use crate::ty::{self, Ty, Infer, TyVar};
+use crate::ty::print::Print;
 use syntax::source_map::CompilerDesugaringKind;
 use syntax_pos::Span;
 use errors::DiagnosticBuilder;
@@ -64,18 +66,26 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
 
 
 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
-    pub fn extract_type_name(&self, ty: &'a Ty<'tcx>) -> String {
+    pub fn extract_type_name(
+        &self,
+        ty: &'a Ty<'tcx>,
+        highlight: Option<ty::print::RegionHighlightMode>,
+    ) -> String {
         if let ty::Infer(ty::TyVar(ty_vid)) = (*ty).sty {
             let ty_vars = self.type_variables.borrow();
             if let TypeVariableOrigin::TypeParameterDefinition(_, name) =
                 *ty_vars.var_origin(ty_vid) {
-                name.to_string()
-            } else {
-                ty.to_string()
+                return name.to_string();
             }
-        } else {
-            ty.to_string()
         }
+
+        let mut s = String::new();
+        let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS);
+        if let Some(highlight) = highlight {
+            printer.region_highlight_mode = highlight;
+        }
+        let _ = ty.print(printer);
+        s
     }
 
     pub fn need_type_info_err(&self,
@@ -84,7 +94,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                             ty: Ty<'tcx>)
                             -> DiagnosticBuilder<'gcx> {
         let ty = self.resolve_type_vars_if_possible(&ty);
-        let name = self.extract_type_name(&ty);
+        let name = self.extract_type_name(&ty, None);
 
         let mut err_span = span;
         let mut labels = vec![(
diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs
index 506388c268b..e708454b5b6 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs
@@ -1,14 +1,17 @@
 use errors::DiagnosticBuilder;
+use crate::hir::def::Namespace;
 use crate::hir::def_id::DefId;
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
 use crate::infer::lexical_region_resolve::RegionResolutionError;
 use crate::infer::ValuePairs;
 use crate::infer::{SubregionOrigin, TypeTrace};
 use crate::traits::{ObligationCause, ObligationCauseCode};
-use crate::ty;
+use crate::ty::{self, TyCtxt};
 use crate::ty::error::ExpectedFound;
 use crate::ty::subst::SubstsRef;
-use crate::util::ppaux::RegionHighlightMode;
+use crate::ty::print::{Print, RegionHighlightMode, FmtPrinter};
+
+use std::fmt::{self, Write};
 
 impl NiceRegionError<'me, 'gcx, 'tcx> {
     /// When given a `ConcreteFailure` for a function with arguments containing a named region and
@@ -193,7 +196,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
             cause.span(&self.tcx()),
             &format!(
                 "implementation of `{}` is not general enough",
-                self.tcx().item_path_str(trait_def_id),
+                self.tcx().def_path_str(trait_def_id),
             ),
         );
 
@@ -201,7 +204,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
             ObligationCauseCode::ItemObligation(def_id) => {
                 err.note(&format!(
                     "Due to a where-clause on `{}`,",
-                    self.tcx().item_path_str(def_id),
+                    self.tcx().def_path_str(def_id),
                 ));
             }
             _ => (),
@@ -309,13 +312,46 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
         sup_placeholder: Option<ty::Region<'tcx>>,
         has_sub: Option<usize>,
         has_sup: Option<usize>,
-        expected_trait_ref: ty::TraitRef<'_>,
-        actual_trait_ref: ty::TraitRef<'_>,
+        expected_trait_ref: ty::TraitRef<'tcx>,
+        actual_trait_ref: ty::TraitRef<'tcx>,
         vid: Option<ty::Region<'tcx>>,
         expected_has_vid: Option<usize>,
         actual_has_vid: Option<usize>,
         any_self_ty_has_vid: bool,
     ) {
+        // HACK(eddyb) maybe move this in a more central location.
+        #[derive(Copy, Clone)]
+        struct Highlighted<'a, 'gcx, 'tcx, T> {
+            tcx: TyCtxt<'a, 'gcx, 'tcx>,
+            highlight: RegionHighlightMode,
+            value: T,
+        }
+
+        impl<'a, 'gcx, 'tcx, T> Highlighted<'a, 'gcx, 'tcx, T> {
+            fn map<U>(self, f: impl FnOnce(T) -> U) -> Highlighted<'a, 'gcx, 'tcx, U> {
+                Highlighted {
+                    tcx: self.tcx,
+                    highlight: self.highlight,
+                    value: f(self.value),
+                }
+            }
+        }
+
+        impl<'a, 'gcx, 'tcx, T> fmt::Display for Highlighted<'a, 'gcx, 'tcx, T>
+            where T: for<'b, 'c> Print<'gcx, 'tcx,
+                FmtPrinter<'a, 'gcx, 'tcx, &'b mut fmt::Formatter<'c>>,
+                Error = fmt::Error,
+            >,
+        {
+            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+                let mut printer = ty::print::FmtPrinter::new(self.tcx, f, Namespace::TypeNS);
+                printer.region_highlight_mode = self.highlight;
+
+                self.value.print(printer)?;
+                Ok(())
+            }
+        }
+
         // The weird thing here with the `maybe_highlighting_region` calls and the
         // the match inside is meant to be like this:
         //
@@ -331,112 +367,93 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
         // None, an then we check again inside the closure, but this
         // setup sort of minimized the number of calls and so form.
 
-        RegionHighlightMode::maybe_highlighting_region(sub_placeholder, has_sub, || {
-            RegionHighlightMode::maybe_highlighting_region(sup_placeholder, has_sup, || {
-                match (has_sub, has_sup) {
-                    (Some(n1), Some(n2)) => {
-                        if any_self_ty_has_vid {
-                            err.note(&format!(
-                                "`{}` would have to be implemented for the type `{}`, \
-                                 for any two lifetimes `'{}` and `'{}`",
-                                expected_trait_ref,
-                                expected_trait_ref.self_ty(),
-                                std::cmp::min(n1, n2),
-                                std::cmp::max(n1, n2),
-                            ));
-                        } else {
-                            err.note(&format!(
-                                "`{}` must implement `{}`, \
-                                 for any two lifetimes `'{}` and `'{}`",
-                                expected_trait_ref.self_ty(),
-                                expected_trait_ref,
-                                std::cmp::min(n1, n2),
-                                std::cmp::max(n1, n2),
-                            ));
-                        }
-                    }
-                    (Some(n), _) | (_, Some(n)) => {
-                        if any_self_ty_has_vid {
-                            err.note(&format!(
-                                "`{}` would have to be implemented for the type `{}`, \
-                                 for any lifetime `'{}`",
-                                expected_trait_ref,
-                                expected_trait_ref.self_ty(),
-                                n,
-                            ));
-                        } else {
-                            err.note(&format!(
-                                "`{}` must implement `{}`, for any lifetime `'{}`",
-                                expected_trait_ref.self_ty(),
-                                expected_trait_ref,
-                                n,
-                            ));
-                        }
-                    }
-                    (None, None) => RegionHighlightMode::maybe_highlighting_region(
-                        vid,
-                        expected_has_vid,
-                        || {
-                            if let Some(n) = expected_has_vid {
-                                err.note(&format!(
-                                    "`{}` would have to be implemented for the type `{}`, \
-                                     for some specific lifetime `'{}`",
-                                    expected_trait_ref,
-                                    expected_trait_ref.self_ty(),
-                                    n,
-                                ));
-                            } else {
-                                if any_self_ty_has_vid {
-                                    err.note(&format!(
-                                        "`{}` would have to be implemented for the type `{}`",
-                                        expected_trait_ref,
-                                        expected_trait_ref.self_ty(),
-                                    ));
-                                } else {
-                                    err.note(&format!(
-                                        "`{}` must implement `{}`",
-                                        expected_trait_ref.self_ty(),
-                                        expected_trait_ref,
-                                    ));
-                                }
-                            }
-                        },
-                    ),
-                }
-            })
-        });
+        let highlight_trait_ref = |trait_ref| Highlighted {
+            tcx: self.tcx(),
+            highlight: RegionHighlightMode::default(),
+            value: trait_ref,
+        };
 
-        RegionHighlightMode::maybe_highlighting_region(
-            vid,
-            actual_has_vid,
-            || match actual_has_vid {
-                Some(n) => {
-                    if any_self_ty_has_vid {
-                        err.note(&format!(
-                            "but `{}` is actually implemented for the type `{}`, \
-                             for some specific lifetime `'{}`",
-                            actual_trait_ref,
-                            actual_trait_ref.self_ty(),
-                            n
-                        ));
-                    } else {
-                        err.note(&format!(
-                            "but `{}` actually implements `{}`, for some specific lifetime `'{}`",
-                            actual_trait_ref.self_ty(),
-                            actual_trait_ref,
-                            n
-                        ));
+        let mut expected_trait_ref = highlight_trait_ref(expected_trait_ref);
+        expected_trait_ref.highlight.maybe_highlighting_region(sub_placeholder, has_sub);
+        expected_trait_ref.highlight.maybe_highlighting_region(sup_placeholder, has_sup);
+        err.note(&{
+            let passive_voice = match (has_sub, has_sup) {
+                (Some(_), _) | (_, Some(_)) => any_self_ty_has_vid,
+                (None, None) => {
+                    expected_trait_ref.highlight.maybe_highlighting_region(vid, expected_has_vid);
+                    match expected_has_vid {
+                        Some(_) => true,
+                        None => any_self_ty_has_vid,
                     }
                 }
+            };
 
-                _ => {
-                    err.note(&format!(
-                        "but `{}` is actually implemented for the type `{}`",
-                        actual_trait_ref,
-                        actual_trait_ref.self_ty(),
-                    ));
+            let mut note = if passive_voice {
+                format!(
+                    "`{}` would have to be implemented for the type `{}`",
+                    expected_trait_ref,
+                    expected_trait_ref.map(|tr| tr.self_ty()),
+                )
+            } else {
+                format!(
+                    "`{}` must implement `{}`",
+                    expected_trait_ref.map(|tr| tr.self_ty()),
+                    expected_trait_ref,
+                )
+            };
+
+            match (has_sub, has_sup) {
+                (Some(n1), Some(n2)) => {
+                    let _ = write!(note,
+                        ", for any two lifetimes `'{}` and `'{}`",
+                        std::cmp::min(n1, n2),
+                        std::cmp::max(n1, n2),
+                    );
                 }
-            },
-        );
+                (Some(n), _) | (_, Some(n)) => {
+                    let _ = write!(note,
+                        ", for any lifetime `'{}`",
+                        n,
+                    );
+                }
+                (None, None) => if let Some(n) = expected_has_vid {
+                    let _ = write!(note,
+                        ", for some specific lifetime `'{}`",
+                        n,
+                    );
+                },
+            }
+
+            note
+        });
+
+        let mut actual_trait_ref = highlight_trait_ref(actual_trait_ref);
+        actual_trait_ref.highlight.maybe_highlighting_region(vid, actual_has_vid);
+        err.note(&{
+            let passive_voice = match actual_has_vid {
+                Some(_) => any_self_ty_has_vid,
+                None => true,
+            };
+
+            let mut note = if passive_voice {
+                format!(
+                    "but `{}` is actually implemented for the type `{}`",
+                    actual_trait_ref,
+                    actual_trait_ref.map(|tr| tr.self_ty()),
+                )
+            } else {
+                format!(
+                    "but `{}` actually implements `{}`",
+                    actual_trait_ref.map(|tr| tr.self_ty()),
+                    actual_trait_ref,
+                )
+            };
+
+            if let Some(n) = actual_has_vid {
+                let _ = write!(note, ", for some specific lifetime `'{}`", n);
+            }
+
+            note
+        });
     }
 }
diff --git a/src/librustc/infer/error_reporting/nice_region_error/util.rs b/src/librustc/infer/error_reporting/nice_region_error/util.rs
index 6db1bc382af..3ed28a1f988 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/util.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/util.rs
@@ -3,7 +3,7 @@
 
 use crate::hir;
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use crate::ty::{self, Region, Ty};
+use crate::ty::{self, DefIdTree, Region, Ty};
 use crate::hir::def_id::DefId;
 use syntax_pos::Span;
 
@@ -44,7 +44,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
         let (id, bound_region) = match *anon_region {
             ty::ReFree(ref free_region) => (free_region.scope, free_region.bound_region),
             ty::ReEarlyBound(ref ebr) => (
-                self.tcx().parent_def_id(ebr.def_id).unwrap(),
+                self.tcx().parent(ebr.def_id).unwrap(),
                 ty::BoundRegion::BrNamed(ebr.def_id, ebr.name),
             ),
             _ => return None, // not a free region
diff --git a/src/librustc/infer/outlives/free_region_map.rs b/src/librustc/infer/outlives/free_region_map.rs
index 78353e52ad4..5349e990a77 100644
--- a/src/librustc/infer/outlives/free_region_map.rs
+++ b/src/librustc/infer/outlives/free_region_map.rs
@@ -91,7 +91,7 @@ impl_stable_hash_for!(struct FreeRegionMap<'tcx> {
 impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> {
     type Lifted = FreeRegionMap<'tcx>;
     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<FreeRegionMap<'tcx>> {
-        self.relation.maybe_map(|&fr| fr.lift_to_tcx(tcx))
+        self.relation.maybe_map(|&fr| tcx.lift(&fr))
                      .map(|relation| FreeRegionMap { relation })
     }
 }
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 6adfaa53946..b6677326227 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -31,6 +31,7 @@
 #![deny(rust_2018_idioms)]
 #![allow(explicit_outlives_requirements)]
 
+#![feature(arbitrary_self_types)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(core_intrinsics)]
@@ -134,9 +135,7 @@ pub mod ty;
 pub mod util {
     pub mod captures;
     pub mod common;
-    pub mod ppaux;
     pub mod nodemap;
-    pub mod time_graph;
     pub mod profiling;
     pub mod bug;
 }
diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs
index 924aa3fde0a..3c6635c0341 100644
--- a/src/librustc/lint/levels.rs
+++ b/src/librustc/lint/levels.rs
@@ -157,6 +157,7 @@ pub struct LintLevelsBuilder<'a> {
 
 pub struct BuilderPush {
     prev: u32,
+    pub(super) changed: bool,
 }
 
 impl<'a> LintLevelsBuilder<'a> {
@@ -454,6 +455,7 @@ impl<'a> LintLevelsBuilder<'a> {
 
         BuilderPush {
             prev: prev,
+            changed: prev != self.cur,
         }
     }
 
@@ -512,11 +514,6 @@ impl LintLevelMap {
             self.sets.get_lint_level(lint, *idx, None, session)
         })
     }
-
-    /// Returns if this `id` has lint level information.
-    pub fn lint_level_set(&self, id: HirId) -> Option<u32> {
-        self.id_to_set.get(&id).cloned()
-    }
 }
 
 impl<'a> HashStable<StableHashingContext<'a>> for LintLevelMap {
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 496ff568b31..c01b0ae2ccc 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -721,6 +721,16 @@ pub fn struct_lint_level<'a>(sess: &'a Session,
     return err
 }
 
+pub fn maybe_lint_level_root(tcx: TyCtxt<'_, '_, '_>, id: hir::HirId) -> bool {
+    let attrs = tcx.hir().attrs_by_hir_id(id);
+    for attr in attrs {
+        if Level::from_str(&attr.name().as_str()).is_some() {
+            return true;
+        }
+    }
+    false
+}
+
 fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum)
     -> Lrc<LintLevelMap>
 {
@@ -731,9 +741,10 @@ fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum)
     };
     let krate = tcx.hir().krate();
 
-    builder.with_lint_attrs(hir::CRATE_HIR_ID, &krate.attrs, |builder| {
-        intravisit::walk_crate(builder, krate);
-    });
+    let push = builder.levels.push(&krate.attrs);
+    builder.levels.register_id(hir::CRATE_HIR_ID);
+    intravisit::walk_crate(&mut builder, krate);
+    builder.levels.pop(push);
 
     Lrc::new(builder.levels.build_map())
 }
@@ -751,7 +762,9 @@ impl<'a, 'tcx> LintLevelMapBuilder<'a, 'tcx> {
         where F: FnOnce(&mut Self)
     {
         let push = self.levels.push(attrs);
-        self.levels.register_id(id);
+        if push.changed {
+            self.levels.register_id(id);
+        }
         f(self);
         self.levels.pop(push);
     }
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 94de999c25d..3da82d728c0 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -12,7 +12,7 @@ use crate::hir::CodegenFnAttrFlags;
 use crate::hir::def_id::{DefId, LOCAL_CRATE};
 use crate::lint;
 use crate::middle::privacy;
-use crate::ty::{self, TyCtxt};
+use crate::ty::{self, DefIdTree, TyCtxt};
 use crate::util::nodemap::FxHashSet;
 
 use rustc_data_structures::fx::FxHashMap;
@@ -78,7 +78,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
             Def::PrimTy(..) | Def::SelfTy(..) | Def::SelfCtor(..) |
             Def::Local(..) | Def::Upvar(..) => {}
             Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => {
-                if let Some(enum_id) = self.tcx.parent_def_id(variant_id) {
+                if let Some(enum_id) = self.tcx.parent(variant_id) {
                     self.check_def_id(enum_id);
                 }
                 if !self.ignore_variant_stack.contains(&variant_id) {
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index a3e8598194e..b36d2a57cb3 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -64,7 +64,7 @@ use crate::hir::Node;
 use crate::infer::InferCtxt;
 use crate::hir::def::{Def, CtorKind};
 use crate::ty::adjustment;
-use crate::ty::{self, Ty, TyCtxt};
+use crate::ty::{self, DefIdTree, Ty, TyCtxt};
 use crate::ty::fold::TypeFoldable;
 use crate::ty::layout::VariantIdx;
 
@@ -786,7 +786,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
         // FnMut          | copied -> &'env mut  | upvar -> &'env mut -> &'up bk
         // FnOnce         | copied               | upvar -> &'up bk
 
-        let kind = match self.node_ty(fn_hir_id)?.sty {
+        let ty = self.node_ty(fn_hir_id)?;
+        let kind = match ty.sty {
             ty::Generator(..) => ty::ClosureKind::FnOnce,
             ty::Closure(closure_def_id, closure_substs) => {
                 match self.infcx {
@@ -803,7 +804,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                                 .closure_kind(closure_def_id, self.tcx.global_tcx()),
                 }
             }
-            ref t => span_bug!(span, "unexpected type for fn in mem_categorization: {:?}", t),
+            _ => span_bug!(span, "unexpected type for fn in mem_categorization: {:?}", ty),
         };
 
         let closure_expr_def_id = self.tcx.hir().local_def_id(fn_node_id);
@@ -1064,7 +1065,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                 let bk = ty::BorrowKind::from_mutbl(mutbl);
                 BorrowedPtr(bk, r)
             }
-            ref ty => bug!("unexpected type in cat_deref: {:?}", ty)
+            _ => bug!("unexpected type in cat_deref: {:?}", base_cmt.ty)
         };
         let ret = cmt_ {
             hir_id: node.hir_id(),
@@ -1132,7 +1133,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                                              variant_did: DefId)
                                              -> cmt<'tcx> {
         // univariant enums do not need downcasts
-        let base_did = self.tcx.parent_def_id(variant_did).unwrap();
+        let base_did = self.tcx.parent(variant_did).unwrap();
         if self.tcx.adt_def(base_did).variants.len() != 1 {
             let base_ty = base_cmt.ty;
             let ret = Rc::new(cmt_ {
@@ -1274,16 +1275,17 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                         return Err(())
                     }
                     Def::VariantCtor(def_id, CtorKind::Fn) => {
-                        let enum_def = self.tcx.parent_def_id(def_id).unwrap();
+                        let enum_def = self.tcx.parent(def_id).unwrap();
                         (self.cat_downcast_if_needed(pat, cmt, def_id),
                         self.tcx.adt_def(enum_def).variant_with_id(def_id).fields.len())
                     }
                     Def::StructCtor(_, CtorKind::Fn) | Def::SelfCtor(..) => {
-                        match self.pat_ty_unadjusted(&pat)?.sty {
+                        let ty = self.pat_ty_unadjusted(&pat)?;
+                        match ty.sty {
                             ty::Adt(adt_def, _) => {
                                 (cmt, adt_def.non_enum_variant().fields.len())
                             }
-                            ref ty => {
+                            _ => {
                                 span_bug!(pat.span,
                                           "tuple struct pattern unexpected type {:?}", ty);
                             }
@@ -1334,9 +1336,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
 
             PatKind::Tuple(ref subpats, ddpos) => {
                 // (p1, ..., pN)
-                let expected_len = match self.pat_ty_unadjusted(&pat)?.sty {
+                let ty = self.pat_ty_unadjusted(&pat)?;
+                let expected_len = match ty.sty {
                     ty::Tuple(ref tys) => tys.len(),
-                    ref ty => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty),
+                    _ => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty),
                 };
                 for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
                     let subpat_ty = self.pat_ty_adjusted(&subpat)?; // see (*2)
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 42e253273ab..2b380238810 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -17,7 +17,7 @@ use rustc_macros::HashStable;
 use syntax::source_map;
 use syntax::ast;
 use syntax_pos::{Span, DUMMY_SP};
-use crate::ty::TyCtxt;
+use crate::ty::{DefIdTree, TyCtxt};
 use crate::ty::query::Providers;
 
 use crate::hir;
@@ -650,7 +650,7 @@ impl<'tcx> ScopeTree {
     pub fn early_free_scope<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
                                       br: &ty::EarlyBoundRegion)
                                       -> Scope {
-        let param_owner = tcx.parent_def_id(br.def_id).unwrap();
+        let param_owner = tcx.parent(br.def_id).unwrap();
 
         let param_owner_id = tcx.hir().as_local_hir_id(param_owner).unwrap();
         let scope = tcx.hir().maybe_body_owned_by_by_hir_id(param_owner_id).map(|body_id| {
@@ -679,7 +679,7 @@ impl<'tcx> ScopeTree {
                                  -> Scope {
         let param_owner = match fr.bound_region {
             ty::BoundRegion::BrNamed(def_id, _) => {
-                tcx.parent_def_id(def_id).unwrap()
+                tcx.parent(def_id).unwrap()
             }
             _ => fr.scope
         };
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 96f0beafa00..ab105360388 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -2299,6 +2299,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         let span = lifetime_refs[0].span;
         let mut late_depth = 0;
         let mut scope = self.scope;
+        let mut lifetime_names = FxHashSet::default();
         let error = loop {
             match *scope {
                 // Do not assign any resolution, it will be inferred.
@@ -2306,12 +2307,18 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
 
                 Scope::Root => break None,
 
-                Scope::Binder { s, .. } => {
+                Scope::Binder { s, ref lifetimes, .. } => {
+                    // collect named lifetimes for suggestions
+                    for name in lifetimes.keys() {
+                        if let hir::ParamName::Plain(name) = name {
+                            lifetime_names.insert(*name);
+                        }
+                    }
                     late_depth += 1;
                     scope = s;
                 }
 
-                Scope::Elision { ref elide, .. } => {
+                Scope::Elision { ref elide, ref s, .. } => {
                     let lifetime = match *elide {
                         Elide::FreshLateAnon(ref counter) => {
                             for lifetime_ref in lifetime_refs {
@@ -2321,7 +2328,17 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                             return;
                         }
                         Elide::Exact(l) => l.shifted(late_depth),
-                        Elide::Error(ref e) => break Some(e),
+                        Elide::Error(ref e) => {
+                            if let Scope::Binder { ref lifetimes, .. } = s {
+                                // collect named lifetimes for suggestions
+                                for name in lifetimes.keys() {
+                                    if let hir::ParamName::Plain(name) = name {
+                                        lifetime_names.insert(*name);
+                                    }
+                                }
+                            }
+                            break Some(e);
+                        }
                     };
                     for lifetime_ref in lifetime_refs {
                         self.insert_lifetime(lifetime_ref, lifetime);
@@ -2344,7 +2361,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             }
         }
         if add_label {
-            add_missing_lifetime_specifiers_label(&mut err, span, lifetime_refs.len());
+            add_missing_lifetime_specifiers_label(
+                &mut err,
+                span,
+                lifetime_refs.len(),
+                &lifetime_names,
+                self.tcx.sess.source_map().span_to_snippet(span).ok().as_ref().map(|s| s.as_str()),
+            );
         }
 
         err.emit();
@@ -2885,10 +2908,23 @@ fn add_missing_lifetime_specifiers_label(
     err: &mut DiagnosticBuilder<'_>,
     span: Span,
     count: usize,
+    lifetime_names: &FxHashSet<ast::Ident>,
+    snippet: Option<&str>,
 ) {
     if count > 1 {
         err.span_label(span, format!("expected {} lifetime parameters", count));
+    } else if let (1, Some(name), Some("&")) = (
+        lifetime_names.len(),
+        lifetime_names.iter().next(),
+        snippet,
+    ) {
+        err.span_suggestion(
+            span,
+            "consider using the named lifetime",
+            format!("&{} ", name),
+            Applicability::MaybeIncorrect,
+        );
     } else {
         err.span_label(span, "expected lifetime parameter");
-    };
+    }
 }
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 1677384059e..0a2a375e1b2 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -593,7 +593,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                                .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
 
                 if !skip {
-                    let path = self.item_path_str(def_id);
+                    let path = self.def_path_str(def_id);
                     let message = format!("use of deprecated item '{}'", path);
                     lint_deprecated(def_id,
                                     id,
@@ -620,7 +620,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         if let Some(id) = id {
             if let Some(stability) = stability {
                 if let Some(depr) = &stability.rustc_depr {
-                    let path = self.item_path_str(def_id);
+                    let path = self.def_path_str(def_id);
                     if deprecation_in_effect(&depr.since.as_str()) {
                         let message = format!("use of deprecated item '{}'", path);
                         lint_deprecated(def_id,
diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index d4ee60eee63..80fef910cc7 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -101,8 +101,7 @@ impl AllocationExtra<(), ()> for () {
 impl<Tag, Extra> Allocation<Tag, Extra> {
     /// Creates a read-only allocation initialized by the given bytes
     pub fn from_bytes(slice: &[u8], align: Align, extra: Extra) -> Self {
-        let mut undef_mask = UndefMask::new(Size::ZERO);
-        undef_mask.grow(Size::from_bytes(slice.len() as u64), true);
+        let undef_mask = UndefMask::new(Size::from_bytes(slice.len() as u64), true);
         Self {
             bytes: slice.to_owned(),
             relocations: Relocations::new(),
@@ -122,7 +121,7 @@ impl<Tag, Extra> Allocation<Tag, Extra> {
         Allocation {
             bytes: vec![0; size.bytes() as usize],
             relocations: Relocations::new(),
-            undef_mask: UndefMask::new(size),
+            undef_mask: UndefMask::new(size, false),
             align,
             mutability: Mutability::Mutable,
             extra,
@@ -614,8 +613,9 @@ impl<Tag> DerefMut for Relocations<Tag> {
 ////////////////////////////////////////////////////////////////////////////////
 
 type Block = u64;
-const BLOCK_SIZE: u64 = 64;
 
+/// A bitmask where each bit refers to the byte with the same index. If the bit is `true`, the byte
+/// is defined. If it is `false` the byte is undefined.
 #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
 pub struct UndefMask {
     blocks: Vec<Block>,
@@ -625,12 +625,14 @@ pub struct UndefMask {
 impl_stable_hash_for!(struct mir::interpret::UndefMask{blocks, len});
 
 impl UndefMask {
-    pub fn new(size: Size) -> Self {
+    pub const BLOCK_SIZE: u64 = 64;
+
+    pub fn new(size: Size, state: bool) -> Self {
         let mut m = UndefMask {
             blocks: vec![],
             len: Size::ZERO,
         };
-        m.grow(size, false);
+        m.grow(size, state);
         m
     }
 
@@ -644,6 +646,7 @@ impl UndefMask {
             return Err(self.len);
         }
 
+        // FIXME(oli-obk): optimize this for allocations larger than a block.
         let idx = (start.bytes()..end.bytes())
             .map(|i| Size::from_bytes(i))
             .find(|&i| !self.get(i));
@@ -663,20 +666,63 @@ impl UndefMask {
     }
 
     pub fn set_range_inbounds(&mut self, start: Size, end: Size, new_state: bool) {
-        for i in start.bytes()..end.bytes() {
-            self.set(Size::from_bytes(i), new_state);
+        let (blocka, bita) = bit_index(start);
+        let (blockb, bitb) = bit_index(end);
+        if blocka == blockb {
+            // first set all bits but the first `bita`
+            // then unset the last `64 - bitb` bits
+            let range = if bitb == 0 {
+                u64::max_value() << bita
+            } else {
+                (u64::max_value() << bita) & (u64::max_value() >> (64 - bitb))
+            };
+            if new_state {
+                self.blocks[blocka] |= range;
+            } else {
+                self.blocks[blocka] &= !range;
+            }
+            return;
+        }
+        // across block boundaries
+        if new_state {
+            // set bita..64 to 1
+            self.blocks[blocka] |= u64::max_value() << bita;
+            // set 0..bitb to 1
+            if bitb != 0 {
+                self.blocks[blockb] |= u64::max_value() >> (64 - bitb);
+            }
+            // fill in all the other blocks (much faster than one bit at a time)
+            for block in (blocka + 1) .. blockb {
+                self.blocks[block] = u64::max_value();
+            }
+        } else {
+            // set bita..64 to 0
+            self.blocks[blocka] &= !(u64::max_value() << bita);
+            // set 0..bitb to 0
+            if bitb != 0 {
+                self.blocks[blockb] &= !(u64::max_value() >> (64 - bitb));
+            }
+            // fill in all the other blocks (much faster than one bit at a time)
+            for block in (blocka + 1) .. blockb {
+                self.blocks[block] = 0;
+            }
         }
     }
 
     #[inline]
     pub fn get(&self, i: Size) -> bool {
         let (block, bit) = bit_index(i);
-        (self.blocks[block] & 1 << bit) != 0
+        (self.blocks[block] & (1 << bit)) != 0
     }
 
     #[inline]
     pub fn set(&mut self, i: Size, new_state: bool) {
         let (block, bit) = bit_index(i);
+        self.set_bit(block, bit, new_state);
+    }
+
+    #[inline]
+    fn set_bit(&mut self, block: usize, bit: usize, new_state: bool) {
         if new_state {
             self.blocks[block] |= 1 << bit;
         } else {
@@ -685,11 +731,15 @@ impl UndefMask {
     }
 
     pub fn grow(&mut self, amount: Size, new_state: bool) {
-        let unused_trailing_bits = self.blocks.len() as u64 * BLOCK_SIZE - self.len.bytes();
+        if amount.bytes() == 0 {
+            return;
+        }
+        let unused_trailing_bits = self.blocks.len() as u64 * Self::BLOCK_SIZE - self.len.bytes();
         if amount.bytes() > unused_trailing_bits {
-            let additional_blocks = amount.bytes() / BLOCK_SIZE + 1;
+            let additional_blocks = amount.bytes() / Self::BLOCK_SIZE + 1;
             assert_eq!(additional_blocks as usize as u64, additional_blocks);
             self.blocks.extend(
+                // FIXME(oli-obk): optimize this by repeating `new_state as Block`
                 iter::repeat(0).take(additional_blocks as usize),
             );
         }
@@ -702,8 +752,8 @@ impl UndefMask {
 #[inline]
 fn bit_index(bits: Size) -> (usize, usize) {
     let bits = bits.bytes();
-    let a = bits / BLOCK_SIZE;
-    let b = bits % BLOCK_SIZE;
+    let a = bits / UndefMask::BLOCK_SIZE;
+    let b = bits % UndefMask::BLOCK_SIZE;
     assert_eq!(a as usize as u64, a);
     assert_eq!(b as usize as u64, b);
     (a as usize, b as usize)
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 3a4422a6239..718b506d051 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -2,7 +2,7 @@
 //!
 //! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/index.html
 
-use crate::hir::def::CtorKind;
+use crate::hir::def::{CtorKind, Namespace};
 use crate::hir::def_id::DefId;
 use crate::hir::{self, HirId, InlineAsm};
 use crate::mir::interpret::{ConstValue, EvalErrorKind, Scalar};
@@ -34,7 +34,7 @@ use crate::ty::{
     self, AdtDef, CanonicalUserTypeAnnotations, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt,
     UserTypeAnnotationIndex,
 };
-use crate::util::ppaux;
+use crate::ty::print::{FmtPrinter, Printer};
 
 pub use crate::mir::interpret::AssertMessage;
 
@@ -2062,7 +2062,7 @@ impl<'tcx> Debug for Place<'tcx> {
             Base(PlaceBase::Static(box self::Static { def_id, ty })) => write!(
                 fmt,
                 "({}: {:?})",
-                ty::tls::with(|tcx| tcx.item_path_str(def_id)),
+                ty::tls::with(|tcx| tcx.def_path_str(def_id)),
                 ty
             ),
             Base(PlaceBase::Promoted(ref promoted)) => write!(
@@ -2369,7 +2369,10 @@ impl<'tcx> Debug for Rvalue<'tcx> {
                 };
 
                 // When printing regions, add trailing space if necessary.
-                let region = if ppaux::verbose() || ppaux::identify_regions() {
+                let print_region = ty::tls::with(|tcx| {
+                    tcx.sess.verbose() || tcx.sess.opts.debugging_opts.identify_regions
+                });
+                let region = if print_region {
                     let mut region = region.to_string();
                     if region.len() > 0 {
                         region.push(' ');
@@ -2403,7 +2406,13 @@ impl<'tcx> Debug for Rvalue<'tcx> {
                     AggregateKind::Adt(adt_def, variant, substs, _user_ty, _) => {
                         let variant_def = &adt_def.variants[variant];
 
-                        ppaux::parameterized(fmt, substs, variant_def.did, &[])?;
+                        let f = &mut *fmt;
+                        ty::tls::with(|tcx| {
+                            let substs = tcx.lift(&substs).expect("could not lift for printing");
+                            FmtPrinter::new(tcx, f, Namespace::ValueNS)
+                                .print_def_path(variant_def.did, substs)?;
+                            Ok(())
+                        })?;
 
                         match variant_def.ctor_kind {
                             CtorKind::Const => Ok(()),
@@ -2729,7 +2738,7 @@ pub fn fmt_const_val(f: &mut impl Write, const_val: ty::Const<'_>) -> fmt::Resul
     }
     // print function definitions
     if let FnDef(did, _) = ty.sty {
-        return write!(f, "{}", item_path_str(did));
+        return write!(f, "{}", def_path_str(did));
     }
     // print string literals
     if let ConstValue::Slice(ptr, len) = value {
@@ -2754,8 +2763,8 @@ pub fn fmt_const_val(f: &mut impl Write, const_val: ty::Const<'_>) -> fmt::Resul
     write!(f, "{:?}:{}", value, ty)
 }
 
-fn item_path_str(def_id: DefId) -> String {
-    ty::tls::with(|tcx| tcx.item_path_str(def_id))
+fn def_path_str(def_id: DefId) -> String {
+    ty::tls::with(|tcx| tcx.def_path_str(def_id))
 }
 
 impl<'tcx> graph::DirectedGraph for Mir<'tcx> {
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 55c4b0e54b8..ff18678f091 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -800,6 +800,7 @@ macro_rules! options {
         pub const parse_opt_pathbuf: Option<&str> = Some("a path");
         pub const parse_list: Option<&str> = Some("a space-separated list of strings");
         pub const parse_opt_list: Option<&str> = Some("a space-separated list of strings");
+        pub const parse_opt_comma_list: Option<&str> = Some("a comma-separated list of strings");
         pub const parse_uint: Option<&str> = Some("a number");
         pub const parse_passes: Option<&str> =
             Some("a space-separated list of passes, or `all`");
@@ -926,6 +927,18 @@ macro_rules! options {
             }
         }
 
+        fn parse_opt_comma_list(slot: &mut Option<Vec<String>>, v: Option<&str>)
+                      -> bool {
+            match v {
+                Some(s) => {
+                    let v = s.split(',').map(|s| s.to_string()).collect();
+                    *slot = Some(v);
+                    true
+                },
+                None => false,
+            }
+        }
+
         fn parse_uint(slot: &mut usize, v: Option<&str>) -> bool {
             match v.and_then(|s| s.parse().ok()) {
                 Some(i) => { *slot = i; true },
@@ -1427,6 +1440,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
     merge_functions: Option<MergeFunctions> = (None, parse_merge_functions, [TRACKED],
         "control the operation of the MergeFunctions LLVM pass, taking
          the same values as the target option of the same name"),
+    allow_features: Option<Vec<String>> = (None, parse_opt_comma_list, [TRACKED],
+        "only allow the listed language features to be enabled in code (space separated)"),
 }
 
 pub fn default_lib_output() -> CrateType {
@@ -3273,6 +3288,10 @@ mod tests {
         opts = reference.clone();
         opts.debugging_opts.merge_functions = Some(MergeFunctions::Disabled);
         assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
+
+        opts = reference.clone();
+        opts.debugging_opts.allow_features = Some(vec![String::from("lang_items")]);
+        assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
     }
 
     #[test]
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index c7674ae7a28..6c8fe0875b6 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -854,10 +854,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                     _ => vec![ArgKind::empty()],
                 };
 
-                let expected = match expected_trait_ref.skip_binder().substs.type_at(1).sty {
+                let expected_ty = expected_trait_ref.skip_binder().substs.type_at(1);
+                let expected = match expected_ty.sty {
                     ty::Tuple(ref tys) => tys.iter()
                         .map(|t| ArgKind::from_expected_ty(t, Some(span))).collect(),
-                    ref sty => vec![ArgKind::Arg("_".to_owned(), sty.to_string())],
+                    _ => vec![ArgKind::Arg("_".to_owned(), expected_ty.to_string())],
                 };
 
                 if found.len() == expected.len() {
@@ -1284,11 +1285,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         let span = self.sess.source_map().def_span(span);
         let mut err = struct_span_err!(self.sess, span, E0072,
                                        "recursive type `{}` has infinite size",
-                                       self.item_path_str(type_def_id));
+                                       self.def_path_str(type_def_id));
         err.span_label(span, "recursive type has infinite size");
         err.help(&format!("insert indirection (e.g., a `Box`, `Rc`, or `&`) \
                            at some point to make `{}` representable",
-                          self.item_path_str(type_def_id)));
+                          self.def_path_str(type_def_id)));
         err
     }
 
@@ -1298,7 +1299,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                                       violations: Vec<ObjectSafetyViolation>)
                                       -> DiagnosticBuilder<'tcx>
     {
-        let trait_str = self.item_path_str(trait_def_id);
+        let trait_str = self.def_path_str(trait_def_id);
         let span = self.sess.source_map().def_span(span);
         let mut err = struct_span_err!(
             self.sess, span, E0038,
@@ -1523,7 +1524,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                                   region, object_ty));
             }
             ObligationCauseCode::ItemObligation(item_def_id) => {
-                let item_name = tcx.item_path_str(item_def_id);
+                let item_name = tcx.def_path_str(item_def_id);
                 let msg = format!("required by `{}`", item_name);
 
                 if let Some(sp) = tcx.hir().span_if_local(item_def_id) {
@@ -1686,10 +1687,10 @@ impl ArgKind {
             ty::Tuple(ref tys) => ArgKind::Tuple(
                 span,
                 tys.iter()
-                   .map(|ty| ("_".to_owned(), ty.sty.to_string()))
+                   .map(|ty| ("_".to_owned(), ty.to_string()))
                    .collect::<Vec<_>>()
             ),
-            _ => ArgKind::Arg("_".to_owned(), t.sty.to_string()),
+            _ => ArgKind::Arg("_".to_owned(), t.to_string()),
         }
     }
 }
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index df127b934b0..78c80b48ee8 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -650,7 +650,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'gcx, 'tcx>(
 ) -> bool {
     debug!("type_known_to_meet_bound_modulo_regions(ty={:?}, bound={:?})",
            ty,
-           infcx.tcx.item_path_str(def_id));
+           infcx.tcx.def_path_str(def_id));
 
     let trait_ref = ty::TraitRef {
         def_id,
@@ -665,7 +665,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'gcx, 'tcx>(
 
     let result = infcx.predicate_must_hold_modulo_regions(&obligation);
     debug!("type_known_to_meet_ty={:?} bound={} => {:?}",
-           ty, infcx.tcx.item_path_str(def_id), result);
+           ty, infcx.tcx.def_path_str(def_id), result);
 
     if result && (ty.has_infer_types() || ty.has_closure_types()) {
         // Because of inference "guessing", selection can sometimes claim
@@ -692,13 +692,13 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'gcx, 'tcx>(
             Ok(()) => {
                 debug!("type_known_to_meet_bound_modulo_regions: ty={:?} bound={} success",
                        ty,
-                       infcx.tcx.item_path_str(def_id));
+                       infcx.tcx.def_path_str(def_id));
                 true
             }
             Err(e) => {
                 debug!("type_known_to_meet_bound_modulo_regions: ty={:?} bound={} errors={:?}",
                        ty,
-                       infcx.tcx.item_path_str(def_id),
+                       infcx.tcx.def_path_str(def_id),
                        e);
                 false
             }
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index e7a5138e689..1c8ea5c7b9c 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -133,7 +133,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
                         hir::CRATE_HIR_ID,
                         *span,
                         &format!("the trait `{}` cannot be made into an object",
-                                 self.item_path_str(trait_def_id)),
+                                 self.def_path_str(trait_def_id)),
                         &violation.error_msg());
                     false
                 } else {
diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs
index c86fd0d52b9..fc0058a1df5 100644
--- a/src/librustc/traits/on_unimplemented.rs
+++ b/src/librustc/traits/on_unimplemented.rs
@@ -276,7 +276,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
                   -> String
     {
         let name = tcx.item_name(trait_ref.def_id);
-        let trait_str = tcx.item_path_str(trait_ref.def_id);
+        let trait_str = tcx.def_path_str(trait_ref.def_id);
         let generics = tcx.generics_of(trait_ref.def_id);
         let generic_map = generics.params.iter().filter_map(|param| {
             let value = match param.kind {
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index 197bea1c311..ab6acc66213 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -1549,7 +1549,7 @@ fn assoc_ty_def<'cx, 'gcx, 'tcx>(
         // should have failed in astconv.
         bug!("No associated type `{}` for {}",
              assoc_ty_name,
-             tcx.item_path_str(impl_def_id))
+             tcx.def_path_str(impl_def_id))
     }
 }
 
diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs
index a2924cb993f..c576586fcad 100644
--- a/src/librustc/traits/specialize/mod.rs
+++ b/src/librustc/traits/specialize/mod.rs
@@ -411,7 +411,7 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_, '_, '_>, impl_def_id: DefId) -> Option<
         w.push('<');
         w.push_str(&substs.iter()
             .map(|k| k.to_string())
-            .filter(|k| &k[..] != "'_")
+            .filter(|k| k != "'_")
             .collect::<Vec<_>>().join(", "));
         w.push('>');
     }
diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs
index b5be1777fa0..f3a800bf46d 100644
--- a/src/librustc/traits/structural_impls.rs
+++ b/src/librustc/traits/structural_impls.rs
@@ -165,7 +165,8 @@ impl<'tcx> fmt::Display for traits::WhereClause<'tcx> {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         use crate::traits::WhereClause::*;
 
-        // Bypass ppaux because it does not print out anonymous regions.
+        // Bypass `ty::print` because it does not print out anonymous regions.
+        // FIXME(eddyb) implement a custom `PrettyPrinter`, or move this to `ty::print`.
         fn write_region_name<'tcx>(
             r: ty::Region<'tcx>,
             fmt: &mut fmt::Formatter<'_>
@@ -256,7 +257,7 @@ impl fmt::Display for traits::QuantifierKind {
 }
 
 /// Collect names for regions / types bound by a quantified goal / clause.
-/// This collector does not try to do anything clever like in ppaux, it's just used
+/// This collector does not try to do anything clever like in `ty::print`, it's just used
 /// for debug output in tests anyway.
 struct BoundNamesCollector {
     // Just sort by name because `BoundRegion::BrNamed` does not have a `BoundVar` index anyway.
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 5e4274fa1c8..1942f98abff 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -26,7 +26,7 @@ use crate::ty::subst::{Kind, InternalSubsts, SubstsRef, Subst};
 use crate::ty::ReprOptions;
 use crate::traits;
 use crate::traits::{Clause, Clauses, GoalKind, Goal, Goals};
-use crate::ty::{self, Ty, TypeAndMut};
+use crate::ty::{self, DefIdTree, Ty, TypeAndMut};
 use crate::ty::{TyS, TyKind, List};
 use crate::ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const, LazyConst};
 use crate::ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate};
@@ -1594,7 +1594,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         let (suitable_region_binding_scope, bound_region) = match *region {
             ty::ReFree(ref free_region) => (free_region.scope, free_region.bound_region),
             ty::ReEarlyBound(ref ebr) => (
-                self.parent_def_id(ebr.def_id).unwrap(),
+                self.parent(ebr.def_id).unwrap(),
                 ty::BoundRegion::BrNamed(ebr.def_id, ebr.name),
             ),
             _ => return None, // not a free region
@@ -2886,30 +2886,44 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         err.emit()
     }
 
-    pub fn lint_level_at_node(self, lint: &'static Lint, mut id: hir::HirId)
-        -> (lint::Level, lint::LintSource)
-    {
-        // Right now we insert a `with_ignore` node in the dep graph here to
-        // ignore the fact that `lint_levels` below depends on the entire crate.
-        // For now this'll prevent false positives of recompiling too much when
-        // anything changes.
-        //
-        // Once red/green incremental compilation lands we should be able to
-        // remove this because while the crate changes often the lint level map
-        // will change rarely.
-        self.dep_graph.with_ignore(|| {
-            let sets = self.lint_levels(LOCAL_CRATE);
-            loop {
-                if let Some(pair) = sets.level_and_source(lint, id, self.sess) {
-                    return pair
-                }
-                let next = self.hir().get_parent_node_by_hir_id(id);
-                if next == id {
-                    bug!("lint traversal reached the root of the crate");
-                }
-                id = next;
+    /// Walks upwards from `id` to find a node which might change lint levels with attributes.
+    /// It stops at `bound` and just returns it if reached.
+    pub fn maybe_lint_level_root_bounded(
+        self,
+        mut id: hir::HirId,
+        bound: hir::HirId,
+    ) -> hir::HirId {
+        loop {
+            if id == bound {
+                return bound;
             }
-        })
+            if lint::maybe_lint_level_root(self, id) {
+                return id;
+            }
+            let next = self.hir().get_parent_node_by_hir_id(id);
+            if next == id {
+                bug!("lint traversal reached the root of the crate");
+            }
+            id = next;
+        }
+    }
+
+    pub fn lint_level_at_node(
+        self,
+        lint: &'static Lint,
+        mut id: hir::HirId
+    ) -> (lint::Level, lint::LintSource) {
+        let sets = self.lint_levels(LOCAL_CRATE);
+        loop {
+            if let Some(pair) = sets.level_and_source(lint, id, self.sess) {
+                return pair
+            }
+            let next = self.hir().get_parent_node_by_hir_id(id);
+            if next == id {
+                bug!("lint traversal reached the root of the crate");
+            }
+            id = next;
+        }
     }
 
     pub fn struct_span_lint_hir<S: Into<MultiSpan>>(self,
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index f58e5e4fb69..fa3c76a817a 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -71,6 +71,13 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
             }
         }
 
+        let br_string = |br: ty::BoundRegion| {
+            match br {
+                ty::BrNamed(_, name) => format!(" {}", name),
+                _ => String::new(),
+            }
+        };
+
         match *self {
             CyclicTy(_) => write!(f, "cyclic type of infinite size"),
             Mismatch => write!(f, "types differ"),
@@ -105,15 +112,13 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
             }
             RegionsInsufficientlyPolymorphic(br, _) => {
                 write!(f,
-                       "expected bound lifetime parameter{}{}, found concrete lifetime",
-                       if br.is_named() { " " } else { "" },
-                       br)
+                       "expected bound lifetime parameter{}, found concrete lifetime",
+                       br_string(br))
             }
             RegionsOverlyPolymorphic(br, _) => {
                 write!(f,
-                       "expected concrete lifetime, found bound lifetime parameter{}{}",
-                       if br.is_named() { " " } else { "" },
-                       br)
+                       "expected concrete lifetime, found bound lifetime parameter{}",
+                       br_string(br))
             }
             RegionsPlaceholderMismatch => {
                 write!(f, "one type is more general than the other")
@@ -125,9 +130,9 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
             Traits(values) => ty::tls::with(|tcx| {
                 report_maybe_different(f,
                                        &format!("trait `{}`",
-                                                tcx.item_path_str(values.expected)),
+                                                tcx.def_path_str(values.expected)),
                                        &format!("trait `{}`",
-                                                tcx.item_path_str(values.found)))
+                                                tcx.def_path_str(values.found)))
             }),
             IntMismatch(ref values) => {
                 write!(f, "expected `{:?}`, found `{:?}`",
@@ -146,8 +151,8 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
             }
             ProjectionMismatched(ref values) => ty::tls::with(|tcx| {
                 write!(f, "expected {}, found {}",
-                       tcx.item_path_str(values.expected),
-                       tcx.item_path_str(values.found))
+                       tcx.def_path_str(values.expected),
+                       tcx.def_path_str(values.found))
             }),
             ProjectionBoundsLength(ref values) => {
                 write!(f, "expected {} associated type bindings, found {}",
@@ -169,8 +174,8 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
             ty::Uint(_) | ty::Float(_) | ty::Str | ty::Never => self.to_string().into(),
             ty::Tuple(ref tys) if tys.is_empty() => self.to_string().into(),
 
-            ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.item_path_str(def.did)).into(),
-            ty::Foreign(def_id) => format!("extern type `{}`", tcx.item_path_str(def_id)).into(),
+            ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.def_path_str(def.did)).into(),
+            ty::Foreign(def_id) => format!("extern type `{}`", tcx.def_path_str(def_id)).into(),
             ty::Array(_, n) => match n {
                 ty::LazyConst::Evaluated(n) => match n.assert_usize(tcx) {
                     Some(n) => format!("array of {} elements", n).into(),
@@ -185,7 +190,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
                 let tymut_string = tymut.to_string();
                 if tymut_string == "_" ||         //unknown type name,
                    tymut_string.len() > 10 ||     //name longer than saying "reference",
-                   region.to_string() != ""       //... or a complex type
+                   region.to_string() != "'_"     //... or a complex type
                 {
                     format!("{}reference", match mutbl {
                         hir::Mutability::MutMutable => "mutable ",
@@ -199,7 +204,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
             ty::FnPtr(_) => "fn pointer".into(),
             ty::Dynamic(ref inner, ..) => {
                 if let Some(principal) = inner.principal() {
-                    format!("trait {}", tcx.item_path_str(principal.def_id())).into()
+                    format!("trait {}", tcx.def_path_str(principal.def_id())).into()
                 } else {
                     "trait".into()
                 }
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index e0b7bbc68e2..995e85fc5f4 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc/ty/instance.rs
@@ -1,10 +1,11 @@
 use crate::hir::Unsafety;
+use crate::hir::def::Namespace;
 use crate::hir::def_id::DefId;
 use crate::ty::{self, Ty, PolyFnSig, TypeFoldable, SubstsRef, TyCtxt};
+use crate::ty::print::{FmtPrinter, Printer};
 use crate::traits;
 use rustc_target::spec::abi::Abi;
 use rustc_macros::HashStable;
-use crate::util::ppaux;
 
 use std::fmt;
 use std::iter;
@@ -175,7 +176,13 @@ impl<'tcx> InstanceDef<'tcx> {
 
 impl<'tcx> fmt::Display for Instance<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        ppaux::parameterized(f, self.substs, self.def_id(), &[])?;
+        ty::tls::with(|tcx| {
+            let substs = tcx.lift(&self.substs).expect("could not lift for printing");
+            FmtPrinter::new(tcx, &mut *f, Namespace::ValueNS)
+                .print_def_path(self.def_id(), substs)?;
+            Ok(())
+        })?;
+
         match self.def {
             InstanceDef::Item(_) => Ok(()),
             InstanceDef::VtableShim(_) => {
diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs
deleted file mode 100644
index 26e2705a7a0..00000000000
--- a/src/librustc/ty/item_path.rs
+++ /dev/null
@@ -1,573 +0,0 @@
-use crate::hir::map::DefPathData;
-use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
-use crate::ty::{self, DefIdTree, Ty, TyCtxt};
-use crate::middle::cstore::{ExternCrate, ExternCrateSource};
-use syntax::ast;
-use syntax::symbol::{keywords, LocalInternedString, Symbol};
-
-use std::cell::Cell;
-use std::fmt::Debug;
-
-thread_local! {
-    static FORCE_ABSOLUTE: Cell<bool> = Cell::new(false);
-    static FORCE_IMPL_FILENAME_LINE: Cell<bool> = Cell::new(false);
-    static SHOULD_PREFIX_WITH_CRATE: Cell<bool> = Cell::new(false);
-}
-
-/// Enforces that item_path_str always returns an absolute path and
-/// also enables "type-based" impl paths. This is used when building
-/// symbols that contain types, where we want the crate name to be
-/// part of the symbol.
-pub fn with_forced_absolute_paths<F: FnOnce() -> R, R>(f: F) -> R {
-    FORCE_ABSOLUTE.with(|force| {
-        let old = force.get();
-        force.set(true);
-        let result = f();
-        force.set(old);
-        result
-    })
-}
-
-/// Force us to name impls with just the filename/line number. We
-/// normally try to use types. But at some points, notably while printing
-/// cycle errors, this can result in extra or suboptimal error output,
-/// so this variable disables that check.
-pub fn with_forced_impl_filename_line<F: FnOnce() -> R, R>(f: F) -> R {
-    FORCE_IMPL_FILENAME_LINE.with(|force| {
-        let old = force.get();
-        force.set(true);
-        let result = f();
-        force.set(old);
-        result
-    })
-}
-
-/// Adds the `crate::` prefix to paths where appropriate.
-pub fn with_crate_prefix<F: FnOnce() -> R, R>(f: F) -> R {
-    SHOULD_PREFIX_WITH_CRATE.with(|flag| {
-        let old = flag.get();
-        flag.set(true);
-        let result = f();
-        flag.set(old);
-        result
-    })
-}
-
-impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
-    /// Returns a string identifying this `DefId`. This string is
-    /// suitable for user output. It is relative to the current crate
-    /// root, unless with_forced_absolute_paths was used.
-    pub fn item_path_str(self, def_id: DefId) -> String {
-        let mode = FORCE_ABSOLUTE.with(|force| {
-            if force.get() {
-                RootMode::Absolute
-            } else {
-                RootMode::Local
-            }
-        });
-        let mut buffer = LocalPathBuffer::new(mode);
-        debug!("item_path_str: buffer={:?} def_id={:?}", buffer, def_id);
-        self.push_item_path(&mut buffer, def_id, false);
-        buffer.into_string()
-    }
-
-    /// Returns a string identifying this local node-id.
-    pub fn node_path_str(self, id: ast::NodeId) -> String {
-        self.item_path_str(self.hir().local_def_id(id))
-    }
-
-    /// Returns a string identifying this def-id. This string is
-    /// suitable for user output. It always begins with a crate identifier.
-    pub fn absolute_item_path_str(self, def_id: DefId) -> String {
-        let mut buffer = LocalPathBuffer::new(RootMode::Absolute);
-        debug!("absolute_item_path_str: buffer={:?} def_id={:?}", buffer, def_id);
-        self.push_item_path(&mut buffer, def_id, false);
-        buffer.into_string()
-    }
-
-    /// Returns the "path" to a particular crate. This can proceed in
-    /// various ways, depending on the `root_mode` of the `buffer`.
-    /// (See `RootMode` enum for more details.)
-    ///
-    /// `pushed_prelude_crate` argument should be `true` when the buffer
-    /// has had a prelude crate pushed to it. If this is the case, then
-    /// we do not want to prepend `crate::` (as that would not be a valid
-    /// path).
-    pub fn push_krate_path<T>(self, buffer: &mut T, cnum: CrateNum, pushed_prelude_crate: bool)
-        where T: ItemPathBuffer + Debug
-    {
-        debug!(
-            "push_krate_path: buffer={:?} cnum={:?} LOCAL_CRATE={:?}",
-            buffer, cnum, LOCAL_CRATE
-        );
-        match *buffer.root_mode() {
-            RootMode::Local => {
-                // In local mode, when we encounter a crate other than
-                // LOCAL_CRATE, execution proceeds in one of two ways:
-                //
-                // 1. for a direct dependency, where user added an
-                //    `extern crate` manually, we put the `extern
-                //    crate` as the parent. So you wind up with
-                //    something relative to the current crate.
-                // 2. for an extern inferred from a path or an indirect crate,
-                //    where there is no explicit `extern crate`, we just prepend
-                //    the crate name.
-                //
-                // Returns `None` for the local crate.
-                if cnum != LOCAL_CRATE {
-                    let opt_extern_crate = self.extern_crate(cnum.as_def_id());
-                    if let Some(ExternCrate {
-                        src: ExternCrateSource::Extern(def_id),
-                        direct: true,
-                        ..
-                    }) = *opt_extern_crate
-                    {
-                        debug!("push_krate_path: def_id={:?}", def_id);
-                        self.push_item_path(buffer, def_id, pushed_prelude_crate);
-                    } else {
-                        let name = self.crate_name(cnum).as_str();
-                        debug!("push_krate_path: name={:?}", name);
-                        buffer.push(&name);
-                    }
-                } else if self.sess.rust_2018() && !pushed_prelude_crate {
-                    SHOULD_PREFIX_WITH_CRATE.with(|flag| {
-                        // We only add the `crate::` keyword where appropriate. In particular,
-                        // when we've not previously pushed a prelude crate to this path.
-                        if flag.get() {
-                            buffer.push(&keywords::Crate.name().as_str())
-                        }
-                    })
-                }
-            }
-            RootMode::Absolute => {
-                // In absolute mode, just write the crate name
-                // unconditionally.
-                let name = self.original_crate_name(cnum).as_str();
-                debug!("push_krate_path: original_name={:?}", name);
-                buffer.push(&name);
-            }
-        }
-    }
-
-    /// If possible, this pushes a global path resolving to `external_def_id` that is visible
-    /// from at least one local module and returns true. If the crate defining `external_def_id` is
-    /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
-    pub fn try_push_visible_item_path<T>(
-        self,
-        buffer: &mut T,
-        external_def_id: DefId,
-        pushed_prelude_crate: bool,
-    ) -> bool
-        where T: ItemPathBuffer + Debug
-    {
-        debug!(
-            "try_push_visible_item_path: buffer={:?} external_def_id={:?}",
-            buffer, external_def_id
-        );
-        let visible_parent_map = self.visible_parent_map(LOCAL_CRATE);
-
-        let (mut cur_def, mut cur_path) = (external_def_id, Vec::<LocalInternedString>::new());
-        loop {
-            debug!(
-                "try_push_visible_item_path: cur_def={:?} cur_path={:?} CRATE_DEF_INDEX={:?}",
-                cur_def, cur_path, CRATE_DEF_INDEX,
-            );
-            // If `cur_def` is a direct or injected extern crate, push the path to the crate
-            // followed by the path to the item within the crate and return.
-            if cur_def.index == CRATE_DEF_INDEX {
-                match *self.extern_crate(cur_def) {
-                    Some(ExternCrate {
-                        src: ExternCrateSource::Extern(def_id),
-                        direct: true,
-                        ..
-                    }) => {
-                        debug!("try_push_visible_item_path: def_id={:?}", def_id);
-                        self.push_item_path(buffer, def_id, pushed_prelude_crate);
-                        cur_path.iter().rev().for_each(|segment| buffer.push(&segment));
-                        return true;
-                    }
-                    None => {
-                        buffer.push(&self.crate_name(cur_def.krate).as_str());
-                        cur_path.iter().rev().for_each(|segment| buffer.push(&segment));
-                        return true;
-                    }
-                    _ => {},
-                }
-            }
-
-            let mut cur_def_key = self.def_key(cur_def);
-            debug!("try_push_visible_item_path: cur_def_key={:?}", cur_def_key);
-
-            // For a UnitStruct or TupleStruct we want the name of its parent rather than <unnamed>.
-            if let DefPathData::StructCtor = cur_def_key.disambiguated_data.data {
-                let parent = DefId {
-                    krate: cur_def.krate,
-                    index: cur_def_key.parent.expect("DefPathData::StructCtor missing a parent"),
-                };
-
-                cur_def_key = self.def_key(parent);
-            }
-
-            let visible_parent = visible_parent_map.get(&cur_def).cloned();
-            let actual_parent = self.parent(cur_def);
-
-            let data = cur_def_key.disambiguated_data.data;
-            debug!(
-                "try_push_visible_item_path: data={:?} visible_parent={:?} actual_parent={:?}",
-                data, visible_parent, actual_parent,
-            );
-            let symbol = match data {
-                // In order to output a path that could actually be imported (valid and visible),
-                // we need to handle re-exports correctly.
-                //
-                // For example, take `std::os::unix::process::CommandExt`, this trait is actually
-                // defined at `std::sys::unix::ext::process::CommandExt` (at time of writing).
-                //
-                // `std::os::unix` rexports the contents of `std::sys::unix::ext`. `std::sys` is
-                // private so the "true" path to `CommandExt` isn't accessible.
-                //
-                // In this case, the `visible_parent_map` will look something like this:
-                //
-                // (child) -> (parent)
-                // `std::sys::unix::ext::process::CommandExt` -> `std::sys::unix::ext::process`
-                // `std::sys::unix::ext::process` -> `std::sys::unix::ext`
-                // `std::sys::unix::ext` -> `std::os`
-                //
-                // This is correct, as the visible parent of `std::sys::unix::ext` is in fact
-                // `std::os`.
-                //
-                // When printing the path to `CommandExt` and looking at the `cur_def_key` that
-                // corresponds to `std::sys::unix::ext`, we would normally print `ext` and then go
-                // to the parent - resulting in a mangled path like
-                // `std::os::ext::process::CommandExt`.
-                //
-                // Instead, we must detect that there was a re-export and instead print `unix`
-                // (which is the name `std::sys::unix::ext` was re-exported as in `std::os`). To
-                // do this, we compare the parent of `std::sys::unix::ext` (`std::sys::unix`) with
-                // the visible parent (`std::os`). If these do not match, then we iterate over
-                // the children of the visible parent (as was done when computing
-                // `visible_parent_map`), looking for the specific child we currently have and then
-                // have access to the re-exported name.
-                DefPathData::Module(actual_name) |
-                DefPathData::TypeNs(actual_name) if visible_parent != actual_parent => {
-                    visible_parent
-                        .and_then(|parent| {
-                            self.item_children(parent)
-                                .iter()
-                                .find(|child| child.def.def_id() == cur_def)
-                                .map(|child| child.ident.as_str())
-                        })
-                        .unwrap_or_else(|| actual_name.as_str())
-                },
-                _ => {
-                    data.get_opt_name().map(|n| n.as_str()).unwrap_or_else(|| {
-                        // Re-exported `extern crate` (#43189).
-                        if let DefPathData::CrateRoot = data {
-                            self.original_crate_name(cur_def.krate).as_str()
-                        } else {
-                            Symbol::intern("<unnamed>").as_str()
-                        }
-                    })
-                },
-            };
-            debug!("try_push_visible_item_path: symbol={:?}", symbol);
-            cur_path.push(symbol);
-
-            match visible_parent {
-                Some(def) => cur_def = def,
-                None => return false,
-            };
-        }
-    }
-
-    pub fn push_item_path<T>(self, buffer: &mut T, def_id: DefId, pushed_prelude_crate: bool)
-        where T: ItemPathBuffer + Debug
-    {
-        debug!(
-            "push_item_path: buffer={:?} def_id={:?} pushed_prelude_crate={:?}",
-            buffer, def_id, pushed_prelude_crate
-        );
-        match *buffer.root_mode() {
-            RootMode::Local if !def_id.is_local() =>
-                if self.try_push_visible_item_path(buffer, def_id, pushed_prelude_crate) { return },
-            _ => {}
-        }
-
-        let key = self.def_key(def_id);
-        debug!("push_item_path: key={:?}", key);
-        match key.disambiguated_data.data {
-            DefPathData::CrateRoot => {
-                assert!(key.parent.is_none());
-                self.push_krate_path(buffer, def_id.krate, pushed_prelude_crate);
-            }
-
-            DefPathData::Impl => {
-                self.push_impl_path(buffer, def_id, pushed_prelude_crate);
-            }
-
-            // Unclear if there is any value in distinguishing these.
-            // Probably eventually (and maybe we would even want
-            // finer-grained distinctions, e.g., between enum/struct).
-            data @ DefPathData::Misc |
-            data @ DefPathData::TypeNs(..) |
-            data @ DefPathData::Trait(..) |
-            data @ DefPathData::TraitAlias(..) |
-            data @ DefPathData::AssocTypeInTrait(..) |
-            data @ DefPathData::AssocTypeInImpl(..) |
-            data @ DefPathData::AssocExistentialInImpl(..) |
-            data @ DefPathData::ValueNs(..) |
-            data @ DefPathData::Module(..) |
-            data @ DefPathData::TypeParam(..) |
-            data @ DefPathData::LifetimeParam(..) |
-            data @ DefPathData::ConstParam(..) |
-            data @ DefPathData::EnumVariant(..) |
-            data @ DefPathData::Field(..) |
-            data @ DefPathData::AnonConst |
-            data @ DefPathData::MacroDef(..) |
-            data @ DefPathData::ClosureExpr |
-            data @ DefPathData::ImplTrait |
-            data @ DefPathData::GlobalMetaData(..) => {
-                let parent_did = self.parent_def_id(def_id).unwrap();
-
-                // Keep track of whether we are one recursion away from the `CrateRoot` and
-                // pushing the name of a prelude crate. If we are, we'll want to know this when
-                // printing the `CrateRoot` so we don't prepend a `crate::` to paths.
-                let mut is_prelude_crate = false;
-                if let DefPathData::CrateRoot = self.def_key(parent_did).disambiguated_data.data {
-                    if self.extern_prelude.contains_key(&data.as_interned_str().as_symbol()) {
-                        is_prelude_crate = true;
-                    }
-                }
-
-                self.push_item_path(
-                    buffer, parent_did, pushed_prelude_crate || is_prelude_crate
-                );
-                buffer.push(&data.as_interned_str().as_symbol().as_str());
-            },
-
-            DefPathData::StructCtor => { // present `X` instead of `X::{{constructor}}`
-                let parent_def_id = self.parent_def_id(def_id).unwrap();
-                self.push_item_path(buffer, parent_def_id, pushed_prelude_crate);
-            }
-        }
-    }
-
-    fn push_impl_path<T>(
-        self,
-         buffer: &mut T,
-         impl_def_id: DefId,
-         pushed_prelude_crate: bool,
-    )
-        where T: ItemPathBuffer + Debug
-    {
-        debug!("push_impl_path: buffer={:?} impl_def_id={:?}", buffer, impl_def_id);
-        let parent_def_id = self.parent_def_id(impl_def_id).unwrap();
-
-        // Always use types for non-local impls, where types are always
-        // available, and filename/line-number is mostly uninteresting.
-        let use_types = !impl_def_id.is_local() || {
-            // Otherwise, use filename/line-number if forced.
-            let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get());
-            !force_no_types
-        };
-
-        if !use_types {
-            return self.push_impl_path_fallback(buffer, impl_def_id, pushed_prelude_crate);
-        }
-
-        // Decide whether to print the parent path for the impl.
-        // Logically, since impls are global, it's never needed, but
-        // users may find it useful. Currently, we omit the parent if
-        // the impl is either in the same module as the self-type or
-        // as the trait.
-        let self_ty = self.type_of(impl_def_id);
-        let in_self_mod = match characteristic_def_id_of_type(self_ty) {
-            None => false,
-            Some(ty_def_id) => self.parent_def_id(ty_def_id) == Some(parent_def_id),
-        };
-
-        let impl_trait_ref = self.impl_trait_ref(impl_def_id);
-        let in_trait_mod = match impl_trait_ref {
-            None => false,
-            Some(trait_ref) => self.parent_def_id(trait_ref.def_id) == Some(parent_def_id),
-        };
-
-        if !in_self_mod && !in_trait_mod {
-            // If the impl is not co-located with either self-type or
-            // trait-type, then fallback to a format that identifies
-            // the module more clearly.
-            self.push_item_path(buffer, parent_def_id, pushed_prelude_crate);
-            if let Some(trait_ref) = impl_trait_ref {
-                buffer.push(&format!("<impl {} for {}>", trait_ref, self_ty));
-            } else {
-                buffer.push(&format!("<impl {}>", self_ty));
-            }
-            return;
-        }
-
-        // Otherwise, try to give a good form that would be valid language
-        // syntax. Preferably using associated item notation.
-
-        if let Some(trait_ref) = impl_trait_ref {
-            // Trait impls.
-            buffer.push(&format!("<{} as {}>", self_ty, trait_ref));
-            return;
-        }
-
-        // Inherent impls. Try to print `Foo::bar` for an inherent
-        // impl on `Foo`, but fallback to `<Foo>::bar` if self-type is
-        // anything other than a simple path.
-        match self_ty.sty {
-            ty::Adt(adt_def, substs) => {
-                if substs.types().next().is_none() { // ignore regions
-                    self.push_item_path(buffer, adt_def.did, pushed_prelude_crate);
-                } else {
-                    buffer.push(&format!("<{}>", self_ty));
-                }
-            }
-
-            ty::Foreign(did) => self.push_item_path(buffer, did, pushed_prelude_crate),
-
-            ty::Bool |
-            ty::Char |
-            ty::Int(_) |
-            ty::Uint(_) |
-            ty::Float(_) |
-            ty::Str => {
-                buffer.push(&self_ty.to_string());
-            }
-
-            _ => {
-                buffer.push(&format!("<{}>", self_ty));
-            }
-        }
-    }
-
-    fn push_impl_path_fallback<T>(
-        self,
-        buffer: &mut T,
-        impl_def_id: DefId,
-        pushed_prelude_crate: bool,
-    )
-        where T: ItemPathBuffer + Debug
-    {
-        // If no type info is available, fall back to
-        // pretty printing some span information. This should
-        // only occur very early in the compiler pipeline.
-        let parent_def_id = self.parent_def_id(impl_def_id).unwrap();
-        self.push_item_path(buffer, parent_def_id, pushed_prelude_crate);
-        let hir_id = self.hir().as_local_hir_id(impl_def_id).unwrap();
-        let item = self.hir().expect_item_by_hir_id(hir_id);
-        let span_str = self.sess.source_map().span_to_string(item.span);
-        buffer.push(&format!("<impl at {}>", span_str));
-    }
-
-    /// Returns the `DefId` of `def_id`'s parent in the def tree. If
-    /// this returns `None`, then `def_id` represents a crate root or
-    /// inlined root.
-    pub fn parent_def_id(self, def_id: DefId) -> Option<DefId> {
-        let key = self.def_key(def_id);
-        key.parent.map(|index| DefId { krate: def_id.krate, index: index })
-    }
-}
-
-/// As a heuristic, when we see an impl, if we see that the
-/// 'self type' is a type defined in the same module as the impl,
-/// we can omit including the path to the impl itself. This
-/// function tries to find a "characteristic `DefId`" for a
-/// type. It's just a heuristic so it makes some questionable
-/// decisions and we may want to adjust it later.
-pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
-    match ty.sty {
-        ty::Adt(adt_def, _) => Some(adt_def.did),
-
-        ty::Dynamic(data, ..) => data.principal_def_id(),
-
-        ty::Array(subty, _) |
-        ty::Slice(subty) => characteristic_def_id_of_type(subty),
-
-        ty::RawPtr(mt) => characteristic_def_id_of_type(mt.ty),
-
-        ty::Ref(_, ty, _) => characteristic_def_id_of_type(ty),
-
-        ty::Tuple(ref tys) => tys.iter()
-                                   .filter_map(|ty| characteristic_def_id_of_type(ty))
-                                   .next(),
-
-        ty::FnDef(def_id, _) |
-        ty::Closure(def_id, _) |
-        ty::Generator(def_id, _, _) |
-        ty::Foreign(def_id) => Some(def_id),
-
-        ty::Bool |
-        ty::Char |
-        ty::Int(_) |
-        ty::Uint(_) |
-        ty::Str |
-        ty::FnPtr(_) |
-        ty::Projection(_) |
-        ty::Placeholder(..) |
-        ty::UnnormalizedProjection(..) |
-        ty::Param(_) |
-        ty::Opaque(..) |
-        ty::Infer(_) |
-        ty::Bound(..) |
-        ty::Error |
-        ty::GeneratorWitness(..) |
-        ty::Never |
-        ty::Float(_) => None,
-    }
-}
-
-/// Unifying Trait for different kinds of item paths we might
-/// construct. The basic interface is that components get pushed: the
-/// instance can also customize how we handle the root of a crate.
-pub trait ItemPathBuffer {
-    fn root_mode(&self) -> &RootMode;
-    fn push(&mut self, text: &str);
-}
-
-#[derive(Debug)]
-pub enum RootMode {
-    /// Try to make a path relative to the local crate. In
-    /// particular, local paths have no prefix, and if the path comes
-    /// from an extern crate, start with the path to the `extern
-    /// crate` declaration.
-    Local,
-
-    /// Always prepend the crate name to the path, forming an absolute
-    /// path from within a given set of crates.
-    Absolute,
-}
-
-#[derive(Debug)]
-struct LocalPathBuffer {
-    root_mode: RootMode,
-    str: String,
-}
-
-impl LocalPathBuffer {
-    fn new(root_mode: RootMode) -> LocalPathBuffer {
-        LocalPathBuffer {
-            root_mode,
-            str: String::new(),
-        }
-    }
-
-    fn into_string(self) -> String {
-        self.str
-    }
-}
-
-impl ItemPathBuffer for LocalPathBuffer {
-    fn root_mode(&self) -> &RootMode {
-        &self.root_mode
-    }
-
-    fn push(&mut self, text: &str) {
-        if !self.str.is_empty() {
-            self.str.push_str("::");
-        }
-        self.str.push_str(text);
-    }
-}
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 68bdae7d744..882e2dc62b1 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -95,10 +95,10 @@ mod erase_regions;
 pub mod fast_reject;
 pub mod fold;
 pub mod inhabitedness;
-pub mod item_path;
 pub mod layout;
 pub mod _match;
 pub mod outlives;
+pub mod print;
 pub mod query;
 pub mod relate;
 pub mod steal;
@@ -1000,7 +1000,7 @@ impl<'a, 'gcx, 'tcx> Generics {
 }
 
 /// Bounds on generics.
-#[derive(Clone, Default, HashStable)]
+#[derive(Clone, Default, Debug, HashStable)]
 pub struct GenericPredicates<'tcx> {
     pub parent: Option<DefId>,
     pub predicates: Vec<(Predicate<'tcx>, Span)>,
@@ -1505,7 +1505,7 @@ impl<'tcx> Predicate<'tcx> {
 /// `[[], [U:Bar<T>]]`. Now if there were some particular reference
 /// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
 /// [usize:Bar<isize>]]`.
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 pub struct InstantiatedPredicates<'tcx> {
     pub predicates: Vec<Predicate<'tcx>>,
 }
@@ -2055,7 +2055,7 @@ impl ReprOptions {
         }
 
         // This is here instead of layout because the choice must make it into metadata.
-        if !tcx.consider_optimizing(|| format!("Reorder fields of {:?}", tcx.item_path_str(did))) {
+        if !tcx.consider_optimizing(|| format!("Reorder fields of {:?}", tcx.def_path_str(did))) {
             flags.insert(ReprFlags::IS_LINEAR);
         }
         ReprOptions { int: size, align: max_align, pack: min_pack, flags: flags }
@@ -2892,14 +2892,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     pub fn expect_variant_def(self, def: Def) -> &'tcx VariantDef {
         match def {
             Def::Variant(did) | Def::VariantCtor(did, ..) => {
-                let enum_did = self.parent_def_id(did).unwrap();
+                let enum_did = self.parent(did).unwrap();
                 self.adt_def(enum_did).variant_with_id(did)
             }
             Def::Struct(did) | Def::Union(did) => {
                 self.adt_def(did).non_enum_variant()
             }
             Def::StructCtor(ctor_did, ..) => {
-                let did = self.parent_def_id(ctor_did).expect("struct ctor has no parent");
+                let did = self.parent(ctor_did).expect("struct ctor has no parent");
                 self.adt_def(did).non_enum_variant()
             }
             _ => bug!("expect_variant_def used with unexpected def {:?}", def)
diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs
new file mode 100644
index 00000000000..ef30a4032d8
--- /dev/null
+++ b/src/librustc/ty/print/mod.rs
@@ -0,0 +1,327 @@
+use crate::hir::map::{DefPathData, DisambiguatedDefPathData};
+use crate::hir::def_id::{CrateNum, DefId};
+use crate::ty::{self, DefIdTree, Ty, TyCtxt};
+use crate::ty::subst::{Kind, Subst};
+
+use rustc_data_structures::fx::FxHashSet;
+
+// `pretty` is a separate module only for organization.
+mod pretty;
+pub use self::pretty::*;
+
+pub trait Print<'gcx, 'tcx, P> {
+    type Output;
+    type Error;
+
+    fn print(&self, cx: P) -> Result<Self::Output, Self::Error>;
+}
+
+/// Interface for outputting user-facing "type-system entities"
+/// (paths, types, lifetimes, constants, etc.) as a side-effect
+/// (e.g. formatting, like `PrettyPrinter` implementors do) or by
+/// constructing some alternative representation (e.g. an AST),
+/// which the associated types allow passing through the methods.
+///
+/// For pretty-printing/formatting in particular, see `PrettyPrinter`.
+// FIXME(eddyb) find a better name, this is more general than "printing".
+pub trait Printer<'gcx: 'tcx, 'tcx>: Sized {
+    type Error;
+
+    type Path;
+    type Region;
+    type Type;
+    type DynExistential;
+
+    fn tcx(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>;
+
+    fn print_def_path(
+        self,
+        def_id: DefId,
+        substs: &'tcx [Kind<'tcx>],
+    ) -> Result<Self::Path, Self::Error> {
+        self.default_print_def_path(def_id, substs)
+    }
+    fn print_impl_path(
+        self,
+        impl_def_id: DefId,
+        substs: &'tcx [Kind<'tcx>],
+        self_ty: Ty<'tcx>,
+        trait_ref: Option<ty::TraitRef<'tcx>>,
+    ) -> Result<Self::Path, Self::Error> {
+        self.default_print_impl_path(impl_def_id, substs, self_ty, trait_ref)
+    }
+
+    fn print_region(
+        self,
+        region: ty::Region<'_>,
+    ) -> Result<Self::Region, Self::Error>;
+
+    fn print_type(
+        self,
+        ty: Ty<'tcx>,
+    ) -> Result<Self::Type, Self::Error>;
+
+    fn print_dyn_existential(
+        self,
+        predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
+    ) -> Result<Self::DynExistential, Self::Error>;
+
+    fn path_crate(
+        self,
+        cnum: CrateNum,
+    ) -> Result<Self::Path, Self::Error>;
+    fn path_qualified(
+        self,
+        self_ty: Ty<'tcx>,
+        trait_ref: Option<ty::TraitRef<'tcx>>,
+    ) -> Result<Self::Path, Self::Error>;
+
+    fn path_append_impl(
+        self,
+        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
+        disambiguated_data: &DisambiguatedDefPathData,
+        self_ty: Ty<'tcx>,
+        trait_ref: Option<ty::TraitRef<'tcx>>,
+    ) -> Result<Self::Path, Self::Error>;
+    fn path_append(
+        self,
+        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
+        disambiguated_data: &DisambiguatedDefPathData,
+    ) -> Result<Self::Path, Self::Error>;
+    fn path_generic_args(
+        self,
+        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
+        args: &[Kind<'tcx>],
+    ) -> Result<Self::Path, Self::Error>;
+
+    // Defaults (should not be overriden):
+
+    fn default_print_def_path(
+        self,
+        def_id: DefId,
+        substs: &'tcx [Kind<'tcx>],
+    ) -> Result<Self::Path, Self::Error> {
+        debug!("default_print_def_path: def_id={:?}, substs={:?}", def_id, substs);
+        let key = self.tcx().def_key(def_id);
+        debug!("default_print_def_path: key={:?}", key);
+
+        match key.disambiguated_data.data {
+            DefPathData::CrateRoot => {
+                assert!(key.parent.is_none());
+                self.path_crate(def_id.krate)
+            }
+
+            DefPathData::Impl => {
+                let generics = self.tcx().generics_of(def_id);
+                let mut self_ty = self.tcx().type_of(def_id);
+                let mut impl_trait_ref = self.tcx().impl_trait_ref(def_id);
+                if substs.len() >= generics.count() {
+                    self_ty = self_ty.subst(self.tcx(), substs);
+                    impl_trait_ref = impl_trait_ref.subst(self.tcx(), substs);
+                }
+                self.print_impl_path(def_id, substs, self_ty, impl_trait_ref)
+            }
+
+            _ => {
+                let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id };
+
+                let mut parent_substs = substs;
+                let mut trait_qualify_parent = false;
+                if !substs.is_empty() {
+                    let generics = self.tcx().generics_of(def_id);
+                    parent_substs = &substs[..generics.parent_count.min(substs.len())];
+
+                    match key.disambiguated_data.data {
+                        // Closures' own generics are only captures, don't print them.
+                        DefPathData::ClosureExpr => {}
+
+                        // If we have any generic arguments to print, we do that
+                        // on top of the same path, but without its own generics.
+                        _ => if !generics.params.is_empty() && substs.len() >= generics.count() {
+                            let args = self.generic_args_to_print(generics, substs);
+                            return self.path_generic_args(
+                                |cx| cx.print_def_path(def_id, parent_substs),
+                                args,
+                            );
+                        }
+                    }
+
+                    // FIXME(eddyb) try to move this into the parent's printing
+                    // logic, instead of doing it when printing the child.
+                    trait_qualify_parent =
+                        generics.has_self &&
+                        generics.parent == Some(parent_def_id) &&
+                        parent_substs.len() == generics.parent_count &&
+                        self.tcx().generics_of(parent_def_id).parent_count == 0;
+                }
+
+                self.path_append(
+                    |cx: Self| if trait_qualify_parent {
+                        let trait_ref = ty::TraitRef::new(
+                            parent_def_id,
+                            cx.tcx().intern_substs(parent_substs),
+                        );
+                        cx.path_qualified(trait_ref.self_ty(), Some(trait_ref))
+                    } else {
+                        cx.print_def_path(parent_def_id, parent_substs)
+                    },
+                    &key.disambiguated_data,
+                )
+            }
+        }
+    }
+
+    fn generic_args_to_print(
+        &self,
+        generics: &'tcx ty::Generics,
+        substs: &'tcx [Kind<'tcx>],
+    ) -> &'tcx [Kind<'tcx>] {
+        let mut own_params = generics.parent_count..generics.count();
+
+        // Don't print args for `Self` parameters (of traits).
+        if generics.has_self && own_params.start == 0 {
+            own_params.start = 1;
+        }
+
+        // Don't print args that are the defaults of their respective parameters.
+        own_params.end -= generics.params.iter().rev().take_while(|param| {
+            match param.kind {
+                ty::GenericParamDefKind::Lifetime => false,
+                ty::GenericParamDefKind::Type { has_default, .. } => {
+                    has_default && substs[param.index as usize] == Kind::from(
+                        self.tcx().type_of(param.def_id).subst(self.tcx(), substs)
+                    )
+                }
+                ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults)
+            }
+        }).count();
+
+        &substs[own_params]
+    }
+
+    fn default_print_impl_path(
+        self,
+        impl_def_id: DefId,
+        _substs: &'tcx [Kind<'tcx>],
+        self_ty: Ty<'tcx>,
+        impl_trait_ref: Option<ty::TraitRef<'tcx>>,
+    ) -> Result<Self::Path, Self::Error> {
+        debug!("default_print_impl_path: impl_def_id={:?}, self_ty={}, impl_trait_ref={:?}",
+               impl_def_id, self_ty, impl_trait_ref);
+
+        let key = self.tcx().def_key(impl_def_id);
+        let parent_def_id = DefId { index: key.parent.unwrap(), ..impl_def_id };
+
+        // Decide whether to print the parent path for the impl.
+        // Logically, since impls are global, it's never needed, but
+        // users may find it useful. Currently, we omit the parent if
+        // the impl is either in the same module as the self-type or
+        // as the trait.
+        let in_self_mod = match characteristic_def_id_of_type(self_ty) {
+            None => false,
+            Some(ty_def_id) => self.tcx().parent(ty_def_id) == Some(parent_def_id),
+        };
+        let in_trait_mod = match impl_trait_ref {
+            None => false,
+            Some(trait_ref) => self.tcx().parent(trait_ref.def_id) == Some(parent_def_id),
+        };
+
+        if !in_self_mod && !in_trait_mod {
+            // If the impl is not co-located with either self-type or
+            // trait-type, then fallback to a format that identifies
+            // the module more clearly.
+            self.path_append_impl(
+                |cx| cx.print_def_path(parent_def_id, &[]),
+                &key.disambiguated_data,
+                self_ty,
+                impl_trait_ref,
+            )
+        } else {
+            // Otherwise, try to give a good form that would be valid language
+            // syntax. Preferably using associated item notation.
+            self.path_qualified(self_ty, impl_trait_ref)
+        }
+    }
+}
+
+/// As a heuristic, when we see an impl, if we see that the
+/// 'self type' is a type defined in the same module as the impl,
+/// we can omit including the path to the impl itself. This
+/// function tries to find a "characteristic `DefId`" for a
+/// type. It's just a heuristic so it makes some questionable
+/// decisions and we may want to adjust it later.
+pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
+    match ty.sty {
+        ty::Adt(adt_def, _) => Some(adt_def.did),
+
+        ty::Dynamic(data, ..) => data.principal_def_id(),
+
+        ty::Array(subty, _) |
+        ty::Slice(subty) => characteristic_def_id_of_type(subty),
+
+        ty::RawPtr(mt) => characteristic_def_id_of_type(mt.ty),
+
+        ty::Ref(_, ty, _) => characteristic_def_id_of_type(ty),
+
+        ty::Tuple(ref tys) => tys.iter()
+                                   .filter_map(|ty| characteristic_def_id_of_type(ty))
+                                   .next(),
+
+        ty::FnDef(def_id, _) |
+        ty::Closure(def_id, _) |
+        ty::Generator(def_id, _, _) |
+        ty::Foreign(def_id) => Some(def_id),
+
+        ty::Bool |
+        ty::Char |
+        ty::Int(_) |
+        ty::Uint(_) |
+        ty::Str |
+        ty::FnPtr(_) |
+        ty::Projection(_) |
+        ty::Placeholder(..) |
+        ty::UnnormalizedProjection(..) |
+        ty::Param(_) |
+        ty::Opaque(..) |
+        ty::Infer(_) |
+        ty::Bound(..) |
+        ty::Error |
+        ty::GeneratorWitness(..) |
+        ty::Never |
+        ty::Float(_) => None,
+    }
+}
+
+impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for ty::RegionKind {
+    type Output = P::Region;
+    type Error = P::Error;
+    fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
+        cx.print_region(self)
+    }
+}
+
+impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for ty::Region<'_> {
+    type Output = P::Region;
+    type Error = P::Error;
+    fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
+        cx.print_region(self)
+    }
+}
+
+impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for Ty<'tcx> {
+    type Output = P::Type;
+    type Error = P::Error;
+    fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
+        cx.print_type(self)
+    }
+}
+
+impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P>
+    for &'tcx ty::List<ty::ExistentialPredicate<'tcx>>
+{
+    type Output = P::DynExistential;
+    type Error = P::Error;
+    fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
+        cx.print_dyn_existential(self)
+    }
+}
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
new file mode 100644
index 00000000000..fa57e0b9674
--- /dev/null
+++ b/src/librustc/ty/print/pretty.rs
@@ -0,0 +1,1621 @@
+use crate::hir;
+use crate::hir::def::Namespace;
+use crate::hir::map::{DefPathData, DisambiguatedDefPathData};
+use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
+use crate::middle::cstore::{ExternCrate, ExternCrateSource};
+use crate::middle::region;
+use crate::ty::{self, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable};
+use crate::ty::subst::{Kind, Subst, UnpackedKind};
+use crate::mir::interpret::ConstValue;
+use syntax::symbol::{keywords, Symbol};
+
+use rustc_target::spec::abi::Abi;
+use syntax::symbol::InternedString;
+
+use std::cell::Cell;
+use std::fmt::{self, Write as _};
+use std::ops::{Deref, DerefMut};
+
+// `pretty` is a separate module only for organization.
+use super::*;
+
+macro_rules! p {
+    (@write($($data:expr),+)) => {
+        write!(scoped_cx!(), $($data),+)?
+    };
+    (@print($x:expr)) => {
+        scoped_cx!() = $x.print(scoped_cx!())?
+    };
+    (@$method:ident($($arg:expr),*)) => {
+        scoped_cx!() = scoped_cx!().$method($($arg),*)?
+    };
+    ($($kind:ident $data:tt),+) => {{
+        $(p!(@$kind $data);)+
+    }};
+}
+macro_rules! define_scoped_cx {
+    ($cx:ident) => {
+        #[allow(unused_macros)]
+        macro_rules! scoped_cx {
+            () => ($cx)
+        }
+    };
+}
+
+thread_local! {
+    static FORCE_IMPL_FILENAME_LINE: Cell<bool> = Cell::new(false);
+    static SHOULD_PREFIX_WITH_CRATE: Cell<bool> = Cell::new(false);
+}
+
+/// Force us to name impls with just the filename/line number. We
+/// normally try to use types. But at some points, notably while printing
+/// cycle errors, this can result in extra or suboptimal error output,
+/// so this variable disables that check.
+pub fn with_forced_impl_filename_line<F: FnOnce() -> R, R>(f: F) -> R {
+    FORCE_IMPL_FILENAME_LINE.with(|force| {
+        let old = force.get();
+        force.set(true);
+        let result = f();
+        force.set(old);
+        result
+    })
+}
+
+/// Adds the `crate::` prefix to paths where appropriate.
+pub fn with_crate_prefix<F: FnOnce() -> R, R>(f: F) -> R {
+    SHOULD_PREFIX_WITH_CRATE.with(|flag| {
+        let old = flag.get();
+        flag.set(true);
+        let result = f();
+        flag.set(old);
+        result
+    })
+}
+
+/// The "region highlights" are used to control region printing during
+/// specific error messages. When a "region highlight" is enabled, it
+/// gives an alternate way to print specific regions. For now, we
+/// always print those regions using a number, so something like "`'0`".
+///
+/// Regions not selected by the region highlight mode are presently
+/// unaffected.
+#[derive(Copy, Clone, Default)]
+pub struct RegionHighlightMode {
+    /// If enabled, when we see the selected region, use "`'N`"
+    /// instead of the ordinary behavior.
+    highlight_regions: [Option<(ty::RegionKind, usize)>; 3],
+
+    /// If enabled, when printing a "free region" that originated from
+    /// the given `ty::BoundRegion`, print it as "`'1`". Free regions that would ordinarily
+    /// have names print as normal.
+    ///
+    /// This is used when you have a signature like `fn foo(x: &u32,
+    /// y: &'a u32)` and we want to give a name to the region of the
+    /// reference `x`.
+    highlight_bound_region: Option<(ty::BoundRegion, usize)>,
+}
+
+impl RegionHighlightMode {
+    /// If `region` and `number` are both `Some`, invokes
+    /// `highlighting_region`.
+    pub fn maybe_highlighting_region(
+        &mut self,
+        region: Option<ty::Region<'_>>,
+        number: Option<usize>,
+    ) {
+        if let Some(k) = region {
+            if let Some(n) = number {
+                self.highlighting_region(k, n);
+            }
+        }
+    }
+
+    /// Highlights the region inference variable `vid` as `'N`.
+    pub fn highlighting_region(
+        &mut self,
+        region: ty::Region<'_>,
+        number: usize,
+    ) {
+        let num_slots = self.highlight_regions.len();
+        let first_avail_slot = self.highlight_regions.iter_mut()
+            .filter(|s| s.is_none())
+            .next()
+            .unwrap_or_else(|| {
+                bug!(
+                    "can only highlight {} placeholders at a time",
+                    num_slots,
+                )
+            });
+        *first_avail_slot = Some((*region, number));
+    }
+
+    /// Convenience wrapper for `highlighting_region`.
+    pub fn highlighting_region_vid(
+        &mut self,
+        vid: ty::RegionVid,
+        number: usize,
+    ) {
+        self.highlighting_region(&ty::ReVar(vid), number)
+    }
+
+    /// Returns `Some(n)` with the number to use for the given region, if any.
+    fn region_highlighted(&self, region: ty::Region<'_>) -> Option<usize> {
+        self
+            .highlight_regions
+            .iter()
+            .filter_map(|h| match h {
+                Some((r, n)) if r == region => Some(*n),
+                _ => None,
+            })
+            .next()
+    }
+
+    /// Highlight the given bound region.
+    /// We can only highlight one bound region at a time. See
+    /// the field `highlight_bound_region` for more detailed notes.
+    pub fn highlighting_bound_region(
+        &mut self,
+        br: ty::BoundRegion,
+        number: usize,
+    ) {
+        assert!(self.highlight_bound_region.is_none());
+        self.highlight_bound_region = Some((br, number));
+    }
+}
+
+/// Trait for printers that pretty-print using `fmt::Write` to the printer.
+pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
+    Printer<'gcx, 'tcx,
+        Error = fmt::Error,
+        Path = Self,
+        Region = Self,
+        Type = Self,
+        DynExistential = Self,
+    > +
+    fmt::Write
+{
+    /// Like `print_def_path` but for value paths.
+    fn print_value_path(
+        self,
+        def_id: DefId,
+        substs: &'tcx [Kind<'tcx>],
+    ) -> Result<Self::Path, Self::Error> {
+        self.print_def_path(def_id, substs)
+    }
+
+    fn in_binder<T>(
+        self,
+        value: &ty::Binder<T>,
+    ) -> Result<Self, Self::Error>
+        where T: Print<'gcx, 'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>
+    {
+        value.skip_binder().print(self)
+    }
+
+    /// Print comma-separated elements.
+    fn comma_sep<T>(
+        mut self,
+        mut elems: impl Iterator<Item = T>,
+    ) -> Result<Self, Self::Error>
+        where T: Print<'gcx, 'tcx, Self, Output = Self, Error = Self::Error>
+    {
+        if let Some(first) = elems.next() {
+            self = first.print(self)?;
+            for elem in elems {
+                self.write_str(", ")?;
+                self = elem.print(self)?;
+            }
+        }
+        Ok(self)
+    }
+
+    /// Print `<...>` around what `f` prints.
+    fn generic_delimiters(
+        self,
+        f: impl FnOnce(Self) -> Result<Self, Self::Error>,
+    ) -> Result<Self, Self::Error>;
+
+    /// Return `true` if the region should be printed in
+    /// optional positions, e.g. `&'a T` or `dyn Tr + 'b`.
+    /// This is typically the case for all non-`'_` regions.
+    fn region_should_not_be_omitted(
+        &self,
+        region: ty::Region<'_>,
+    ) -> bool;
+
+    // Defaults (should not be overriden):
+
+    /// If possible, this returns a global path resolving to `def_id` that is visible
+    /// from at least one local module and returns true. If the crate defining `def_id` is
+    /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
+    fn try_print_visible_def_path(
+        mut self,
+        def_id: DefId,
+    ) -> Result<(Self, bool), Self::Error> {
+        define_scoped_cx!(self);
+
+        debug!("try_print_visible_def_path: def_id={:?}", def_id);
+
+        // If `def_id` is a direct or injected extern crate, return the
+        // path to the crate followed by the path to the item within the crate.
+        if def_id.index == CRATE_DEF_INDEX {
+            let cnum = def_id.krate;
+
+            if cnum == LOCAL_CRATE {
+                return Ok((self.path_crate(cnum)?, true));
+            }
+
+            // In local mode, when we encounter a crate other than
+            // LOCAL_CRATE, execution proceeds in one of two ways:
+            //
+            // 1. for a direct dependency, where user added an
+            //    `extern crate` manually, we put the `extern
+            //    crate` as the parent. So you wind up with
+            //    something relative to the current crate.
+            // 2. for an extern inferred from a path or an indirect crate,
+            //    where there is no explicit `extern crate`, we just prepend
+            //    the crate name.
+            match *self.tcx().extern_crate(def_id) {
+                Some(ExternCrate {
+                    src: ExternCrateSource::Extern(def_id),
+                    direct: true,
+                    span,
+                    ..
+                }) => {
+                    debug!("try_print_visible_def_path: def_id={:?}", def_id);
+                    return Ok((if !span.is_dummy() {
+                        self.print_def_path(def_id, &[])?
+                    } else {
+                        self.path_crate(cnum)?
+                    }, true));
+                }
+                None => {
+                    return Ok((self.path_crate(cnum)?, true));
+                }
+                _ => {},
+            }
+        }
+
+        if def_id.is_local() {
+            return Ok((self, false));
+        }
+
+        let visible_parent_map = self.tcx().visible_parent_map(LOCAL_CRATE);
+
+        let mut cur_def_key = self.tcx().def_key(def_id);
+        debug!("try_print_visible_def_path: cur_def_key={:?}", cur_def_key);
+
+        // For a UnitStruct or TupleStruct we want the name of its parent rather than <unnamed>.
+        if let DefPathData::StructCtor = cur_def_key.disambiguated_data.data {
+            let parent = DefId {
+                krate: def_id.krate,
+                index: cur_def_key.parent.expect("DefPathData::StructCtor missing a parent"),
+            };
+
+            cur_def_key = self.tcx().def_key(parent);
+        }
+
+        let visible_parent = match visible_parent_map.get(&def_id).cloned() {
+            Some(parent) => parent,
+            None => return Ok((self, false)),
+        };
+        // HACK(eddyb) this bypasses `path_append`'s prefix printing to avoid
+        // knowing ahead of time whether the entire path will succeed or not.
+        // To support printers that do not implement `PrettyPrinter`, a `Vec` or
+        // linked list on the stack would need to be built, before any printing.
+        match self.try_print_visible_def_path(visible_parent)? {
+            (cx, false) => return Ok((cx, false)),
+            (cx, true) => self = cx,
+        }
+        let actual_parent = self.tcx().parent(def_id);
+        debug!(
+            "try_print_visible_def_path: visible_parent={:?} actual_parent={:?}",
+            visible_parent, actual_parent,
+        );
+
+        let mut data = cur_def_key.disambiguated_data.data;
+        debug!(
+            "try_print_visible_def_path: data={:?} visible_parent={:?} actual_parent={:?}",
+            data, visible_parent, actual_parent,
+        );
+
+        match data {
+            // In order to output a path that could actually be imported (valid and visible),
+            // we need to handle re-exports correctly.
+            //
+            // For example, take `std::os::unix::process::CommandExt`, this trait is actually
+            // defined at `std::sys::unix::ext::process::CommandExt` (at time of writing).
+            //
+            // `std::os::unix` rexports the contents of `std::sys::unix::ext`. `std::sys` is
+            // private so the "true" path to `CommandExt` isn't accessible.
+            //
+            // In this case, the `visible_parent_map` will look something like this:
+            //
+            // (child) -> (parent)
+            // `std::sys::unix::ext::process::CommandExt` -> `std::sys::unix::ext::process`
+            // `std::sys::unix::ext::process` -> `std::sys::unix::ext`
+            // `std::sys::unix::ext` -> `std::os`
+            //
+            // This is correct, as the visible parent of `std::sys::unix::ext` is in fact
+            // `std::os`.
+            //
+            // When printing the path to `CommandExt` and looking at the `cur_def_key` that
+            // corresponds to `std::sys::unix::ext`, we would normally print `ext` and then go
+            // to the parent - resulting in a mangled path like
+            // `std::os::ext::process::CommandExt`.
+            //
+            // Instead, we must detect that there was a re-export and instead print `unix`
+            // (which is the name `std::sys::unix::ext` was re-exported as in `std::os`). To
+            // do this, we compare the parent of `std::sys::unix::ext` (`std::sys::unix`) with
+            // the visible parent (`std::os`). If these do not match, then we iterate over
+            // the children of the visible parent (as was done when computing
+            // `visible_parent_map`), looking for the specific child we currently have and then
+            // have access to the re-exported name.
+            DefPathData::Module(ref mut name) |
+            DefPathData::TypeNs(ref mut name) if Some(visible_parent) != actual_parent => {
+                let reexport = self.tcx().item_children(visible_parent)
+                    .iter()
+                    .find(|child| child.def.def_id() == def_id)
+                    .map(|child| child.ident.as_interned_str());
+                if let Some(reexport) = reexport {
+                    *name = reexport;
+                }
+            }
+            // Re-exported `extern crate` (#43189).
+            DefPathData::CrateRoot => {
+                data = DefPathData::Module(
+                    self.tcx().original_crate_name(def_id.krate).as_interned_str(),
+                );
+            }
+            _ => {}
+        }
+        debug!("try_print_visible_def_path: data={:?}", data);
+
+        Ok((self.path_append(Ok, &DisambiguatedDefPathData {
+            data,
+            disambiguator: 0,
+        })?, true))
+    }
+
+    fn pretty_path_qualified(
+        self,
+        self_ty: Ty<'tcx>,
+        trait_ref: Option<ty::TraitRef<'tcx>>,
+    ) -> Result<Self::Path, Self::Error> {
+        if trait_ref.is_none() {
+            // Inherent impls. Try to print `Foo::bar` for an inherent
+            // impl on `Foo`, but fallback to `<Foo>::bar` if self-type is
+            // anything other than a simple path.
+            match self_ty.sty {
+                ty::Adt(..) | ty::Foreign(_) |
+                ty::Bool | ty::Char | ty::Str |
+                ty::Int(_) | ty::Uint(_) | ty::Float(_) => {
+                    return self_ty.print(self);
+                }
+
+                _ => {}
+            }
+        }
+
+        self.generic_delimiters(|mut cx| {
+            define_scoped_cx!(cx);
+
+            p!(print(self_ty));
+            if let Some(trait_ref) = trait_ref {
+                p!(write(" as "), print(trait_ref));
+            }
+            Ok(cx)
+        })
+    }
+
+    fn pretty_path_append_impl(
+        mut self,
+        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
+        self_ty: Ty<'tcx>,
+        trait_ref: Option<ty::TraitRef<'tcx>>,
+    ) -> Result<Self::Path, Self::Error> {
+        self = print_prefix(self)?;
+
+        self.generic_delimiters(|mut cx| {
+            define_scoped_cx!(cx);
+
+            p!(write("impl "));
+            if let Some(trait_ref) = trait_ref {
+                p!(print(trait_ref), write(" for "));
+            }
+            p!(print(self_ty));
+
+            Ok(cx)
+        })
+    }
+
+    fn pretty_print_type(
+        mut self,
+        ty: Ty<'tcx>,
+    ) -> Result<Self::Type, Self::Error> {
+        define_scoped_cx!(self);
+
+        match ty.sty {
+            ty::Bool => p!(write("bool")),
+            ty::Char => p!(write("char")),
+            ty::Int(t) => p!(write("{}", t.ty_to_string())),
+            ty::Uint(t) => p!(write("{}", t.ty_to_string())),
+            ty::Float(t) => p!(write("{}", t.ty_to_string())),
+            ty::RawPtr(ref tm) => {
+                p!(write("*{} ", match tm.mutbl {
+                    hir::MutMutable => "mut",
+                    hir::MutImmutable => "const",
+                }));
+                p!(print(tm.ty))
+            }
+            ty::Ref(r, ty, mutbl) => {
+                p!(write("&"));
+                if self.region_should_not_be_omitted(r) {
+                    p!(print(r), write(" "));
+                }
+                p!(print(ty::TypeAndMut { ty, mutbl }))
+            }
+            ty::Never => p!(write("!")),
+            ty::Tuple(ref tys) => {
+                p!(write("("));
+                let mut tys = tys.iter();
+                if let Some(&ty) = tys.next() {
+                    p!(print(ty), write(","));
+                    if let Some(&ty) = tys.next() {
+                        p!(write(" "), print(ty));
+                        for &ty in tys {
+                            p!(write(", "), print(ty));
+                        }
+                    }
+                }
+                p!(write(")"))
+            }
+            ty::FnDef(def_id, substs) => {
+                let sig = self.tcx().fn_sig(def_id).subst(self.tcx(), substs);
+                p!(print(sig), write(" {{"), print_value_path(def_id, substs), write("}}"));
+            }
+            ty::FnPtr(ref bare_fn) => {
+                p!(print(bare_fn))
+            }
+            ty::Infer(infer_ty) => p!(write("{}", infer_ty)),
+            ty::Error => p!(write("[type error]")),
+            ty::Param(ref param_ty) => p!(write("{}", param_ty)),
+            ty::Bound(debruijn, bound_ty) => {
+                match bound_ty.kind {
+                    ty::BoundTyKind::Anon => {
+                        if debruijn == ty::INNERMOST {
+                            p!(write("^{}", bound_ty.var.index()))
+                        } else {
+                            p!(write("^{}_{}", debruijn.index(), bound_ty.var.index()))
+                        }
+                    }
+
+                    ty::BoundTyKind::Param(p) => p!(write("{}", p)),
+                }
+            }
+            ty::Adt(def, substs) => {
+                p!(print_def_path(def.did, substs));
+            }
+            ty::Dynamic(data, r) => {
+                let print_r = self.region_should_not_be_omitted(r);
+                if print_r {
+                    p!(write("("));
+                }
+                p!(write("dyn "), print(data));
+                if print_r {
+                    p!(write(" + "), print(r), write(")"));
+                }
+            }
+            ty::Foreign(def_id) => {
+                p!(print_def_path(def_id, &[]));
+            }
+            ty::Projection(ref data) => p!(print(data)),
+            ty::UnnormalizedProjection(ref data) => {
+                p!(write("Unnormalized("), print(data), write(")"))
+            }
+            ty::Placeholder(placeholder) => {
+                p!(write("Placeholder({:?})", placeholder))
+            }
+            ty::Opaque(def_id, substs) => {
+                // FIXME(eddyb) print this with `print_def_path`.
+                if self.tcx().sess.verbose() {
+                    p!(write("Opaque({:?}, {:?})", def_id, substs));
+                    return Ok(self);
+                }
+
+                let def_key = self.tcx().def_key(def_id);
+                if let Some(name) = def_key.disambiguated_data.data.get_opt_name() {
+                    p!(write("{}", name));
+                    let mut substs = substs.iter();
+                    // FIXME(eddyb) print this with `print_def_path`.
+                    if let Some(first) = substs.next() {
+                        p!(write("::<"));
+                        p!(print(first));
+                        for subst in substs {
+                            p!(write(", "), print(subst));
+                        }
+                        p!(write(">"));
+                    }
+                    return Ok(self);
+                }
+                // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
+                // by looking up the projections associated with the def_id.
+                let bounds = self.tcx().predicates_of(def_id).instantiate(self.tcx(), substs);
+
+                let mut first = true;
+                let mut is_sized = false;
+                p!(write("impl"));
+                for predicate in bounds.predicates {
+                    if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() {
+                        // Don't print +Sized, but rather +?Sized if absent.
+                        if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() {
+                            is_sized = true;
+                            continue;
+                        }
+
+                        p!(
+                                write("{}", if first { " " } else { "+" }),
+                                print(trait_ref));
+                        first = false;
+                    }
+                }
+                if !is_sized {
+                    p!(write("{}?Sized", if first { " " } else { "+" }));
+                } else if first {
+                    p!(write(" Sized"));
+                }
+            }
+            ty::Str => p!(write("str")),
+            ty::Generator(did, substs, movability) => {
+                let upvar_tys = substs.upvar_tys(did, self.tcx());
+                let witness = substs.witness(did, self.tcx());
+                if movability == hir::GeneratorMovability::Movable {
+                    p!(write("[generator"));
+                } else {
+                    p!(write("[static generator"));
+                }
+
+                // FIXME(eddyb) should use `def_span`.
+                if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) {
+                    p!(write("@{:?}", self.tcx().hir().span_by_hir_id(hir_id)));
+                    let mut sep = " ";
+                    for (freevar, upvar_ty) in self.tcx().freevars(did)
+                        .as_ref()
+                        .map_or(&[][..], |fv| &fv[..])
+                        .iter()
+                        .zip(upvar_tys)
+                    {
+                        p!(
+                            write("{}{}:",
+                                    sep,
+                                    self.tcx().hir().name(freevar.var_id())),
+                            print(upvar_ty));
+                        sep = ", ";
+                    }
+                } else {
+                    // cross-crate closure types should only be
+                    // visible in codegen bug reports, I imagine.
+                    p!(write("@{:?}", did));
+                    let mut sep = " ";
+                    for (index, upvar_ty) in upvar_tys.enumerate() {
+                        p!(
+                                write("{}{}:", sep, index),
+                                print(upvar_ty));
+                        sep = ", ";
+                    }
+                }
+
+                p!(write(" "), print(witness), write("]"))
+            },
+            ty::GeneratorWitness(types) => {
+                p!(in_binder(&types));
+            }
+            ty::Closure(did, substs) => {
+                let upvar_tys = substs.upvar_tys(did, self.tcx());
+                p!(write("[closure"));
+
+                // FIXME(eddyb) should use `def_span`.
+                if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) {
+                    if self.tcx().sess.opts.debugging_opts.span_free_formats {
+                        p!(write("@{:?}", hir_id));
+                    } else {
+                        p!(write("@{:?}", self.tcx().hir().span_by_hir_id(hir_id)));
+                    }
+                    let mut sep = " ";
+                    for (freevar, upvar_ty) in self.tcx().freevars(did)
+                        .as_ref()
+                        .map_or(&[][..], |fv| &fv[..])
+                        .iter()
+                        .zip(upvar_tys)
+                    {
+                        p!(
+                            write("{}{}:",
+                                    sep,
+                                    self.tcx().hir().name(freevar.var_id())),
+                            print(upvar_ty));
+                        sep = ", ";
+                    }
+                } else {
+                    // cross-crate closure types should only be
+                    // visible in codegen bug reports, I imagine.
+                    p!(write("@{:?}", did));
+                    let mut sep = " ";
+                    for (index, upvar_ty) in upvar_tys.enumerate() {
+                        p!(
+                                write("{}{}:", sep, index),
+                                print(upvar_ty));
+                        sep = ", ";
+                    }
+                }
+
+                if self.tcx().sess.verbose() {
+                    p!(write(
+                        " closure_kind_ty={:?} closure_sig_ty={:?}",
+                        substs.closure_kind_ty(did, self.tcx()),
+                        substs.closure_sig_ty(did, self.tcx())
+                    ));
+                }
+
+                p!(write("]"))
+            },
+            ty::Array(ty, sz) => {
+                p!(write("["), print(ty), write("; "));
+                match sz {
+                    ty::LazyConst::Unevaluated(_def_id, _substs) => {
+                        p!(write("_"));
+                    }
+                    ty::LazyConst::Evaluated(c) => {
+                        match c.val {
+                            ConstValue::Infer(..) => p!(write("_")),
+                            ConstValue::Param(ParamConst { name, .. }) =>
+                                p!(write("{}", name)),
+                            _ => p!(write("{}", c.unwrap_usize(self.tcx()))),
+                        }
+                    }
+                }
+                p!(write("]"))
+            }
+            ty::Slice(ty) => {
+                p!(write("["), print(ty), write("]"))
+            }
+        }
+
+        Ok(self)
+    }
+
+    fn pretty_print_dyn_existential(
+        mut self,
+        predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
+    ) -> Result<Self::DynExistential, Self::Error> {
+        define_scoped_cx!(self);
+
+        // Generate the main trait ref, including associated types.
+        let mut first = true;
+
+        if let Some(principal) = predicates.principal() {
+            p!(print_def_path(principal.def_id, &[]));
+
+            let mut resugared = false;
+
+            // Special-case `Fn(...) -> ...` and resugar it.
+            let fn_trait_kind = self.tcx().lang_items().fn_trait_kind(principal.def_id);
+            if !self.tcx().sess.verbose() && fn_trait_kind.is_some() {
+                if let ty::Tuple(ref args) = principal.substs.type_at(0).sty {
+                    let mut projections = predicates.projection_bounds();
+                    if let (Some(proj), None) = (projections.next(), projections.next()) {
+                        p!(pretty_fn_sig(args, false, proj.ty));
+                        resugared = true;
+                    }
+                }
+            }
+
+            // HACK(eddyb) this duplicates `FmtPrinter`'s `path_generic_args`,
+            // in order to place the projections inside the `<...>`.
+            if !resugared {
+                // Use a type that can't appear in defaults of type parameters.
+                let dummy_self = self.tcx().mk_infer(ty::FreshTy(0));
+                let principal = principal.with_self_ty(self.tcx(), dummy_self);
+
+                let args = self.generic_args_to_print(
+                    self.tcx().generics_of(principal.def_id),
+                    principal.substs,
+                );
+
+                // Don't print `'_` if there's no unerased regions.
+                let print_regions = args.iter().any(|arg| {
+                    match arg.unpack() {
+                        UnpackedKind::Lifetime(r) => *r != ty::ReErased,
+                        _ => false,
+                    }
+                });
+                let mut args = args.iter().cloned().filter(|arg| {
+                    match arg.unpack() {
+                        UnpackedKind::Lifetime(_) => print_regions,
+                        _ => true,
+                    }
+                });
+                let mut projections = predicates.projection_bounds();
+
+                let arg0 = args.next();
+                let projection0 = projections.next();
+                if arg0.is_some() || projection0.is_some() {
+                    let args = arg0.into_iter().chain(args);
+                    let projections = projection0.into_iter().chain(projections);
+
+                    p!(generic_delimiters(|mut cx| {
+                        cx = cx.comma_sep(args)?;
+                        if arg0.is_some() && projection0.is_some() {
+                            write!(cx, ", ")?;
+                        }
+                        cx.comma_sep(projections)
+                    }));
+                }
+            }
+            first = false;
+        }
+
+        // Builtin bounds.
+        // FIXME(eddyb) avoid printing twice (needed to ensure
+        // that the auto traits are sorted *and* printed via cx).
+        let mut auto_traits: Vec<_> = predicates.auto_traits().map(|did| {
+            (self.tcx().def_path_str(did), did)
+        }).collect();
+
+        // The auto traits come ordered by `DefPathHash`. While
+        // `DefPathHash` is *stable* in the sense that it depends on
+        // neither the host nor the phase of the moon, it depends
+        // "pseudorandomly" on the compiler version and the target.
+        //
+        // To avoid that causing instabilities in compiletest
+        // output, sort the auto-traits alphabetically.
+        auto_traits.sort();
+
+        for (_, def_id) in auto_traits {
+            if !first {
+                p!(write(" + "));
+            }
+            first = false;
+
+            p!(print_def_path(def_id, &[]));
+        }
+
+        Ok(self)
+    }
+
+    fn pretty_fn_sig(
+        mut self,
+        inputs: &[Ty<'tcx>],
+        c_variadic: bool,
+        output: Ty<'tcx>,
+    ) -> Result<Self, Self::Error> {
+        define_scoped_cx!(self);
+
+        p!(write("("));
+        let mut inputs = inputs.iter();
+        if let Some(&ty) = inputs.next() {
+            p!(print(ty));
+            for &ty in inputs {
+                p!(write(", "), print(ty));
+            }
+            if c_variadic {
+                p!(write(", ..."));
+            }
+        }
+        p!(write(")"));
+        if !output.is_unit() {
+            p!(write(" -> "), print(output));
+        }
+
+        Ok(self)
+    }
+}
+
+// HACK(eddyb) boxed to avoid moving around a large struct by-value.
+pub struct FmtPrinter<'a, 'gcx, 'tcx, F>(Box<FmtPrinterData<'a, 'gcx, 'tcx, F>>);
+
+pub struct FmtPrinterData<'a, 'gcx, 'tcx, F> {
+    tcx: TyCtxt<'a, 'gcx, 'tcx>,
+    fmt: F,
+
+    empty_path: bool,
+    in_value: bool,
+
+    used_region_names: FxHashSet<InternedString>,
+    region_index: usize,
+    binder_depth: usize,
+
+    pub region_highlight_mode: RegionHighlightMode,
+}
+
+impl<F> Deref for FmtPrinter<'a, 'gcx, 'tcx, F> {
+    type Target = FmtPrinterData<'a, 'gcx, 'tcx, F>;
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+impl<F> DerefMut for FmtPrinter<'_, '_, '_, F> {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.0
+    }
+}
+
+impl<F> FmtPrinter<'a, 'gcx, 'tcx, F> {
+    pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, fmt: F, ns: Namespace) -> Self {
+        FmtPrinter(Box::new(FmtPrinterData {
+            tcx,
+            fmt,
+            empty_path: false,
+            in_value: ns == Namespace::ValueNS,
+            used_region_names: Default::default(),
+            region_index: 0,
+            binder_depth: 0,
+            region_highlight_mode: RegionHighlightMode::default(),
+        }))
+    }
+}
+
+impl TyCtxt<'_, '_, '_> {
+    // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always
+    // (but also some things just print a `DefId` generally so maybe we need this?)
+    fn guess_def_namespace(self, def_id: DefId) -> Namespace {
+        match self.def_key(def_id).disambiguated_data.data {
+            DefPathData::ValueNs(..) |
+            DefPathData::EnumVariant(..) |
+            DefPathData::Field(..) |
+            DefPathData::AnonConst |
+            DefPathData::ConstParam(..) |
+            DefPathData::ClosureExpr |
+            DefPathData::StructCtor => Namespace::ValueNS,
+
+            DefPathData::MacroDef(..) => Namespace::MacroNS,
+
+            _ => Namespace::TypeNS,
+        }
+    }
+
+    /// Returns a string identifying this `DefId`. This string is
+    /// suitable for user output.
+    pub fn def_path_str(self, def_id: DefId) -> String {
+        let ns = self.guess_def_namespace(def_id);
+        debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns);
+        let mut s = String::new();
+        let _ = FmtPrinter::new(self, &mut s, ns)
+            .print_def_path(def_id, &[]);
+        s
+    }
+}
+
+impl<F: fmt::Write> fmt::Write for FmtPrinter<'_, '_, '_, F> {
+    fn write_str(&mut self, s: &str) -> fmt::Result {
+        self.fmt.write_str(s)
+    }
+}
+
+impl<F: fmt::Write> Printer<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> {
+    type Error = fmt::Error;
+
+    type Path = Self;
+    type Region = Self;
+    type Type = Self;
+    type DynExistential = Self;
+
+    fn tcx(&'a self) -> TyCtxt<'a, 'gcx, 'tcx> {
+        self.tcx
+    }
+
+    fn print_def_path(
+        mut self,
+        def_id: DefId,
+        substs: &'tcx [Kind<'tcx>],
+    ) -> Result<Self::Path, Self::Error> {
+        define_scoped_cx!(self);
+
+        if substs.is_empty() {
+            match self.try_print_visible_def_path(def_id)? {
+                (cx, true) => return Ok(cx),
+                (cx, false) => self = cx,
+            }
+        }
+
+        let key = self.tcx.def_key(def_id);
+        if let DefPathData::Impl = key.disambiguated_data.data {
+            // Always use types for non-local impls, where types are always
+            // available, and filename/line-number is mostly uninteresting.
+            let use_types =
+                !def_id.is_local() || {
+                    // Otherwise, use filename/line-number if forced.
+                    let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get());
+                    !force_no_types
+                };
+
+            if !use_types {
+                // If no type info is available, fall back to
+                // pretty printing some span information. This should
+                // only occur very early in the compiler pipeline.
+                let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id };
+                let span = self.tcx.def_span(def_id);
+
+                self = self.print_def_path(parent_def_id, &[])?;
+
+                // HACK(eddyb) copy of `path_append` to avoid
+                // constructing a `DisambiguatedDefPathData`.
+                if !self.empty_path {
+                    write!(self, "::")?;
+                }
+                write!(self, "<impl at {:?}>", span)?;
+                self.empty_path = false;
+
+                return Ok(self);
+            }
+        }
+
+        self.default_print_def_path(def_id, substs)
+    }
+
+    fn print_region(
+        self,
+        region: ty::Region<'_>,
+    ) -> Result<Self::Region, Self::Error> {
+        self.pretty_print_region(region)
+    }
+
+    fn print_type(
+        self,
+        ty: Ty<'tcx>,
+    ) -> Result<Self::Type, Self::Error> {
+        self.pretty_print_type(ty)
+    }
+
+    fn print_dyn_existential(
+        self,
+        predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
+    ) -> Result<Self::DynExistential, Self::Error> {
+        self.pretty_print_dyn_existential(predicates)
+    }
+
+    fn path_crate(
+        mut self,
+        cnum: CrateNum,
+    ) -> Result<Self::Path, Self::Error> {
+        self.empty_path = true;
+        if cnum == LOCAL_CRATE {
+            if self.tcx.sess.rust_2018() {
+                // We add the `crate::` keyword on Rust 2018, only when desired.
+                if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) {
+                    write!(self, "{}", keywords::Crate.name())?;
+                    self.empty_path = false;
+                }
+            }
+        } else {
+            write!(self, "{}", self.tcx.crate_name(cnum))?;
+            self.empty_path = false;
+        }
+        Ok(self)
+    }
+    fn path_qualified(
+        mut self,
+        self_ty: Ty<'tcx>,
+        trait_ref: Option<ty::TraitRef<'tcx>>,
+    ) -> Result<Self::Path, Self::Error> {
+        self = self.pretty_path_qualified(self_ty, trait_ref)?;
+        self.empty_path = false;
+        Ok(self)
+    }
+
+    fn path_append_impl(
+        mut self,
+        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
+        _disambiguated_data: &DisambiguatedDefPathData,
+        self_ty: Ty<'tcx>,
+        trait_ref: Option<ty::TraitRef<'tcx>>,
+    ) -> Result<Self::Path, Self::Error> {
+        self = self.pretty_path_append_impl(|mut cx| {
+            cx = print_prefix(cx)?;
+            if !cx.empty_path {
+                write!(cx, "::")?;
+            }
+
+            Ok(cx)
+        }, self_ty, trait_ref)?;
+        self.empty_path = false;
+        Ok(self)
+    }
+    fn path_append(
+        mut self,
+        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
+        disambiguated_data: &DisambiguatedDefPathData,
+    ) -> Result<Self::Path, Self::Error> {
+        self = print_prefix(self)?;
+
+        // Skip `::{{constructor}}` on tuple/unit structs.
+        match disambiguated_data.data {
+            DefPathData::StructCtor => return Ok(self),
+            _ => {}
+        }
+
+        // FIXME(eddyb) `name` should never be empty, but it
+        // currently is for `extern { ... }` "foreign modules".
+        let name = disambiguated_data.data.as_interned_str().as_str();
+        if !name.is_empty() {
+            if !self.empty_path {
+                write!(self, "::")?;
+            }
+            write!(self, "{}", name)?;
+
+            // FIXME(eddyb) this will print e.g. `{{closure}}#3`, but it
+            // might be nicer to use something else, e.g. `{closure#3}`.
+            let dis = disambiguated_data.disambiguator;
+            let print_dis =
+                disambiguated_data.data.get_opt_name().is_none() ||
+                dis != 0 && self.tcx.sess.verbose();
+            if print_dis {
+                write!(self, "#{}", dis)?;
+            }
+
+            self.empty_path = false;
+        }
+
+        Ok(self)
+    }
+    fn path_generic_args(
+        mut self,
+        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
+        args: &[Kind<'tcx>],
+    ) -> Result<Self::Path, Self::Error> {
+        self = print_prefix(self)?;
+
+        // Don't print `'_` if there's no unerased regions.
+        let print_regions = args.iter().any(|arg| {
+            match arg.unpack() {
+                UnpackedKind::Lifetime(r) => *r != ty::ReErased,
+                _ => false,
+            }
+        });
+        let args = args.iter().cloned().filter(|arg| {
+            match arg.unpack() {
+                UnpackedKind::Lifetime(_) => print_regions,
+                _ => true,
+            }
+        });
+
+        if args.clone().next().is_some() {
+            if self.in_value {
+                write!(self, "::")?;
+            }
+            self.generic_delimiters(|cx| cx.comma_sep(args))
+        } else {
+            Ok(self)
+        }
+    }
+}
+
+impl<F: fmt::Write> PrettyPrinter<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> {
+    fn print_value_path(
+        mut self,
+        def_id: DefId,
+        substs: &'tcx [Kind<'tcx>],
+    ) -> Result<Self::Path, Self::Error> {
+        let was_in_value = std::mem::replace(&mut self.in_value, true);
+        self = self.print_def_path(def_id, substs)?;
+        self.in_value = was_in_value;
+
+        Ok(self)
+    }
+
+    fn in_binder<T>(
+        self,
+        value: &ty::Binder<T>,
+    ) -> Result<Self, Self::Error>
+        where T: Print<'gcx, 'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>
+    {
+        self.pretty_in_binder(value)
+    }
+
+    fn generic_delimiters(
+        mut self,
+        f: impl FnOnce(Self) -> Result<Self, Self::Error>,
+    ) -> Result<Self, Self::Error> {
+        write!(self, "<")?;
+
+        let was_in_value = std::mem::replace(&mut self.in_value, false);
+        let mut inner = f(self)?;
+        inner.in_value = was_in_value;
+
+        write!(inner, ">")?;
+        Ok(inner)
+    }
+
+    fn region_should_not_be_omitted(
+        &self,
+        region: ty::Region<'_>,
+    ) -> bool {
+        let highlight = self.region_highlight_mode;
+        if highlight.region_highlighted(region).is_some() {
+            return true;
+        }
+
+        if self.tcx.sess.verbose() {
+            return true;
+        }
+
+        let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions;
+
+        match *region {
+            ty::ReEarlyBound(ref data) => {
+                data.name != "" && data.name != "'_"
+            }
+
+            ty::ReLateBound(_, br) |
+            ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
+            ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
+                if let ty::BrNamed(_, name) = br {
+                    if name != "" && name != "'_" {
+                        return true;
+                    }
+                }
+
+                if let Some((region, _)) = highlight.highlight_bound_region {
+                    if br == region {
+                        return true;
+                    }
+                }
+
+                false
+            }
+
+            ty::ReScope(_) |
+            ty::ReVar(_) if identify_regions => true,
+
+            ty::ReVar(_) |
+            ty::ReScope(_) |
+            ty::ReErased => false,
+
+            ty::ReStatic |
+            ty::ReEmpty |
+            ty::ReClosureBound(_) => true,
+        }
+    }
+}
+
+// HACK(eddyb) limited to `FmtPrinter` because of `region_highlight_mode`.
+impl<F: fmt::Write> FmtPrinter<'_, '_, '_, F> {
+    pub fn pretty_print_region(
+        mut self,
+        region: ty::Region<'_>,
+    ) -> Result<Self, fmt::Error> {
+        define_scoped_cx!(self);
+
+        // Watch out for region highlights.
+        let highlight = self.region_highlight_mode;
+        if let Some(n) = highlight.region_highlighted(region) {
+            p!(write("'{}", n));
+            return Ok(self);
+        }
+
+        if self.tcx.sess.verbose() {
+            p!(write("{:?}", region));
+            return Ok(self);
+        }
+
+        let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions;
+
+        // These printouts are concise.  They do not contain all the information
+        // the user might want to diagnose an error, but there is basically no way
+        // to fit that into a short string.  Hence the recommendation to use
+        // `explain_region()` or `note_and_explain_region()`.
+        match *region {
+            ty::ReEarlyBound(ref data) => {
+                if data.name != "" {
+                    p!(write("{}", data.name));
+                    return Ok(self);
+                }
+            }
+            ty::ReLateBound(_, br) |
+            ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
+            ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
+                if let ty::BrNamed(_, name) = br {
+                    if name != "" && name != "'_" {
+                        p!(write("{}", name));
+                        return Ok(self);
+                    }
+                }
+
+                if let Some((region, counter)) = highlight.highlight_bound_region {
+                    if br == region {
+                        p!(write("'{}", counter));
+                        return Ok(self);
+                    }
+                }
+            }
+            ty::ReScope(scope) if identify_regions => {
+                match scope.data {
+                    region::ScopeData::Node =>
+                        p!(write("'{}s", scope.item_local_id().as_usize())),
+                    region::ScopeData::CallSite =>
+                        p!(write("'{}cs", scope.item_local_id().as_usize())),
+                    region::ScopeData::Arguments =>
+                        p!(write("'{}as", scope.item_local_id().as_usize())),
+                    region::ScopeData::Destruction =>
+                        p!(write("'{}ds", scope.item_local_id().as_usize())),
+                    region::ScopeData::Remainder(first_statement_index) => p!(write(
+                        "'{}_{}rs",
+                        scope.item_local_id().as_usize(),
+                        first_statement_index.index()
+                    )),
+                }
+                return Ok(self);
+            }
+            ty::ReVar(region_vid) if identify_regions => {
+                p!(write("{:?}", region_vid));
+                return Ok(self);
+            }
+            ty::ReVar(_) => {}
+            ty::ReScope(_) |
+            ty::ReErased => {}
+            ty::ReStatic => {
+                p!(write("'static"));
+                return Ok(self);
+            }
+            ty::ReEmpty => {
+                p!(write("'<empty>"));
+                return Ok(self);
+            }
+
+            // The user should never encounter these in unsubstituted form.
+            ty::ReClosureBound(vid) => {
+                p!(write("{:?}", vid));
+                return Ok(self);
+            }
+        }
+
+        p!(write("'_"));
+
+        Ok(self)
+    }
+}
+
+// HACK(eddyb) limited to `FmtPrinter` because of `binder_depth`,
+// `region_index` and `used_region_names`.
+impl<F: fmt::Write> FmtPrinter<'_, 'gcx, 'tcx, F> {
+    pub fn pretty_in_binder<T>(
+        mut self,
+        value: &ty::Binder<T>,
+    ) -> Result<Self, fmt::Error>
+        where T: Print<'gcx, 'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>
+    {
+        fn name_by_region_index(index: usize) -> InternedString {
+            match index {
+                0 => Symbol::intern("'r"),
+                1 => Symbol::intern("'s"),
+                i => Symbol::intern(&format!("'t{}", i-2)),
+            }.as_interned_str()
+        }
+
+        // Replace any anonymous late-bound regions with named
+        // variants, using gensym'd identifiers, so that we can
+        // clearly differentiate between named and unnamed regions in
+        // the output. We'll probably want to tweak this over time to
+        // decide just how much information to give.
+        if self.binder_depth == 0 {
+            self.prepare_late_bound_region_info(value);
+        }
+
+        let mut empty = true;
+        let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
+            write!(cx, "{}", if empty {
+                empty = false;
+                start
+            } else {
+                cont
+            })
+        };
+
+        define_scoped_cx!(self);
+
+        let old_region_index = self.region_index;
+        let mut region_index = old_region_index;
+        let new_value = self.tcx.replace_late_bound_regions(value, |br| {
+            let _ = start_or_continue(&mut self, "for<", ", ");
+            let br = match br {
+                ty::BrNamed(_, name) => {
+                    let _ = write!(self, "{}", name);
+                    br
+                }
+                ty::BrAnon(_) |
+                ty::BrFresh(_) |
+                ty::BrEnv => {
+                    let name = loop {
+                        let name = name_by_region_index(region_index);
+                        region_index += 1;
+                        if !self.used_region_names.contains(&name) {
+                            break name;
+                        }
+                    };
+                    let _ = write!(self, "{}", name);
+                    ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name)
+                }
+            };
+            self.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br))
+        }).0;
+        start_or_continue(&mut self, "", "> ")?;
+
+        self.binder_depth += 1;
+        self.region_index = region_index;
+        let mut inner = new_value.print(self)?;
+        inner.region_index = old_region_index;
+        inner.binder_depth -= 1;
+        Ok(inner)
+    }
+
+    fn prepare_late_bound_region_info<T>(&mut self, value: &ty::Binder<T>)
+        where T: TypeFoldable<'tcx>
+    {
+
+        struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet<InternedString>);
+        impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> {
+            fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
+                match *r {
+                    ty::ReLateBound(_, ty::BrNamed(_, name)) => {
+                        self.0.insert(name);
+                    },
+                    _ => {},
+                }
+                r.super_visit_with(self)
+            }
+        }
+
+        self.used_region_names.clear();
+        let mut collector = LateBoundRegionNameCollector(&mut self.used_region_names);
+        value.visit_with(&mut collector);
+        self.region_index = 0;
+    }
+}
+
+impl<'gcx: 'tcx, 'tcx, T, P: PrettyPrinter<'gcx, 'tcx>> Print<'gcx, 'tcx, P>
+    for ty::Binder<T>
+    where T: Print<'gcx, 'tcx, P, Output = P, Error = P::Error> + TypeFoldable<'tcx>
+{
+    type Output = P;
+    type Error = P::Error;
+    fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
+        cx.in_binder(self)
+    }
+}
+
+impl<'gcx: 'tcx, 'tcx, T, U, P: PrettyPrinter<'gcx, 'tcx>> Print<'gcx, 'tcx, P>
+    for ty::OutlivesPredicate<T, U>
+    where T: Print<'gcx, 'tcx, P, Output = P, Error = P::Error>,
+          U: Print<'gcx, 'tcx, P, Output = P, Error = P::Error>,
+{
+    type Output = P;
+    type Error = P::Error;
+    fn print(&self, mut cx: P) -> Result<Self::Output, Self::Error> {
+        define_scoped_cx!(cx);
+        p!(print(self.0), write(" : "), print(self.1));
+        Ok(cx)
+    }
+}
+
+macro_rules! forward_display_to_print {
+    ($($ty:ty),+) => {
+        $(impl fmt::Display for $ty {
+            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+                ty::tls::with(|tcx| {
+                    tcx.lift(self)
+                        .expect("could not lift for printing")
+                        .print(FmtPrinter::new(tcx, f, Namespace::TypeNS))?;
+                    Ok(())
+                })
+            }
+        })+
+    };
+}
+
+macro_rules! define_print_and_forward_display {
+    (($self:ident, $cx:ident): $($ty:ty $print:block)+) => {
+        $(impl<'gcx: 'tcx, 'tcx, P: PrettyPrinter<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for $ty {
+            type Output = P;
+            type Error = fmt::Error;
+            fn print(&$self, $cx: P) -> Result<Self::Output, Self::Error> {
+                #[allow(unused_mut)]
+                let mut $cx = $cx;
+                define_scoped_cx!($cx);
+                let _: () = $print;
+                #[allow(unreachable_code)]
+                Ok($cx)
+            }
+        })+
+
+        forward_display_to_print!($($ty),+);
+    };
+}
+
+// HACK(eddyb) this is separate because `ty::RegionKind` doesn't need lifting.
+impl fmt::Display for ty::RegionKind {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        ty::tls::with(|tcx| {
+            self.print(FmtPrinter::new(tcx, f, Namespace::TypeNS))?;
+            Ok(())
+        })
+    }
+}
+
+forward_display_to_print! {
+    Ty<'tcx>,
+    &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
+
+    // HACK(eddyb) these are exhaustive instead of generic,
+    // because `for<'gcx: 'tcx, 'tcx>` isn't possible yet.
+    ty::Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>,
+    ty::Binder<ty::TraitRef<'tcx>>,
+    ty::Binder<ty::FnSig<'tcx>>,
+    ty::Binder<ty::TraitPredicate<'tcx>>,
+    ty::Binder<ty::SubtypePredicate<'tcx>>,
+    ty::Binder<ty::ProjectionPredicate<'tcx>>,
+    ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>,
+    ty::Binder<ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>>,
+
+    ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>,
+    ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>
+}
+
+define_print_and_forward_display! {
+    (self, cx):
+
+    &'tcx ty::List<Ty<'tcx>> {
+        p!(write("{{"));
+        let mut tys = self.iter();
+        if let Some(&ty) = tys.next() {
+            p!(print(ty));
+            for &ty in tys {
+                p!(write(", "), print(ty));
+            }
+        }
+        p!(write("}}"))
+    }
+
+    ty::TypeAndMut<'tcx> {
+        p!(write("{}", if self.mutbl == hir::MutMutable { "mut " } else { "" }),
+            print(self.ty))
+    }
+
+    ty::ExistentialTraitRef<'tcx> {
+        // Use a type that can't appear in defaults of type parameters.
+        let dummy_self = cx.tcx().mk_infer(ty::FreshTy(0));
+        let trait_ref = self.with_self_ty(cx.tcx(), dummy_self);
+        p!(print(trait_ref))
+    }
+
+    ty::ExistentialProjection<'tcx> {
+        let name = cx.tcx().associated_item(self.item_def_id).ident;
+        p!(write("{} = ", name), print(self.ty))
+    }
+
+    ty::ExistentialPredicate<'tcx> {
+        match *self {
+            ty::ExistentialPredicate::Trait(x) => p!(print(x)),
+            ty::ExistentialPredicate::Projection(x) => p!(print(x)),
+            ty::ExistentialPredicate::AutoTrait(def_id) => {
+                p!(print_def_path(def_id, &[]));
+            }
+        }
+    }
+
+    ty::FnSig<'tcx> {
+        if self.unsafety == hir::Unsafety::Unsafe {
+            p!(write("unsafe "));
+        }
+
+        if self.abi != Abi::Rust {
+            p!(write("extern {} ", self.abi));
+        }
+
+        p!(write("fn"), pretty_fn_sig(self.inputs(), self.c_variadic, self.output()));
+    }
+
+    ty::InferTy {
+        if cx.tcx().sess.verbose() {
+            p!(write("{:?}", self));
+            return Ok(cx);
+        }
+        match *self {
+            ty::TyVar(_) => p!(write("_")),
+            ty::IntVar(_) => p!(write("{}", "{integer}")),
+            ty::FloatVar(_) => p!(write("{}", "{float}")),
+            ty::FreshTy(v) => p!(write("FreshTy({})", v)),
+            ty::FreshIntTy(v) => p!(write("FreshIntTy({})", v)),
+            ty::FreshFloatTy(v) => p!(write("FreshFloatTy({})", v))
+        }
+    }
+
+    ty::TraitRef<'tcx> {
+        p!(print_def_path(self.def_id, self.substs));
+    }
+
+    ConstValue<'tcx> {
+        match self {
+            ConstValue::Infer(..) => p!(write("_")),
+            ConstValue::Param(ParamConst { name, .. }) => p!(write("{}", name)),
+            _ => p!(write("{:?}", self)),
+        }
+    }
+
+    ty::Const<'tcx> {
+        p!(write("{} : {}", self.val, self.ty))
+    }
+
+    &'tcx ty::LazyConst<'tcx> {
+        match self {
+            // FIXME(const_generics) this should print at least the type.
+            ty::LazyConst::Unevaluated(..) => p!(write("_ : _")),
+            ty::LazyConst::Evaluated(c) => p!(write("{}", c)),
+        }
+    }
+
+    ty::ParamTy {
+        p!(write("{}", self.name))
+    }
+
+    ty::ParamConst {
+        p!(write("{}", self.name))
+    }
+
+    ty::SubtypePredicate<'tcx> {
+        p!(print(self.a), write(" <: "), print(self.b))
+    }
+
+    ty::TraitPredicate<'tcx> {
+        p!(print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref))
+    }
+
+    ty::ProjectionPredicate<'tcx> {
+        p!(print(self.projection_ty), write(" == "), print(self.ty))
+    }
+
+    ty::ProjectionTy<'tcx> {
+        p!(print_def_path(self.item_def_id, self.substs));
+    }
+
+    ty::ClosureKind {
+        match *self {
+            ty::ClosureKind::Fn => p!(write("Fn")),
+            ty::ClosureKind::FnMut => p!(write("FnMut")),
+            ty::ClosureKind::FnOnce => p!(write("FnOnce")),
+        }
+    }
+
+    ty::Predicate<'tcx> {
+        match *self {
+            ty::Predicate::Trait(ref data) => p!(print(data)),
+            ty::Predicate::Subtype(ref predicate) => p!(print(predicate)),
+            ty::Predicate::RegionOutlives(ref predicate) => p!(print(predicate)),
+            ty::Predicate::TypeOutlives(ref predicate) => p!(print(predicate)),
+            ty::Predicate::Projection(ref predicate) => p!(print(predicate)),
+            ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")),
+            ty::Predicate::ObjectSafe(trait_def_id) => {
+                p!(write("the trait `"),
+                   print_def_path(trait_def_id, &[]),
+                   write("` is object-safe"))
+            }
+            ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => {
+                p!(write("the closure `"),
+                   print_value_path(closure_def_id, &[]),
+                   write("` implements the trait `{}`", kind))
+            }
+            ty::Predicate::ConstEvaluatable(def_id, substs) => {
+                p!(write("the constant `"),
+                   print_value_path(def_id, substs),
+                   write("` can be evaluated"))
+            }
+        }
+    }
+
+    Kind<'tcx> {
+        match self.unpack() {
+            UnpackedKind::Lifetime(lt) => p!(print(lt)),
+            UnpackedKind::Type(ty) => p!(print(ty)),
+            UnpackedKind::Const(ct) => p!(print(ct)),
+        }
+    }
+}
diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs
index 6488c0db42b..395b288df14 100644
--- a/src/librustc/ty/query/config.rs
+++ b/src/librustc/ty/query/config.rs
@@ -71,7 +71,7 @@ pub(super) trait QueryDescription<'tcx>: QueryAccessors<'tcx> {
 impl<'tcx, M: QueryAccessors<'tcx, Key=DefId>> QueryDescription<'tcx> for M {
     default fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
         if !tcx.sess.verbose() {
-            format!("processing `{}`", tcx.item_path_str(def_id)).into()
+            format!("processing `{}`", tcx.def_path_str(def_id)).into()
         } else {
             let name = unsafe { ::std::intrinsics::type_name::<M>() };
             format!("processing {:?} with query `{}`", def_id, name).into()
@@ -301,7 +301,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::layout_raw<'tcx> {
 impl<'tcx> QueryDescription<'tcx> for queries::super_predicates_of<'tcx> {
     fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
         format!("computing the supertraits of `{}`",
-                tcx.item_path_str(def_id)).into()
+                tcx.def_path_str(def_id)).into()
     }
 }
 
@@ -322,7 +322,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::type_param_predicates<'tcx> {
 impl<'tcx> QueryDescription<'tcx> for queries::coherent_trait<'tcx> {
     fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
         format!("coherence checking all impls of trait `{}`",
-                tcx.item_path_str(def_id)).into()
+                tcx.def_path_str(def_id)).into()
     }
 }
 
@@ -359,7 +359,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::inferred_outlives_crate<'tcx> {
 impl<'tcx> QueryDescription<'tcx> for queries::mir_shims<'tcx> {
     fn describe(tcx: TyCtxt<'_, '_, '_>, def: ty::InstanceDef<'tcx>) -> Cow<'static, str> {
         format!("generating MIR shim for `{}`",
-                tcx.item_path_str(def.def_id())).into()
+                tcx.def_path_str(def.def_id())).into()
     }
 }
 
@@ -394,7 +394,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> {
     ) -> Cow<'static, str> {
         format!(
             "const-evaluating + checking `{}`",
-            tcx.item_path_str(key.value.instance.def.def_id()),
+            tcx.def_path_str(key.value.instance.def.def_id()),
         ).into()
     }
 
@@ -415,7 +415,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval_raw<'tcx> {
     fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
         -> Cow<'static, str>
     {
-        format!("const-evaluating `{}`", tcx.item_path_str(key.value.instance.def.def_id())).into()
+        format!("const-evaluating `{}`", tcx.def_path_str(key.value.instance.def.def_id())).into()
     }
 
     #[inline]
@@ -513,7 +513,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::trait_of_item<'tcx> {
 impl<'tcx> QueryDescription<'tcx> for queries::const_is_rvalue_promotable_to_static<'tcx> {
     fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
         format!("const checking if rvalue is promotable to static `{}`",
-            tcx.item_path_str(def_id)).into()
+            tcx.def_path_str(def_id)).into()
     }
 
     #[inline]
@@ -532,21 +532,21 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_is_rvalue_promotable_to_sta
 impl<'tcx> QueryDescription<'tcx> for queries::rvalue_promotable_map<'tcx> {
     fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
         format!("checking which parts of `{}` are promotable to static",
-                tcx.item_path_str(def_id)).into()
+                tcx.def_path_str(def_id)).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::is_mir_available<'tcx> {
     fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
         format!("checking if item is mir available: `{}`",
-                tcx.item_path_str(def_id)).into()
+                tcx.def_path_str(def_id)).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::codegen_fulfill_obligation<'tcx> {
     fn describe(tcx: TyCtxt<'_, '_, '_>,
                 key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> Cow<'static, str> {
-        format!("checking if `{}` fulfills its obligations", tcx.item_path_str(key.1.def_id()))
+        format!("checking if `{}` fulfills its obligations", tcx.def_path_str(key.1.def_id()))
             .into()
     }
 
@@ -565,19 +565,19 @@ impl<'tcx> QueryDescription<'tcx> for queries::codegen_fulfill_obligation<'tcx>
 
 impl<'tcx> QueryDescription<'tcx> for queries::trait_impls_of<'tcx> {
     fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
-        format!("trait impls of `{}`", tcx.item_path_str(def_id)).into()
+        format!("trait impls of `{}`", tcx.def_path_str(def_id)).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::is_object_safe<'tcx> {
     fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
-        format!("determine object safety of trait `{}`", tcx.item_path_str(def_id)).into()
+        format!("determine object safety of trait `{}`", tcx.def_path_str(def_id)).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::is_const_fn_raw<'tcx> {
     fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
-        format!("checking if item is const fn: `{}`", tcx.item_path_str(def_id)).into()
+        format!("checking if item is const fn: `{}`", tcx.def_path_str(def_id)).into()
     }
 }
 
@@ -883,7 +883,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::output_filenames<'tcx> {
 
 impl<'tcx> QueryDescription<'tcx> for queries::vtable_methods<'tcx> {
     fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::PolyTraitRef<'tcx> ) -> Cow<'static, str> {
-        format!("finding all methods for trait {}", tcx.item_path_str(key.def_id())).into()
+        format!("finding all methods for trait {}", tcx.def_path_str(key.def_id())).into()
     }
 }
 
@@ -927,7 +927,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::optimized_mir<'tcx> {
 
 impl<'tcx> QueryDescription<'tcx> for queries::substitute_normalize_and_test_predicates<'tcx> {
     fn describe(tcx: TyCtxt<'_, '_, '_>, key: (DefId, SubstsRef<'tcx>)) -> Cow<'static, str> {
-        format!("testing substituted normalized predicates:`{}`", tcx.item_path_str(key.0)).into()
+        format!("testing substituted normalized predicates:`{}`", tcx.def_path_str(key.0)).into()
     }
 }
 
@@ -945,7 +945,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::target_features_whitelist<'tcx> {
 
 impl<'tcx> QueryDescription<'tcx> for queries::instance_def_size_estimate<'tcx> {
     fn describe(tcx: TyCtxt<'_, '_, '_>, def: ty::InstanceDef<'tcx>) -> Cow<'static, str> {
-        format!("estimating size for `{}`", tcx.item_path_str(def.def_id())).into()
+        format!("estimating size for `{}`", tcx.def_path_str(def.def_id())).into()
     }
 }
 
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index e3276ba0bea..cff99f23d0e 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -4,11 +4,10 @@
 
 use crate::dep_graph::{DepNodeIndex, DepNode, DepKind, SerializedDepNodeIndex};
 use crate::ty::tls;
-use crate::ty::{TyCtxt};
+use crate::ty::{self, TyCtxt};
 use crate::ty::query::Query;
 use crate::ty::query::config::{QueryConfig, QueryDescription};
 use crate::ty::query::job::{QueryJob, QueryResult, QueryInfo};
-use crate::ty::item_path;
 
 use crate::util::common::{profq_msg, ProfileQueriesMsg, QueryMsg};
 
@@ -299,7 +298,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         // sometimes cycles itself, leading to extra cycle errors.
         // (And cycle errors around impls tend to occur during the
         // collect/coherence phases anyhow.)
-        item_path::with_forced_impl_filename_line(|| {
+        ty::print::with_forced_impl_filename_line(|| {
             let span = fix_span(stack[1 % stack.len()].span, &stack[0].query);
             let mut err = struct_span_err!(self.sess,
                                            span,
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index 3a31801b3be..b245d903799 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -351,10 +351,8 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
     where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
 {
     let tcx = relation.tcx();
-    let a_sty = &a.sty;
-    let b_sty = &b.sty;
-    debug!("super_relate_tys: a_sty={:?} b_sty={:?}", a_sty, b_sty);
-    match (a_sty, b_sty) {
+    debug!("super_relate_tys: a={:?} b={:?}", a, b);
+    match (&a.sty, &b.sty) {
         (&ty::Infer(_), _) |
         (_, &ty::Infer(_)) =>
         {
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index f9eb336a4a3..ecfb034e4f2 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -3,17 +3,288 @@
 //! hand, though we've recently added some macros (e.g.,
 //! `BraceStructLiftImpl!`) to help with the tedium.
 
+use crate::hir::def::Namespace;
 use crate::mir::ProjectionKind;
 use crate::mir::interpret::ConstValue;
 use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid, InferConst};
 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
+use crate::ty::print::{FmtPrinter, Printer};
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 use smallvec::SmallVec;
 use crate::mir::interpret;
 
+use std::fmt;
 use std::marker::PhantomData;
 use std::rc::Rc;
 
+impl fmt::Debug for ty::GenericParamDef {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let type_name = match self.kind {
+            ty::GenericParamDefKind::Lifetime => "Lifetime",
+            ty::GenericParamDefKind::Type {..} => "Type",
+            ty::GenericParamDefKind::Const => "Const",
+        };
+        write!(f, "{}({}, {:?}, {})",
+               type_name,
+               self.name,
+               self.def_id,
+               self.index)
+    }
+}
+
+impl fmt::Debug for ty::TraitDef {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        ty::tls::with(|tcx| {
+            FmtPrinter::new(tcx, f, Namespace::TypeNS)
+                .print_def_path(self.def_id, &[])?;
+            Ok(())
+        })
+    }
+}
+
+impl fmt::Debug for ty::AdtDef {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        ty::tls::with(|tcx| {
+            FmtPrinter::new(tcx, f, Namespace::TypeNS)
+                .print_def_path(self.did, &[])?;
+            Ok(())
+        })
+    }
+}
+
+impl fmt::Debug for ty::ClosureUpvar<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "ClosureUpvar({:?},{:?})",
+               self.def,
+               self.ty)
+    }
+}
+
+impl fmt::Debug for ty::UpvarId {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let name = ty::tls::with(|tcx| {
+            tcx.hir().name_by_hir_id(self.var_path.hir_id)
+        });
+        write!(f, "UpvarId({:?};`{}`;{:?})",
+            self.var_path.hir_id,
+            name,
+            self.closure_expr_id)
+    }
+}
+
+impl fmt::Debug for ty::UpvarBorrow<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "UpvarBorrow({:?}, {:?})",
+               self.kind, self.region)
+    }
+}
+
+impl fmt::Debug for ty::ExistentialTraitRef<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(self, f)
+    }
+}
+
+impl fmt::Debug for ty::adjustment::Adjustment<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{:?} -> {}", self.kind, self.target)
+    }
+}
+
+impl fmt::Debug for ty::BoundRegion {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match *self {
+            ty::BrAnon(n) => write!(f, "BrAnon({:?})", n),
+            ty::BrFresh(n) => write!(f, "BrFresh({:?})", n),
+            ty::BrNamed(did, name) => {
+                write!(f, "BrNamed({:?}:{:?}, {})",
+                        did.krate, did.index, name)
+            }
+            ty::BrEnv => write!(f, "BrEnv"),
+        }
+    }
+}
+
+impl fmt::Debug for ty::RegionKind {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match *self {
+            ty::ReEarlyBound(ref data) => {
+                write!(f, "ReEarlyBound({}, {})",
+                        data.index,
+                        data.name)
+            }
+
+            ty::ReClosureBound(ref vid) => {
+                write!(f, "ReClosureBound({:?})", vid)
+            }
+
+            ty::ReLateBound(binder_id, ref bound_region) => {
+                write!(f, "ReLateBound({:?}, {:?})", binder_id, bound_region)
+            }
+
+            ty::ReFree(ref fr) => fr.fmt(f),
+
+            ty::ReScope(id) => write!(f, "ReScope({:?})", id),
+
+            ty::ReStatic => write!(f, "ReStatic"),
+
+            ty::ReVar(ref vid) => vid.fmt(f),
+
+            ty::RePlaceholder(placeholder) => {
+                write!(f, "RePlaceholder({:?})", placeholder)
+            }
+
+            ty::ReEmpty => write!(f, "ReEmpty"),
+
+            ty::ReErased => write!(f, "ReErased"),
+        }
+    }
+}
+
+impl fmt::Debug for ty::FreeRegion {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region)
+    }
+}
+
+impl fmt::Debug for ty::Variance {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str(match *self {
+            ty::Covariant => "+",
+            ty::Contravariant => "-",
+            ty::Invariant => "o",
+            ty::Bivariant => "*",
+        })
+    }
+}
+
+impl fmt::Debug for ty::FnSig<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "({:?}; c_variadic: {})->{:?}",
+                self.inputs(), self.c_variadic, self.output())
+    }
+}
+
+impl fmt::Debug for ty::TyVid {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "_#{}t", self.index)
+    }
+}
+
+impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "_#{}c", self.index)
+    }
+}
+
+impl fmt::Debug for ty::IntVid {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "_#{}i", self.index)
+    }
+}
+
+impl fmt::Debug for ty::FloatVid {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "_#{}f", self.index)
+    }
+}
+
+impl fmt::Debug for ty::RegionVid {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "'_#{}r", self.index())
+    }
+}
+
+impl fmt::Debug for ty::InferTy {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match *self {
+            ty::TyVar(ref v) => v.fmt(f),
+            ty::IntVar(ref v) => v.fmt(f),
+            ty::FloatVar(ref v) => v.fmt(f),
+            ty::FreshTy(v) => write!(f, "FreshTy({:?})", v),
+            ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
+            ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v),
+        }
+    }
+}
+
+impl fmt::Debug for ty::IntVarValue {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match *self {
+            ty::IntType(ref v) => v.fmt(f),
+            ty::UintType(ref v) => v.fmt(f),
+        }
+    }
+}
+
+impl fmt::Debug for ty::FloatVarValue {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.0.fmt(f)
+    }
+}
+
+impl fmt::Debug for ty::TraitRef<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        // FIXME(#59188) this is used across the compiler to print
+        // a `TraitRef` qualified (with the Self type explicit),
+        // instead of having a different way to make that choice.
+        write!(f, "<{} as {}>", self.self_ty(), self)
+    }
+}
+
+impl fmt::Debug for Ty<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(self, f)
+    }
+}
+
+impl fmt::Debug for ty::ParamTy {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}/#{}", self.name, self.idx)
+    }
+}
+
+impl fmt::Debug for ty::ParamConst {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}/#{}", self.name, self.index)
+    }
+}
+
+impl fmt::Debug for ty::TraitPredicate<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "TraitPredicate({:?})", self.trait_ref)
+    }
+}
+
+impl fmt::Debug for ty::ProjectionPredicate<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.ty)
+    }
+}
+
+impl fmt::Debug for ty::Predicate<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match *self {
+            ty::Predicate::Trait(ref a) => a.fmt(f),
+            ty::Predicate::Subtype(ref pair) => pair.fmt(f),
+            ty::Predicate::RegionOutlives(ref pair) => pair.fmt(f),
+            ty::Predicate::TypeOutlives(ref pair) => pair.fmt(f),
+            ty::Predicate::Projection(ref pair) => pair.fmt(f),
+            ty::Predicate::WellFormed(ty) => write!(f, "WellFormed({:?})", ty),
+            ty::Predicate::ObjectSafe(trait_def_id) => {
+                write!(f, "ObjectSafe({:?})", trait_def_id)
+            }
+            ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
+                write!(f, "ClosureKind({:?}, {:?}, {:?})",
+                    closure_def_id, closure_substs, kind)
+            }
+            ty::Predicate::ConstEvaluatable(def_id, substs) => {
+                write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs)
+            }
+        }
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // Atomic structs
 //
@@ -48,10 +319,14 @@ CloneTypeFoldableAndLiftImpls! {
     // really meant to be folded. In general, we can only fold a fully
     // general `Region`.
     crate::ty::BoundRegion,
+    crate::ty::Placeholder<crate::ty::BoundRegion>,
     crate::ty::ClosureKind,
+    crate::ty::FreeRegion,
+    crate::ty::InferTy,
     crate::ty::IntVarValue,
     crate::ty::ParamConst,
     crate::ty::ParamTy,
+    crate::ty::RegionVid,
     crate::ty::UniverseIndex,
     crate::ty::Variance,
     ::syntax_pos::Span,
@@ -60,6 +335,7 @@ CloneTypeFoldableAndLiftImpls! {
 ///////////////////////////////////////////////////////////////////////////
 // Lift implementations
 
+// FIXME(eddyb) replace all the uses of `Option::map` with `?`.
 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {
     type Lifted = (A::Lifted, B::Lifted);
     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
@@ -156,6 +432,23 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> {
     }
 }
 
+impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> {
+    type Lifted = ty::ExistentialPredicate<'tcx>;
+    fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
+        match self {
+            ty::ExistentialPredicate::Trait(x) => {
+                tcx.lift(x).map(ty::ExistentialPredicate::Trait)
+            }
+            ty::ExistentialPredicate::Projection(x) => {
+                tcx.lift(x).map(ty::ExistentialPredicate::Projection)
+            }
+            ty::ExistentialPredicate::AutoTrait(def_id) => {
+                Some(ty::ExistentialPredicate::AutoTrait(*def_id))
+            }
+        }
+    }
+}
+
 impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
     type Lifted = ty::TraitPredicate<'tcx>;
     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
@@ -481,6 +774,13 @@ impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
 }
 
 BraceStructLiftImpl! {
+    impl<'a, 'tcx> Lift<'tcx> for ty::TypeAndMut<'a> {
+        type Lifted = ty::TypeAndMut<'tcx>;
+        ty, mutbl
+    }
+}
+
+BraceStructLiftImpl! {
     impl<'a, 'tcx> Lift<'tcx> for ty::Instance<'a> {
         type Lifted = ty::Instance<'tcx>;
         def, substs
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 39728cc8cd5..7b6a51c0184 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -9,7 +9,7 @@ use polonius_engine::Atom;
 use rustc_data_structures::indexed_vec::Idx;
 use rustc_macros::HashStable;
 use crate::ty::subst::{InternalSubsts, Subst, SubstsRef, Kind, UnpackedKind};
-use crate::ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable};
+use crate::ty::{self, AdtDef, DefIdTree, TypeFlags, Ty, TyCtxt, TypeFoldable};
 use crate::ty::{List, TyS, ParamEnvAnd, ParamEnv};
 use crate::util::captures::Captures;
 use crate::mir::interpret::{Scalar, Pointer};
@@ -84,7 +84,7 @@ impl BoundRegion {
 
 /// N.B., if you change this, you'll probably want to change the corresponding
 /// AST structure in `libsyntax/ast.rs` as well.
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug,
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
          RustcEncodable, RustcDecodable, HashStable)]
 pub enum TyKind<'tcx> {
     /// The primitive boolean type. Written as `bool`.
@@ -383,9 +383,10 @@ impl<'tcx> ClosureSubsts<'tcx> {
     ///
     /// If you have an inference context, use `infcx.closure_sig()`.
     pub fn closure_sig(self, def_id: DefId, tcx: TyCtxt<'_, 'tcx, 'tcx>) -> ty::PolyFnSig<'tcx> {
-        match self.closure_sig_ty(def_id, tcx).sty {
+        let ty = self.closure_sig_ty(def_id, tcx);
+        match ty.sty {
             ty::FnPtr(sig) => sig,
-            ref t => bug!("closure_sig_ty is not a fn-ptr: {:?}", t),
+            _ => bug!("closure_sig_ty is not a fn-ptr: {:?}", ty),
         }
     }
 }
@@ -1590,7 +1591,7 @@ impl RegionKind {
     pub fn free_region_binding_scope(&self, tcx: TyCtxt<'_, '_, '_>) -> DefId {
         match self {
             ty::ReEarlyBound(br) => {
-                tcx.parent_def_id(br.def_id).unwrap()
+                tcx.parent(br.def_id).unwrap()
             }
             ty::ReFree(fr) => fr.scope,
             _ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self),
@@ -1910,7 +1911,6 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
 
     pub fn is_machine(&self) -> bool {
         match self.sty {
-            Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => false,
             Int(..) | Uint(..) | Float(..) => true,
             _ => false,
         }
diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs
index 38be19a71c4..84642865614 100644
--- a/src/librustc/ty/subst.rs
+++ b/src/librustc/ty/subst.rs
@@ -12,8 +12,8 @@ use smallvec::SmallVec;
 use rustc_macros::HashStable;
 
 use core::intrinsics;
-use std::cmp::Ordering;
 use std::fmt;
+use std::cmp::Ordering;
 use std::marker::PhantomData;
 use std::mem;
 use std::num::NonZeroUsize;
@@ -70,6 +70,16 @@ impl<'tcx> UnpackedKind<'tcx> {
     }
 }
 
+impl fmt::Debug for Kind<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self.unpack() {
+            UnpackedKind::Lifetime(lt) => lt.fmt(f),
+            UnpackedKind::Type(ty) => ty.fmt(f),
+            UnpackedKind::Const(ct) => ct.fmt(f),
+        }
+    }
+}
+
 impl<'tcx> Ord for Kind<'tcx> {
     fn cmp(&self, other: &Kind<'_>) -> Ordering {
         self.unpack().cmp(&other.unpack())
@@ -115,34 +125,14 @@ impl<'tcx> Kind<'tcx> {
     }
 }
 
-impl<'tcx> fmt::Debug for Kind<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.unpack() {
-            UnpackedKind::Lifetime(lt) => write!(f, "{:?}", lt),
-            UnpackedKind::Type(ty) => write!(f, "{:?}", ty),
-            UnpackedKind::Const(ct) => write!(f, "{:?}", ct),
-        }
-    }
-}
-
-impl<'tcx> fmt::Display for Kind<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.unpack() {
-            UnpackedKind::Lifetime(lt) => write!(f, "{}", lt),
-            UnpackedKind::Type(ty) => write!(f, "{}", ty),
-            UnpackedKind::Const(ct) => write!(f, "{}", ct),
-        }
-    }
-}
-
 impl<'a, 'tcx> Lift<'tcx> for Kind<'a> {
     type Lifted = Kind<'tcx>;
 
     fn lift_to_tcx<'cx, 'gcx>(&self, tcx: TyCtxt<'cx, 'gcx, 'tcx>) -> Option<Self::Lifted> {
         match self.unpack() {
-            UnpackedKind::Lifetime(lt) => lt.lift_to_tcx(tcx).map(|lt| lt.into()),
-            UnpackedKind::Type(ty) => ty.lift_to_tcx(tcx).map(|ty| ty.into()),
-            UnpackedKind::Const(ct) => ct.lift_to_tcx(tcx).map(|ct| ct.into()),
+            UnpackedKind::Lifetime(lt) => tcx.lift(&lt).map(|lt| lt.into()),
+            UnpackedKind::Type(ty) => tcx.lift(&ty).map(|ty| ty.into()),
+            UnpackedKind::Const(ct) => tcx.lift(&ct).map(|ct| ct.into()),
         }
     }
 }
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 422f97b2996..65918a90821 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -7,7 +7,7 @@ use crate::hir::{self, Node};
 use crate::mir::interpret::{sign_extend, truncate};
 use crate::ich::NodeIdHashingMode;
 use crate::traits::{self, ObligationCause};
-use crate::ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable};
+use crate::ty::{self, DefIdTree, Ty, TyCtxt, GenericParamDefKind, TypeFoldable};
 use crate::ty::subst::{Subst, InternalSubsts, SubstsRef, UnpackedKind};
 use crate::ty::query::TyCtxtAt;
 use crate::ty::TyKind::*;
@@ -563,7 +563,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     pub fn closure_base_def_id(self, def_id: DefId) -> DefId {
         let mut def_id = def_id;
         while self.is_closure(def_id) {
-            def_id = self.parent_def_id(def_id).unwrap_or_else(|| {
+            def_id = self.parent(def_id).unwrap_or_else(|| {
                 bug!("closure {:?} has no parent", def_id);
             });
         }
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
deleted file mode 100644
index a1398c69ff0..00000000000
--- a/src/librustc/util/ppaux.rs
+++ /dev/null
@@ -1,1667 +0,0 @@
-use crate::hir::def_id::DefId;
-use crate::hir::map::definitions::DefPathData;
-use crate::middle::region;
-use crate::ty::subst::{self, Subst, SubstsRef};
-use crate::ty::{BrAnon, BrEnv, BrFresh, BrNamed};
-use crate::ty::{Bool, Char, Adt};
-use crate::ty::{Error, Str, Array, Slice, Float, FnDef, FnPtr};
-use crate::ty::{Param, Bound, RawPtr, Ref, Never, Tuple};
-use crate::ty::{Closure, Generator, GeneratorWitness, Foreign, Projection, Opaque};
-use crate::ty::{Placeholder, UnnormalizedProjection, Dynamic, Int, Uint, Infer};
-use crate::ty::{self, Ty, TyCtxt, TypeFoldable, GenericParamCount, GenericParamDefKind, ParamConst};
-use crate::mir::interpret::ConstValue;
-use crate::util::nodemap::FxHashSet;
-
-use std::cell::Cell;
-use std::fmt;
-use std::usize;
-
-use rustc_target::spec::abi::Abi;
-use syntax::ast::CRATE_NODE_ID;
-use syntax::symbol::{Symbol, InternedString};
-use crate::hir;
-
-/// The "region highlights" are used to control region printing during
-/// specific error messages. When a "region highlight" is enabled, it
-/// gives an alternate way to print specific regions. For now, we
-/// always print those regions using a number, so something like "`'0`".
-///
-/// Regions not selected by the region highlight mode are presently
-/// unaffected.
-#[derive(Copy, Clone, Default)]
-pub struct RegionHighlightMode {
-    /// If enabled, when we see the selected region, use "`'N`"
-    /// instead of the ordinary behavior.
-    highlight_regions: [Option<(ty::RegionKind, usize)>; 3],
-
-    /// If enabled, when printing a "free region" that originated from
-    /// the given `ty::BoundRegion`, print it as "`'1`". Free regions that would ordinarily
-    /// have names print as normal.
-    ///
-    /// This is used when you have a signature like `fn foo(x: &u32,
-    /// y: &'a u32)` and we want to give a name to the region of the
-    /// reference `x`.
-    highlight_bound_region: Option<(ty::BoundRegion, usize)>,
-}
-
-thread_local! {
-    /// Mechanism for highlighting of specific regions for display in NLL region inference errors.
-    /// Contains region to highlight and counter for number to use when highlighting.
-    static REGION_HIGHLIGHT_MODE: Cell<RegionHighlightMode> =
-        Cell::new(RegionHighlightMode::default())
-}
-
-impl RegionHighlightMode {
-    /// Reads and returns the current region highlight settings (accesses thread-local state).
-    pub fn get() -> Self {
-        REGION_HIGHLIGHT_MODE.with(|c| c.get())
-    }
-
-    // Internal helper to update current settings during the execution of `op`.
-    fn set<R>(
-        old_mode: Self,
-        new_mode: Self,
-        op: impl FnOnce() -> R,
-    ) -> R {
-        REGION_HIGHLIGHT_MODE.with(|c| {
-            c.set(new_mode);
-            let result = op();
-            c.set(old_mode);
-            result
-        })
-    }
-
-    /// If `region` and `number` are both `Some`, invokes
-    /// `highlighting_region`; otherwise, just invokes `op` directly.
-    pub fn maybe_highlighting_region<R>(
-        region: Option<ty::Region<'_>>,
-        number: Option<usize>,
-        op: impl FnOnce() -> R,
-    ) -> R {
-        if let Some(k) = region {
-            if let Some(n) = number {
-                return Self::highlighting_region(k, n, op);
-            }
-        }
-
-        op()
-    }
-
-    /// During the execution of `op`, highlights the region inference
-    /// variable `vid` as `'N`. We can only highlight one region `vid`
-    /// at a time.
-    pub fn highlighting_region<R>(
-        region: ty::Region<'_>,
-        number: usize,
-        op: impl FnOnce() -> R,
-    ) -> R {
-        let old_mode = Self::get();
-        let mut new_mode = old_mode;
-        let first_avail_slot = new_mode.highlight_regions.iter_mut()
-            .filter(|s| s.is_none())
-            .next()
-            .unwrap_or_else(|| {
-                panic!(
-                    "can only highlight {} placeholders at a time",
-                    old_mode.highlight_regions.len(),
-                )
-            });
-        *first_avail_slot = Some((*region, number));
-        Self::set(old_mode, new_mode, op)
-    }
-
-    /// Convenience wrapper for `highlighting_region`.
-    pub fn highlighting_region_vid<R>(
-        vid: ty::RegionVid,
-        number: usize,
-        op: impl FnOnce() -> R,
-    ) -> R {
-        Self::highlighting_region(&ty::ReVar(vid), number, op)
-    }
-
-    /// Returns `true` if any placeholders are highlighted, and `false` otherwise.
-    fn any_region_vids_highlighted(&self) -> bool {
-        Self::get()
-            .highlight_regions
-            .iter()
-            .any(|h| match h {
-                Some((ty::ReVar(_), _)) => true,
-                _ => false,
-            })
-    }
-
-    /// Returns `Some(n)` with the number to use for the given region, if any.
-    fn region_highlighted(&self, region: ty::Region<'_>) -> Option<usize> {
-        Self::get()
-            .highlight_regions
-            .iter()
-            .filter_map(|h| match h {
-                Some((r, n)) if r == region => Some(*n),
-                _ => None,
-            })
-            .next()
-    }
-
-    /// During the execution of `op`, highlight the given bound
-    /// region. We can only highlight one bound region at a time. See
-    /// the field `highlight_bound_region` for more detailed notes.
-    pub fn highlighting_bound_region<R>(
-        br: ty::BoundRegion,
-        number: usize,
-        op: impl FnOnce() -> R,
-    ) -> R {
-        let old_mode = Self::get();
-        assert!(old_mode.highlight_bound_region.is_none());
-        Self::set(
-            old_mode,
-            Self {
-                highlight_bound_region: Some((br, number)),
-                ..old_mode
-            },
-            op,
-        )
-    }
-
-    /// Returns `true` if any placeholders are highlighted, and `false` otherwise.
-    pub fn any_placeholders_highlighted(&self) -> bool {
-        Self::get()
-            .highlight_regions
-            .iter()
-            .any(|h| match h {
-                Some((ty::RePlaceholder(_), _)) => true,
-                _ => false,
-            })
-    }
-
-    /// Returns `Some(N)` if the placeholder `p` is highlighted to print as "`'N`".
-    pub fn placeholder_highlight(&self, p: ty::PlaceholderRegion) -> Option<usize> {
-        self.region_highlighted(&ty::RePlaceholder(p))
-    }
-}
-
-macro_rules! gen_display_debug_body {
-    ( $with:path ) => {
-        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-            let mut cx = PrintContext::new();
-            $with(self, f, &mut cx)
-        }
-    };
-}
-macro_rules! gen_display_debug {
-    ( ($($x:tt)+) $target:ty, display yes ) => {
-        impl<$($x)+> fmt::Display for $target {
-            gen_display_debug_body! { Print::print_display }
-        }
-    };
-    ( () $target:ty, display yes ) => {
-        impl fmt::Display for $target {
-            gen_display_debug_body! { Print::print_display }
-        }
-    };
-    ( ($($x:tt)+) $target:ty, debug yes ) => {
-        impl<$($x)+> fmt::Debug for $target {
-            gen_display_debug_body! { Print::print_debug }
-        }
-    };
-    ( () $target:ty, debug yes ) => {
-        impl fmt::Debug for $target {
-            gen_display_debug_body! { Print::print_debug }
-        }
-    };
-    ( $generic:tt $target:ty, $t:ident no ) => {};
-}
-macro_rules! gen_print_impl {
-    ( ($($x:tt)+) $target:ty, ($self:ident, $f:ident, $cx:ident) $disp:block $dbg:block ) => {
-        impl<$($x)+> Print for $target {
-            fn print<F: fmt::Write>(&$self, $f: &mut F, $cx: &mut PrintContext) -> fmt::Result {
-                if $cx.is_debug $dbg
-                else $disp
-            }
-        }
-    };
-    ( () $target:ty, ($self:ident, $f:ident, $cx:ident) $disp:block $dbg:block ) => {
-        impl Print for $target {
-            fn print<F: fmt::Write>(&$self, $f: &mut F, $cx: &mut PrintContext) -> fmt::Result {
-                if $cx.is_debug $dbg
-                else $disp
-            }
-        }
-    };
-    ( $generic:tt $target:ty,
-      $vars:tt $gendisp:ident $disp:block $gendbg:ident $dbg:block ) => {
-        gen_print_impl! { $generic $target, $vars $disp $dbg }
-        gen_display_debug! { $generic $target, display $gendisp }
-        gen_display_debug! { $generic $target, debug $gendbg }
-    }
-}
-macro_rules! define_print {
-    ( $generic:tt $target:ty,
-      $vars:tt { display $disp:block debug $dbg:block } ) => {
-        gen_print_impl! { $generic $target, $vars yes $disp yes $dbg }
-    };
-    ( $generic:tt $target:ty,
-      $vars:tt { debug $dbg:block display $disp:block } ) => {
-        gen_print_impl! { $generic $target, $vars yes $disp yes $dbg }
-    };
-    ( $generic:tt $target:ty,
-      $vars:tt { debug $dbg:block } ) => {
-        gen_print_impl! { $generic $target, $vars no {
-            bug!(concat!("display not implemented for ", stringify!($target)));
-        } yes $dbg }
-    };
-    ( $generic:tt $target:ty,
-      ($self:ident, $f:ident, $cx:ident) { display $disp:block } ) => {
-        gen_print_impl! { $generic $target, ($self, $f, $cx) yes $disp no {
-            write!($f, "{:?}", $self)
-        } }
-    };
-}
-macro_rules! define_print_multi {
-    ( [ $($generic:tt $target:ty),* ] $vars:tt $def:tt ) => {
-        $(define_print! { $generic $target, $vars $def })*
-    };
-}
-macro_rules! print_inner {
-    ( $f:expr, $cx:expr, write ($($data:expr),+) ) => {
-        write!($f, $($data),+)
-    };
-    ( $f:expr, $cx:expr, $kind:ident ($data:expr) ) => {
-        $data.$kind($f, $cx)
-    };
-}
-macro_rules! print {
-    ( $f:expr, $cx:expr $(, $kind:ident $data:tt)+ ) => {
-        Ok(())$(.and_then(|_| print_inner!($f, $cx, $kind $data)))+
-    };
-}
-
-
-struct LateBoundRegionNameCollector(FxHashSet<InternedString>);
-impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector {
-    fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
-        match *r {
-            ty::ReLateBound(_, ty::BrNamed(_, name)) => {
-                self.0.insert(name);
-            },
-            _ => {},
-        }
-        r.super_visit_with(self)
-    }
-}
-
-#[derive(Debug)]
-pub struct PrintContext {
-    is_debug: bool,
-    is_verbose: bool,
-    identify_regions: bool,
-    used_region_names: Option<FxHashSet<InternedString>>,
-    region_index: usize,
-    binder_depth: usize,
-}
-impl PrintContext {
-    fn new() -> Self {
-        ty::tls::with_opt(|tcx| {
-            let (is_verbose, identify_regions) = tcx.map(
-                |tcx| (tcx.sess.verbose(), tcx.sess.opts.debugging_opts.identify_regions)
-            ).unwrap_or((false, false));
-            PrintContext {
-                is_debug: false,
-                is_verbose: is_verbose,
-                identify_regions: identify_regions,
-                used_region_names: None,
-                region_index: 0,
-                binder_depth: 0,
-            }
-        })
-    }
-    fn prepare_late_bound_region_info<'tcx, T>(&mut self, value: &ty::Binder<T>)
-    where T: TypeFoldable<'tcx>
-    {
-        let mut collector = LateBoundRegionNameCollector(Default::default());
-        value.visit_with(&mut collector);
-        self.used_region_names = Some(collector.0);
-        self.region_index = 0;
-    }
-}
-
-pub trait Print {
-    fn print<F: fmt::Write>(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result;
-    fn print_to_string(&self, cx: &mut PrintContext) -> String {
-        let mut result = String::new();
-        let _ = self.print(&mut result, cx);
-        result
-    }
-    fn print_display<F: fmt::Write>(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result {
-        let old_debug = cx.is_debug;
-        cx.is_debug = false;
-        let result = self.print(f, cx);
-        cx.is_debug = old_debug;
-        result
-    }
-    fn print_display_to_string(&self, cx: &mut PrintContext) -> String {
-        let mut result = String::new();
-        let _ = self.print_display(&mut result, cx);
-        result
-    }
-    fn print_debug<F: fmt::Write>(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result {
-        let old_debug = cx.is_debug;
-        cx.is_debug = true;
-        let result = self.print(f, cx);
-        cx.is_debug = old_debug;
-        result
-    }
-    fn print_debug_to_string(&self, cx: &mut PrintContext) -> String {
-        let mut result = String::new();
-        let _ = self.print_debug(&mut result, cx);
-        result
-    }
-}
-
-impl PrintContext {
-    fn fn_sig<F: fmt::Write>(&mut self,
-                             f: &mut F,
-                             inputs: &[Ty<'_>],
-                             c_variadic: bool,
-                             output: Ty<'_>)
-                             -> fmt::Result {
-        write!(f, "(")?;
-        let mut inputs = inputs.iter();
-        if let Some(&ty) = inputs.next() {
-            print!(f, self, print_display(ty))?;
-            for &ty in inputs {
-                print!(f, self, write(", "), print_display(ty))?;
-            }
-            if c_variadic {
-                write!(f, ", ...")?;
-            }
-        }
-        write!(f, ")")?;
-        if !output.is_unit() {
-            print!(f, self, write(" -> "), print_display(output))?;
-        }
-
-        Ok(())
-    }
-
-    fn parameterized<F: fmt::Write>(&mut self,
-                                    f: &mut F,
-                                    substs: SubstsRef<'_>,
-                                    did: DefId,
-                                    projections: &[ty::ProjectionPredicate<'_>])
-                                    -> fmt::Result {
-        let key = ty::tls::with(|tcx| tcx.def_key(did));
-
-        let verbose = self.is_verbose;
-        let mut num_supplied_defaults = 0;
-        let mut has_self = false;
-        let mut own_counts: GenericParamCount = Default::default();
-        let mut is_value_path = false;
-        let mut item_name = Some(key.disambiguated_data.data.as_interned_str());
-        let fn_trait_kind = ty::tls::with(|tcx| {
-            // Unfortunately, some kinds of items (e.g., closures) don't have
-            // generics. So walk back up the find the closest parent that DOES
-            // have them.
-            let mut item_def_id = did;
-            loop {
-                let key = tcx.def_key(item_def_id);
-                match key.disambiguated_data.data {
-                    DefPathData::AssocTypeInTrait(_) |
-                    DefPathData::AssocTypeInImpl(_) |
-                    DefPathData::AssocExistentialInImpl(_) |
-                    DefPathData::Trait(_) |
-                    DefPathData::TraitAlias(_) |
-                    DefPathData::Impl |
-                    DefPathData::TypeNs(_) => {
-                        break;
-                    }
-                    DefPathData::ValueNs(_) |
-                    DefPathData::EnumVariant(_) => {
-                        is_value_path = true;
-                        break;
-                    }
-                    DefPathData::CrateRoot |
-                    DefPathData::Misc |
-                    DefPathData::Module(_) |
-                    DefPathData::MacroDef(_) |
-                    DefPathData::ClosureExpr |
-                    DefPathData::TypeParam(_) |
-                    DefPathData::LifetimeParam(_) |
-                    DefPathData::ConstParam(_) |
-                    DefPathData::Field(_) |
-                    DefPathData::StructCtor |
-                    DefPathData::AnonConst |
-                    DefPathData::ImplTrait |
-                    DefPathData::GlobalMetaData(_) => {
-                        // if we're making a symbol for something, there ought
-                        // to be a value or type-def or something in there
-                        // *somewhere*
-                        item_def_id.index = key.parent.unwrap_or_else(|| {
-                            bug!("finding type for {:?}, encountered def-id {:?} with no \
-                                 parent", did, item_def_id);
-                        });
-                    }
-                }
-            }
-            let mut generics = tcx.generics_of(item_def_id);
-            let child_own_counts = generics.own_counts();
-            let mut path_def_id = did;
-            has_self = generics.has_self;
-
-            let mut child_types = 0;
-            if let Some(def_id) = generics.parent {
-                // Methods.
-                assert!(is_value_path);
-                child_types = child_own_counts.types;
-                generics = tcx.generics_of(def_id);
-                own_counts = generics.own_counts();
-
-                if has_self {
-                    print!(f, self, write("<"), print_display(substs.type_at(0)), write(" as "))?;
-                }
-
-                path_def_id = def_id;
-            } else {
-                item_name = None;
-
-                if is_value_path {
-                    // Functions.
-                    assert_eq!(has_self, false);
-                } else {
-                    // Types and traits.
-                    own_counts = child_own_counts;
-                }
-            }
-
-            if !verbose {
-                let mut type_params =
-                    generics.params.iter().rev().filter_map(|param| match param.kind {
-                        GenericParamDefKind::Lifetime => None,
-                        GenericParamDefKind::Type { has_default, .. } => {
-                            Some((param.def_id, has_default))
-                        }
-                        GenericParamDefKind::Const => None, // FIXME(const_generics:defaults)
-                    }).peekable();
-                let has_default = {
-                    let has_default = type_params.peek().map(|(_, has_default)| has_default);
-                    *has_default.unwrap_or(&false)
-                };
-                if has_default {
-                    if let Some(substs) = tcx.lift(&substs) {
-                        let types = substs.types().rev().skip(child_types);
-                        for ((def_id, has_default), actual) in type_params.zip(types) {
-                            if !has_default {
-                                break;
-                            }
-                            if tcx.type_of(def_id).subst(tcx, substs) != actual {
-                                break;
-                            }
-                            num_supplied_defaults += 1;
-                        }
-                    }
-                }
-            }
-
-            print!(f, self, write("{}", tcx.item_path_str(path_def_id)))?;
-            Ok(tcx.lang_items().fn_trait_kind(path_def_id))
-        })?;
-
-        if !verbose && fn_trait_kind.is_some() && projections.len() == 1 {
-            let projection_ty = projections[0].ty;
-            if let Tuple(ref args) = substs.type_at(1).sty {
-                return self.fn_sig(f, args, false, projection_ty);
-            }
-        }
-
-        let empty = Cell::new(true);
-        let start_or_continue = |f: &mut F, start: &str, cont: &str| {
-            if empty.get() {
-                empty.set(false);
-                write!(f, "{}", start)
-            } else {
-                write!(f, "{}", cont)
-            }
-        };
-
-        let print_regions = |f: &mut F, start: &str, skip, count| {
-            // Don't print any regions if they're all erased.
-            let regions = || substs.regions().skip(skip).take(count);
-            if regions().all(|r: ty::Region<'_>| *r == ty::ReErased) {
-                return Ok(());
-            }
-
-            for region in regions() {
-                let region: ty::Region<'_> = region;
-                start_or_continue(f, start, ", ")?;
-                if verbose {
-                    write!(f, "{:?}", region)?;
-                } else {
-                    let s = region.to_string();
-                    if s.is_empty() {
-                        // This happens when the value of the region
-                        // parameter is not easily serialized. This may be
-                        // because the user omitted it in the first place,
-                        // or because it refers to some block in the code,
-                        // etc. I'm not sure how best to serialize this.
-                        write!(f, "'_")?;
-                    } else {
-                        write!(f, "{}", s)?;
-                    }
-                }
-            }
-
-            Ok(())
-        };
-
-        print_regions(f, "<", 0, own_counts.lifetimes)?;
-
-        let tps = substs.types()
-                        .take(own_counts.types - num_supplied_defaults)
-                        .skip(has_self as usize);
-
-        for ty in tps {
-            start_or_continue(f, "<", ", ")?;
-            ty.print_display(f, self)?;
-        }
-
-        for projection in projections {
-            start_or_continue(f, "<", ", ")?;
-            ty::tls::with(|tcx|
-                print!(f, self,
-                       write("{}=",
-                             tcx.associated_item(projection.projection_ty.item_def_id).ident),
-                       print_display(projection.ty))
-            )?;
-        }
-
-        // FIXME(const_generics::defaults)
-        let consts = substs.consts();
-
-        for ct in consts {
-            start_or_continue(f, "<", ", ")?;
-            ct.print_display(f, self)?;
-        }
-
-        start_or_continue(f, "", ">")?;
-
-        // For values, also print their name and type parameters.
-        if is_value_path {
-            empty.set(true);
-
-            if has_self {
-                write!(f, ">")?;
-            }
-
-            if let Some(item_name) = item_name {
-                write!(f, "::{}", item_name)?;
-            }
-
-            print_regions(f, "::<", own_counts.lifetimes, usize::MAX)?;
-
-            // FIXME: consider being smart with defaults here too
-            for ty in substs.types().skip(own_counts.types) {
-                start_or_continue(f, "::<", ", ")?;
-                ty.print_display(f, self)?;
-            }
-
-            start_or_continue(f, "", ">")?;
-        }
-
-        Ok(())
-    }
-
-    fn in_binder<'a, 'gcx, 'tcx, T, U, F>(&mut self,
-                                          f: &mut F,
-                                          tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                                          original: &ty::Binder<T>,
-                                          lifted: Option<ty::Binder<U>>) -> fmt::Result
-        where T: Print, U: Print + TypeFoldable<'tcx>, F: fmt::Write
-    {
-        fn name_by_region_index(index: usize) -> InternedString {
-            match index {
-                0 => Symbol::intern("'r"),
-                1 => Symbol::intern("'s"),
-                i => Symbol::intern(&format!("'t{}", i-2)),
-            }.as_interned_str()
-        }
-
-        // Replace any anonymous late-bound regions with named
-        // variants, using gensym'd identifiers, so that we can
-        // clearly differentiate between named and unnamed regions in
-        // the output. We'll probably want to tweak this over time to
-        // decide just how much information to give.
-        let value = if let Some(v) = lifted {
-            v
-        } else {
-            return original.skip_binder().print_display(f, self);
-        };
-
-        if self.binder_depth == 0 {
-            self.prepare_late_bound_region_info(&value);
-        }
-
-        let mut empty = true;
-        let mut start_or_continue = |f: &mut F, start: &str, cont: &str| {
-            if empty {
-                empty = false;
-                write!(f, "{}", start)
-            } else {
-                write!(f, "{}", cont)
-            }
-        };
-
-        let old_region_index = self.region_index;
-        let mut region_index = old_region_index;
-        let new_value = tcx.replace_late_bound_regions(&value, |br| {
-            let _ = start_or_continue(f, "for<", ", ");
-            let br = match br {
-                ty::BrNamed(_, name) => {
-                    let _ = write!(f, "{}", name);
-                    br
-                }
-                ty::BrAnon(_) |
-                ty::BrFresh(_) |
-                ty::BrEnv => {
-                    let name = loop {
-                        let name = name_by_region_index(region_index);
-                        region_index += 1;
-                        if !self.is_name_used(&name) {
-                            break name;
-                        }
-                    };
-                    let _ = write!(f, "{}", name);
-                    ty::BrNamed(tcx.hir().local_def_id(CRATE_NODE_ID), name)
-                }
-            };
-            tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br))
-        }).0;
-        start_or_continue(f, "", "> ")?;
-
-        // Push current state to gcx, and restore after writing new_value.
-        self.binder_depth += 1;
-        self.region_index = region_index;
-        let result = new_value.print_display(f, self);
-        self.region_index = old_region_index;
-        self.binder_depth -= 1;
-        result
-    }
-
-    fn is_name_used(&self, name: &InternedString) -> bool {
-        match self.used_region_names {
-            Some(ref names) => names.contains(name),
-            None => false,
-        }
-    }
-}
-
-pub fn verbose() -> bool {
-    ty::tls::with(|tcx| tcx.sess.verbose())
-}
-
-pub fn identify_regions() -> bool {
-    ty::tls::with(|tcx| tcx.sess.opts.debugging_opts.identify_regions)
-}
-
-pub fn parameterized<F: fmt::Write>(f: &mut F,
-                                    substs: SubstsRef<'_>,
-                                    did: DefId,
-                                    projections: &[ty::ProjectionPredicate<'_>])
-                                    -> fmt::Result {
-    PrintContext::new().parameterized(f, substs, did, projections)
-}
-
-impl<'a, T: Print> Print for &'a T {
-    fn print<F: fmt::Write>(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result {
-        (*self).print(f, cx)
-    }
-}
-
-define_print! {
-    ('tcx) &'tcx ty::List<ty::ExistentialPredicate<'tcx>>, (self, f, cx) {
-        display {
-            // Generate the main trait ref, including associated types.
-            ty::tls::with(|tcx| {
-                // Use a type that can't appear in defaults of type parameters.
-                let dummy_self = tcx.mk_infer(ty::FreshTy(0));
-                let mut first = true;
-
-                if let Some(principal) = self.principal() {
-                    let principal = tcx
-                        .lift(&principal)
-                        .expect("could not lift TraitRef for printing")
-                        .with_self_ty(tcx, dummy_self);
-                    let projections = self.projection_bounds().map(|p| {
-                        tcx.lift(&p)
-                            .expect("could not lift projection for printing")
-                            .with_self_ty(tcx, dummy_self)
-                    }).collect::<Vec<_>>();
-                    cx.parameterized(f, principal.substs, principal.def_id, &projections)?;
-                    first = false;
-                }
-
-                // Builtin bounds.
-                let mut auto_traits: Vec<_> = self.auto_traits().map(|did| {
-                    tcx.item_path_str(did)
-                }).collect();
-
-                // The auto traits come ordered by `DefPathHash`. While
-                // `DefPathHash` is *stable* in the sense that it depends on
-                // neither the host nor the phase of the moon, it depends
-                // "pseudorandomly" on the compiler version and the target.
-                //
-                // To avoid that causing instabilities in compiletest
-                // output, sort the auto-traits alphabetically.
-                auto_traits.sort();
-
-                for auto_trait in auto_traits {
-                    if !first {
-                        write!(f, " + ")?;
-                    }
-                    first = false;
-
-                    write!(f, "{}", auto_trait)?;
-                }
-
-                Ok(())
-            })?;
-
-            Ok(())
-        }
-    }
-}
-
-impl fmt::Debug for ty::GenericParamDef {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let type_name = match self.kind {
-            ty::GenericParamDefKind::Lifetime => "Lifetime",
-            ty::GenericParamDefKind::Type { .. } => "Type",
-            ty::GenericParamDefKind::Const => "Const",
-        };
-        write!(f, "{}({}, {:?}, {})",
-               type_name,
-               self.name,
-               self.def_id,
-               self.index)
-    }
-}
-
-impl fmt::Debug for ty::TraitDef {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        ty::tls::with(|tcx| {
-            write!(f, "{}", tcx.item_path_str(self.def_id))
-        })
-    }
-}
-
-impl fmt::Debug for ty::AdtDef {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        ty::tls::with(|tcx| {
-            write!(f, "{}", tcx.item_path_str(self.did))
-        })
-    }
-}
-
-impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "ClosureUpvar({:?},{:?})",
-               self.def,
-               self.ty)
-    }
-}
-
-impl fmt::Debug for ty::UpvarId {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "UpvarId({:?};`{}`;{:?})",
-               self.var_path.hir_id,
-               ty::tls::with(|tcx| tcx.hir().name_by_hir_id(self.var_path.hir_id)),
-               self.closure_expr_id)
-    }
-}
-
-impl<'tcx> fmt::Debug for ty::UpvarBorrow<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "UpvarBorrow({:?}, {:?})",
-               self.kind, self.region)
-    }
-}
-
-define_print! {
-    ('tcx) &'tcx ty::List<Ty<'tcx>>, (self, f, cx) {
-        display {
-            write!(f, "{{")?;
-            let mut tys = self.iter();
-            if let Some(&ty) = tys.next() {
-                print!(f, cx, print(ty))?;
-                for &ty in tys {
-                    print!(f, cx, write(", "), print(ty))?;
-                }
-            }
-            write!(f, "}}")
-        }
-    }
-}
-
-define_print! {
-    ('tcx) ty::TypeAndMut<'tcx>, (self, f, cx) {
-        display {
-            print!(f, cx,
-                   write("{}", if self.mutbl == hir::MutMutable { "mut " } else { "" }),
-                   print(self.ty))
-        }
-    }
-}
-
-define_print! {
-    ('tcx) ty::ExistentialTraitRef<'tcx>, (self, f, cx) {
-        display {
-            cx.parameterized(f, self.substs, self.def_id, &[])
-        }
-        debug {
-            ty::tls::with(|tcx| {
-                let dummy_self = tcx.mk_infer(ty::FreshTy(0));
-
-                let trait_ref = *tcx.lift(&ty::Binder::bind(*self))
-                                   .expect("could not lift TraitRef for printing")
-                                   .with_self_ty(tcx, dummy_self).skip_binder();
-                cx.parameterized(f, trait_ref.substs, trait_ref.def_id, &[])
-            })
-        }
-    }
-}
-
-define_print! {
-    ('tcx) ty::adjustment::Adjustment<'tcx>, (self, f, cx) {
-        debug {
-            print!(f, cx, write("{:?} -> ", self.kind), print(self.target))
-        }
-    }
-}
-
-define_print! {
-    () ty::BoundRegion, (self, f, cx) {
-        display {
-            if cx.is_verbose {
-                return self.print_debug(f, cx);
-            }
-
-            if let Some((region, counter)) = RegionHighlightMode::get().highlight_bound_region {
-                if *self == region {
-                    return match *self {
-                        BrNamed(_, name) => write!(f, "{}", name),
-                        BrAnon(_) | BrFresh(_) | BrEnv => write!(f, "'{}", counter)
-                    };
-                }
-            }
-
-            match *self {
-                BrNamed(_, name) => write!(f, "{}", name),
-                BrAnon(_) | BrFresh(_) | BrEnv => Ok(())
-            }
-        }
-        debug {
-            return match *self {
-                BrAnon(n) => write!(f, "BrAnon({:?})", n),
-                BrFresh(n) => write!(f, "BrFresh({:?})", n),
-                BrNamed(did, name) => {
-                    write!(f, "BrNamed({:?}:{:?}, {})",
-                           did.krate, did.index, name)
-                }
-                BrEnv => write!(f, "BrEnv"),
-            };
-        }
-    }
-}
-
-define_print! {
-    () ty::PlaceholderRegion, (self, f, cx) {
-        display {
-            if cx.is_verbose {
-                return self.print_debug(f, cx);
-            }
-
-            let highlight = RegionHighlightMode::get();
-            if let Some(counter) = highlight.placeholder_highlight(*self) {
-                write!(f, "'{}", counter)
-            } else if highlight.any_placeholders_highlighted() {
-                write!(f, "'_")
-            } else {
-                write!(f, "{}", self.name)
-            }
-        }
-    }
-}
-
-define_print! {
-    () ty::RegionKind, (self, f, cx) {
-        display {
-            if cx.is_verbose {
-                return self.print_debug(f, cx);
-            }
-
-            // Watch out for region highlights.
-            if let Some(n) = RegionHighlightMode::get().region_highlighted(self) {
-                return write!(f, "'{:?}", n);
-            }
-
-            // These printouts are concise.  They do not contain all the information
-            // the user might want to diagnose an error, but there is basically no way
-            // to fit that into a short string.  Hence the recommendation to use
-            // `explain_region()` or `note_and_explain_region()`.
-            match *self {
-                ty::ReEarlyBound(ref data) => {
-                    write!(f, "{}", data.name)
-                }
-                ty::ReLateBound(_, br) |
-                ty::ReFree(ty::FreeRegion { bound_region: br, .. }) => {
-                    write!(f, "{}", br)
-                }
-                ty::RePlaceholder(p) => {
-                    write!(f, "{}", p)
-                }
-                ty::ReScope(scope) if cx.identify_regions => {
-                    match scope.data {
-                        region::ScopeData::Node =>
-                            write!(f, "'{}s", scope.item_local_id().as_usize()),
-                        region::ScopeData::CallSite =>
-                            write!(f, "'{}cs", scope.item_local_id().as_usize()),
-                        region::ScopeData::Arguments =>
-                            write!(f, "'{}as", scope.item_local_id().as_usize()),
-                        region::ScopeData::Destruction =>
-                            write!(f, "'{}ds", scope.item_local_id().as_usize()),
-                        region::ScopeData::Remainder(first_statement_index) => write!(
-                            f,
-                            "'{}_{}rs",
-                            scope.item_local_id().as_usize(),
-                            first_statement_index.index()
-                        ),
-                    }
-                }
-                ty::ReVar(region_vid) => {
-                    if RegionHighlightMode::get().any_region_vids_highlighted() {
-                        write!(f, "{:?}", region_vid)
-                    } else if cx.identify_regions {
-                        write!(f, "'{}rv", region_vid.index())
-                    } else {
-                        Ok(())
-                    }
-                }
-                ty::ReScope(_) |
-                ty::ReErased => Ok(()),
-                ty::ReStatic => write!(f, "'static"),
-                ty::ReEmpty => write!(f, "'<empty>"),
-
-                // The user should never encounter these in unsubstituted form.
-                ty::ReClosureBound(vid) => write!(f, "{:?}", vid),
-            }
-        }
-        debug {
-            match *self {
-                ty::ReEarlyBound(ref data) => {
-                    write!(f, "ReEarlyBound({}, {})",
-                           data.index,
-                           data.name)
-                }
-
-                ty::ReClosureBound(ref vid) => {
-                    write!(f, "ReClosureBound({:?})",
-                           vid)
-                }
-
-                ty::ReLateBound(binder_id, ref bound_region) => {
-                    write!(f, "ReLateBound({:?}, {:?})",
-                           binder_id,
-                           bound_region)
-                }
-
-                ty::ReFree(ref fr) => write!(f, "{:?}", fr),
-
-                ty::ReScope(id) => {
-                    write!(f, "ReScope({:?})", id)
-                }
-
-                ty::ReStatic => write!(f, "ReStatic"),
-
-                ty::ReVar(ref vid) => {
-                    write!(f, "{:?}", vid)
-                }
-
-                ty::RePlaceholder(placeholder) => {
-                    write!(f, "RePlaceholder({:?})", placeholder)
-                }
-
-                ty::ReEmpty => write!(f, "ReEmpty"),
-
-                ty::ReErased => write!(f, "ReErased")
-            }
-        }
-    }
-}
-
-define_print! {
-    () ty::FreeRegion, (self, f, cx) {
-        debug {
-            write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region)
-        }
-    }
-}
-
-define_print! {
-    () ty::Variance, (self, f, cx) {
-        debug {
-            f.write_str(match *self {
-                ty::Covariant => "+",
-                ty::Contravariant => "-",
-                ty::Invariant => "o",
-                ty::Bivariant => "*",
-            })
-        }
-    }
-}
-
-define_print! {
-    ('tcx) ty::GenericPredicates<'tcx>, (self, f, cx) {
-        debug {
-            write!(f, "GenericPredicates({:?})", self.predicates)
-        }
-    }
-}
-
-define_print! {
-    ('tcx) ty::InstantiatedPredicates<'tcx>, (self, f, cx) {
-        debug {
-            write!(f, "InstantiatedPredicates({:?})", self.predicates)
-        }
-    }
-}
-
-define_print! {
-    ('tcx) ty::FnSig<'tcx>, (self, f, cx) {
-        display {
-            if self.unsafety == hir::Unsafety::Unsafe {
-                write!(f, "unsafe ")?;
-            }
-
-            if self.abi != Abi::Rust {
-                write!(f, "extern {} ", self.abi)?;
-            }
-
-            write!(f, "fn")?;
-            cx.fn_sig(f, self.inputs(), self.c_variadic, self.output())
-        }
-        debug {
-            write!(f, "({:?}; c_variadic: {})->{:?}", self.inputs(), self.c_variadic, self.output())
-        }
-    }
-}
-
-impl fmt::Debug for ty::TyVid {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "_#{}t", self.index)
-    }
-}
-
-impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "_#{}f", self.index)
-    }
-}
-
-impl fmt::Debug for ty::IntVid {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "_#{}i", self.index)
-    }
-}
-
-impl fmt::Debug for ty::FloatVid {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "_#{}f", self.index)
-    }
-}
-
-impl fmt::Debug for ty::RegionVid {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        if let Some(counter) = RegionHighlightMode::get().region_highlighted(&ty::ReVar(*self)) {
-            return write!(f, "'{:?}", counter);
-        } else if RegionHighlightMode::get().any_region_vids_highlighted() {
-            return write!(f, "'_");
-        }
-
-        write!(f, "'_#{}r", self.index())
-    }
-}
-
-define_print! {
-    () ty::InferTy, (self, f, cx) {
-        display {
-            if cx.is_verbose {
-                print!(f, cx, print_debug(self))
-            } else {
-                match *self {
-                    ty::TyVar(_) => write!(f, "_"),
-                    ty::IntVar(_) => write!(f, "{}", "{integer}"),
-                    ty::FloatVar(_) => write!(f, "{}", "{float}"),
-                    ty::FreshTy(v) => write!(f, "FreshTy({})", v),
-                    ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v),
-                    ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v)
-                }
-            }
-        }
-        debug {
-            match *self {
-                ty::TyVar(ref v) => write!(f, "{:?}", v),
-                ty::IntVar(ref v) => write!(f, "{:?}", v),
-                ty::FloatVar(ref v) => write!(f, "{:?}", v),
-                ty::FreshTy(v) => write!(f, "FreshTy({:?})", v),
-                ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
-                ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v)
-            }
-        }
-    }
-}
-
-impl fmt::Debug for ty::IntVarValue {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {
-            ty::IntType(ref v) => v.fmt(f),
-            ty::UintType(ref v) => v.fmt(f),
-        }
-    }
-}
-
-impl fmt::Debug for ty::FloatVarValue {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.0.fmt(f)
-    }
-}
-
-// The generic impl doesn't work yet because projections are not
-// normalized under HRTB.
-/*impl<T> fmt::Display for ty::Binder<T>
-    where T: fmt::Display + for<'a> ty::Lift<'a>,
-          for<'a> <T as ty::Lift<'a>>::Lifted: fmt::Display + TypeFoldable<'a>
-{
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
-    }
-}*/
-
-define_print_multi! {
-    [
-    ('tcx) ty::Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>,
-    ('tcx) ty::Binder<ty::TraitRef<'tcx>>,
-    ('tcx) ty::Binder<ty::FnSig<'tcx>>,
-    ('tcx) ty::Binder<ty::TraitPredicate<'tcx>>,
-    ('tcx) ty::Binder<ty::SubtypePredicate<'tcx>>,
-    ('tcx) ty::Binder<ty::ProjectionPredicate<'tcx>>,
-    ('tcx) ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>,
-    ('tcx) ty::Binder<ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>>
-    ]
-    (self, f, cx) {
-        display {
-            ty::tls::with(|tcx| cx.in_binder(f, tcx, self, tcx.lift(self)))
-        }
-    }
-}
-
-define_print! {
-    ('tcx) ty::TraitRef<'tcx>, (self, f, cx) {
-        display {
-            cx.parameterized(f, self.substs, self.def_id, &[])
-        }
-        debug {
-            // when printing out the debug representation, we don't need
-            // to enumerate the `for<...>` etc because the debruijn index
-            // tells you everything you need to know.
-            print!(f, cx,
-                   write("<"),
-                   print(self.self_ty()),
-                   write(" as "))?;
-            cx.parameterized(f, self.substs, self.def_id, &[])?;
-            write!(f, ">")
-        }
-    }
-}
-
-define_print! {
-    ('tcx) ty::TyKind<'tcx>, (self, f, cx) {
-        display {
-            match *self {
-                Bool => write!(f, "bool"),
-                Char => write!(f, "char"),
-                Int(t) => write!(f, "{}", t.ty_to_string()),
-                Uint(t) => write!(f, "{}", t.ty_to_string()),
-                Float(t) => write!(f, "{}", t.ty_to_string()),
-                RawPtr(ref tm) => {
-                    write!(f, "*{} ", match tm.mutbl {
-                        hir::MutMutable => "mut",
-                        hir::MutImmutable => "const",
-                    })?;
-                    tm.ty.print(f, cx)
-                }
-                Ref(r, ty, mutbl) => {
-                    write!(f, "&")?;
-                    let s = r.print_to_string(cx);
-                    if s != "'_" {
-                        write!(f, "{}", s)?;
-                        if !s.is_empty() {
-                            write!(f, " ")?;
-                        }
-                    }
-                    ty::TypeAndMut { ty, mutbl }.print(f, cx)
-                }
-                Never => write!(f, "!"),
-                Tuple(ref tys) => {
-                    write!(f, "(")?;
-                    let mut tys = tys.iter();
-                    if let Some(&ty) = tys.next() {
-                        print!(f, cx, print(ty), write(","))?;
-                        if let Some(&ty) = tys.next() {
-                            print!(f, cx, write(" "), print(ty))?;
-                            for &ty in tys {
-                                print!(f, cx, write(", "), print(ty))?;
-                            }
-                        }
-                    }
-                    write!(f, ")")
-                }
-                FnDef(def_id, substs) => {
-                    ty::tls::with(|tcx| {
-                        let mut sig = tcx.fn_sig(def_id);
-                        if let Some(substs) = tcx.lift(&substs) {
-                            sig = sig.subst(tcx, substs);
-                        }
-                        print!(f, cx, print(sig), write(" {{"))
-                    })?;
-                    cx.parameterized(f, substs, def_id, &[])?;
-                    write!(f, "}}")
-                }
-                FnPtr(ref bare_fn) => {
-                    bare_fn.print(f, cx)
-                }
-                Infer(infer_ty) => write!(f, "{}", infer_ty),
-                Error => write!(f, "[type error]"),
-                Param(ref param_ty) => write!(f, "{}", param_ty),
-                Bound(debruijn, bound_ty) => {
-                    match bound_ty.kind {
-                        ty::BoundTyKind::Anon => {
-                            if debruijn == ty::INNERMOST {
-                                write!(f, "^{}", bound_ty.var.index())
-                            } else {
-                                write!(f, "^{}_{}", debruijn.index(), bound_ty.var.index())
-                            }
-                        }
-
-                        ty::BoundTyKind::Param(p) => write!(f, "{}", p),
-                    }
-                }
-                Adt(def, substs) => cx.parameterized(f, substs, def.did, &[]),
-                Dynamic(data, r) => {
-                    let r = r.print_to_string(cx);
-                    if !r.is_empty() {
-                        write!(f, "(")?;
-                    }
-                    write!(f, "dyn ")?;
-                    data.print(f, cx)?;
-                    if !r.is_empty() {
-                        write!(f, " + {})", r)
-                    } else {
-                        Ok(())
-                    }
-                }
-                Foreign(def_id) => parameterized(f, subst::InternalSubsts::empty(), def_id, &[]),
-                Projection(ref data) => data.print(f, cx),
-                UnnormalizedProjection(ref data) => {
-                    write!(f, "Unnormalized(")?;
-                    data.print(f, cx)?;
-                    write!(f, ")")
-                }
-                Placeholder(placeholder) => {
-                    write!(f, "Placeholder({:?})", placeholder)
-                }
-                Opaque(def_id, substs) => {
-                    if cx.is_verbose {
-                        return write!(f, "Opaque({:?}, {:?})", def_id, substs);
-                    }
-
-                    ty::tls::with(|tcx| {
-                        let def_key = tcx.def_key(def_id);
-                        if let Some(name) = def_key.disambiguated_data.data.get_opt_name() {
-                            write!(f, "{}", name)?;
-                            let mut substs = substs.iter();
-                            if let Some(first) = substs.next() {
-                                write!(f, "::<")?;
-                                write!(f, "{}", first)?;
-                                for subst in substs {
-                                    write!(f, ", {}", subst)?;
-                                }
-                                write!(f, ">")?;
-                            }
-                            return Ok(());
-                        }
-                        // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
-                        // by looking up the projections associated with the def_id.
-                        let predicates_of = tcx.predicates_of(def_id);
-                        let substs = tcx.lift(&substs).unwrap_or_else(|| {
-                            tcx.intern_substs(&[])
-                        });
-                        let bounds = predicates_of.instantiate(tcx, substs);
-
-                        let mut first = true;
-                        let mut is_sized = false;
-                        write!(f, "impl")?;
-                        for predicate in bounds.predicates {
-                            if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() {
-                                // Don't print +Sized, but rather +?Sized if absent.
-                                if Some(trait_ref.def_id()) == tcx.lang_items().sized_trait() {
-                                    is_sized = true;
-                                    continue;
-                                }
-
-                                print!(f, cx,
-                                       write("{}", if first { " " } else { "+" }),
-                                       print(trait_ref))?;
-                                first = false;
-                            }
-                        }
-                        if !is_sized {
-                            write!(f, "{}?Sized", if first { " " } else { "+" })?;
-                        } else if first {
-                            write!(f, " Sized")?;
-                        }
-                        Ok(())
-                    })
-                }
-                Str => write!(f, "str"),
-                Generator(did, substs, movability) => ty::tls::with(|tcx| {
-                    let upvar_tys = substs.upvar_tys(did, tcx);
-                    let witness = substs.witness(did, tcx);
-                    if movability == hir::GeneratorMovability::Movable {
-                        write!(f, "[generator")?;
-                    } else {
-                        write!(f, "[static generator")?;
-                    }
-
-                    if let Some(hir_id) = tcx.hir().as_local_hir_id(did) {
-                        write!(f, "@{:?}", tcx.hir().span_by_hir_id(hir_id))?;
-                        let mut sep = " ";
-                        tcx.with_freevars(hir_id, |freevars| {
-                            for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) {
-                                print!(f, cx,
-                                       write("{}{}:",
-                                             sep,
-                                             tcx.hir().name(freevar.var_id())),
-                                       print(upvar_ty))?;
-                                sep = ", ";
-                            }
-                            Ok(())
-                        })?
-                    } else {
-                        // cross-crate closure types should only be
-                        // visible in codegen bug reports, I imagine.
-                        write!(f, "@{:?}", did)?;
-                        let mut sep = " ";
-                        for (index, upvar_ty) in upvar_tys.enumerate() {
-                            print!(f, cx,
-                                   write("{}{}:", sep, index),
-                                   print(upvar_ty))?;
-                            sep = ", ";
-                        }
-                    }
-
-                    print!(f, cx, write(" "), print(witness), write("]"))
-                }),
-                GeneratorWitness(types) => {
-                    ty::tls::with(|tcx| cx.in_binder(f, tcx, &types, tcx.lift(&types)))
-                }
-                Closure(did, substs) => ty::tls::with(|tcx| {
-                    let upvar_tys = substs.upvar_tys(did, tcx);
-                    write!(f, "[closure")?;
-
-                    if let Some(hir_id) = tcx.hir().as_local_hir_id(did) {
-                        if tcx.sess.opts.debugging_opts.span_free_formats {
-                            write!(f, "@{:?}", hir_id)?;
-                        } else {
-                            write!(f, "@{:?}", tcx.hir().span_by_hir_id(hir_id))?;
-                        }
-                        let mut sep = " ";
-                        tcx.with_freevars(hir_id, |freevars| {
-                            for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) {
-                                print!(f, cx,
-                                       write("{}{}:",
-                                             sep,
-                                             tcx.hir().name(freevar.var_id())),
-                                       print(upvar_ty))?;
-                                sep = ", ";
-                            }
-                            Ok(())
-                        })?
-                    } else {
-                        // cross-crate closure types should only be
-                        // visible in codegen bug reports, I imagine.
-                        write!(f, "@{:?}", did)?;
-                        let mut sep = " ";
-                        for (index, upvar_ty) in upvar_tys.enumerate() {
-                            print!(f, cx,
-                                   write("{}{}:", sep, index),
-                                   print(upvar_ty))?;
-                            sep = ", ";
-                        }
-                    }
-
-                    if cx.is_verbose {
-                        write!(
-                            f,
-                            " closure_kind_ty={:?} closure_sig_ty={:?}",
-                            substs.closure_kind_ty(did, tcx),
-                            substs.closure_sig_ty(did, tcx),
-                        )?;
-                    }
-
-                    write!(f, "]")
-                }),
-                Array(ty, sz) => {
-                    print!(f, cx, write("["), print(ty), write("; "))?;
-                    match sz {
-                        ty::LazyConst::Unevaluated(_def_id, _substs) => {
-                            write!(f, "_")?;
-                        }
-                        ty::LazyConst::Evaluated(c) => ty::tls::with(|tcx| {
-                            match c.val {
-                                ConstValue::Infer(..) => write!(f, "_"),
-                                ConstValue::Param(ParamConst { name, .. }) =>
-                                    write!(f, "{}", name),
-                                _ => write!(f, "{}", c.unwrap_usize(tcx)),
-                            }
-                        })?,
-                    }
-                    write!(f, "]")
-                }
-                Slice(ty) => {
-                    print!(f, cx, write("["), print(ty), write("]"))
-                }
-            }
-        }
-    }
-}
-
-define_print! {
-    ('tcx) ty::TyS<'tcx>, (self, f, cx) {
-        display {
-            self.sty.print(f, cx)
-        }
-        debug {
-            self.sty.print_display(f, cx)
-        }
-    }
-}
-
-define_print! {
-    ('tcx) ConstValue<'tcx>, (self, f, cx) {
-        display {
-            match self {
-                ConstValue::Infer(..) => write!(f, "_"),
-                ConstValue::Param(ParamConst { name, .. }) => write!(f, "{}", name),
-                _ => write!(f, "{:?}", self),
-            }
-        }
-    }
-}
-
-define_print! {
-    ('tcx) ty::Const<'tcx>, (self, f, cx) {
-        display {
-            write!(f, "{} : {}", self.val, self.ty)
-        }
-    }
-}
-
-define_print! {
-    ('tcx) ty::LazyConst<'tcx>, (self, f, cx) {
-        display {
-            match self {
-                ty::LazyConst::Unevaluated(..) => write!(f, "_ : _"),
-                ty::LazyConst::Evaluated(c) => write!(f, "{}", c),
-            }
-        }
-    }
-}
-
-define_print! {
-    () ty::ParamTy, (self, f, cx) {
-        display {
-            write!(f, "{}", self.name)
-        }
-        debug {
-            write!(f, "{}/#{}", self.name, self.idx)
-        }
-    }
-}
-
-define_print! {
-    () ty::ParamConst, (self, f, cx) {
-        display {
-            write!(f, "{}", self.name)
-        }
-        debug {
-            write!(f, "{}/#{}", self.name, self.index)
-        }
-    }
-}
-
-define_print! {
-    ('tcx, T: Print + fmt::Debug, U: Print + fmt::Debug) ty::OutlivesPredicate<T, U>,
-    (self, f, cx) {
-        display {
-            print!(f, cx, print(self.0), write(" : "), print(self.1))
-        }
-    }
-}
-
-define_print! {
-    ('tcx) ty::SubtypePredicate<'tcx>, (self, f, cx) {
-        display {
-            print!(f, cx, print(self.a), write(" <: "), print(self.b))
-        }
-    }
-}
-
-define_print! {
-    ('tcx) ty::TraitPredicate<'tcx>, (self, f, cx) {
-        debug {
-            write!(f, "TraitPredicate({:?})",
-                   self.trait_ref)
-        }
-        display {
-            print!(f, cx, print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref))
-        }
-    }
-}
-
-define_print! {
-    ('tcx) ty::ProjectionPredicate<'tcx>, (self, f, cx) {
-        debug {
-            print!(f, cx,
-                   write("ProjectionPredicate("),
-                   print(self.projection_ty),
-                   write(", "),
-                   print(self.ty),
-                   write(")"))
-        }
-        display {
-            print!(f, cx, print(self.projection_ty), write(" == "), print(self.ty))
-        }
-    }
-}
-
-define_print! {
-    ('tcx) ty::ProjectionTy<'tcx>, (self, f, cx) {
-        display {
-            // FIXME(tschottdorf): use something like
-            //   parameterized(f, self.substs, self.item_def_id, &[])
-            // (which currently ICEs).
-            let (trait_ref, item_name) = ty::tls::with(|tcx|
-                (self.trait_ref(tcx), tcx.associated_item(self.item_def_id).ident)
-            );
-            print!(f, cx, print_debug(trait_ref), write("::{}", item_name))
-        }
-    }
-}
-
-define_print! {
-    () ty::ClosureKind, (self, f, cx) {
-        display {
-            match *self {
-                ty::ClosureKind::Fn => write!(f, "Fn"),
-                ty::ClosureKind::FnMut => write!(f, "FnMut"),
-                ty::ClosureKind::FnOnce => write!(f, "FnOnce"),
-            }
-        }
-    }
-}
-
-define_print! {
-    ('tcx) ty::Predicate<'tcx>, (self, f, cx) {
-        display {
-            match *self {
-                ty::Predicate::Trait(ref data) => data.print(f, cx),
-                ty::Predicate::Subtype(ref predicate) => predicate.print(f, cx),
-                ty::Predicate::RegionOutlives(ref predicate) => predicate.print(f, cx),
-                ty::Predicate::TypeOutlives(ref predicate) => predicate.print(f, cx),
-                ty::Predicate::Projection(ref predicate) => predicate.print(f, cx),
-                ty::Predicate::WellFormed(ty) => print!(f, cx, print(ty), write(" well-formed")),
-                ty::Predicate::ObjectSafe(trait_def_id) =>
-                    ty::tls::with(|tcx| {
-                        write!(f, "the trait `{}` is object-safe", tcx.item_path_str(trait_def_id))
-                    }),
-                ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) =>
-                    ty::tls::with(|tcx| {
-                        write!(f, "the closure `{}` implements the trait `{}`",
-                               tcx.item_path_str(closure_def_id), kind)
-                    }),
-                ty::Predicate::ConstEvaluatable(def_id, substs) => {
-                    write!(f, "the constant `")?;
-                    cx.parameterized(f, substs, def_id, &[])?;
-                    write!(f, "` can be evaluated")
-                }
-            }
-        }
-        debug {
-            match *self {
-                ty::Predicate::Trait(ref a) => a.print(f, cx),
-                ty::Predicate::Subtype(ref pair) => pair.print(f, cx),
-                ty::Predicate::RegionOutlives(ref pair) => pair.print(f, cx),
-                ty::Predicate::TypeOutlives(ref pair) => pair.print(f, cx),
-                ty::Predicate::Projection(ref pair) => pair.print(f, cx),
-                ty::Predicate::WellFormed(ty) => ty.print(f, cx),
-                ty::Predicate::ObjectSafe(trait_def_id) => {
-                    write!(f, "ObjectSafe({:?})", trait_def_id)
-                }
-                ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
-                    write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind)
-                }
-                ty::Predicate::ConstEvaluatable(def_id, substs) => {
-                    write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs)
-                }
-            }
-        }
-    }
-}
diff --git a/src/librustc/util/profiling.rs b/src/librustc/util/profiling.rs
index c134d48f987..2739a30a291 100644
--- a/src/librustc/util/profiling.rs
+++ b/src/librustc/util/profiling.rs
@@ -1,3 +1,4 @@
+use std::borrow::Cow;
 use std::fs;
 use std::io::{BufWriter, Write};
 use std::mem;
@@ -20,12 +21,12 @@ pub enum ProfileCategory {
     Other,
 }
 
-#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+#[derive(Clone, Debug, Eq, PartialEq)]
 pub enum ProfilerEvent {
     QueryStart { query_name: &'static str, category: ProfileCategory, time: u64 },
     QueryEnd { query_name: &'static str, category: ProfileCategory, time: u64 },
-    GenericActivityStart { category: ProfileCategory, time: u64 },
-    GenericActivityEnd { category: ProfileCategory, time: u64 },
+    GenericActivityStart { category: ProfileCategory, label: Cow<'static, str>, time: u64 },
+    GenericActivityEnd { category: ProfileCategory, label: Cow<'static, str>, time: u64 },
     IncrementalLoadResultStart { query_name: &'static str, time: u64 },
     IncrementalLoadResultEnd { query_name: &'static str, time: u64 },
     QueryCacheHit { query_name: &'static str, category: ProfileCategory, time: u64 },
@@ -75,17 +76,27 @@ impl SelfProfiler {
     }
 
     #[inline]
-    pub fn start_activity(&mut self, category: ProfileCategory) {
+    pub fn start_activity(
+        &mut self,
+        category: ProfileCategory,
+        label: impl Into<Cow<'static, str>>,
+    ) {
         self.record(ProfilerEvent::GenericActivityStart {
             category,
+            label: label.into(),
             time: self.get_time_from_start(),
         })
     }
 
     #[inline]
-    pub fn end_activity(&mut self, category: ProfileCategory) {
+    pub fn end_activity(
+        &mut self,
+        category: ProfileCategory,
+        label: impl Into<Cow<'static, str>>,
+    ) {
         self.record(ProfilerEvent::GenericActivityEnd {
             category,
+            label: label.into(),
             time: self.get_time_from_start(),
         })
     }
@@ -273,11 +284,12 @@ impl SelfProfiler {
                             nanos,
                             thread_id,
                         ).unwrap(),
-                    GenericActivityStart { category, time: _ } =>
+                    GenericActivityStart { category, label, time: _ } =>
                         write!(file,
                             "{{
                                 \"GenericActivityStart\": {{\
                                     \"category\": \"{:?}\",\
+                                    \"label\": \"{}\",\
                                     \"time\": {{\
                                         \"secs\": {},\
                                         \"nanos\": {}\
@@ -286,15 +298,17 @@ impl SelfProfiler {
                                 }}\
                             }}",
                             category,
+                            label,
                             secs,
                             nanos,
                             thread_id,
                         ).unwrap(),
-                    GenericActivityEnd { category, time: _ } =>
+                    GenericActivityEnd { category, label, time: _ } =>
                         write!(file,
                             "{{\
                                 \"GenericActivityEnd\": {{\
                                     \"category\": \"{:?}\",\
+                                    \"label\": \"{}\",\
                                     \"time\": {{\
                                         \"secs\": {},\
                                         \"nanos\": {}\
@@ -303,6 +317,7 @@ impl SelfProfiler {
                                 }}\
                             }}",
                             category,
+                            label,
                             secs,
                             nanos,
                             thread_id,
@@ -418,7 +433,7 @@ impl SelfProfiler {
                             secs,
                             nanos,
                             thread_id,
-                        ).unwrap()
+                        ).unwrap(),
                 }
             }
         }
diff --git a/src/librustc/util/time_graph.rs b/src/librustc/util/time_graph.rs
deleted file mode 100644
index 4dd383fd234..00000000000
--- a/src/librustc/util/time_graph.rs
+++ /dev/null
@@ -1,268 +0,0 @@
-use rustc_data_structures::fx::FxHashMap;
-use std::fs::File;
-use std::io::prelude::*;
-use std::marker::PhantomData;
-use std::mem;
-use std::sync::{Arc, Mutex};
-use std::time::Instant;
-
-const OUTPUT_WIDTH_IN_PX: u64 = 1000;
-const TIME_LINE_HEIGHT_IN_PX: u64 = 20;
-const TIME_LINE_HEIGHT_STRIDE_IN_PX: usize = 30;
-
-#[derive(Clone)]
-struct Timing {
-    start: Instant,
-    end: Instant,
-    work_package_kind: WorkPackageKind,
-    name: String,
-    events: Vec<(String, Instant)>,
-}
-
-#[derive(Clone, Copy, Hash, Eq, PartialEq, Debug)]
-pub struct TimelineId(pub usize);
-
-#[derive(Clone)]
-struct PerThread {
-    timings: Vec<Timing>,
-    open_work_package: Option<(Instant, WorkPackageKind, String)>,
-}
-
-#[derive(Clone)]
-pub struct TimeGraph {
-    data: Arc<Mutex<FxHashMap<TimelineId, PerThread>>>,
-}
-
-#[derive(Clone, Copy)]
-pub struct WorkPackageKind(pub &'static [&'static str]);
-
-pub struct Timeline {
-    token: Option<RaiiToken>,
-}
-
-struct RaiiToken {
-    graph: TimeGraph,
-    timeline: TimelineId,
-    events: Vec<(String, Instant)>,
-    // The token must not be Send:
-    _marker: PhantomData<*const ()>
-}
-
-
-impl Drop for RaiiToken {
-    fn drop(&mut self) {
-        self.graph.end(self.timeline, mem::replace(&mut self.events, Vec::new()));
-    }
-}
-
-impl TimeGraph {
-    pub fn new() -> TimeGraph {
-        TimeGraph {
-            data: Arc::new(Mutex::new(FxHashMap::default()))
-        }
-    }
-
-    pub fn start(&self,
-                 timeline: TimelineId,
-                 work_package_kind: WorkPackageKind,
-                 name: &str) -> Timeline {
-        {
-            let mut table = self.data.lock().unwrap();
-
-            let data = table.entry(timeline).or_insert(PerThread {
-                timings: Vec::new(),
-                open_work_package: None,
-            });
-
-            assert!(data.open_work_package.is_none());
-            data.open_work_package = Some((Instant::now(), work_package_kind, name.to_string()));
-        }
-
-        Timeline {
-            token: Some(RaiiToken {
-                graph: self.clone(),
-                timeline,
-                events: Vec::new(),
-                _marker: PhantomData,
-            }),
-        }
-    }
-
-    fn end(&self, timeline: TimelineId, events: Vec<(String, Instant)>) {
-        let end = Instant::now();
-
-        let mut table = self.data.lock().unwrap();
-        let data = table.get_mut(&timeline).unwrap();
-
-        if let Some((start, work_package_kind, name)) = data.open_work_package.take() {
-            data.timings.push(Timing {
-                start,
-                end,
-                work_package_kind,
-                name,
-                events,
-            });
-        } else {
-            bug!("end timing without start?")
-        }
-    }
-
-    pub fn dump(&self, output_filename: &str) {
-        let table = self.data.lock().unwrap();
-
-        for data in table.values() {
-            assert!(data.open_work_package.is_none());
-        }
-
-        let mut threads: Vec<PerThread> =
-            table.values().map(|data| data.clone()).collect();
-
-        threads.sort_by_key(|timeline| timeline.timings[0].start);
-
-        let earliest_instant = threads[0].timings[0].start;
-        let latest_instant = threads.iter()
-                                       .map(|timeline| timeline.timings
-                                                               .last()
-                                                               .unwrap()
-                                                               .end)
-                                       .max()
-                                       .unwrap();
-        let max_distance = distance(earliest_instant, latest_instant);
-
-        let mut file = File::create(format!("{}.html", output_filename)).unwrap();
-
-        writeln!(file, "
-            <html>
-            <head>
-                <style>
-                    #threads a {{
-                        position: absolute;
-                        overflow: hidden;
-                    }}
-                    #threads {{
-                        height: {total_height}px;
-                        width: {width}px;
-                    }}
-
-                    .timeline {{
-                        display: none;
-                        width: {width}px;
-                        position: relative;
-                    }}
-
-                    .timeline:target {{
-                        display: block;
-                    }}
-
-                    .event {{
-                        position: absolute;
-                    }}
-                </style>
-            </head>
-            <body>
-                <div id='threads'>
-        ",
-            total_height = threads.len() * TIME_LINE_HEIGHT_STRIDE_IN_PX,
-            width = OUTPUT_WIDTH_IN_PX,
-        ).unwrap();
-
-        let mut color = 0;
-        for (line_index, thread) in threads.iter().enumerate() {
-            let line_top = line_index * TIME_LINE_HEIGHT_STRIDE_IN_PX;
-
-            for span in &thread.timings {
-                let start = distance(earliest_instant, span.start);
-                let end = distance(earliest_instant, span.end);
-
-                let start = normalize(start, max_distance, OUTPUT_WIDTH_IN_PX);
-                let end = normalize(end, max_distance, OUTPUT_WIDTH_IN_PX);
-
-                let colors = span.work_package_kind.0;
-
-                writeln!(file, "<a href='#timing{}'
-                                   style='top:{}px; \
-                                          left:{}px; \
-                                          width:{}px; \
-                                          height:{}px; \
-                                          background:{};'>{}</a>",
-                    color,
-                    line_top,
-                    start,
-                    end - start,
-                    TIME_LINE_HEIGHT_IN_PX,
-                    colors[color % colors.len()],
-                    span.name,
-                    ).unwrap();
-
-                color += 1;
-            }
-        }
-
-        writeln!(file, "
-            </div>
-        ").unwrap();
-
-        let mut idx = 0;
-        for thread in threads.iter() {
-            for timing in &thread.timings {
-                let colors = timing.work_package_kind.0;
-                let height = TIME_LINE_HEIGHT_STRIDE_IN_PX * timing.events.len();
-                writeln!(file, "<div class='timeline'
-                                     id='timing{}'
-                                     style='background:{};height:{}px;'>",
-                         idx,
-                         colors[idx % colors.len()],
-                         height).unwrap();
-                idx += 1;
-                let max = distance(timing.start, timing.end);
-                for (i, &(ref event, time)) in timing.events.iter().enumerate() {
-                    let i = i as u64;
-                    let time = distance(timing.start, time);
-                    let at = normalize(time, max, OUTPUT_WIDTH_IN_PX);
-                    writeln!(file, "<span class='event'
-                                          style='left:{}px;\
-                                                 top:{}px;'>{}</span>",
-                             at,
-                             TIME_LINE_HEIGHT_IN_PX * i,
-                             event).unwrap();
-                }
-                writeln!(file, "</div>").unwrap();
-            }
-        }
-
-        writeln!(file, "
-            </body>
-            </html>
-        ").unwrap();
-    }
-}
-
-impl Timeline {
-    pub fn noop() -> Timeline {
-        Timeline { token: None }
-    }
-
-    /// Record an event which happened at this moment on this timeline.
-    ///
-    /// Events are displayed in the eventual HTML output where you can click on
-    /// a particular timeline and it'll expand to all of the events that
-    /// happened on that timeline. This can then be used to drill into a
-    /// particular timeline and see what events are happening and taking the
-    /// most time.
-    pub fn record(&mut self, name: &str) {
-        if let Some(ref mut token) = self.token {
-            token.events.push((name.to_string(), Instant::now()));
-        }
-    }
-}
-
-fn distance(zero: Instant, x: Instant) -> u64 {
-
-    let duration = x.duration_since(zero);
-    (duration.as_secs() * 1_000_000_000 + duration.subsec_nanos() as u64) // / div
-}
-
-fn normalize(distance: u64, max: u64, max_pixels: u64) -> u64 {
-    (max_pixels * distance) / max
-}
-
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index da065f9e05d..01bfe5d5af7 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -1406,7 +1406,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                 out.push('(');
                 self.append_loan_path_to_string(&lp_base, out);
                 out.push_str(DOWNCAST_PRINTED_OPERATOR);
-                out.push_str(&self.tcx.item_path_str(variant_def_id));
+                out.push_str(&self.tcx.def_path_str(variant_def_id));
                 out.push(')');
             }
 
@@ -1443,7 +1443,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                 out.push('(');
                 self.append_autoderefd_loan_path_to_string(&lp_base, out);
                 out.push_str(DOWNCAST_PRINTED_OPERATOR);
-                out.push_str(&self.tcx.item_path_str(variant_def_id));
+                out.push_str(&self.tcx.def_path_str(variant_def_id));
                 out.push(')');
             }
 
@@ -1523,7 +1523,7 @@ impl<'tcx> fmt::Debug for LoanPath<'tcx> {
 
             LpDowncast(ref lp, variant_def_id) => {
                 let variant_str = if variant_def_id.is_local() {
-                    ty::tls::with(|tcx| tcx.item_path_str(variant_def_id))
+                    ty::tls::with(|tcx| tcx.def_path_str(variant_def_id))
                 } else {
                     format!("{:?}", variant_def_id)
                 };
@@ -1558,7 +1558,7 @@ impl<'tcx> fmt::Display for LoanPath<'tcx> {
 
             LpDowncast(ref lp, variant_def_id) => {
                 let variant_str = if variant_def_id.is_local() {
-                    ty::tls::with(|tcx| tcx.item_path_str(variant_def_id))
+                    ty::tls::with(|tcx| tcx.def_path_str(variant_def_id))
                 } else {
                     format!("{:?}", variant_def_id)
                 };
diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs
index 944569c8b74..84c652ff238 100644
--- a/src/librustc_codegen_llvm/back/lto.rs
+++ b/src/librustc_codegen_llvm/back/lto.rs
@@ -3,7 +3,6 @@ use crate::back::write::{self, DiagnosticHandlers, with_llvm_pmb, save_temp_bitc
     to_llvm_opt_settings};
 use crate::llvm::archive_ro::ArchiveRO;
 use crate::llvm::{self, True, False};
-use crate::time_graph::Timeline;
 use crate::{ModuleLlvm, LlvmCodegenBackend};
 use rustc_codegen_ssa::back::symbol_export;
 use rustc_codegen_ssa::back::write::{ModuleConfig, CodegenContext, FatLTOInput};
@@ -16,6 +15,7 @@ use rustc::hir::def_id::LOCAL_CRATE;
 use rustc::middle::exported_symbols::SymbolExportLevel;
 use rustc::session::config::{self, Lto};
 use rustc::util::common::time_ext;
+use rustc::util::profiling::ProfileCategory;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_codegen_ssa::{ModuleCodegen, ModuleKind};
 
@@ -37,7 +37,6 @@ pub fn crate_type_allows_lto(crate_type: config::CrateType) -> bool {
 }
 
 fn prepare_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
-               timeline: &mut Timeline,
                diag_handler: &Handler)
     -> Result<(Vec<CString>, Vec<(SerializedModule<ModuleBuffer>, CString)>), FatalError>
 {
@@ -68,7 +67,8 @@ fn prepare_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
         .iter()
         .filter_map(symbol_filter)
         .collect::<Vec<CString>>();
-    timeline.record("whitelist");
+    let _timer = cgcx.profile_activity(ProfileCategory::Codegen,
+                                       "generate_symbol_white_list_for_thinlto");
     info!("{} symbols to preserve in this crate", symbol_white_list.len());
 
     // If we're performing LTO for the entire crate graph, then for each of our
@@ -97,6 +97,8 @@ fn prepare_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
         }
 
         for &(cnum, ref path) in cgcx.each_linked_rlib_for_lto.iter() {
+            let _timer = cgcx.profile_activity(ProfileCategory::Codegen,
+                                               format!("load: {}", path.display()));
             let exported_symbols = cgcx.exported_symbols
                 .as_ref().expect("needs exported symbols for LTO");
             symbol_white_list.extend(
@@ -121,7 +123,6 @@ fn prepare_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
                 let bc = SerializedModule::FromRlib(bc);
                 upstream_modules.push((bc, CString::new(id).unwrap()));
             }
-            timeline.record(&format!("load: {}", path.display()));
         }
     }
 
@@ -132,12 +133,11 @@ fn prepare_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
 /// for further optimization.
 pub(crate) fn run_fat(cgcx: &CodegenContext<LlvmCodegenBackend>,
                       modules: Vec<FatLTOInput<LlvmCodegenBackend>>,
-                      cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
-                      timeline: &mut Timeline)
+                      cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>)
     -> Result<LtoModuleCodegen<LlvmCodegenBackend>, FatalError>
 {
     let diag_handler = cgcx.create_diag_handler();
-    let (symbol_white_list, upstream_modules) = prepare_lto(cgcx, timeline, &diag_handler)?;
+    let (symbol_white_list, upstream_modules) = prepare_lto(cgcx, &diag_handler)?;
     let symbol_white_list = symbol_white_list.iter()
                                              .map(|c| c.as_ptr())
                                              .collect::<Vec<_>>();
@@ -148,7 +148,6 @@ pub(crate) fn run_fat(cgcx: &CodegenContext<LlvmCodegenBackend>,
         cached_modules,
         upstream_modules,
         &symbol_white_list,
-        timeline,
     )
 }
 
@@ -157,12 +156,11 @@ pub(crate) fn run_fat(cgcx: &CodegenContext<LlvmCodegenBackend>,
 /// can simply be copied over from the incr. comp. cache.
 pub(crate) fn run_thin(cgcx: &CodegenContext<LlvmCodegenBackend>,
                        modules: Vec<(String, ThinBuffer)>,
-                       cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
-                       timeline: &mut Timeline)
+                       cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>)
     -> Result<(Vec<LtoModuleCodegen<LlvmCodegenBackend>>, Vec<WorkProduct>), FatalError>
 {
     let diag_handler = cgcx.create_diag_handler();
-    let (symbol_white_list, upstream_modules) = prepare_lto(cgcx, timeline, &diag_handler)?;
+    let (symbol_white_list, upstream_modules) = prepare_lto(cgcx, &diag_handler)?;
     let symbol_white_list = symbol_white_list.iter()
                                              .map(|c| c.as_ptr())
                                              .collect::<Vec<_>>();
@@ -175,8 +173,7 @@ pub(crate) fn run_thin(cgcx: &CodegenContext<LlvmCodegenBackend>,
              modules,
              upstream_modules,
              cached_modules,
-             &symbol_white_list,
-             timeline)
+             &symbol_white_list)
 }
 
 pub(crate) fn prepare_thin(
@@ -192,8 +189,7 @@ fn fat_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
            mut modules: Vec<FatLTOInput<LlvmCodegenBackend>>,
            cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
            mut serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
-           symbol_white_list: &[*const libc::c_char],
-           timeline: &mut Timeline)
+           symbol_white_list: &[*const libc::c_char])
     -> Result<LtoModuleCodegen<LlvmCodegenBackend>, FatalError>
 {
     info!("going for a fat lto");
@@ -303,7 +299,6 @@ fn fat_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
                     write::llvm_err(&diag_handler, &msg)
                 })
             })?;
-            timeline.record(&format!("link {:?}", name));
             serialized_bitcode.push(bc_decoded);
         }
         drop(linker);
@@ -325,7 +320,6 @@ fn fat_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
             }
             save_temp_bitcode(&cgcx, &module, "lto.after-nounwind");
         }
-        timeline.record("passes");
     }
 
     Ok(LtoModuleCodegen::Fat {
@@ -395,8 +389,7 @@ fn thin_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
             modules: Vec<(String, ThinBuffer)>,
             serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
             cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
-            symbol_white_list: &[*const libc::c_char],
-            timeline: &mut Timeline)
+            symbol_white_list: &[*const libc::c_char])
     -> Result<(Vec<LtoModuleCodegen<LlvmCodegenBackend>>, Vec<WorkProduct>), FatalError>
 {
     unsafe {
@@ -422,7 +415,6 @@ fn thin_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
             });
             thin_buffers.push(buffer);
             module_names.push(cname);
-            timeline.record(&name);
         }
 
         // FIXME: All upstream crates are deserialized internally in the
@@ -475,7 +467,6 @@ fn thin_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
         })?;
 
         info!("thin LTO data created");
-        timeline.record("data");
 
         let import_map = if cgcx.incr_comp_session_dir.is_some() {
             ThinLTOImports::from_thin_lto_data(data)
@@ -486,7 +477,6 @@ fn thin_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
             ThinLTOImports::default()
         };
         info!("thin LTO import map loaded");
-        timeline.record("import-map-loaded");
 
         let data = ThinData(data);
 
@@ -691,7 +681,6 @@ impl Drop for ThinBuffer {
 pub unsafe fn optimize_thin_module(
     thin_module: &mut ThinModule<LlvmCodegenBackend>,
     cgcx: &CodegenContext<LlvmCodegenBackend>,
-    timeline: &mut Timeline
 ) -> Result<ModuleCodegen<ModuleLlvm>, FatalError> {
     let diag_handler = cgcx.create_diag_handler();
     let tm = (cgcx.tm_factory.0)().map_err(|e| {
@@ -738,9 +727,10 @@ pub unsafe fn optimize_thin_module(
         // Like with "fat" LTO, get some better optimizations if landing pads
         // are disabled by removing all landing pads.
         if cgcx.no_landing_pads {
+            let _timer = cgcx.profile_activity(ProfileCategory::Codegen,
+                                               "LLVM_remove_landing_pads");
             llvm::LLVMRustMarkAllFunctionsNounwind(llmod);
             save_temp_bitcode(&cgcx, &module, "thin-lto-after-nounwind");
-            timeline.record("nounwind");
         }
 
         // Up next comes the per-module local analyses that we do for Thin LTO.
@@ -756,25 +746,21 @@ pub unsafe fn optimize_thin_module(
             return Err(write::llvm_err(&diag_handler, msg))
         }
         save_temp_bitcode(cgcx, &module, "thin-lto-after-rename");
-        timeline.record("rename");
         if !llvm::LLVMRustPrepareThinLTOResolveWeak(thin_module.shared.data.0, llmod) {
             let msg = "failed to prepare thin LTO module";
             return Err(write::llvm_err(&diag_handler, msg))
         }
         save_temp_bitcode(cgcx, &module, "thin-lto-after-resolve");
-        timeline.record("resolve");
         if !llvm::LLVMRustPrepareThinLTOInternalize(thin_module.shared.data.0, llmod) {
             let msg = "failed to prepare thin LTO module";
             return Err(write::llvm_err(&diag_handler, msg))
         }
         save_temp_bitcode(cgcx, &module, "thin-lto-after-internalize");
-        timeline.record("internalize");
         if !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod) {
             let msg = "failed to prepare thin LTO module";
             return Err(write::llvm_err(&diag_handler, msg))
         }
         save_temp_bitcode(cgcx, &module, "thin-lto-after-import");
-        timeline.record("import");
 
         // Ok now this is a bit unfortunate. This is also something you won't
         // find upstream in LLVM's ThinLTO passes! This is a hack for now to
@@ -807,7 +793,6 @@ pub unsafe fn optimize_thin_module(
         // fixed in LLVM.
         llvm::LLVMRustThinLTOPatchDICompileUnit(llmod, cu1);
         save_temp_bitcode(cgcx, &module, "thin-lto-after-patch");
-        timeline.record("patch");
 
         // Alright now that we've done everything related to the ThinLTO
         // analysis it's time to run some optimizations! Here we use the same
@@ -818,7 +803,6 @@ pub unsafe fn optimize_thin_module(
         let config = cgcx.config(module.kind);
         run_pass_manager(cgcx, &module, config, true);
         save_temp_bitcode(cgcx, &module, "thin-lto-after-pm");
-        timeline.record("thin-done");
     }
     Ok(module)
 }
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index db5430a4219..dc4dd4e39e1 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -3,7 +3,6 @@ use crate::back::bytecode::{self, RLIB_BYTECODE_EXTENSION};
 use crate::back::lto::ThinBuffer;
 use crate::base;
 use crate::consts;
-use crate::time_graph::Timeline;
 use crate::llvm::{self, DiagnosticInfo, PassManager, SMDiagnostic};
 use crate::llvm_util;
 use crate::ModuleLlvm;
@@ -19,6 +18,7 @@ use rustc::session::Session;
 use rustc::ty::TyCtxt;
 use rustc_codegen_ssa::{ModuleCodegen, CompiledModule};
 use rustc::util::common::time_ext;
+use rustc::util::profiling::ProfileCategory;
 use rustc_fs_util::{path_to_c_string, link_or_copy};
 use rustc_data_structures::small_c_str::SmallCStr;
 use errors::{Handler, FatalError};
@@ -305,8 +305,7 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
 pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>,
                    diag_handler: &Handler,
                    module: &ModuleCodegen<ModuleLlvm>,
-                   config: &ModuleConfig,
-                   timeline: &mut Timeline)
+                   config: &ModuleConfig)
     -> Result<(), FatalError>
 {
     let llmod = module.module_llvm.llmod();
@@ -415,19 +414,24 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>,
         diag_handler.abort_if_errors();
 
         // Finally, run the actual optimization passes
-        time_ext(config.time_passes,
-                 None,
-                 &format!("llvm function passes [{}]", module_name.unwrap()),
-                 || {
-            llvm::LLVMRustRunFunctionPassManager(fpm, llmod)
-        });
-        timeline.record("fpm");
-        time_ext(config.time_passes,
-                 None,
-                 &format!("llvm module passes [{}]", module_name.unwrap()),
-                 || {
-            llvm::LLVMRunPassManager(mpm, llmod)
-        });
+        {
+            let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_function_passes");
+            time_ext(config.time_passes,
+                        None,
+                        &format!("llvm function passes [{}]", module_name.unwrap()),
+                        || {
+                llvm::LLVMRustRunFunctionPassManager(fpm, llmod)
+            });
+        }
+        {
+            let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_module_passes");
+            time_ext(config.time_passes,
+                    None,
+                    &format!("llvm module passes [{}]", module_name.unwrap()),
+                    || {
+                llvm::LLVMRunPassManager(mpm, llmod)
+            });
+        }
 
         // Deallocate managers that we're now done with
         llvm::LLVMDisposePassManager(fpm);
@@ -439,11 +443,10 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>,
 pub(crate) unsafe fn codegen(cgcx: &CodegenContext<LlvmCodegenBackend>,
                   diag_handler: &Handler,
                   module: ModuleCodegen<ModuleLlvm>,
-                  config: &ModuleConfig,
-                  timeline: &mut Timeline)
+                  config: &ModuleConfig)
     -> Result<CompiledModule, FatalError>
 {
-    timeline.record("codegen");
+    let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "codegen");
     {
         let llmod = module.module_llvm.llmod();
         let llcx = &*module.module_llvm.llcx;
@@ -494,29 +497,30 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext<LlvmCodegenBackend>,
 
 
         if write_bc || config.emit_bc_compressed || config.embed_bitcode {
+            let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_make_bitcode");
             let thin = ThinBuffer::new(llmod);
             let data = thin.data();
-            timeline.record("make-bc");
 
             if write_bc {
+                let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_emit_bitcode");
                 if let Err(e) = fs::write(&bc_out, data) {
                     diag_handler.err(&format!("failed to write bytecode: {}", e));
                 }
-                timeline.record("write-bc");
             }
 
             if config.embed_bitcode {
+                let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_embed_bitcode");
                 embed_bitcode(cgcx, llcx, llmod, Some(data));
-                timeline.record("embed-bc");
             }
 
             if config.emit_bc_compressed {
+                let _timer = cgcx.profile_activity(ProfileCategory::Codegen,
+                                                   "LLVM_compress_bitcode");
                 let dst = bc_out.with_extension(RLIB_BYTECODE_EXTENSION);
                 let data = bytecode::encode(&module.name, data);
                 if let Err(e) = fs::write(&dst, data) {
                     diag_handler.err(&format!("failed to write bytecode: {}", e));
                 }
-                timeline.record("compress-bc");
             }
         } else if config.embed_bitcode_marker {
             embed_bitcode(cgcx, llcx, llmod, None);
@@ -525,6 +529,7 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext<LlvmCodegenBackend>,
         time_ext(config.time_passes, None, &format!("codegen passes [{}]", module_name.unwrap()),
             || -> Result<(), FatalError> {
             if config.emit_ir {
+                let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_emit_ir");
                 let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
                 let out = path_to_c_string(&out);
 
@@ -563,10 +568,10 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext<LlvmCodegenBackend>,
                     llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr(), demangle_callback);
                     llvm::LLVMDisposePassManager(cpm);
                 });
-                timeline.record("ir");
             }
 
             if config.emit_asm || asm_to_obj {
+                let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_emit_asm");
                 let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
 
                 // We can't use the same module for asm and binary output, because that triggers
@@ -581,19 +586,18 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext<LlvmCodegenBackend>,
                     write_output_file(diag_handler, tm, cpm, llmod, &path,
                                       llvm::FileType::AssemblyFile)
                 })?;
-                timeline.record("asm");
             }
 
             if write_obj {
+                let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_emit_obj");
                 with_codegen(tm, llmod, config.no_builtins, |cpm| {
                     write_output_file(diag_handler, tm, cpm, llmod, &obj_out,
                                       llvm::FileType::ObjectFile)
                 })?;
-                timeline.record("obj");
             } else if asm_to_obj {
+                let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_asm_to_obj");
                 let assembly = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
                 run_assembler(cgcx, diag_handler, &assembly, &obj_out);
-                timeline.record("asm_to_obj");
 
                 if !config.emit_asm && !cgcx.save_temps {
                     drop(fs::remove_file(&assembly));
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index 3268af396a2..ceb08f94367 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -513,8 +513,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
 
             },
             "fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" => {
-                let sty = &arg_tys[0].sty;
-                match float_type_width(sty) {
+                match float_type_width(arg_tys[0]) {
                     Some(_width) =>
                         match name {
                             "fadd_fast" => self.fadd_fast(args[0].immediate(), args[1].immediate()),
@@ -528,7 +527,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
                         span_invalid_monomorphization_error(
                             tcx.sess, span,
                             &format!("invalid monomorphization of `{}` intrinsic: \
-                                      expected basic float type, found `{}`", name, sty));
+                                      expected basic float type, found `{}`", name, arg_tys[0]));
                         return;
                     }
                 }
@@ -1473,8 +1472,8 @@ fn generic_simd_intrinsic(
                 require!(false, "expected element type `{}` of second argument `{}` \
                                  to be a pointer to the element type `{}` of the first \
                                  argument `{}`, found `{}` != `*_ {}`",
-                         arg_tys[1].simd_type(tcx).sty, arg_tys[1], in_elem, in_ty,
-                         arg_tys[1].simd_type(tcx).sty, in_elem);
+                         arg_tys[1].simd_type(tcx), arg_tys[1], in_elem, in_ty,
+                         arg_tys[1].simd_type(tcx), in_elem);
                 unreachable!();
             }
         };
@@ -1488,7 +1487,7 @@ fn generic_simd_intrinsic(
             _ => {
                 require!(false, "expected element type `{}` of third argument `{}` \
                                  to be a signed integer type",
-                         arg_tys[2].simd_type(tcx).sty, arg_tys[2]);
+                         arg_tys[2].simd_type(tcx), arg_tys[2]);
             }
         }
 
@@ -1573,8 +1572,8 @@ fn generic_simd_intrinsic(
                 require!(false, "expected element type `{}` of second argument `{}` \
                                  to be a pointer to the element type `{}` of the first \
                                  argument `{}`, found `{}` != `*mut {}`",
-                         arg_tys[1].simd_type(tcx).sty, arg_tys[1], in_elem, in_ty,
-                         arg_tys[1].simd_type(tcx).sty, in_elem);
+                         arg_tys[1].simd_type(tcx), arg_tys[1], in_elem, in_ty,
+                         arg_tys[1].simd_type(tcx), in_elem);
                 unreachable!();
             }
         };
@@ -1588,7 +1587,7 @@ fn generic_simd_intrinsic(
             _ => {
                 require!(false, "expected element type `{}` of third argument `{}` \
                                  to be a signed integer type",
-                         arg_tys[2].simd_type(tcx).sty, arg_tys[2]);
+                         arg_tys[2].simd_type(tcx), arg_tys[2]);
             }
         }
 
@@ -1904,7 +1903,7 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
                 return_error!(
                     "expected element type `{}` of vector type `{}` \
                      to be a signed or unsigned integer type",
-                    arg_tys[0].simd_type(tcx).sty, arg_tys[0]
+                    arg_tys[0].simd_type(tcx), arg_tys[0]
                 );
             }
         };
@@ -1954,10 +1953,10 @@ fn int_type_width_signed(ty: Ty<'_>, cx: &CodegenCx<'_, '_>) -> Option<(u64, boo
     }
 }
 
-// Returns the width of a float TypeVariant
+// Returns the width of a float Ty
 // Returns None if the type is not a float
-fn float_type_width<'tcx>(sty: &ty::TyKind<'tcx>) -> Option<u64> {
-    match *sty {
+fn float_type_width(ty: Ty<'_>) -> Option<u64> {
+    match ty.sty {
         ty::Float(t) => Some(t.bit_width() as u64),
         _ => None,
     }
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index 7b2b9ec24ea..c75788ecb4f 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -15,7 +15,6 @@
 #![allow(unused_attributes)]
 #![feature(libc)]
 #![feature(nll)]
-#![feature(range_contains)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(optin_builtin_traits)]
 #![feature(concat_idents)]
@@ -53,7 +52,6 @@ use rustc_codegen_ssa::back::lto::{SerializedModule, LtoModuleCodegen, ThinModul
 use rustc_codegen_ssa::CompiledModule;
 use errors::{FatalError, Handler};
 use rustc::dep_graph::WorkProduct;
-use rustc::util::time_graph::Timeline;
 use syntax_pos::symbol::InternedString;
 use rustc::mir::mono::Stats;
 pub use llvm_util::target_features;
@@ -66,7 +64,6 @@ use rustc::middle::cstore::{EncodedMetadata, MetadataLoader};
 use rustc::session::Session;
 use rustc::session::config::{OutputFilenames, OutputType, PrintRequest, OptLevel};
 use rustc::ty::{self, TyCtxt};
-use rustc::util::time_graph;
 use rustc::util::profiling::ProfileCategory;
 use rustc::util::common::ErrorReported;
 use rustc_mir::monomorphize;
@@ -167,42 +164,37 @@ impl WriteBackendMethods for LlvmCodegenBackend {
         cgcx: &CodegenContext<Self>,
         modules: Vec<FatLTOInput<Self>>,
         cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>,
-        timeline: &mut Timeline
     ) -> Result<LtoModuleCodegen<Self>, FatalError> {
-        back::lto::run_fat(cgcx, modules, cached_modules, timeline)
+        back::lto::run_fat(cgcx, modules, cached_modules)
     }
     fn run_thin_lto(
         cgcx: &CodegenContext<Self>,
         modules: Vec<(String, Self::ThinBuffer)>,
         cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>,
-        timeline: &mut Timeline
     ) -> Result<(Vec<LtoModuleCodegen<Self>>, Vec<WorkProduct>), FatalError> {
-        back::lto::run_thin(cgcx, modules, cached_modules, timeline)
+        back::lto::run_thin(cgcx, modules, cached_modules)
     }
     unsafe fn optimize(
         cgcx: &CodegenContext<Self>,
         diag_handler: &Handler,
         module: &ModuleCodegen<Self::Module>,
         config: &ModuleConfig,
-        timeline: &mut Timeline
     ) -> Result<(), FatalError> {
-        back::write::optimize(cgcx, diag_handler, module, config, timeline)
+        back::write::optimize(cgcx, diag_handler, module, config)
     }
     unsafe fn optimize_thin(
         cgcx: &CodegenContext<Self>,
         thin: &mut ThinModule<Self>,
-        timeline: &mut Timeline
     ) -> Result<ModuleCodegen<Self::Module>, FatalError> {
-        back::lto::optimize_thin_module(thin, cgcx, timeline)
+        back::lto::optimize_thin_module(thin, cgcx)
     }
     unsafe fn codegen(
         cgcx: &CodegenContext<Self>,
         diag_handler: &Handler,
         module: ModuleCodegen<Self::Module>,
         config: &ModuleConfig,
-        timeline: &mut Timeline
     ) -> Result<CompiledModule, FatalError> {
-        back::write::codegen(cgcx, diag_handler, module, config, timeline)
+        back::write::codegen(cgcx, diag_handler, module, config)
     }
     fn prepare_thin(
         module: ModuleCodegen<Self::Module>
@@ -336,12 +328,12 @@ impl CodegenBackend for LlvmCodegenBackend {
 
         // Run the linker on any artifacts that resulted from the LLVM run.
         // This should produce either a finished executable or library.
-        sess.profiler(|p| p.start_activity(ProfileCategory::Linking));
+        sess.profiler(|p| p.start_activity(ProfileCategory::Linking, "link_crate"));
         time(sess, "linking", || {
             back::link::link_binary(sess, &codegen_results,
                                     outputs, &codegen_results.crate_name.as_str());
         });
-        sess.profiler(|p| p.end_activity(ProfileCategory::Linking));
+        sess.profiler(|p| p.end_activity(ProfileCategory::Linking, "link_crate"));
 
         // Now that we won't touch anything in the incremental compilation directory
         // any more, we can finalize it (which involves renaming it)
diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs
index 1f4c5543fa9..e6470dbb61c 100644
--- a/src/librustc_codegen_ssa/back/linker.rs
+++ b/src/librustc_codegen_ssa/back/linker.rs
@@ -382,20 +382,19 @@ impl<'a> Linker for GccLinker<'a> {
 
         if self.sess.target.target.options.is_like_osx {
             // Write a plain, newline-separated list of symbols
-            let res = (|| -> io::Result<()> {
+            let res: io::Result<()> = try {
                 let mut f = BufWriter::new(File::create(&path)?);
                 for sym in self.info.exports[&crate_type].iter() {
                     debug!("  _{}", sym);
                     writeln!(f, "_{}", sym)?;
                 }
-                Ok(())
-            })();
+            };
             if let Err(e) = res {
                 self.sess.fatal(&format!("failed to write lib.def file: {}", e));
             }
         } else {
             // Write an LD version script
-            let res = (|| -> io::Result<()> {
+            let res: io::Result<()> = try {
                 let mut f = BufWriter::new(File::create(&path)?);
                 writeln!(f, "{{\n  global:")?;
                 for sym in self.info.exports[&crate_type].iter() {
@@ -403,8 +402,7 @@ impl<'a> Linker for GccLinker<'a> {
                     writeln!(f, "    {};", sym)?;
                 }
                 writeln!(f, "\n  local:\n    *;\n}};")?;
-                Ok(())
-            })();
+            };
             if let Err(e) = res {
                 self.sess.fatal(&format!("failed to write version script: {}", e));
             }
@@ -644,7 +642,7 @@ impl<'a> Linker for MsvcLinker<'a> {
                       tmpdir: &Path,
                       crate_type: CrateType) {
         let path = tmpdir.join("lib.def");
-        let res = (|| -> io::Result<()> {
+        let res: io::Result<()> = try {
             let mut f = BufWriter::new(File::create(&path)?);
 
             // Start off with the standard module name header and then go
@@ -655,8 +653,7 @@ impl<'a> Linker for MsvcLinker<'a> {
                 debug!("  _{}", symbol);
                 writeln!(f, "  {}", symbol)?;
             }
-            Ok(())
-        })();
+        };
         if let Err(e) = res {
             self.sess.fatal(&format!("failed to write lib.def file: {}", e));
         }
diff --git a/src/librustc_codegen_ssa/back/lto.rs b/src/librustc_codegen_ssa/back/lto.rs
index 7f0eba7b085..47e5d9af33b 100644
--- a/src/librustc_codegen_ssa/back/lto.rs
+++ b/src/librustc_codegen_ssa/back/lto.rs
@@ -2,7 +2,6 @@ use super::write::CodegenContext;
 use crate::traits::*;
 use crate::ModuleCodegen;
 
-use rustc::util::time_graph::Timeline;
 use rustc_errors::FatalError;
 
 use std::sync::Arc;
@@ -67,7 +66,6 @@ impl<B: WriteBackendMethods> LtoModuleCodegen<B> {
     pub unsafe fn optimize(
         &mut self,
         cgcx: &CodegenContext<B>,
-        timeline: &mut Timeline
     ) -> Result<ModuleCodegen<B::Module>, FatalError> {
         match *self {
             LtoModuleCodegen::Fat { ref mut module, .. } => {
@@ -75,11 +73,10 @@ impl<B: WriteBackendMethods> LtoModuleCodegen<B> {
                 {
                     let config = cgcx.config(module.kind);
                     B::run_lto_pass_manager(cgcx, &module, config, false);
-                    timeline.record("fat-done");
                 }
                 Ok(module)
             }
-            LtoModuleCodegen::Thin(ref mut thin) => B::optimize_thin(cgcx, thin, timeline),
+            LtoModuleCodegen::Thin(ref mut thin) => B::optimize_thin(cgcx, thin),
         }
     }
 
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index c84b38cde81..859dfb99d92 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -15,11 +15,10 @@ use rustc::middle::cstore::EncodedMetadata;
 use rustc::session::config::{self, OutputFilenames, OutputType, Passes, Sanitizer, Lto};
 use rustc::session::Session;
 use rustc::util::nodemap::FxHashMap;
-use rustc::util::time_graph::{self, TimeGraph, Timeline};
 use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc::ty::TyCtxt;
 use rustc::util::common::{time_depth, set_time_depth, print_time_passes_entry};
-use rustc::util::profiling::SelfProfiler;
+use rustc::util::profiling::{ProfileCategory, SelfProfiler};
 use rustc_fs_util::link_or_copy;
 use rustc_data_structures::svh::Svh;
 use rustc_errors::{Handler, Level, DiagnosticBuilder, FatalError, DiagnosticId};
@@ -33,6 +32,7 @@ use jobserver::{Client, Acquired};
 use parking_lot::Mutex as PlMutex;
 
 use std::any::Any;
+use std::borrow::Cow;
 use std::fs;
 use std::io;
 use std::mem;
@@ -197,6 +197,40 @@ impl<B: WriteBackendMethods> Clone for TargetMachineFactory<B> {
     }
 }
 
+pub struct ProfileGenericActivityTimer {
+    profiler: Option<Arc<PlMutex<SelfProfiler>>>,
+    category: ProfileCategory,
+    label: Cow<'static, str>,
+}
+
+impl ProfileGenericActivityTimer {
+    pub fn start(
+        profiler: Option<Arc<PlMutex<SelfProfiler>>>,
+        category: ProfileCategory,
+        label: Cow<'static, str>,
+    ) -> ProfileGenericActivityTimer {
+        if let Some(profiler) = &profiler {
+            let mut p = profiler.lock();
+            p.start_activity(category, label.clone());
+        }
+
+        ProfileGenericActivityTimer {
+            profiler,
+            category,
+            label,
+        }
+    }
+}
+
+impl Drop for ProfileGenericActivityTimer {
+    fn drop(&mut self) {
+        if let Some(profiler) = &self.profiler {
+            let mut p = profiler.lock();
+            p.end_activity(self.category, self.label.clone());
+        }
+    }
+}
+
 /// Additional resources used by optimize_and_codegen (not module specific)
 #[derive(Clone)]
 pub struct CodegenContext<B: WriteBackendMethods> {
@@ -238,9 +272,6 @@ pub struct CodegenContext<B: WriteBackendMethods> {
     pub cgu_reuse_tracker: CguReuseTracker,
     // Channel back to the main control thread to send messages to
     pub coordinator_send: Sender<Box<dyn Any + Send>>,
-    // A reference to the TimeGraph so we can register timings. None means that
-    // measuring is disabled.
-    pub time_graph: Option<TimeGraph>,
     // The assembler command if no_integrated_as option is enabled, None otherwise
     pub assembler_cmd: Option<Arc<AssemblerCommand>>
 }
@@ -277,6 +308,14 @@ impl<B: WriteBackendMethods> CodegenContext<B> {
             self.profiler_active(f)
         }
     }
+
+    pub fn profile_activity(
+        &self,
+        category: ProfileCategory,
+        label: impl Into<Cow<'static, str>>,
+    ) -> ProfileGenericActivityTimer {
+        ProfileGenericActivityTimer::start(self.profiler.clone(), category, label.into())
+    }
 }
 
 fn generate_lto_work<B: ExtraBackendMethods>(
@@ -285,11 +324,7 @@ fn generate_lto_work<B: ExtraBackendMethods>(
     needs_thin_lto: Vec<(String, B::ThinBuffer)>,
     import_only_modules: Vec<(SerializedModule<B::ModuleBuffer>, WorkProduct)>
 ) -> Vec<(WorkItem<B>, u64)> {
-    let mut timeline = cgcx.time_graph.as_ref().map(|tg| {
-        tg.start(CODEGEN_WORKER_TIMELINE,
-                 CODEGEN_WORK_PACKAGE_KIND,
-                 "generate lto")
-    }).unwrap_or(Timeline::noop());
+    cgcx.profile(|p| p.start_activity(ProfileCategory::Linking, "codegen_run_lto"));
 
     let (lto_modules, copy_jobs) = if !needs_fat_lto.is_empty() {
         assert!(needs_thin_lto.is_empty());
@@ -297,17 +332,16 @@ fn generate_lto_work<B: ExtraBackendMethods>(
             cgcx,
             needs_fat_lto,
             import_only_modules,
-            &mut timeline,
         )
         .unwrap_or_else(|e| e.raise());
         (vec![lto_module], vec![])
     } else {
         assert!(needs_fat_lto.is_empty());
-        B::run_thin_lto(cgcx, needs_thin_lto, import_only_modules, &mut timeline)
+        B::run_thin_lto(cgcx, needs_thin_lto, import_only_modules)
             .unwrap_or_else(|e| e.raise())
     };
 
-    lto_modules.into_iter().map(|module| {
+    let result = lto_modules.into_iter().map(|module| {
         let cost = module.cost();
         (WorkItem::LTO(module), cost)
     }).chain(copy_jobs.into_iter().map(|wp| {
@@ -315,7 +349,11 @@ fn generate_lto_work<B: ExtraBackendMethods>(
             name: wp.cgu_name.clone(),
             source: wp,
         }), 0)
-    })).collect()
+    })).collect();
+
+    cgcx.profile(|p| p.end_activity(ProfileCategory::Linking, "codegen_run_lto"));
+
+    result
 }
 
 pub struct CompiledModules {
@@ -345,7 +383,6 @@ fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool {
 pub fn start_async_codegen<B: ExtraBackendMethods>(
     backend: B,
     tcx: TyCtxt<'_, '_, '_>,
-    time_graph: Option<TimeGraph>,
     metadata: EncodedMetadata,
     coordinator_receive: Receiver<Box<dyn Any + Send>>,
     total_cgus: usize
@@ -469,7 +506,6 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
                                                   coordinator_receive,
                                                   total_cgus,
                                                   sess.jobserver.clone(),
-                                                  time_graph.clone(),
                                                   Arc::new(modules_config),
                                                   Arc::new(metadata_config),
                                                   Arc::new(allocator_config));
@@ -483,7 +519,6 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
         linker_info,
         crate_info,
 
-        time_graph,
         coordinator_send: tcx.tx_to_llvm_workers.lock().clone(),
         codegen_worker_receive,
         shared_emitter_main,
@@ -728,19 +763,18 @@ pub enum FatLTOInput<B: WriteBackendMethods> {
 fn execute_work_item<B: ExtraBackendMethods>(
     cgcx: &CodegenContext<B>,
     work_item: WorkItem<B>,
-    timeline: &mut Timeline
 ) -> Result<WorkItemResult<B>, FatalError> {
     let module_config = cgcx.config(work_item.module_kind());
 
     match work_item {
         WorkItem::Optimize(module) => {
-            execute_optimize_work_item(cgcx, module, module_config, timeline)
+            execute_optimize_work_item(cgcx, module, module_config)
         }
         WorkItem::CopyPostLtoArtifacts(module) => {
-            execute_copy_from_cache_work_item(cgcx, module, module_config, timeline)
+            execute_copy_from_cache_work_item(cgcx, module, module_config)
         }
         WorkItem::LTO(module) => {
-            execute_lto_work_item(cgcx, module, module_config, timeline)
+            execute_lto_work_item(cgcx, module, module_config)
         }
     }
 }
@@ -756,12 +790,11 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
     cgcx: &CodegenContext<B>,
     module: ModuleCodegen<B::Module>,
     module_config: &ModuleConfig,
-    timeline: &mut Timeline
 ) -> Result<WorkItemResult<B>, FatalError> {
     let diag_handler = cgcx.create_diag_handler();
 
     unsafe {
-        B::optimize(cgcx, &diag_handler, &module, module_config, timeline)?;
+        B::optimize(cgcx, &diag_handler, &module, module_config)?;
     }
 
     // After we've done the initial round of optimizations we need to
@@ -818,7 +851,7 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
     Ok(match lto_type {
         ComputedLtoType::No => {
             let module = unsafe {
-                B::codegen(cgcx, &diag_handler, module, module_config, timeline)?
+                B::codegen(cgcx, &diag_handler, module, module_config)?
             };
             WorkItemResult::Compiled(module)
         }
@@ -854,7 +887,6 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
     cgcx: &CodegenContext<B>,
     module: CachedModuleCodegen,
     module_config: &ModuleConfig,
-    _: &mut Timeline
 ) -> Result<WorkItemResult<B>, FatalError> {
     let incr_comp_session_dir = cgcx.incr_comp_session_dir
                                     .as_ref()
@@ -916,13 +948,12 @@ fn execute_lto_work_item<B: ExtraBackendMethods>(
     cgcx: &CodegenContext<B>,
     mut module: lto::LtoModuleCodegen<B>,
     module_config: &ModuleConfig,
-    timeline: &mut Timeline
 ) -> Result<WorkItemResult<B>, FatalError> {
     let diag_handler = cgcx.create_diag_handler();
 
     unsafe {
-        let module = module.optimize(cgcx, timeline)?;
-        let module = B::codegen(cgcx, &diag_handler, module, module_config, timeline)?;
+        let module = module.optimize(cgcx)?;
+        let module = B::codegen(cgcx, &diag_handler, module, module_config)?;
         Ok(WorkItemResult::Compiled(module))
     }
 }
@@ -977,7 +1008,6 @@ fn start_executing_work<B: ExtraBackendMethods>(
     coordinator_receive: Receiver<Box<dyn Any + Send>>,
     total_cgus: usize,
     jobserver: Client,
-    time_graph: Option<TimeGraph>,
     modules_config: Arc<ModuleConfig>,
     metadata_config: Arc<ModuleConfig>,
     allocator_config: Arc<ModuleConfig>
@@ -1065,7 +1095,6 @@ fn start_executing_work<B: ExtraBackendMethods>(
         cgu_reuse_tracker: sess.cgu_reuse_tracker.clone(),
         coordinator_send,
         diag_emitter: shared_emitter.clone(),
-        time_graph,
         output_filenames: tcx.output_filenames(LOCAL_CRATE),
         regular_module_config: modules_config,
         metadata_module_config: metadata_config,
@@ -1570,12 +1599,6 @@ fn start_executing_work<B: ExtraBackendMethods>(
 }
 
 pub const CODEGEN_WORKER_ID: usize = ::std::usize::MAX;
-pub const CODEGEN_WORKER_TIMELINE: time_graph::TimelineId =
-    time_graph::TimelineId(CODEGEN_WORKER_ID);
-pub const CODEGEN_WORK_PACKAGE_KIND: time_graph::WorkPackageKind =
-    time_graph::WorkPackageKind(&["#DE9597", "#FED1D3", "#FDC5C7", "#B46668", "#88494B"]);
-const LLVM_WORK_PACKAGE_KIND: time_graph::WorkPackageKind =
-    time_graph::WorkPackageKind(&["#7DB67A", "#C6EEC4", "#ACDAAA", "#579354", "#3E6F3C"]);
 
 fn spawn_work<B: ExtraBackendMethods>(
     cgcx: CodegenContext<B>,
@@ -1625,13 +1648,12 @@ fn spawn_work<B: ExtraBackendMethods>(
         // as a diagnostic was already sent off to the main thread - just
         // surface that there was an error in this worker.
         bomb.result = {
-            let timeline = cgcx.time_graph.as_ref().map(|tg| {
-                tg.start(time_graph::TimelineId(cgcx.worker),
-                         LLVM_WORK_PACKAGE_KIND,
-                         &work.name())
-            });
-            let mut timeline = timeline.unwrap_or(Timeline::noop());
-            execute_work_item(&cgcx, work, &mut timeline).ok()
+            let label = work.name();
+            cgcx.profile(|p| p.start_activity(ProfileCategory::Codegen, label.clone()));
+            let result = execute_work_item(&cgcx, work).ok();
+            cgcx.profile(|p| p.end_activity(ProfileCategory::Codegen, label));
+
+            result
         };
     });
 }
@@ -1785,7 +1807,6 @@ pub struct OngoingCodegen<B: ExtraBackendMethods> {
     pub windows_subsystem: Option<String>,
     pub linker_info: LinkerInfo,
     pub crate_info: CrateInfo,
-    pub time_graph: Option<TimeGraph>,
     pub coordinator_send: Sender<Box<dyn Any + Send>>,
     pub codegen_worker_receive: Receiver<Message<B>>,
     pub shared_emitter_main: SharedEmitterMain,
@@ -1814,10 +1835,6 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
 
         sess.abort_if_errors();
 
-        if let Some(time_graph) = self.time_graph {
-            time_graph.dump(&format!("{}-timings", self.crate_name));
-        }
-
         let work_products =
             copy_all_cgu_workproducts_to_incr_comp_cache_dir(sess,
                                                              &compiled_modules);
diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs
index 39ce15e4772..48743be3a25 100644
--- a/src/librustc_codegen_ssa/base.rs
+++ b/src/librustc_codegen_ssa/base.rs
@@ -29,7 +29,6 @@ use rustc::util::profiling::ProfileCategory;
 use rustc::session::config::{self, EntryFnType, Lto};
 use rustc::session::Session;
 use rustc_mir::monomorphize::item::DefPathBasedNames;
-use rustc::util::time_graph;
 use rustc_mir::monomorphize::Instance;
 use rustc_mir::monomorphize::partitioning::{CodegenUnit, CodegenUnitExt};
 use rustc::util::nodemap::FxHashMap;
@@ -528,11 +527,6 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
 }
 
 pub const CODEGEN_WORKER_ID: usize = ::std::usize::MAX;
-pub const CODEGEN_WORKER_TIMELINE: time_graph::TimelineId =
-    time_graph::TimelineId(CODEGEN_WORKER_ID);
-pub const CODEGEN_WORK_PACKAGE_KIND: time_graph::WorkPackageKind =
-    time_graph::WorkPackageKind(&["#DE9597", "#FED1D3", "#FDC5C7", "#B46668", "#88494B"]);
-
 
 pub fn codegen_crate<B: ExtraBackendMethods>(
     backend: B,
@@ -545,7 +539,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
     let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx);
 
     // Codegen the metadata.
-    tcx.sess.profiler(|p| p.start_activity(ProfileCategory::Codegen));
+    tcx.sess.profiler(|p| p.start_activity(ProfileCategory::Codegen, "codegen crate metadata"));
 
     let metadata_cgu_name = cgu_name_builder.build_cgu_name(LOCAL_CRATE,
                                                             &["crate"],
@@ -555,7 +549,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
     let metadata = time(tcx.sess, "write metadata", || {
         backend.write_metadata(tcx, &mut metadata_llvm_module)
     });
-    tcx.sess.profiler(|p| p.end_activity(ProfileCategory::Codegen));
+    tcx.sess.profiler(|p| p.end_activity(ProfileCategory::Codegen, "codegen crate metadata"));
 
     let metadata_module = ModuleCodegen {
         name: metadata_cgu_name,
@@ -563,19 +557,12 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
         kind: ModuleKind::Metadata,
     };
 
-    let time_graph = if tcx.sess.opts.debugging_opts.codegen_time_graph {
-        Some(time_graph::TimeGraph::new())
-    } else {
-        None
-    };
-
     // Skip crate items and just output metadata in -Z no-codegen mode.
     if tcx.sess.opts.debugging_opts.no_codegen ||
        !tcx.sess.opts.output_types.should_codegen() {
         let ongoing_codegen = start_async_codegen(
             backend,
             tcx,
-            time_graph,
             metadata,
             rx,
             1);
@@ -609,7 +596,6 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
     let ongoing_codegen = start_async_codegen(
         backend.clone(),
         tcx,
-        time_graph.clone(),
         metadata,
         rx,
         codegen_units.len());
@@ -676,15 +662,14 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
 
         match cgu_reuse {
             CguReuse::No => {
-                let _timing_guard = time_graph.as_ref().map(|time_graph| {
-                    time_graph.start(CODEGEN_WORKER_TIMELINE,
-                                     CODEGEN_WORK_PACKAGE_KIND,
-                                     &format!("codegen {}", cgu.name()))
-                });
+                tcx.sess.profiler(|p| p.start_activity(ProfileCategory::Codegen,
+                                                       format!("codegen {}", cgu.name())));
                 let start_time = Instant::now();
                 let stats = backend.compile_codegen_unit(tcx, *cgu.name());
                 all_stats.extend(stats);
                 total_codegen_time += start_time.elapsed();
+                tcx.sess.profiler(|p| p.end_activity(ProfileCategory::Codegen,
+                                                     format!("codegen {}", cgu.name())));
                 false
             }
             CguReuse::PreLto => {
diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs
index fec41936a23..fe9b88c85f0 100644
--- a/src/librustc_codegen_ssa/lib.rs
+++ b/src/librustc_codegen_ssa/lib.rs
@@ -7,6 +7,7 @@
 #![feature(libc)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(stmt_expr_attributes)]
+#![feature(try_blocks)]
 #![feature(in_band_lifetimes)]
 #![feature(nll)]
 #![allow(unused_attributes)]
diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs
index 349c9132842..2bb68dc687c 100644
--- a/src/librustc_codegen_ssa/mir/constant.rs
+++ b/src/librustc_codegen_ssa/mir/constant.rs
@@ -53,7 +53,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 let field_ty = c.ty.builtin_index().unwrap();
                 let fields = match c.ty.sty {
                     ty::Array(_, n) => n.unwrap_usize(bx.tcx()),
-                    ref other => bug!("invalid simd shuffle type: {}", other),
+                    _ => bug!("invalid simd shuffle type: {}", c.ty),
                 };
                 let values: Vec<_> = (0..fields).map(|field| {
                     let field = const_field(
diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/src/librustc_codegen_ssa/traits/type_.rs
index 7c5e615f224..fe00276a55a 100644
--- a/src/librustc_codegen_ssa/traits/type_.rs
+++ b/src/librustc_codegen_ssa/traits/type_.rs
@@ -148,7 +148,7 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
         match tail.sty {
             ty::Foreign(..) => false,
             ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
-            _ => bug!("unexpected unsized tail: {:?}", tail.sty),
+            _ => bug!("unexpected unsized tail: {:?}", tail),
         }
     }
 }
diff --git a/src/librustc_codegen_ssa/traits/write.rs b/src/librustc_codegen_ssa/traits/write.rs
index d8fb7c608c8..23bb7179557 100644
--- a/src/librustc_codegen_ssa/traits/write.rs
+++ b/src/librustc_codegen_ssa/traits/write.rs
@@ -3,7 +3,6 @@ use crate::back::write::{CodegenContext, ModuleConfig, FatLTOInput};
 use crate::{CompiledModule, ModuleCodegen};
 
 use rustc::dep_graph::WorkProduct;
-use rustc::util::time_graph::Timeline;
 use rustc_errors::{FatalError, Handler};
 
 pub trait WriteBackendMethods: 'static + Sized + Clone {
@@ -20,7 +19,6 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
         cgcx: &CodegenContext<Self>,
         modules: Vec<FatLTOInput<Self>>,
         cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>,
-        timeline: &mut Timeline,
     ) -> Result<LtoModuleCodegen<Self>, FatalError>;
     /// Performs thin LTO by performing necessary global analysis and returning two
     /// lists, one of the modules that need optimization and another for modules that
@@ -29,7 +27,6 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
         cgcx: &CodegenContext<Self>,
         modules: Vec<(String, Self::ThinBuffer)>,
         cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>,
-        timeline: &mut Timeline,
     ) -> Result<(Vec<LtoModuleCodegen<Self>>, Vec<WorkProduct>), FatalError>;
     fn print_pass_timings(&self);
     unsafe fn optimize(
@@ -37,19 +34,16 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
         diag_handler: &Handler,
         module: &ModuleCodegen<Self::Module>,
         config: &ModuleConfig,
-        timeline: &mut Timeline,
     ) -> Result<(), FatalError>;
     unsafe fn optimize_thin(
         cgcx: &CodegenContext<Self>,
         thin: &mut ThinModule<Self>,
-        timeline: &mut Timeline,
     ) -> Result<ModuleCodegen<Self::Module>, FatalError>;
     unsafe fn codegen(
         cgcx: &CodegenContext<Self>,
         diag_handler: &Handler,
         module: ModuleCodegen<Self::Module>,
         config: &ModuleConfig,
-        timeline: &mut Timeline,
     ) -> Result<CompiledModule, FatalError>;
     fn prepare_thin(
         module: ModuleCodegen<Self::Module>
diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs
index 2b70141894b..466cf40a157 100644
--- a/src/librustc_codegen_utils/lib.rs
+++ b/src/librustc_codegen_utils/lib.rs
@@ -4,6 +4,7 @@
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
 
+#![feature(arbitrary_self_types)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(custom_attribute)]
diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs
index 5de5c297c30..0fa935199f9 100644
--- a/src/librustc_codegen_utils/symbol_names.rs
+++ b/src/librustc_codegen_utils/symbol_names.rs
@@ -87,14 +87,14 @@
 //! virtually impossible. Thus, symbol hash generation exclusively relies on
 //! DefPaths which are much more robust in the face of changes to the code base.
 
-use rustc::hir::def_id::{DefId, LOCAL_CRATE};
+use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc::hir::Node;
 use rustc::hir::CodegenFnAttrFlags;
-use rustc::hir::map::definitions::DefPathData;
+use rustc::hir::map::{DefPathData, DisambiguatedDefPathData};
 use rustc::ich::NodeIdHashingMode;
-use rustc::ty::item_path::{self, ItemPathBuffer, RootMode};
+use rustc::ty::print::{PrettyPrinter, Printer, Print};
 use rustc::ty::query::Providers;
-use rustc::ty::subst::SubstsRef;
+use rustc::ty::subst::{Kind, SubstsRef, UnpackedKind};
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc::util::common::record_time;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -105,8 +105,8 @@ use syntax_pos::symbol::Symbol;
 
 use log::debug;
 
-use std::fmt::Write;
-use std::mem::discriminant;
+use std::fmt::{self, Write};
+use std::mem::{self, discriminant};
 
 pub fn provide(providers: &mut Providers<'_>) {
     *providers = Providers {
@@ -223,11 +223,11 @@ fn get_symbol_hash<'a, 'tcx>(
 }
 
 fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName {
-    let mut buffer = SymbolPathBuffer::new(tcx);
-    item_path::with_forced_absolute_paths(|| {
-        tcx.push_item_path(&mut buffer, def_id, false);
-    });
-    buffer.into_interned()
+    SymbolPrinter {
+        tcx,
+        path: SymbolPath::new(),
+        keep_within_component: false,
+    }.print_def_path(def_id, &[]).unwrap().path.into_interned()
 }
 
 fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> ty::SymbolName {
@@ -319,13 +319,17 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
 
     let hash = get_symbol_hash(tcx, def_id, instance, instance_ty, substs);
 
-    let mut buf = SymbolPathBuffer::from_interned(tcx.def_symbol_name(def_id), tcx);
+    let mut printer = SymbolPrinter {
+        tcx,
+        path: SymbolPath::from_interned(tcx.def_symbol_name(def_id)),
+        keep_within_component: false,
+    };
 
     if instance.is_vtable_shim() {
-        buf.push("{{vtable-shim}}");
+        let _ = printer.write_str("{{vtable-shim}}");
     }
 
-    buf.finish(hash)
+    printer.path.finish(hash)
 }
 
 // Follow C++ namespace-mangling style, see
@@ -342,126 +346,312 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
 // To be able to work on all platforms and get *some* reasonable output, we
 // use C++ name-mangling.
 #[derive(Debug)]
-struct SymbolPathBuffer {
+struct SymbolPath {
     result: String,
     temp_buf: String,
-    strict_naming: bool,
 }
 
-impl SymbolPathBuffer {
-    fn new(tcx: TyCtxt<'_, '_, '_>) -> Self {
-        let mut result = SymbolPathBuffer {
+impl SymbolPath {
+    fn new() -> Self {
+        let mut result = SymbolPath {
             result: String::with_capacity(64),
             temp_buf: String::with_capacity(16),
-            strict_naming: tcx.has_strict_asm_symbol_naming(),
         };
         result.result.push_str("_ZN"); // _Z == Begin name-sequence, N == nested
         result
     }
 
-    fn from_interned(symbol: ty::SymbolName, tcx: TyCtxt<'_, '_, '_>) -> Self {
-        let mut result = SymbolPathBuffer {
+    fn from_interned(symbol: ty::SymbolName) -> Self {
+        let mut result = SymbolPath {
             result: String::with_capacity(64),
             temp_buf: String::with_capacity(16),
-            strict_naming: tcx.has_strict_asm_symbol_naming(),
         };
         result.result.push_str(&symbol.as_str());
         result
     }
 
-    fn into_interned(self) -> ty::SymbolName {
+    fn into_interned(mut self) -> ty::SymbolName {
+        self.finalize_pending_component();
         ty::SymbolName {
             name: Symbol::intern(&self.result).as_interned_str(),
         }
     }
 
+    fn finalize_pending_component(&mut self) {
+        if !self.temp_buf.is_empty() {
+            let _ = write!(self.result, "{}{}", self.temp_buf.len(), self.temp_buf);
+            self.temp_buf.clear();
+        }
+    }
+
     fn finish(mut self, hash: u64) -> String {
+        self.finalize_pending_component();
         // E = end name-sequence
         let _ = write!(self.result, "17h{:016x}E", hash);
         self.result
     }
+}
+
+struct SymbolPrinter<'a, 'tcx> {
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    path: SymbolPath,
+
+    // When `true`, `finalize_pending_component` isn't used.
+    // This is needed when recursing into `path_qualified`,
+    // or `path_generic_args`, as any nested paths are
+    // logically within one component.
+    keep_within_component: bool,
+}
 
-    // Name sanitation. LLVM will happily accept identifiers with weird names, but
-    // gas doesn't!
-    // gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $
-    // NVPTX assembly has more strict naming rules than gas, so additionally, dots
-    // are replaced with '$' there.
-    fn sanitize_and_append(&mut self, s: &str) {
-        self.temp_buf.clear();
+// HACK(eddyb) this relies on using the `fmt` interface to get
+// `PrettyPrinter` aka pretty printing of e.g. types in paths,
+// symbol names should have their own printing machinery.
+
+impl Printer<'tcx, 'tcx> for SymbolPrinter<'_, 'tcx> {
+    type Error = fmt::Error;
+
+    type Path = Self;
+    type Region = Self;
+    type Type = Self;
+    type DynExistential = Self;
+
+    fn tcx(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
+        self.tcx
+    }
+
+    fn print_region(
+        self,
+        _region: ty::Region<'_>,
+    ) -> Result<Self::Region, Self::Error> {
+        Ok(self)
+    }
+
+    fn print_type(
+        self,
+        ty: Ty<'tcx>,
+    ) -> Result<Self::Type, Self::Error> {
+        match ty.sty {
+            // Print all nominal types as paths (unlike `pretty_print_type`).
+            ty::FnDef(def_id, substs) |
+            ty::Opaque(def_id, substs) |
+            ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs }) |
+            ty::UnnormalizedProjection(ty::ProjectionTy { item_def_id: def_id, substs }) |
+            ty::Closure(def_id, ty::ClosureSubsts { substs }) |
+            ty::Generator(def_id, ty::GeneratorSubsts { substs }, _) => {
+                self.print_def_path(def_id, substs)
+            }
+            _ => self.pretty_print_type(ty),
+        }
+    }
+
+    fn print_dyn_existential(
+        mut self,
+        predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
+    ) -> Result<Self::DynExistential, Self::Error> {
+        let mut first = false;
+        for p in predicates {
+            if !first {
+                write!(self, "+")?;
+            }
+            first = false;
+            self = p.print(self)?;
+        }
+        Ok(self)
+    }
+
+    fn path_crate(
+        mut self,
+        cnum: CrateNum,
+    ) -> Result<Self::Path, Self::Error> {
+        self.write_str(&self.tcx.original_crate_name(cnum).as_str())?;
+        Ok(self)
+    }
+    fn path_qualified(
+        self,
+        self_ty: Ty<'tcx>,
+        trait_ref: Option<ty::TraitRef<'tcx>>,
+    ) -> Result<Self::Path, Self::Error> {
+        // Similar to `pretty_path_qualified`, but for the other
+        // types that are printed as paths (see `print_type` above).
+        match self_ty.sty {
+            ty::FnDef(..) |
+            ty::Opaque(..) |
+            ty::Projection(_) |
+            ty::UnnormalizedProjection(_) |
+            ty::Closure(..) |
+            ty::Generator(..)
+                if trait_ref.is_none() =>
+            {
+                self.print_type(self_ty)
+            }
+
+            _ => self.pretty_path_qualified(self_ty, trait_ref)
+        }
+    }
+
+    fn path_append_impl(
+        self,
+        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
+        _disambiguated_data: &DisambiguatedDefPathData,
+        self_ty: Ty<'tcx>,
+        trait_ref: Option<ty::TraitRef<'tcx>>,
+    ) -> Result<Self::Path, Self::Error> {
+        self.pretty_path_append_impl(
+            |mut cx| {
+                cx = print_prefix(cx)?;
+
+                if cx.keep_within_component {
+                    // HACK(eddyb) print the path similarly to how `FmtPrinter` prints it.
+                    cx.write_str("::")?;
+                } else {
+                    cx.path.finalize_pending_component();
+                }
+
+                Ok(cx)
+            },
+            self_ty,
+            trait_ref,
+        )
+    }
+    fn path_append(
+        mut self,
+        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
+        disambiguated_data: &DisambiguatedDefPathData,
+    ) -> Result<Self::Path, Self::Error> {
+        self = print_prefix(self)?;
+
+        // Skip `::{{constructor}}` on tuple/unit structs.
+        match disambiguated_data.data {
+            DefPathData::StructCtor => return Ok(self),
+            _ => {}
+        }
+
+        if self.keep_within_component {
+            // HACK(eddyb) print the path similarly to how `FmtPrinter` prints it.
+            self.write_str("::")?;
+        } else {
+            self.path.finalize_pending_component();
+        }
+
+        self.write_str(&disambiguated_data.data.as_interned_str().as_str())?;
+        Ok(self)
+    }
+    fn path_generic_args(
+        mut self,
+        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
+        args: &[Kind<'tcx>],
+    )  -> Result<Self::Path, Self::Error> {
+        self = print_prefix(self)?;
+
+        let args = args.iter().cloned().filter(|arg| {
+            match arg.unpack() {
+                UnpackedKind::Lifetime(_) => false,
+                _ => true,
+            }
+        });
+
+        if args.clone().next().is_some() {
+            self.generic_delimiters(|cx| cx.comma_sep(args))
+        } else {
+            Ok(self)
+        }
+    }
+}
+
+impl PrettyPrinter<'tcx, 'tcx> for SymbolPrinter<'_, 'tcx> {
+    fn region_should_not_be_omitted(
+        &self,
+        _region: ty::Region<'_>,
+    ) -> bool {
+        false
+    }
+    fn comma_sep<T>(
+        mut self,
+        mut elems: impl Iterator<Item = T>,
+    ) -> Result<Self, Self::Error>
+        where T: Print<'tcx, 'tcx, Self, Output = Self, Error = Self::Error>
+    {
+        if let Some(first) = elems.next() {
+            self = first.print(self)?;
+            for elem in elems {
+                self.write_str(",")?;
+                self = elem.print(self)?;
+            }
+        }
+        Ok(self)
+    }
+
+    fn generic_delimiters(
+        mut self,
+        f: impl FnOnce(Self) -> Result<Self, Self::Error>,
+    ) -> Result<Self, Self::Error> {
+        write!(self, "<")?;
+
+        let kept_within_component =
+            mem::replace(&mut self.keep_within_component, true);
+        self = f(self)?;
+        self.keep_within_component = kept_within_component;
+
+        write!(self, ">")?;
+
+        Ok(self)
+    }
+}
+
+impl fmt::Write for SymbolPrinter<'_, '_> {
+    fn write_str(&mut self, s: &str) -> fmt::Result {
+        // Name sanitation. LLVM will happily accept identifiers with weird names, but
+        // gas doesn't!
+        // gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $
+        // NVPTX assembly has more strict naming rules than gas, so additionally, dots
+        // are replaced with '$' there.
 
         for c in s.chars() {
+            if self.path.temp_buf.is_empty() {
+                match c {
+                    'a'..='z' | 'A'..='Z' | '_' => {}
+                    _ => {
+                        // Underscore-qualify anything that didn't start as an ident.
+                        self.path.temp_buf.push('_');
+                    }
+                }
+            }
             match c {
                 // Escape these with $ sequences
-                '@' => self.temp_buf.push_str("$SP$"),
-                '*' => self.temp_buf.push_str("$BP$"),
-                '&' => self.temp_buf.push_str("$RF$"),
-                '<' => self.temp_buf.push_str("$LT$"),
-                '>' => self.temp_buf.push_str("$GT$"),
-                '(' => self.temp_buf.push_str("$LP$"),
-                ')' => self.temp_buf.push_str("$RP$"),
-                ',' => self.temp_buf.push_str("$C$"),
-
-                '-' | ':' => if self.strict_naming {
+                '@' => self.path.temp_buf.push_str("$SP$"),
+                '*' => self.path.temp_buf.push_str("$BP$"),
+                '&' => self.path.temp_buf.push_str("$RF$"),
+                '<' => self.path.temp_buf.push_str("$LT$"),
+                '>' => self.path.temp_buf.push_str("$GT$"),
+                '(' => self.path.temp_buf.push_str("$LP$"),
+                ')' => self.path.temp_buf.push_str("$RP$"),
+                ',' => self.path.temp_buf.push_str("$C$"),
+
+                '-' | ':' | '.' if self.tcx.has_strict_asm_symbol_naming() => {
                     // NVPTX doesn't support these characters in symbol names.
-                    self.temp_buf.push('$')
-                }
-                else {
-                    // '.' doesn't occur in types and functions, so reuse it
-                    // for ':' and '-'
-                    self.temp_buf.push('.')
-                },
-
-                '.' => if self.strict_naming {
-                    self.temp_buf.push('$')
+                    self.path.temp_buf.push('$')
                 }
-                else {
-                    self.temp_buf.push('.')
-                },
+
+                // '.' doesn't occur in types and functions, so reuse it
+                // for ':' and '-'
+                '-' | ':' => self.path.temp_buf.push('.'),
 
                 // These are legal symbols
-                'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '$' => self.temp_buf.push(c),
+                'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '.' | '$' => self.path.temp_buf.push(c),
 
                 _ => {
-                    self.temp_buf.push('$');
+                    self.path.temp_buf.push('$');
                     for c in c.escape_unicode().skip(1) {
                         match c {
                             '{' => {}
-                            '}' => self.temp_buf.push('$'),
-                            c => self.temp_buf.push(c),
+                            '}' => self.path.temp_buf.push('$'),
+                            c => self.path.temp_buf.push(c),
                         }
                     }
                 }
             }
         }
 
-        let need_underscore = {
-            // Underscore-qualify anything that didn't start as an ident.
-            !self.temp_buf.is_empty()
-                && self.temp_buf.as_bytes()[0] != '_' as u8
-                && !(self.temp_buf.as_bytes()[0] as char).is_xid_start()
-        };
-
-        let _ = write!(
-            self.result,
-            "{}",
-            self.temp_buf.len() + (need_underscore as usize)
-        );
-
-        if need_underscore {
-            self.result.push('_');
-        }
-
-        self.result.push_str(&self.temp_buf);
-    }
-}
-
-impl ItemPathBuffer for SymbolPathBuffer {
-    fn root_mode(&self) -> &RootMode {
-        const ABSOLUTE: &RootMode = &RootMode::Absolute;
-        ABSOLUTE
-    }
-
-    fn push(&mut self, text: &str) {
-        self.sanitize_and_append(text);
+        Ok(())
     }
 }
diff --git a/src/librustc_codegen_utils/symbol_names_test.rs b/src/librustc_codegen_utils/symbol_names_test.rs
index c4952681546..6a2b6f1321b 100644
--- a/src/librustc_codegen_utils/symbol_names_test.rs
+++ b/src/librustc_codegen_utils/symbol_names_test.rs
@@ -1,7 +1,7 @@
 //! Walks the crate looking for items/impl-items/trait-items that have
-//! either a `rustc_symbol_name` or `rustc_item_path` attribute and
+//! either a `rustc_symbol_name` or `rustc_def_path` attribute and
 //! generates an error giving, respectively, the symbol name or
-//! item-path. This is used for unit testing the code that generates
+//! def-path. This is used for unit testing the code that generates
 //! paths etc in all kinds of annoying scenarios.
 
 use rustc::hir;
@@ -10,7 +10,7 @@ use rustc::ty::TyCtxt;
 use rustc_mir::monomorphize::Instance;
 
 const SYMBOL_NAME: &'static str = "rustc_symbol_name";
-const ITEM_PATH: &'static str = "rustc_item_path";
+const DEF_PATH: &'static str = "rustc_def_path";
 
 pub fn report_symbol_names<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     // if the `rustc_attrs` feature is not enabled, then the
@@ -41,9 +41,9 @@ impl<'a, 'tcx> SymbolNamesTest<'a, 'tcx> {
                 let instance = Instance::mono(tcx, def_id);
                 let name = self.tcx.symbol_name(instance);
                 tcx.sess.span_err(attr.span, &format!("symbol-name({})", name));
-            } else if attr.check_name(ITEM_PATH) {
-                let path = tcx.item_path_str(def_id);
-                tcx.sess.span_err(attr.span, &format!("item-path({})", path));
+            } else if attr.check_name(DEF_PATH) {
+                let path = tcx.def_path_str(def_id);
+                tcx.sess.span_err(attr.span, &format!("def-path({})", path));
             }
 
             // (*) The formatting of `tag({})` is chosen so that tests can elect
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 3182b2ce30c..dde88a21240 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -471,7 +471,7 @@ impl<'b, 'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> {
     }
 
     fn node_path(&self, id: ast::NodeId) -> Option<String> {
-        Some(self.tcx.node_path_str(id))
+        Some(self.tcx.def_path_str(self.tcx.hir().local_def_id(id)))
     }
 }
 
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 7c7698ddd3d..6b4b437930d 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -2,7 +2,6 @@
 
 #![feature(custom_attribute)]
 #![allow(unused_attributes)]
-#![feature(range_contains)]
 #![cfg_attr(unix, feature(libc))]
 #![feature(nll)]
 #![feature(optin_builtin_traits)]
diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs
index 1f69d617c83..9fe9a60b9aa 100644
--- a/src/librustc_incremental/assert_dep_graph.rs
+++ b/src/librustc_incremental/assert_dep_graph.rs
@@ -206,7 +206,7 @@ fn check_paths<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 tcx.sess.span_err(
                     target_span,
                     &format!("no path from `{}` to `{}`",
-                             tcx.item_path_str(source_def_id),
+                             tcx.def_path_str(source_def_id),
                              target_pass));
             } else {
                 tcx.sess.span_err(
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index 2794b6c556f..633e61a0034 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -463,7 +463,7 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
         if let Some(def_id) = dep_node.extract_def_id(self.tcx) {
             format!("{:?}({})",
                     dep_node.kind,
-                    self.tcx.item_path_str(def_id))
+                    self.tcx.def_path_str(def_id))
         } else {
             format!("{:?}({:?})", dep_node.kind, dep_node.hash)
         }
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index d61ccd5605b..0c710fd283b 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -67,7 +67,7 @@ pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
         .set_continue_after_error(sess.opts.debugging_opts.continue_parse_after_error);
     hygiene::set_default_edition(sess.edition());
 
-    sess.profiler(|p| p.start_activity(ProfileCategory::Parsing));
+    sess.profiler(|p| p.start_activity(ProfileCategory::Parsing, "parsing"));
     let krate = time(sess, "parsing", || match *input {
         Input::File(ref file) => parse::parse_crate_from_file(file, &sess.parse_sess),
         Input::Str {
@@ -75,7 +75,7 @@ pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
             ref name,
         } => parse::parse_crate_from_source_str(name.clone(), input.clone(), &sess.parse_sess),
     })?;
-    sess.profiler(|p| p.end_activity(ProfileCategory::Parsing));
+    sess.profiler(|p| p.end_activity(ProfileCategory::Parsing, "parsing"));
 
     sess.diagnostic().set_continue_after_error(true);
 
@@ -243,6 +243,7 @@ pub fn register_plugins<'a>(
         krate,
         &sess.parse_sess,
         sess.edition(),
+        &sess.opts.debugging_opts.allow_features,
     );
     // these need to be set "early" so that expansion sees `quote` if enabled.
     sess.init_features(features);
@@ -374,7 +375,7 @@ fn configure_and_expand_inner<'a>(
     syntax_ext::register_builtins(&mut resolver, plugin_info.syntax_exts);
 
     // Expand all macros
-    sess.profiler(|p| p.start_activity(ProfileCategory::Expansion));
+    sess.profiler(|p| p.start_activity(ProfileCategory::Expansion, "macro expansion"));
     krate = time(sess, "expansion", || {
         // Windows dlls do not have rpaths, so they don't know how to find their
         // dependencies. It's up to us to tell the system where to find all the
@@ -449,7 +450,7 @@ fn configure_and_expand_inner<'a>(
         }
         krate
     });
-    sess.profiler(|p| p.end_activity(ProfileCategory::Expansion));
+    sess.profiler(|p| p.end_activity(ProfileCategory::Expansion, "macro expansion"));
 
     time(sess, "maybe building test harness", || {
         syntax::test::modify_for_testing(
@@ -1018,9 +1019,9 @@ pub fn start_codegen<'tcx>(
         ::rustc::middle::dependency_format::calculate(tcx)
     });
 
-    tcx.sess.profiler(|p| p.start_activity(ProfileCategory::Codegen));
+    tcx.sess.profiler(|p| p.start_activity(ProfileCategory::Codegen, "codegen crate"));
     let codegen = time(tcx.sess, "codegen", move || codegen_backend.codegen_crate(tcx, rx));
-    tcx.sess.profiler(|p| p.end_activity(ProfileCategory::Codegen));
+    tcx.sess.profiler(|p| p.end_activity(ProfileCategory::Codegen, "codegen crate"));
 
     if log_enabled!(::log::Level::Info) {
         println!("Post-codegen");
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 86b8b276eaf..7d61547527f 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -182,7 +182,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
             for attr in cx.tcx.get_attrs(def_id).iter() {
                 if attr.check_name("must_use") {
                     let msg = format!("unused {}`{}`{} that must be used",
-                        descr_pre_path, cx.tcx.item_path_str(def_id), descr_post_path);
+                        descr_pre_path, cx.tcx.def_path_str(def_id), descr_post_path);
                     let mut err = cx.struct_span_lint(UNUSED_MUST_USE, sp, &msg);
                     // check for #[must_use = "..."]
                     if let Some(note) = attr.value_str() {
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index fe07cc0698a..86134647324 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -3,6 +3,7 @@ use crate::borrow_check::nll::region_infer::{RegionName, RegionNameSource};
 use crate::borrow_check::prefixes::IsPrefixOf;
 use crate::borrow_check::WriteKind;
 use rustc::hir;
+use rustc::hir::def::Namespace;
 use rustc::hir::def_id::DefId;
 use rustc::middle::region::ScopeTree;
 use rustc::mir::{
@@ -12,7 +13,7 @@ use rustc::mir::{
     TerminatorKind, VarBindingForm,
 };
 use rustc::ty::{self, DefIdTree};
-use rustc::util::ppaux::RegionHighlightMode;
+use rustc::ty::print::Print;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::indexed_vec::Idx;
 use rustc_data_structures::sync::Lrc;
@@ -831,7 +832,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         );
 
         if let Some(annotation) = self.annotate_argument_and_return_for_borrow(borrow) {
-            let region_name = annotation.emit(&mut err);
+            let region_name = annotation.emit(self, &mut err);
 
             err.span_label(
                 borrow_span,
@@ -1799,7 +1800,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     // (https://github.com/rust-lang/rfcs/pull/1546)
                     bug!(
                         "End-user description not implemented for field access on `{:?}`",
-                        ty.sty
+                        ty
                     );
                 }
             }
@@ -1875,7 +1876,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
     fn annotate_argument_and_return_for_borrow(
         &self,
         borrow: &BorrowData<'tcx>,
-    ) -> Option<AnnotatedBorrowFnSignature<'_>> {
+    ) -> Option<AnnotatedBorrowFnSignature<'tcx>> {
         // Define a fallback for when we can't match a closure.
         let fallback = || {
             let is_closure = self.infcx.tcx.is_closure(self.mir_def_id);
@@ -2099,7 +2100,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         &self,
         did: DefId,
         sig: ty::PolyFnSig<'tcx>,
-    ) -> Option<AnnotatedBorrowFnSignature<'_>> {
+    ) -> Option<AnnotatedBorrowFnSignature<'tcx>> {
         debug!("annotate_fn_sig: did={:?} sig={:?}", did, sig);
         let is_closure = self.infcx.tcx.is_closure(did);
         let fn_hir_id = self.infcx.tcx.hir().as_local_hir_id(did)?;
@@ -2245,7 +2246,11 @@ enum AnnotatedBorrowFnSignature<'tcx> {
 impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
     /// Annotate the provided diagnostic with information about borrow from the fn signature that
     /// helps explain.
-    fn emit(&self, diag: &mut DiagnosticBuilder<'_>) -> String {
+    fn emit(
+        &self,
+        cx: &mut MirBorrowckCtxt<'_, '_, 'tcx>,
+        diag: &mut DiagnosticBuilder<'_>,
+    ) -> String {
         match self {
             AnnotatedBorrowFnSignature::Closure {
                 argument_ty,
@@ -2253,10 +2258,10 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
             } => {
                 diag.span_label(
                     *argument_span,
-                    format!("has type `{}`", self.get_name_for_ty(argument_ty, 0)),
+                    format!("has type `{}`", cx.get_name_for_ty(argument_ty, 0)),
                 );
 
-                self.get_region_name_for_ty(argument_ty, 0)
+                cx.get_region_name_for_ty(argument_ty, 0)
             }
             AnnotatedBorrowFnSignature::AnonymousFunction {
                 argument_ty,
@@ -2264,10 +2269,10 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
                 return_ty,
                 return_span,
             } => {
-                let argument_ty_name = self.get_name_for_ty(argument_ty, 0);
+                let argument_ty_name = cx.get_name_for_ty(argument_ty, 0);
                 diag.span_label(*argument_span, format!("has type `{}`", argument_ty_name));
 
-                let return_ty_name = self.get_name_for_ty(return_ty, 0);
+                let return_ty_name = cx.get_name_for_ty(return_ty, 0);
                 let types_equal = return_ty_name == argument_ty_name;
                 diag.span_label(
                     *return_span,
@@ -2286,7 +2291,7 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
                      lifetime-syntax.html#lifetime-elision>",
                 );
 
-                self.get_region_name_for_ty(return_ty, 0)
+                cx.get_region_name_for_ty(return_ty, 0)
             }
             AnnotatedBorrowFnSignature::NamedFunction {
                 arguments,
@@ -2294,7 +2299,7 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
                 return_span,
             } => {
                 // Region of return type and arguments checked to be the same earlier.
-                let region_name = self.get_region_name_for_ty(return_ty, 0);
+                let region_name = cx.get_region_name_for_ty(return_ty, 0);
                 for (_, argument_span) in arguments {
                     diag.span_label(*argument_span, format!("has lifetime `{}`", region_name));
                 }
@@ -2314,10 +2319,15 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
             }
         }
     }
+}
 
+impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
     /// Return the name of the provided `Ty` (that must be a reference) with a synthesized lifetime
     /// name where required.
     fn get_name_for_ty(&self, ty: ty::Ty<'tcx>, counter: usize) -> String {
+        let mut s = String::new();
+        let mut printer = ty::print::FmtPrinter::new(self.infcx.tcx, &mut s, Namespace::TypeNS);
+
         // We need to add synthesized lifetimes where appropriate. We do
         // this by hooking into the pretty printer and telling it to label the
         // lifetimes without names with the value `'0`.
@@ -2327,28 +2337,37 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
                 ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }),
                 _,
                 _,
-            ) => RegionHighlightMode::highlighting_bound_region(*br, counter, || ty.to_string()),
-            _ => ty.to_string(),
+            ) => printer.region_highlight_mode.highlighting_bound_region(*br, counter),
+            _ => {}
         }
+
+        let _ = ty.print(printer);
+        s
     }
 
     /// Returns the name of the provided `Ty` (that must be a reference)'s region with a
     /// synthesized lifetime name where required.
     fn get_region_name_for_ty(&self, ty: ty::Ty<'tcx>, counter: usize) -> String {
-        match ty.sty {
-            ty::TyKind::Ref(region, _, _) => match region {
-                ty::RegionKind::ReLateBound(_, br)
-                | ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => {
-                    RegionHighlightMode::highlighting_bound_region(
-                        *br,
-                        counter,
-                        || region.to_string(),
-                    )
+        let mut s = String::new();
+        let mut printer = ty::print::FmtPrinter::new(self.infcx.tcx, &mut s, Namespace::TypeNS);
+
+        let region = match ty.sty {
+            ty::TyKind::Ref(region, _, _) => {
+                match region {
+                    ty::RegionKind::ReLateBound(_, br)
+                    | ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => {
+                        printer.region_highlight_mode.highlighting_bound_region(*br, counter)
+                    }
+                    _ => {}
                 }
-                _ => region.to_string(),
-            },
+
+                region
+            }
             _ => bug!("ty for annotation of borrow region is not a reference"),
-        }
+        };
+
+        let _ = region.print(printer);
+        s
     }
 }
 
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 0bdf44c2ae0..c4e371d5afe 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -68,7 +68,7 @@ pub fn provide(providers: &mut Providers<'_>) {
 
 fn mir_borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> BorrowCheckResult<'tcx> {
     let input_mir = tcx.mir_validated(def_id);
-    debug!("run query mir_borrowck: {}", tcx.item_path_str(def_id));
+    debug!("run query mir_borrowck: {}", tcx.def_path_str(def_id));
 
     let mut return_early;
 
diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
index 17f8c23f4fd..dfa5af444d3 100644
--- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
@@ -93,7 +93,7 @@ impl BorrowExplanation {
                     // simplify output by reporting just the ADT name.
                     ty::Adt(adt, _substs) if adt.has_dtor(tcx) && !adt.is_box() => (
                         "`Drop` code",
-                        format!("type `{}`", tcx.item_path_str(adt.did)),
+                        format!("type `{}`", tcx.def_path_str(adt.did)),
                     ),
 
                     // Otherwise, just report the whole type (and use
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
index fdede054e15..362214d3257 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
@@ -8,7 +8,7 @@ use rustc::infer::InferCtxt;
 use rustc::mir::Mir;
 use rustc::ty::subst::{SubstsRef, UnpackedKind};
 use rustc::ty::{self, RegionKind, RegionVid, Ty, TyCtxt};
-use rustc::util::ppaux::RegionHighlightMode;
+use rustc::ty::print::RegionHighlightMode;
 use rustc_errors::DiagnosticBuilder;
 use syntax::ast::Name;
 use syntax::symbol::keywords;
@@ -396,9 +396,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         argument_ty: Ty<'tcx>,
         counter: &mut usize,
     ) -> Option<RegionName> {
-        let type_name = RegionHighlightMode::highlighting_region_vid(needle_fr, *counter, || {
-            infcx.extract_type_name(&argument_ty)
-        });
+        let mut highlight = RegionHighlightMode::default();
+        highlight.highlighting_region_vid(needle_fr, *counter);
+        let type_name = infcx.extract_type_name(&argument_ty, Some(highlight));
 
         debug!(
             "give_name_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}",
@@ -680,9 +680,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             return None;
         }
 
-        let type_name = RegionHighlightMode::highlighting_region_vid(
-            fr, *counter, || infcx.extract_type_name(&return_ty),
-        );
+        let mut highlight = RegionHighlightMode::default();
+        highlight.highlighting_region_vid(fr, *counter);
+        let type_name = infcx.extract_type_name(&return_ty, Some(highlight));
 
         let mir_node_id = tcx.hir().as_local_node_id(mir_def_id).expect("non-local mir");
 
diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs
index d60a0941b59..77978d7d38f 100644
--- a/src/librustc_mir/build/matches/simplify.rs
+++ b/src/librustc_mir/build/matches/simplify.rs
@@ -114,14 +114,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                         (Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32))), 0)
                     }
                     ty::Int(ity) => {
-                        // FIXME(49937): refactor these bit manipulations into interpret.
                         let size = Integer::from_attr(&tcx, SignedInt(ity)).size();
                         let max = truncate(u128::max_value(), size);
                         let bias = 1u128 << (size.bits() - 1);
                         (Some((0, max, size)), bias)
                     }
                     ty::Uint(uty) => {
-                        // FIXME(49937): refactor these bit manipulations into interpret.
                         let size = Integer::from_attr(&tcx, UnsignedInt(uty)).size();
                         let max = truncate(u128::max_value(), size);
                         (Some((0, max, size)), 0)
diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs
index 4189e3e7ddb..4aa463b37ab 100644
--- a/src/librustc_mir/build/scope.rs
+++ b/src/librustc_mir/build/scope.rs
@@ -82,7 +82,6 @@ use crate::hair::LintLevel;
 use rustc::middle::region;
 use rustc::ty::Ty;
 use rustc::hir;
-use rustc::hir::def_id::LOCAL_CRATE;
 use rustc::mir::*;
 use syntax_pos::{Span};
 use rustc_data_structures::fx::FxHashMap;
@@ -309,16 +308,25 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
         let source_scope = self.source_scope;
         let tcx = self.hir.tcx();
         if let LintLevel::Explicit(current_hir_id) = lint_level {
-            let same_lint_scopes = tcx.dep_graph.with_ignore(|| {
-                let sets = tcx.lint_levels(LOCAL_CRATE);
-                let parent_hir_id = self.source_scope_local_data[source_scope].lint_root;
-                sets.lint_level_set(parent_hir_id) == sets.lint_level_set(current_hir_id)
-            });
-
-            if !same_lint_scopes {
-                self.source_scope =
-                    self.new_source_scope(region_scope.1.span, lint_level,
-                                          None);
+            // Use `maybe_lint_level_root_bounded` with `root_lint_level` as a bound
+            // to avoid adding Hir dependences on our parents.
+            // We estimate the true lint roots here to avoid creating a lot of source scopes.
+
+            let parent_root = tcx.maybe_lint_level_root_bounded(
+                self.source_scope_local_data[source_scope].lint_root,
+                self.hir.root_lint_level,
+            );
+            let current_root = tcx.maybe_lint_level_root_bounded(
+                current_hir_id,
+                self.hir.root_lint_level
+            );
+
+            if parent_root != current_root {
+                self.source_scope = self.new_source_scope(
+                    region_scope.1.span,
+                    LintLevel::Explicit(current_root),
+                    None
+                );
             }
         }
         self.push_scope(region_scope);
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 365cb508b09..71d9398c686 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -65,12 +65,12 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>(
 fn mplace_to_const<'tcx>(
     ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
     mplace: MPlaceTy<'tcx>,
-) -> EvalResult<'tcx, ty::Const<'tcx>> {
+) -> ty::Const<'tcx> {
     let MemPlace { ptr, align, meta } = *mplace;
     // extract alloc-offset pair
     assert!(meta.is_none());
-    let ptr = ptr.to_ptr()?;
-    let alloc = ecx.memory.get(ptr.alloc_id)?;
+    let ptr = ptr.to_ptr().unwrap();
+    let alloc = ecx.memory.get(ptr.alloc_id).unwrap();
     assert!(alloc.align >= align);
     assert!(alloc.bytes.len() as u64 - ptr.offset.bytes() >= mplace.layout.size.bytes());
     let mut alloc = alloc.clone();
@@ -79,16 +79,16 @@ fn mplace_to_const<'tcx>(
     // interned this?  I thought that is the entire point of that `FinishStatic` stuff?
     let alloc = ecx.tcx.intern_const_alloc(alloc);
     let val = ConstValue::ByRef(ptr, alloc);
-    Ok(ty::Const { val, ty: mplace.layout.ty })
+    ty::Const { val, ty: mplace.layout.ty }
 }
 
 fn op_to_const<'tcx>(
     ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
     op: OpTy<'tcx>,
-) -> EvalResult<'tcx, ty::Const<'tcx>> {
-    // We do not normalize just any data.  Only scalar layout and slices.
+) -> ty::Const<'tcx> {
+    // We do not normalize just any data.  Only non-union scalars and slices.
     let normalize = match op.layout.abi {
-        layout::Abi::Scalar(..) => true,
+        layout::Abi::Scalar(..) => op.layout.ty.ty_adt_def().map_or(true, |adt| !adt.is_union()),
         layout::Abi::ScalarPair(..) => op.layout.ty.is_slice(),
         _ => false,
     };
@@ -100,11 +100,11 @@ fn op_to_const<'tcx>(
     let val = match normalized_op {
         Ok(mplace) => return mplace_to_const(ecx, mplace),
         Err(Immediate::Scalar(x)) =>
-            ConstValue::Scalar(x.not_undef()?),
+            ConstValue::Scalar(x.not_undef().unwrap()),
         Err(Immediate::ScalarPair(a, b)) =>
-            ConstValue::Slice(a.not_undef()?, b.to_usize(ecx)?),
+            ConstValue::Slice(a.not_undef().unwrap(), b.to_usize(ecx).unwrap()),
     };
-    Ok(ty::Const { val, ty: op.layout.ty })
+    ty::Const { val, ty: op.layout.ty }
 }
 
 fn eval_body_and_ecx<'a, 'mir, 'tcx>(
@@ -142,7 +142,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
     assert!(!layout.is_unsized());
     let ret = ecx.allocate(layout, MemoryKind::Stack);
 
-    let name = ty::tls::with(|tcx| tcx.item_path_str(cid.instance.def_id()));
+    let name = ty::tls::with(|tcx| tcx.def_path_str(cid.instance.def_id()));
     let prom = cid.promoted.map_or(String::new(), |p| format!("::promoted[{:?}]", p));
     trace!("eval_body_using_ecx: pushing stack frame for global: {}{}", name, prom);
     assert!(mir.arg_count == 0);
@@ -488,7 +488,7 @@ pub fn const_field<'a, 'tcx>(
     let field = ecx.operand_field(down, field.index() as u64).unwrap();
     // and finally move back to the const world, always normalizing because
     // this is not called for statics.
-    op_to_const(&ecx, field).unwrap()
+    op_to_const(&ecx, field)
 }
 
 // this function uses `unwrap` copiously, because an already validated constant must have valid
@@ -534,9 +534,9 @@ fn validate_and_turn_into_const<'a, 'tcx>(
         // Now that we validated, turn this into a proper constant.
         let def_id = cid.instance.def.def_id();
         if tcx.is_static(def_id).is_some() || cid.promoted.is_some() {
-            mplace_to_const(&ecx, mplace)
+            Ok(mplace_to_const(&ecx, mplace))
         } else {
-            op_to_const(&ecx, mplace.into())
+            Ok(op_to_const(&ecx, mplace.into()))
         }
     })();
 
@@ -602,14 +602,15 @@ pub fn const_eval_raw_provider<'a, 'tcx>(
             other => return other,
         }
     }
-    // the first trace is for replicating an ice
-    // There's no tracking issue, but the next two lines concatenated link to the discussion on
-    // zulip. It's not really possible to test this, because it doesn't show up in diagnostics
-    // or MIR.
-    // https://rust-lang.zulipchat.com/#narrow/stream/146212-t-compiler.2Fconst-eval/
-    // subject/anon_const_instance_printing/near/135980032
-    trace!("const eval: {}", key.value.instance);
-    trace!("const eval: {:?}", key);
+    if cfg!(debug_assertions) {
+        // Make sure we format the instance even if we do not print it.
+        // This serves as a regression test against an ICE on printing.
+        // The next two lines concatenated contain some discussion:
+        // https://rust-lang.zulipchat.com/#narrow/stream/146212-t-compiler.2Fconst-eval/
+        // subject/anon_const_instance_printing/near/135980032
+        let instance = key.value.instance.to_string();
+        trace!("const eval: {:?} ({})", key, instance);
+    }
 
     let cid = key.value;
     let def_id = cid.instance.def.def_id();
diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs
index f58e61915e8..17fab6c5ddc 100644
--- a/src/librustc_mir/hair/cx/block.rs
+++ b/src/librustc_mir/hair/cx/block.rs
@@ -103,7 +103,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                         },
                         pattern,
                         initializer: local.init.to_ref(),
-                        lint_level: cx.lint_level_of(local.hir_id),
+                        lint_level: LintLevel::Explicit(local.hir_id),
                     },
                     opt_destruction_scope: opt_dxn_ext,
                     span: stmt_span,
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index ad0a22cc782..c8c6d73d453 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -44,7 +44,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
             kind: ExprKind::Scope {
                 region_scope: expr_scope,
                 value: expr.to_ref(),
-                lint_level: cx.lint_level_of(self.hir_id),
+                lint_level: LintLevel::Explicit(self.hir_id),
             },
         };
 
@@ -955,7 +955,8 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             let user_provided_types = cx.tables.user_provided_types();
             let user_provided_type = user_provided_types.get(expr.hir_id).map(|u_ty| *u_ty);
             debug!("convert_path_expr: user_provided_type={:?}", user_provided_type);
-            match cx.tables().node_type(expr.hir_id).sty {
+            let ty = cx.tables().node_type(expr.hir_id);
+            match ty.sty {
                 // A unit struct/variant which is used as a value.
                 // We return a completely different ExprKind here to account for this special case.
                 ty::Adt(adt_def, substs) => {
@@ -968,7 +969,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                         base: None,
                     }
                 }
-                ref sty => bug!("unexpected sty: {:?}", sty),
+                _ => bug!("unexpected ty: {:?}", ty),
             }
         }
 
diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs
index 8b16eeeea23..c0f3989b4ba 100644
--- a/src/librustc_mir/hair/cx/mod.rs
+++ b/src/librustc_mir/hair/cx/mod.rs
@@ -6,7 +6,7 @@ use crate::hair::*;
 use crate::hair::util::UserAnnotatedTyHelpers;
 
 use rustc_data_structures::indexed_vec::Idx;
-use rustc::hir::def_id::{DefId, LOCAL_CRATE};
+use rustc::hir::def_id::DefId;
 use rustc::hir::Node;
 use rustc::middle::region;
 use rustc::infer::InferCtxt;
@@ -76,11 +76,10 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
         // Constants always need overflow checks.
         check_overflow |= constness == hir::Constness::Const;
 
-        let lint_level = lint_level_for_hir_id(tcx, src_id);
         Cx {
             tcx,
             infcx,
-            root_lint_level: lint_level,
+            root_lint_level: src_id,
             param_env: tcx.param_env(src_def_id),
             identity_substs: InternalSubsts::identity_for_item(tcx.global_tcx(), src_def_id),
             region_scope_tree: tcx.region_scope_tree(src_def_id),
@@ -197,18 +196,6 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
         ty.needs_drop(self.tcx.global_tcx(), param_env)
     }
 
-    fn lint_level_of(&self, hir_id: hir::HirId) -> LintLevel {
-        let has_lint_level = self.tcx.dep_graph.with_ignore(|| {
-            self.tcx.lint_levels(LOCAL_CRATE).lint_level_set(hir_id).is_some()
-        });
-
-        if has_lint_level {
-            LintLevel::Explicit(hir_id)
-        } else {
-            LintLevel::Inherited
-        }
-    }
-
     pub fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
         self.tcx
     }
@@ -236,30 +223,6 @@ impl UserAnnotatedTyHelpers<'gcx, 'tcx> for Cx<'_, 'gcx, 'tcx> {
     }
 }
 
-fn lint_level_for_hir_id(tcx: TyCtxt<'_, '_, '_>, mut id: hir::HirId) -> hir::HirId {
-    // Right now we insert a `with_ignore` node in the dep graph here to
-    // ignore the fact that `lint_levels` below depends on the entire crate.
-    // For now this'll prevent false positives of recompiling too much when
-    // anything changes.
-    //
-    // Once red/green incremental compilation lands we should be able to
-    // remove this because while the crate changes often the lint level map
-    // will change rarely.
-    tcx.dep_graph.with_ignore(|| {
-        let sets = tcx.lint_levels(LOCAL_CRATE);
-        loop {
-            if sets.lint_level_set(id).is_some() {
-                return id
-            }
-            let next = tcx.hir().get_parent_node_by_hir_id(id);
-            if next == id {
-                bug!("lint traversal reached the root of the crate");
-            }
-            id = next;
-        }
-    })
-}
-
 mod block;
 mod expr;
 mod to_ref;
diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs
index 586a3fdb907..44bcb9de0e1 100644
--- a/src/librustc_mir/hair/pattern/_match.rs
+++ b/src/librustc_mir/hair/pattern/_match.rs
@@ -172,7 +172,7 @@ use rustc::ty::{self, subst::SubstsRef, Ty, TyCtxt, TypeFoldable, Const};
 use rustc::ty::layout::{Integer, IntegerExt, VariantIdx, Size};
 
 use rustc::mir::Field;
-use rustc::mir::interpret::{ConstValue, Scalar};
+use rustc::mir::interpret::{ConstValue, Scalar, truncate};
 use rustc::util::common::ErrorReported;
 
 use syntax::attr::{SignedInt, UnsignedInt};
@@ -678,16 +678,14 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
             ]
         }
         ty::Int(ity) => {
-            // FIXME(49937): refactor these bit manipulations into interpret.
             let bits = Integer::from_attr(&cx.tcx, SignedInt(ity)).size().bits() as u128;
             let min = 1u128 << (bits - 1);
-            let max = (1u128 << (bits - 1)) - 1;
+            let max = min - 1;
             vec![ConstantRange(min, max, pcx.ty, RangeEnd::Included)]
         }
         ty::Uint(uty) => {
-            // FIXME(49937): refactor these bit manipulations into interpret.
-            let bits = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size().bits() as u128;
-            let max = !0u128 >> (128 - bits);
+            let size = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size();
+            let max = truncate(u128::max_value(), size);
             vec![ConstantRange(0, max, pcx.ty, RangeEnd::Included)]
         }
         _ => {
diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index 41babc1ad12..49967df0889 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -319,7 +319,7 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pa
                     if edef.is_enum() && edef.variants.iter().any(|variant| {
                         variant.ident == ident && variant.ctor_kind == CtorKind::Const
                     }) {
-                        let ty_path = cx.tcx.item_path_str(edef.did);
+                        let ty_path = cx.tcx.def_path_str(edef.did);
                         let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170,
                             "pattern binding `{}` is named the same as one \
                             of the variants of the type `{}`",
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 67d40197290..ad7b45d8945 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -13,7 +13,7 @@ use crate::hair::constant::*;
 use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability};
 use rustc::mir::{UserTypeProjection};
 use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend};
-use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, Lift, UserType};
+use rustc::ty::{self, DefIdTree, Region, TyCtxt, AdtDef, Ty, Lift, UserType};
 use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations};
 use rustc::ty::subst::{SubstsRef, Kind};
 use rustc::ty::layout::VariantIdx;
@@ -529,11 +529,11 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
                     ty::Error => { // Avoid ICE
                         return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) };
                     }
-                    ref sty =>
+                    _ =>
                         span_bug!(
                             pat.span,
                             "unexpanded type for vector pattern: {:?}",
-                            sty),
+                            ty),
                 }
             }
 
@@ -554,7 +554,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
                     ty::Error => { // Avoid ICE (#50577)
                         return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) };
                     }
-                    ref sty => span_bug!(pat.span, "unexpected type for tuple pattern: {:?}", sty),
+                    _ => span_bug!(pat.span, "unexpected type for tuple pattern: {:?}", ty),
                 }
             }
 
@@ -608,7 +608,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
                     }
                     _ => span_bug!(pat.span,
                                    "tuple struct pattern not applied to an ADT {:?}",
-                                   ty.sty),
+                                   ty),
                 };
                 let variant_def = adt_def.variant_of_def(def);
 
@@ -735,7 +735,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
     ) -> PatternKind<'tcx> {
         let mut kind = match def {
             Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => {
-                let enum_id = self.tcx.parent_def_id(variant_id).unwrap();
+                let enum_id = self.tcx.parent(variant_id).unwrap();
                 let adt_def = self.tcx.adt_def(enum_id);
                 if adt_def.is_enum() {
                     let substs = match ty.sty {
@@ -744,7 +744,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
                         ty::Error => {  // Avoid ICE (#50585)
                             return PatternKind::Wild;
                         }
-                        _ => bug!("inappropriate type for def: {:?}", ty.sty),
+                        _ => bug!("inappropriate type for def: {:?}", ty),
                     };
                     PatternKind::Variant {
                         adt_def,
@@ -969,8 +969,8 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
             ty::Adt(adt_def, _) if !self.tcx.has_attr(adt_def.did, "structural_match") => {
                 let msg = format!("to use a constant of type `{}` in a pattern, \
                                     `{}` must be annotated with `#[derive(PartialEq, Eq)]`",
-                                    self.tcx.item_path_str(adt_def.did),
-                                    self.tcx.item_path_str(adt_def.did));
+                                    self.tcx.def_path_str(adt_def.did),
+                                    self.tcx.def_path_str(adt_def.did));
                 self.tcx.sess.span_err(span, &msg);
                 PatternKind::Wild
             }
diff --git a/src/librustc_mir/hair/util.rs b/src/librustc_mir/hair/util.rs
index 4618cd42686..c9dae699079 100644
--- a/src/librustc_mir/hair/util.rs
+++ b/src/librustc_mir/hair/util.rs
@@ -16,7 +16,8 @@ crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> {
         let user_provided_types = self.tables().user_provided_types();
         let mut user_ty = *user_provided_types.get(hir_id)?;
         debug!("user_subts_applied_to_ty_of_hir_id: user_ty={:?}", user_ty);
-        match &self.tables().node_type(hir_id).sty {
+        let ty = self.tables().node_type(hir_id);
+        match ty.sty {
             ty::Adt(adt_def, ..) => {
                 if let UserType::TypeOf(ref mut did, _) = &mut user_ty.value {
                     *did = adt_def.did;
@@ -24,8 +25,11 @@ crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> {
                 Some(user_ty)
             }
             ty::FnDef(..) => Some(user_ty),
-            sty =>
-                bug!("sty: {:?} should not have user provided type {:?} recorded ", sty, user_ty),
+            _ => bug!(
+                "ty: {:?} should not have user provided type {:?} recorded ",
+                ty,
+                user_ty
+            ),
         }
     }
 }
diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs
index 73c73cc23dc..7543dd678d0 100644
--- a/src/librustc_mir/interpret/cast.rs
+++ b/src/librustc_mir/interpret/cast.rs
@@ -90,7 +90,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
                         let fn_ptr = self.memory.create_fn_alloc(instance?).with_default_tag();
                         self.write_scalar(Scalar::Ptr(fn_ptr.into()), dest)?;
                     }
-                    ref other => bug!("reify fn pointer on {:?}", other),
+                    _ => bug!("reify fn pointer on {:?}", src.layout.ty),
                 }
             }
 
@@ -101,7 +101,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
                         // No change to value
                         self.write_immediate(*src, dest)?;
                     }
-                    ref other => bug!("fn to unsafe fn cast on {:?}", other),
+                    _ => bug!("fn to unsafe fn cast on {:?}", dest.layout.ty),
                 }
             }
 
@@ -120,7 +120,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
                         let val = Immediate::Scalar(Scalar::Ptr(fn_ptr.into()).into());
                         self.write_immediate(val, dest)?;
                     }
-                    ref other => bug!("closure fn pointer on {:?}", other),
+                    _ => bug!("closure fn pointer on {:?}", src.layout.ty),
                 }
             }
         }
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 8a32c3b636c..e81d0a56b2b 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -283,7 +283,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
             ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) {
                 Ok(self.tcx.optimized_mir(did))
             } else {
-                err!(NoMirFor(self.tcx.item_path_str(def_id)))
+                err!(NoMirFor(self.tcx.def_path_str(def_id)))
             },
             _ => Ok(self.tcx.instance_mir(instance)),
         }
@@ -450,7 +450,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
         return_place: Option<PlaceTy<'tcx, M::PointerTag>>,
         return_to_block: StackPopCleanup,
     ) -> EvalResult<'tcx> {
-        if self.stack.len() > 1 { // FIXME should be "> 0", printing topmost frame crashes rustc...
+        if self.stack.len() > 0 {
             info!("PAUSING({}) {}", self.cur_frame(), self.frame().instance);
         }
         ::log_settings::settings().indentation += 1;
@@ -525,9 +525,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
             self.frame_mut().locals = locals;
         }
 
-        if self.stack.len() > 1 { // FIXME no check should be needed, but some instances ICE
-            info!("ENTERING({}) {}", self.cur_frame(), self.frame().instance);
-        }
+        info!("ENTERING({}) {}", self.cur_frame(), self.frame().instance);
 
         if self.stack.len() > self.tcx.sess.const_eval_stack_frame_limit {
             err!(StackFrameLimitReached)
@@ -537,9 +535,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
     }
 
     pub(super) fn pop_stack_frame(&mut self) -> EvalResult<'tcx> {
-        if self.stack.len() > 1 { // FIXME no check should be needed, but some instances ICE
-            info!("LEAVING({}) {}", self.cur_frame(), self.frame().instance);
-        }
+        info!("LEAVING({}) {}", self.cur_frame(), self.frame().instance);
         ::log_settings::settings().indentation -= 1;
         let frame = self.stack.pop().expect(
             "tried to pop a stack frame, but there were none",
@@ -591,7 +587,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
             StackPopCleanup::None { .. } => {}
         }
 
-        if self.stack.len() > 1 { // FIXME should be "> 0", printing topmost frame crashes rustc...
+        if self.stack.len() > 0 {
             info!("CONTINUING({}) {}", self.cur_frame(), self.frame().instance);
         }
 
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 88b936afaa4..6ea200d4e4f 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -700,24 +700,29 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
         // relocations overlapping the edges; those would not be handled correctly).
         let relocations = {
             let relocations = self.get(src.alloc_id)?.relocations(self, src, size);
-            let mut new_relocations = Vec::with_capacity(relocations.len() * (length as usize));
-            for i in 0..length {
-                new_relocations.extend(
-                    relocations
-                    .iter()
-                    .map(|&(offset, reloc)| {
-                        // compute offset for current repetition
-                        let dest_offset = dest.offset + (i * size);
-                        (
-                            // shift offsets from source allocation to destination allocation
-                            offset + dest_offset - src.offset,
-                            reloc,
-                        )
-                    })
-                );
-            }
+            if relocations.is_empty() {
+                // nothing to copy, ignore even the `length` loop
+                Vec::new()
+            } else {
+                let mut new_relocations = Vec::with_capacity(relocations.len() * (length as usize));
+                for i in 0..length {
+                    new_relocations.extend(
+                        relocations
+                        .iter()
+                        .map(|&(offset, reloc)| {
+                            // compute offset for current repetition
+                            let dest_offset = dest.offset + (i * size);
+                            (
+                                // shift offsets from source allocation to destination allocation
+                                offset + dest_offset - src.offset,
+                                reloc,
+                            )
+                        })
+                    );
+                }
 
-            new_relocations
+                new_relocations
+            }
         };
 
         let tcx = self.tcx.tcx;
@@ -784,20 +789,65 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
         // The bits have to be saved locally before writing to dest in case src and dest overlap.
         assert_eq!(size.bytes() as usize as u64, size.bytes());
 
-        let undef_mask = self.get(src.alloc_id)?.undef_mask.clone();
-        let dest_allocation = self.get_mut(dest.alloc_id)?;
+        let undef_mask = &self.get(src.alloc_id)?.undef_mask;
+
+        // Since we are copying `size` bytes from `src` to `dest + i * size` (`for i in 0..repeat`),
+        // a naive undef mask copying algorithm would repeatedly have to read the undef mask from
+        // the source and write it to the destination. Even if we optimized the memory accesses,
+        // we'd be doing all of this `repeat` times.
+        // Therefor we precompute a compressed version of the undef mask of the source value and
+        // then write it back `repeat` times without computing any more information from the source.
+
+        // a precomputed cache for ranges of defined/undefined bits
+        // 0000010010001110 will become
+        // [5, 1, 2, 1, 3, 3, 1]
+        // where each element toggles the state
+        let mut ranges = smallvec::SmallVec::<[u64; 1]>::new();
+        let first = undef_mask.get(src.offset);
+        let mut cur_len = 1;
+        let mut cur = first;
+        for i in 1..size.bytes() {
+            // FIXME: optimize to bitshift the current undef block's bits and read the top bit
+            if undef_mask.get(src.offset + Size::from_bytes(i)) == cur {
+                cur_len += 1;
+            } else {
+                ranges.push(cur_len);
+                cur_len = 1;
+                cur = !cur;
+            }
+        }
 
-        for i in 0..size.bytes() {
-            let defined = undef_mask.get(src.offset + Size::from_bytes(i));
+        // now fill in all the data
+        let dest_allocation = self.get_mut(dest.alloc_id)?;
+        // an optimization where we can just overwrite an entire range of definedness bits if
+        // they are going to be uniformly `1` or `0`.
+        if ranges.is_empty() {
+            dest_allocation.undef_mask.set_range_inbounds(
+                dest.offset,
+                dest.offset + size * repeat,
+                first,
+            );
+            return Ok(())
+        }
 
-            for j in 0..repeat {
-                dest_allocation.undef_mask.set(
-                    dest.offset + Size::from_bytes(i + (size.bytes() * j)),
-                    defined
+        // remember to fill in the trailing bits
+        ranges.push(cur_len);
+
+        for mut j in 0..repeat {
+            j *= size.bytes();
+            j += dest.offset.bytes();
+            let mut cur = first;
+            for range in &ranges {
+                let old_j = j;
+                j += range;
+                dest_allocation.undef_mask.set_range_inbounds(
+                    Size::from_bytes(old_j),
+                    Size::from_bytes(j),
+                    cur,
                 );
+                cur = !cur;
             }
         }
-
         Ok(())
     }
 }
diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs
index b3b9c742d6c..944e393d296 100644
--- a/src/librustc_mir/interpret/operator.rs
+++ b/src/librustc_mir/interpret/operator.rs
@@ -336,7 +336,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
 
         let layout = val.layout;
         let val = val.to_scalar()?;
-        trace!("Running unary op {:?}: {:?} ({:?})", un_op, val, layout.ty.sty);
+        trace!("Running unary op {:?}: {:?} ({:?})", un_op, val, layout.ty);
 
         match layout.ty.sty {
             ty::Bool => {
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 4df274bc9df..755bbd96b02 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -354,7 +354,7 @@ where
             ty::Ref(_, _, mutbl) => Some(mutbl),
             ty::Adt(def, _) if def.is_box() => Some(hir::MutMutable),
             ty::RawPtr(_) => None,
-            _ => bug!("Unexpected pointer type {}", val.layout.ty.sty),
+            _ => bug!("Unexpected pointer type {}", val.layout.ty),
         };
         place.mplace.ptr = M::tag_dereference(self, place, mutbl)?;
         Ok(place)
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index 0b735b4b39c..c45e694ebf8 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -14,7 +14,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
 #![feature(const_fn)]
 #![feature(decl_macro)]
 #![feature(exhaustive_patterns)]
-#![feature(range_contains)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_attrs)]
 #![feature(never_type)]
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 1e245faddf0..307cee5d972 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -198,6 +198,8 @@ use crate::monomorphize::item::{MonoItemExt, DefPathBasedNames, InstantiationMod
 use rustc_data_structures::bit_set::GrowableBitSet;
 use rustc_data_structures::sync::{MTRef, MTLock, ParallelIterator, par_iter};
 
+use std::iter;
+
 #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
 pub enum MonoItemCollectionMode {
     Eager,
@@ -487,21 +489,33 @@ fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // We include the const length in the type length, as it's better
     // to be overly conservative.
     if type_length + const_length > type_length_limit {
-        // The instance name is already known to be too long for rustc. Use
-        // `{:.64}` to avoid blasting the user's terminal with thousands of
-        // lines of type-name.
-        let instance_name = instance.to_string();
-        let msg = format!("reached the type-length limit while instantiating `{:.64}...`",
-                          instance_name);
-        let mut diag = if let Some(hir_id) = tcx.hir().as_local_hir_id(instance.def_id()) {
-            tcx.sess.struct_span_fatal(tcx.hir().span_by_hir_id(hir_id), &msg)
-        } else {
-            tcx.sess.struct_fatal(&msg)
+        // The instance name is already known to be too long for rustc.
+        // Show only the first and last 32 characters to avoid blasting
+        // the user's terminal with thousands of lines of type-name.
+        let shrink = |s: String, before: usize, after: usize| {
+            // An iterator of all byte positions including the end of the string.
+            let positions = || s.char_indices().map(|(i, _)| i).chain(iter::once(s.len()));
+
+            let shrunk = format!(
+                "{before}...{after}",
+                before = &s[..positions().nth(before).unwrap_or(s.len())],
+                after = &s[positions().rev().nth(after).unwrap_or(0)..],
+            );
+
+            // Only use the shrunk version if it's really shorter.
+            // This also avoids the case where before and after slices overlap.
+            if shrunk.len() < s.len() {
+                shrunk
+            } else {
+                s
+            }
         };
-
+        let msg = format!("reached the type-length limit while instantiating `{}`",
+                          shrink(instance.to_string(), 32, 32));
+        let mut diag = tcx.sess.struct_span_fatal(tcx.def_span(instance.def_id()), &msg);
         diag.note(&format!(
             "consider adding a `#![type_length_limit=\"{}\"]` attribute to your crate",
-            type_length_limit * 2));
+            type_length));
         diag.emit();
         tcx.sess.abort_if_errors();
     }
@@ -836,7 +850,7 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             match tail.sty {
                 ty::Foreign(..) => false,
                 ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
-                _ => bug!("unexpected unsized tail: {:?}", tail.sty),
+                _ => bug!("unexpected unsized tail: {:?}", tail),
             }
         };
         if type_has_metadata(inner_source) {
diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs
index 211f9ad1735..68d13bf2dcb 100644
--- a/src/librustc_mir/monomorphize/item.rs
+++ b/src/librustc_mir/monomorphize/item.rs
@@ -216,9 +216,8 @@ impl<'a, 'tcx> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
 // 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 the
-//       ppaux module. It would be good to refactor things so we only have one
-//       parameterizable implementation for printing types.
+// Note: A lot of this could looks very similar to what's already in `ty::print`.
+// FIXME(eddyb) implement a custom `PrettyPrinter` for this.
 
 /// Same as `unique_type_name()` but with the result pushed onto the given
 /// `output` parameter.
diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs
index c0e2186d9f3..4a2c05b2013 100644
--- a/src/librustc_mir/monomorphize/partitioning.rs
+++ b/src/librustc_mir/monomorphize/partitioning.rs
@@ -104,7 +104,7 @@ use rustc::hir::map::DefPathData;
 use rustc::mir::mono::{Linkage, Visibility, CodegenUnitNameBuilder};
 use rustc::middle::exported_symbols::SymbolExportLevel;
 use rustc::ty::{self, TyCtxt, InstanceDef};
-use rustc::ty::item_path::characteristic_def_id_of_type;
+use rustc::ty::print::characteristic_def_id_of_type;
 use rustc::ty::query::Providers;
 use rustc::util::common::time;
 use rustc::util::nodemap::{DefIdSet, FxHashMap, FxHashSet};
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 97d566e586e..001a61959c2 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -1253,7 +1253,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                                     if !self.span.allows_unstable(&feature.as_str()) {
                                         let mut err = self.tcx.sess.struct_span_err(self.span,
                                             &format!("`{}` is not yet stable as a const fn",
-                                                    self.tcx.item_path_str(def_id)));
+                                                    self.tcx.def_path_str(def_id)));
                                         if nightly_options::is_nightly_build() {
                                             help!(&mut err,
                                                   "add `#![feature({})]` to the \
diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs
index f078316b97c..f9f8abbe6c0 100644
--- a/src/librustc_mir/transform/rustc_peek.rs
+++ b/src/librustc_mir/transform/rustc_peek.rs
@@ -29,10 +29,10 @@ impl MirPass for SanityCheck {
         let def_id = src.def_id();
         let id = tcx.hir().as_local_hir_id(def_id).unwrap();
         if !tcx.has_attr(def_id, "rustc_mir") {
-            debug!("skipping rustc_peek::SanityCheck on {}", tcx.item_path_str(def_id));
+            debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
             return;
         } else {
-            debug!("running rustc_peek::SanityCheck on {}", tcx.item_path_str(def_id));
+            debug!("running rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
         }
 
         let attributes = tcx.get_attrs(def_id);
diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs
index 61b1a5a850d..69a2adcfce0 100644
--- a/src/librustc_mir/util/graphviz.rs
+++ b/src/librustc_mir/util/graphviz.rs
@@ -127,7 +127,7 @@ fn write_graph_label<'a, 'gcx, 'tcx, W: Write>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                                                mir: &Mir<'_>,
                                                w: &mut W)
                                                -> io::Result<()> {
-    write!(w, "    label=<fn {}(", dot::escape_html(&tcx.item_path_str(def_id)))?;
+    write!(w, "    label=<fn {}(", dot::escape_html(&tcx.def_path_str(def_id)))?;
 
     // fn argument types.
     for (i, arg) in mir.args_iter().enumerate() {
@@ -141,7 +141,7 @@ fn write_graph_label<'a, 'gcx, 'tcx, W: Write>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
         )?;
     }
 
-    write!(w, ") -&gt; {}", escape(mir.return_ty()))?;
+    write!(w, ") -&gt; {}", escape(&mir.return_ty()))?;
     write!(w, r#"<br align="left"/>"#)?;
 
     for local in mir.vars_and_temps_iter() {
diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs
index d08fb40966c..cbdd50cf405 100644
--- a/src/librustc_mir/util/liveness.rs
+++ b/src/librustc_mir/util/liveness.rs
@@ -29,7 +29,7 @@ use rustc::mir::visit::{
 };
 use rustc::mir::Local;
 use rustc::mir::*;
-use rustc::ty::{item_path, TyCtxt};
+use rustc::ty::{self, TyCtxt};
 use rustc_data_structures::bit_set::BitSet;
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
 use rustc_data_structures::work_queue::WorkQueue;
@@ -265,9 +265,9 @@ pub fn dump_mir<'a, 'tcx>(
     if !dump_enabled(tcx, pass_name, source) {
         return;
     }
-    let node_path = item_path::with_forced_impl_filename_line(|| {
+    let node_path = ty::print::with_forced_impl_filename_line(|| {
         // see notes on #41697 below
-        tcx.item_path_str(source.def_id())
+        tcx.def_path_str(source.def_id())
     });
     dump_matched_mir_node(tcx, pass_name, &node_path, source, mir, result);
 }
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index c3fbee3a2a6..c7c77d351a7 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -1,8 +1,8 @@
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
+use rustc::hir::def::CtorKind;
 use rustc::mir::*;
 use rustc::mir::visit::Visitor;
 use rustc::ty::{self, TyCtxt};
-use rustc::ty::item_path;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::indexed_vec::Idx;
 use std::fmt::Display;
@@ -78,9 +78,9 @@ pub fn dump_mir<'a, 'gcx, 'tcx, F>(
         return;
     }
 
-    let node_path = item_path::with_forced_impl_filename_line(|| {
+    let node_path = ty::print::with_forced_impl_filename_line(|| {
         // see notes on #41697 below
-        tcx.item_path_str(source.def_id())
+        tcx.def_path_str(source.def_id())
     });
     dump_matched_mir_node(
         tcx,
@@ -103,9 +103,9 @@ pub fn dump_enabled<'a, 'gcx, 'tcx>(
         None => return false,
         Some(ref filters) => filters,
     };
-    let node_path = item_path::with_forced_impl_filename_line(|| {
+    let node_path = ty::print::with_forced_impl_filename_line(|| {
         // see notes on #41697 below
-        tcx.item_path_str(source.def_id())
+        tcx.def_path_str(source.def_id())
     });
     filters.split('|').any(|or_filter| {
         or_filter.split('&').all(|and_filter| {
@@ -115,7 +115,7 @@ pub fn dump_enabled<'a, 'gcx, 'tcx>(
 }
 
 // #41697 -- we use `with_forced_impl_filename_line()` because
-// `item_path_str()` would otherwise trigger `type_of`, and this can
+// `def_path_str()` would otherwise trigger `type_of`, and this can
 // run while we are already attempting to evaluate `type_of`.
 
 fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
@@ -597,7 +597,8 @@ fn write_mir_sig(
     trace!("write_mir_sig: {:?}", src.instance);
     let descr = tcx.describe_def(src.def_id());
     let is_function = match descr {
-        Some(Def::Fn(_)) | Some(Def::Method(_)) | Some(Def::StructCtor(..)) => true,
+        Some(Def::Fn(_)) | Some(Def::Method(_)) | Some(Def::Variant(..)) |
+        Some(Def::StructCtor(_, CtorKind::Fn)) => true,
         _ => tcx.is_closure(src.def_id()),
     };
     match (descr, src.promoted) {
@@ -612,9 +613,9 @@ fn write_mir_sig(
         _ => bug!("Unexpected def description {:?}", descr),
     }
 
-    item_path::with_forced_impl_filename_line(|| {
+    ty::print::with_forced_impl_filename_line(|| {
         // see notes on #41697 elsewhere
-        write!(w, "{}", tcx.item_path_str(src.def_id()))
+        write!(w, " {}", tcx.def_path_str(src.def_id()))
     })?;
 
     if src.promoted.is_none() && is_function {
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 52514a3ca97..5065c1de97b 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -134,7 +134,7 @@ impl<'a, 'tcx, V> TypeVisitor<'tcx> for DefIdVisitorSkeleton<'_, 'a, 'tcx, V>
             ty::FnDef(def_id, ..) |
             ty::Closure(def_id, ..) |
             ty::Generator(def_id, ..) => {
-                if self.def_id_visitor.visit_def_id(def_id, "type", ty) {
+                if self.def_id_visitor.visit_def_id(def_id, "type", &ty) {
                     return true;
                 }
                 if self.def_id_visitor.shallow() {
@@ -816,7 +816,7 @@ impl<'a, 'tcx> NamePrivacyVisitor<'a, 'tcx> {
         let def_id = self.tcx.adjust_ident(ident, def.did, current_hir).1;
         if !def.is_enum() && !field.vis.is_accessible_from(def_id, self.tcx) {
             struct_span_err!(self.tcx.sess, span, E0451, "field `{}` of {} `{}` is private",
-                             field.ident, def.variant_descr(), self.tcx.item_path_str(def.did))
+                             field.ident, def.variant_descr(), self.tcx.def_path_str(def.did))
                 .span_label(span, format!("field `{}` is private", field.ident))
                 .emit();
         }
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index b82aee7c96a..3fea515ae40 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -17,7 +17,7 @@ use rustc::hir::def::Def as HirDef;
 use rustc::hir::def_id::DefId;
 use rustc::session::config::Input;
 use rustc::span_bug;
-use rustc::ty::{self, TyCtxt};
+use rustc::ty::{self, DefIdTree, TyCtxt};
 use rustc_data_structures::fx::FxHashSet;
 
 use std::path::Path;
@@ -429,7 +429,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
         vis: ast::Visibility,
         attrs: &'l [Attribute],
     ) {
-        let qualname = format!("::{}", self.tcx.node_path_str(id));
+        let qualname = format!("::{}",
+            self.tcx.def_path_str(self.tcx.hir().local_def_id(id)));
 
         if !self.span.filter_generated(ident.span) {
             let sig = sig::assoc_const_signature(id, ident.name, typ, expr, &self.save_ctxt);
@@ -470,7 +471,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
     ) {
         debug!("process_struct {:?} {:?}", item, item.span);
         let name = item.ident.to_string();
-        let qualname = format!("::{}", self.tcx.node_path_str(item.id));
+        let qualname = format!("::{}",
+            self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
 
         let kind = match item.node {
             ast::ItemKind::Struct(_, _) => DefKind::Struct,
@@ -682,7 +684,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
         methods: &'l [ast::TraitItem],
     ) {
         let name = item.ident.to_string();
-        let qualname = format!("::{}", self.tcx.node_path_str(item.id));
+        let qualname = format!("::{}",
+            self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
         let mut val = name.clone();
         if !generics.params.is_empty() {
             val.push_str(&generic_params_to_string(&generics.params));
@@ -1093,7 +1096,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
             ast::TraitItemKind::Type(ref bounds, ref default_ty) => {
                 // FIXME do something with _bounds (for type refs)
                 let name = trait_item.ident.name.to_string();
-                let qualname = format!("::{}", self.tcx.node_path_str(trait_item.id));
+                let qualname = format!("::{}",
+                    self.tcx.def_path_str(self.tcx.hir().local_def_id(trait_item.id)));
 
                 if !self.span.filter_generated(trait_item.ident.span) {
                     let span = self.span_from_span(trait_item.ident.span);
@@ -1201,7 +1205,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
 
         // The parent def id of a given use tree is always the enclosing item.
         let parent = self.save_ctxt.tcx.hir().opt_local_def_id(id)
-            .and_then(|id| self.save_ctxt.tcx.parent_def_id(id))
+            .and_then(|id| self.save_ctxt.tcx.parent(id))
             .map(id_from_def_id);
 
         match use_tree.kind {
@@ -1300,7 +1304,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
         // only get called for the root module of a crate.
         assert_eq!(id, ast::CRATE_NODE_ID);
 
-        let qualname = format!("::{}", self.tcx.node_path_str(id));
+        let qualname = format!("::{}",
+            self.tcx.def_path_str(self.tcx.hir().local_def_id(id)));
 
         let cm = self.tcx.sess.source_map();
         let filename = cm.span_to_filename(span);
@@ -1350,7 +1355,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
                 if !self.span.filter_generated(name_span) {
                     let span = self.span_from_span(name_span);
                     let parent = self.save_ctxt.tcx.hir().opt_local_def_id(item.id)
-                        .and_then(|id| self.save_ctxt.tcx.parent_def_id(id))
+                        .and_then(|id| self.save_ctxt.tcx.parent(id))
                         .map(id_from_def_id);
                     self.dumper.import(
                         &Access {
@@ -1389,7 +1394,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
                 self.nest_scope(item.id, |v| visit::walk_mod(v, m));
             }
             Ty(ref ty, ref ty_params) => {
-                let qualname = format!("::{}", self.tcx.node_path_str(item.id));
+                let qualname = format!("::{}",
+                    self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
                 let value = ty_to_string(&ty);
                 if !self.span.filter_generated(item.ident.span) {
                     let span = self.span_from_span(item.ident.span);
@@ -1418,7 +1424,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
                 self.process_generic_params(ty_params, &qualname, item.id);
             }
             Existential(ref _bounds, ref ty_params) => {
-                let qualname = format!("::{}", self.tcx.node_path_str(item.id));
+                let qualname = format!("::{}",
+                    self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
                 // FIXME do something with _bounds
                 let value = String::new();
                 if !self.span.filter_generated(item.ident.span) {
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index d80f3e5ce75..7ad5b7ce8c7 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -20,7 +20,7 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::middle::privacy::AccessLevels;
 use rustc::middle::cstore::ExternCrate;
 use rustc::session::config::{CrateType, Input, OutputType};
-use rustc::ty::{self, TyCtxt};
+use rustc::ty::{self, DefIdTree, TyCtxt};
 use rustc::{bug, span_bug};
 use rustc_typeck::hir_ty_to_ty;
 use rustc_codegen_utils::link::{filename_for_metadata, out_filename};
@@ -134,7 +134,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
     }
 
     pub fn get_extern_item_data(&self, item: &ast::ForeignItem) -> Option<Data> {
-        let qualname = format!("::{}", self.tcx.node_path_str(item.id));
+        let qualname = format!("::{}",
+            self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
         match item.node {
             ast::ForeignItemKind::Fn(ref decl, ref generics) => {
                 filter!(self.span_utils, item.ident.span);
@@ -184,7 +185,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
     pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
         match item.node {
             ast::ItemKind::Fn(ref decl, .., ref generics, _) => {
-                let qualname = format!("::{}", self.tcx.node_path_str(item.id));
+                let qualname = format!("::{}",
+                    self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
                 filter!(self.span_utils, item.ident.span);
                 Some(Data::DefData(Def {
                     kind: DefKind::Function,
@@ -202,7 +204,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                 }))
             }
             ast::ItemKind::Static(ref typ, ..) => {
-                let qualname = format!("::{}", self.tcx.node_path_str(item.id));
+                let qualname = format!("::{}",
+                    self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
 
                 filter!(self.span_utils, item.ident.span);
 
@@ -225,7 +228,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                 }))
             }
             ast::ItemKind::Const(ref typ, _) => {
-                let qualname = format!("::{}", self.tcx.node_path_str(item.id));
+                let qualname = format!("::{}",
+                    self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
                 filter!(self.span_utils, item.ident.span);
 
                 let id = id_from_node_id(item.id, self);
@@ -247,7 +251,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                 }))
             }
             ast::ItemKind::Mod(ref m) => {
-                let qualname = format!("::{}", self.tcx.node_path_str(item.id));
+                let qualname = format!("::{}",
+                    self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
 
                 let cm = self.tcx.sess.source_map();
                 let filename = cm.span_to_filename(m.inner);
@@ -274,7 +279,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
             }
             ast::ItemKind::Enum(ref def, _) => {
                 let name = item.ident.to_string();
-                let qualname = format!("::{}", self.tcx.node_path_str(item.id));
+                let qualname = format!("::{}",
+                    self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
                 filter!(self.span_utils, item.ident.span);
                 let variants_str = def.variants
                     .iter()
@@ -358,7 +364,9 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
     pub fn get_field_data(&self, field: &ast::StructField, scope: NodeId) -> Option<Def> {
         if let Some(ident) = field.ident {
             let name = ident.to_string();
-            let qualname = format!("::{}::{}", self.tcx.node_path_str(scope), ident);
+            let qualname = format!("::{}::{}",
+                self.tcx.def_path_str(self.tcx.hir().local_def_id(scope)),
+                ident);
             filter!(self.span_utils, ident.span);
             let def_id = self.tcx.hir().local_def_id(field.id);
             let typ = self.tcx.type_of(def_id).to_string();
@@ -411,7 +419,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                             if let Some(def_id) = trait_id {
                                 // A method in a trait impl.
                                 qualname.push_str(" as ");
-                                qualname.push_str(&self.tcx.item_path_str(def_id));
+                                qualname.push_str(&self.tcx.def_path_str(def_id));
                                 self.tcx
                                     .associated_items(def_id)
                                     .find(|item| item.ident.name == ident.name)
@@ -451,7 +459,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                         }
 
                         (
-                            format!("::{}", self.tcx.item_path_str(def_id)),
+                            format!("::{}", self.tcx.def_path_str(def_id)),
                             Some(def_id),
                             None,
                             docs,
@@ -763,7 +771,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                 // This is a reference to a tuple struct where the def_id points
                 // to an invisible constructor function. That is not a very useful
                 // def, so adjust to point to the tuple struct itself.
-                let parent_def_id = self.tcx.parent_def_id(def_id).unwrap();
+                let parent_def_id = self.tcx.parent(def_id).unwrap();
                 Some(Ref {
                     kind: RefKind::Type,
                     span,
diff --git a/src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs b/src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs
new file mode 100644
index 00000000000..f4729145849
--- /dev/null
+++ b/src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs
@@ -0,0 +1,23 @@
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    Ok(Target {
+        llvm_target: "mipsisa32r6-unknown-linux-gnu".to_string(),
+        target_endian: "big".to_string(),
+        target_pointer_width: "32".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(),
+        arch: "mips".to_string(),
+        target_os: "linux".to_string(),
+        target_env: "gnu".to_string(),
+        target_vendor: "unknown".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+        options: TargetOptions {
+            cpu: "mips32r6".to_string(),
+            features: "+mips32r6".to_string(),
+            max_atomic_width: Some(32),
+
+            ..super::linux_base::opts()
+        },
+    })
+}
diff --git a/src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs b/src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs
new file mode 100644
index 00000000000..f4f98d33571
--- /dev/null
+++ b/src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs
@@ -0,0 +1,24 @@
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    Ok(Target {
+        llvm_target: "mipsisa32r6el-unknown-linux-gnu".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "32".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(),
+        arch: "mips".to_string(),
+        target_os: "linux".to_string(),
+        target_env: "gnu".to_string(),
+        target_vendor: "unknown".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+
+        options: TargetOptions {
+            cpu: "mips32r6".to_string(),
+            features: "+mips32r6".to_string(),
+            max_atomic_width: Some(32),
+
+            ..super::linux_base::opts()
+        },
+    })
+}
diff --git a/src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs b/src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs
new file mode 100644
index 00000000000..7faed3adc79
--- /dev/null
+++ b/src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs
@@ -0,0 +1,24 @@
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    Ok(Target {
+        llvm_target: "mipsisa64r6-unknown-linux-gnuabi64".to_string(),
+        target_endian: "big".to_string(),
+        target_pointer_width: "64".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
+        arch: "mips64".to_string(),
+        target_os: "linux".to_string(),
+        target_env: "gnu".to_string(),
+        target_vendor: "unknown".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+        options: TargetOptions {
+            // NOTE(mips64r6) matches C toolchain
+            cpu: "mips64r6".to_string(),
+            features: "+mips64r6".to_string(),
+            max_atomic_width: Some(64),
+
+            ..super::linux_base::opts()
+        },
+    })
+}
diff --git a/src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs b/src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs
new file mode 100644
index 00000000000..58a814a759e
--- /dev/null
+++ b/src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs
@@ -0,0 +1,24 @@
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    Ok(Target {
+        llvm_target: "mipsisa64r6el-unknown-linux-gnuabi64".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "64".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
+        arch: "mips64".to_string(),
+        target_os: "linux".to_string(),
+        target_env: "gnu".to_string(),
+        target_vendor: "unknown".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+        options: TargetOptions {
+            // NOTE(mips64r6) matches C toolchain
+            cpu: "mips64r6".to_string(),
+            features: "+mips64r6".to_string(),
+            max_atomic_width: Some(64),
+
+            ..super::linux_base::opts()
+        },
+    })
+}
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 2824d9cb6c3..fdb1db645c3 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -335,6 +335,10 @@ supported_targets! {
     ("mips-unknown-linux-gnu", mips_unknown_linux_gnu),
     ("mips64-unknown-linux-gnuabi64", mips64_unknown_linux_gnuabi64),
     ("mips64el-unknown-linux-gnuabi64", mips64el_unknown_linux_gnuabi64),
+    ("mipsisa32r6-unknown-linux-gnu", mipsisa32r6_unknown_linux_gnu),
+    ("mipsisa32r6el-unknown-linux-gnu", mipsisa32r6el_unknown_linux_gnu),
+    ("mipsisa64r6-unknown-linux-gnuabi64", mipsisa64r6_unknown_linux_gnuabi64),
+    ("mipsisa64r6el-unknown-linux-gnuabi64", mipsisa64r6el_unknown_linux_gnuabi64),
     ("mipsel-unknown-linux-gnu", mipsel_unknown_linux_gnu),
     ("powerpc-unknown-linux-gnu", powerpc_unknown_linux_gnu),
     ("powerpc-unknown-linux-gnuspe", powerpc_unknown_linux_gnuspe),
diff --git a/src/librustc_target/spec/uefi_base.rs b/src/librustc_target/spec/uefi_base.rs
index 631966c09a4..956767a22a0 100644
--- a/src/librustc_target/spec/uefi_base.rs
+++ b/src/librustc_target/spec/uefi_base.rs
@@ -59,7 +59,7 @@ pub fn opts() -> TargetOptions {
         singlethread: true,
         emit_debug_gdb_scripts: false,
 
-        linker: Some("lld-link".to_string()),
+        linker: Some("rust-lld".to_string()),
         lld_flavor: LldFlavor::Link,
         pre_link_args,
 
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 89ec92a6521..9ca75566b42 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -12,7 +12,7 @@ use crate::middle::resolve_lifetime as rl;
 use crate::namespace::Namespace;
 use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
 use rustc::traits;
-use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
+use rustc::ty::{self, DefIdTree, Ty, TyCtxt, ToPredicate, TypeFoldable};
 use rustc::ty::{GenericParamDef, GenericParamDefKind};
 use rustc::ty::subst::{Kind, Subst, InternalSubsts, SubstsRef};
 use rustc::ty::wf::object_region_bounds;
@@ -922,7 +922,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
                                      "the value of the associated type `{}` (from the trait `{}`) \
                                       is already specified",
                                      binding.item_name,
-                                     tcx.item_path_str(assoc_ty.container.id()))
+                                     tcx.def_path_str(assoc_ty.container.id()))
                         .span_label(binding.span, "re-bound here")
                         .span_label(*prev_span, format!("`{}` bound here first", binding.item_name))
                         .emit();
@@ -959,7 +959,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
     /// removing the dummy `Self` type (`TRAIT_OBJECT_DUMMY_SELF`).
     fn trait_ref_to_existential(&self, trait_ref: ty::TraitRef<'tcx>)
                                 -> ty::ExistentialTraitRef<'tcx> {
-        assert_eq!(trait_ref.self_ty().sty, TRAIT_OBJECT_DUMMY_SELF);
+        if trait_ref.self_ty().sty != TRAIT_OBJECT_DUMMY_SELF {
+            bug!("trait_ref_to_existential called on {:?} with non-dummy Self", trait_ref);
+        }
         ty::ExistentialTraitRef::erase_self_ty(self.tcx(), trait_ref)
     }
 
@@ -1069,7 +1071,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
                 format!(
                     "`{}` (from the trait `{}`)",
                     assoc_item.ident,
-                    tcx.item_path_str(trait_def_id),
+                    tcx.def_path_str(trait_def_id),
                 )
             }).collect::<Vec<_>>().join(", ");
             let mut err = struct_span_err!(
@@ -1450,14 +1452,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
                    -> Ty<'tcx>
     {
         let tcx = self.tcx();
-        let trait_def_id = tcx.parent_def_id(item_def_id).unwrap();
+        let trait_def_id = tcx.parent(item_def_id).unwrap();
 
         self.prohibit_generics(slice::from_ref(item_segment));
 
         let self_ty = if let Some(ty) = opt_self_ty {
             ty
         } else {
-            let path_str = tcx.item_path_str(trait_def_id);
+            let path_str = tcx.def_path_str(trait_def_id);
             self.report_ambiguous_associated_type(span,
                                                   "Type",
                                                   &path_str,
@@ -1619,7 +1621,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
                 } else if last >= 1 && segments[last - 1].args.is_some() {
                     // Everything but the penultimate segment should have no
                     // parameters at all.
-                    let enum_def_id = tcx.parent_def_id(def_id).unwrap();
+                    let enum_def_id = tcx.parent(def_id).unwrap();
                     (enum_def_id, last - 1)
                 } else {
                     // FIXME: lint here recommending `Enum::<...>::Variant` form
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 1a3ade7f8ba..c6b66393dd2 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -88,7 +88,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             // See the examples in `run-pass/match-defbm*.rs`.
             let mut pat_adjustments = vec![];
             while let ty::Ref(_, inner_ty, inner_mutability) = exp_ty.sty {
-                debug!("inspecting {:?} with type {:?}", exp_ty, exp_ty.sty);
+                debug!("inspecting {:?}", exp_ty);
 
                 debug!("current discriminant is Ref, inserting implicit deref");
                 // Preserve the reference type. We'll need it later during HAIR lowering.
@@ -894,7 +894,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
                 subpats.len() < variant.fields.len() && ddpos.is_some() {
             let substs = match pat_ty.sty {
                 ty::Adt(_, substs) => substs,
-                ref ty => bug!("unexpected pattern type {:?}", ty),
+                _ => bug!("unexpected pattern type {:?}", pat_ty),
             };
             for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
                 let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
@@ -1001,13 +1001,13 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
                                            E0026,
                                            "{} `{}` does not have {}",
                                            kind_name,
-                                           tcx.item_path_str(variant.did),
+                                           tcx.def_path_str(variant.did),
                                            field_names);
             if let Some((span, ident)) = inexistent_fields.last() {
                 err.span_label(*span,
                                format!("{} `{}` does not have {} field{}",
                                        kind_name,
-                                       tcx.item_path_str(variant.did),
+                                       tcx.def_path_str(variant.did),
                                        t,
                                        plural));
                 if plural == "" {
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index f79bf4e999d..e6e5c46c473 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -719,7 +719,7 @@ fn compare_number_of_method_arguments<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                         trait `{}` has {}",
                                        trait_m.ident,
                                        potentially_plural_count(impl_number_args, "parameter"),
-                                       tcx.item_path_str(trait_m.def_id),
+                                       tcx.def_path_str(trait_m.def_id),
                                        trait_number_args);
         if let Some(trait_span) = trait_span {
             err.span_label(trait_span, format!("trait requires {}",
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 32ca854b277..3a7308d0917 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -130,7 +130,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         let sole_field = &variant.fields[0];
                         let sole_field_ty = sole_field.ty(self.tcx, substs);
                         if self.can_coerce(expr_ty, sole_field_ty) {
-                            let variant_path = self.tcx.item_path_str(variant.did);
+                            let variant_path = self.tcx.def_path_str(variant.did);
                             // FIXME #56861: DRYer prelude filtering
                             Some(variant_path.trim_start_matches("std::prelude::v1::").to_string())
                         } else {
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index efae870c3c3..1f0ab3abb28 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -1195,7 +1195,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
         // `report_method_error()`.
         diag.help(&format!(
             "call with fully qualified syntax `{}(...)` to keep using the current method",
-            self.tcx.item_path_str(stable_pick.item.def_id),
+            self.tcx.def_path_str(stable_pick.item.def_id),
         ));
 
         if nightly_options::is_nightly_build() {
@@ -1203,7 +1203,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
                 diag.help(&format!(
                     "add #![feature({})] to the crate attributes to enable `{}`",
                     feature,
-                    self.tcx.item_path_str(candidate.item.def_id),
+                    self.tcx.def_path_str(candidate.item.def_id),
                 ));
             }
         }
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 4bf6471a629..b4a1a2d76c2 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -15,7 +15,7 @@ use rustc::hir::print;
 use rustc::infer::type_variable::TypeVariableOrigin;
 use rustc::traits::Obligation;
 use rustc::ty::{self, Adt, Ty, TyCtxt, ToPolyTraitRef, ToPredicate, TypeFoldable};
-use rustc::ty::item_path::with_crate_prefix;
+use rustc::ty::print::with_crate_prefix;
 use syntax_pos::{Span, FileName};
 use syntax::ast;
 use syntax::util::lev_distance::find_best_match_for_name;
@@ -102,7 +102,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                             None => String::new(),
                             Some(trait_ref) => {
                                 format!(" of the trait `{}`",
-                                        self.tcx.item_path_str(trait_ref.def_id))
+                                        self.tcx.def_path_str(trait_ref.def_id))
                             }
                         };
 
@@ -135,16 +135,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                        item_span,
                                        "candidate #{} is defined in the trait `{}`",
                                        idx + 1,
-                                       self.tcx.item_path_str(trait_did));
+                                       self.tcx.def_path_str(trait_did));
                         } else {
                             span_note!(err,
                                        item_span,
                                        "the candidate is defined in the trait `{}`",
-                                       self.tcx.item_path_str(trait_did));
+                                       self.tcx.def_path_str(trait_did));
                         }
                         err.help(&format!("to disambiguate the method call, write `{}::{}({}{})` \
                                           instead",
-                                          self.tcx.item_path_str(trait_did),
+                                          self.tcx.def_path_str(trait_did),
                                           item_name,
                                           if rcvr_ty.is_region_ptr() && args.is_some() {
                                               if rcvr_ty.is_mutable_pointer() {
@@ -516,7 +516,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 };
                 format!(
                     "use {};\n{}",
-                    with_crate_prefix(|| self.tcx.item_path_str(*did)),
+                    with_crate_prefix(|| self.tcx.def_path_str(*did)),
                     additional_newline
                 )
             });
@@ -530,14 +530,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         &format!(
                             "\ncandidate #{}: `use {};`",
                             i + 1,
-                            with_crate_prefix(|| self.tcx.item_path_str(*trait_did))
+                            with_crate_prefix(|| self.tcx.def_path_str(*trait_did))
                         )
                     );
                 } else {
                     msg.push_str(
                         &format!(
                             "\n`use {};`",
-                            with_crate_prefix(|| self.tcx.item_path_str(*trait_did))
+                            with_crate_prefix(|| self.tcx.def_path_str(*trait_did))
                         )
                     );
                 }
@@ -638,7 +638,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             for (i, trait_info) in candidates.iter().enumerate() {
                 msg.push_str(&format!("\ncandidate #{}: `{}`",
                                       i + 1,
-                                      self.tcx.item_path_str(trait_info.def_id)));
+                                      self.tcx.def_path_str(trait_info.def_id)));
             }
             err.note(&msg[..]);
         }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 28c79ce0c74..fa4bb02189f 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1328,7 +1328,7 @@ pub fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Ite
     debug!(
         "check_item_type(it.hir_id={}, it.name={})",
         it.hir_id,
-        tcx.item_path_str(tcx.hir().local_def_id_from_hir_id(it.hir_id))
+        tcx.def_path_str(tcx.hir().local_def_id_from_hir_id(it.hir_id))
     );
     let _indenter = indenter();
     match it.node {
@@ -3534,7 +3534,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         autoderef.unambiguous_final_ty(self);
 
         if let Some((did, field_ty)) = private_candidate {
-            let struct_path = self.tcx().item_path_str(did);
+            let struct_path = self.tcx().def_path_str(did);
             let mut err = struct_span_err!(self.tcx().sess, expr.span, E0616,
                                            "field `{}` of struct `{}` is private",
                                            field, struct_path);
@@ -3885,7 +3885,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     ty::Adt(adt, substs) => {
                         Some((adt.variant_of_def(def), adt.did, substs))
                     }
-                    _ => bug!("unexpected type: {:?}", ty.sty)
+                    _ => bug!("unexpected type: {:?}", ty)
                 }
             }
             Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) |
@@ -5226,8 +5226,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.node);
                 let sp = ty.span;
                 let ty = AstConv::ast_ty_to_ty(self, ty);
-                debug!("suggest_missing_return_type: return type sty {:?}", ty.sty);
-                debug!("suggest_missing_return_type: expected type sty {:?}", ty.sty);
+                debug!("suggest_missing_return_type: return type {:?}", ty);
+                debug!("suggest_missing_return_type: expected type {:?}", ty);
                 if ty.sty == expected.sty {
                     err.span_label(sp, format!("expected `{}` because of return type",
                                                expected));
@@ -5288,6 +5288,53 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         Some(original_span.with_lo(original_span.hi() - BytePos(1)))
     }
 
+    // Rewrite `SelfCtor` to `StructCtor`
+    pub fn rewrite_self_ctor(&self, def: Def, span: Span) -> (Def, DefId, Ty<'tcx>) {
+        let tcx = self.tcx;
+        if let Def::SelfCtor(impl_def_id) = def {
+            let ty = self.impl_self_ty(span, impl_def_id).ty;
+            let adt_def = ty.ty_adt_def();
+
+            match adt_def {
+                Some(adt_def) if adt_def.has_ctor() => {
+                    let variant = adt_def.non_enum_variant();
+                    let def = Def::StructCtor(variant.did, variant.ctor_kind);
+                    (def, variant.did, tcx.type_of(variant.did))
+                }
+                _ => {
+                    let mut err = tcx.sess.struct_span_err(span,
+                        "the `Self` constructor can only be used with tuple or unit structs");
+                    if let Some(adt_def) = adt_def {
+                        match adt_def.adt_kind() {
+                            AdtKind::Enum => {
+                                err.help("did you mean to use one of the enum's variants?");
+                            },
+                            AdtKind::Struct |
+                            AdtKind::Union => {
+                                err.span_suggestion(
+                                    span,
+                                    "use curly brackets",
+                                    String::from("Self { /* fields */ }"),
+                                    Applicability::HasPlaceholders,
+                                );
+                            }
+                        }
+                    }
+                    err.emit();
+
+                    (def, impl_def_id, tcx.types.err)
+                }
+            }
+        } else {
+            let def_id = def.def_id();
+
+            // The things we are substituting into the type should not contain
+            // escaping late-bound regions, and nor should the base type scheme.
+            let ty = tcx.type_of(def_id);
+            (def, def_id, ty)
+        }
+    }
+
     // Instantiates the given path, which must refer to an item with the given
     // number of type parameters and type.
     pub fn instantiate_value_path(&self,
@@ -5307,6 +5354,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
         let tcx = self.tcx;
 
+        match def {
+            Def::Local(nid) | Def::Upvar(nid, ..) => {
+                let hid = self.tcx.hir().node_to_hir_id(nid);
+                let ty = self.local_ty(span, hid).decl_ty;
+                let ty = self.normalize_associated_types_in(span, &ty);
+                self.write_ty(hir_id, ty);
+                return (ty, def);
+            }
+            _ => {}
+        }
+
+        let (def, def_id, ty) = self.rewrite_self_ctor(def, span);
         let path_segs = AstConv::def_ids_for_path_segments(self, segments, self_ty, def);
 
         let mut user_self_ty = None;
@@ -5368,17 +5427,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             user_self_ty = None;
         }
 
-        match def {
-            Def::Local(nid) | Def::Upvar(nid, ..) => {
-                let hid = self.tcx.hir().node_to_hir_id(nid);
-                let ty = self.local_ty(span, hid).decl_ty;
-                let ty = self.normalize_associated_types_in(span, &ty);
-                self.write_ty(hir_id, ty);
-                return (ty, def);
-            }
-            _ => {}
-        }
-
         // Now we have to compare the types that the user *actually*
         // provided against the types that were *expected*. If the user
         // did not provide any types, then we want to substitute inference
@@ -5411,53 +5459,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             tcx.generics_of(*def_id).has_self
         }).unwrap_or(false);
 
-        let mut new_def = def;
-        let (def_id, ty) = match def {
-            Def::SelfCtor(impl_def_id) => {
-                let ty = self.impl_self_ty(span, impl_def_id).ty;
-                let adt_def = ty.ty_adt_def();
-
-                match adt_def {
-                    Some(adt_def) if adt_def.has_ctor() => {
-                        let variant = adt_def.non_enum_variant();
-                        new_def = Def::StructCtor(variant.did, variant.ctor_kind);
-                        (variant.did, tcx.type_of(variant.did))
-                    }
-                    _ => {
-                        let mut err = tcx.sess.struct_span_err(span,
-                            "the `Self` constructor can only be used with tuple or unit structs");
-                        if let Some(adt_def) = adt_def {
-                            match adt_def.adt_kind() {
-                                AdtKind::Enum => {
-                                    err.help("did you mean to use one of the enum's variants?");
-                                },
-                                AdtKind::Struct |
-                                AdtKind::Union => {
-                                    err.span_suggestion(
-                                        span,
-                                        "use curly brackets",
-                                        String::from("Self { /* fields */ }"),
-                                        Applicability::HasPlaceholders,
-                                    );
-                                }
-                            }
-                        }
-                        err.emit();
-
-                        (impl_def_id, tcx.types.err)
-                    }
-                }
-            }
-            _ => {
-                let def_id = def.def_id();
-
-                // The things we are substituting into the type should not contain
-                // escaping late-bound regions, and nor should the base type scheme.
-                let ty = tcx.type_of(def_id);
-                (def_id, ty)
-            }
-        };
-
         let substs = AstConv::create_substs_for_generic_args(
             tcx,
             def_id,
@@ -5573,7 +5574,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                ty_substituted);
         self.write_substs(hir_id, substs);
 
-        (ty_substituted, new_def)
+        (ty_substituted, def)
     }
 
     fn check_rustc_args_require_const(&self,
diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs
index 3e6e6576b63..a76dfdd69ba 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/src/librustc_typeck/check/upvar.rs
@@ -93,19 +93,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         );
 
         // Extract the type of the closure.
-        let (closure_def_id, substs) = match self.node_ty(closure_hir_id).sty {
+        let ty = self.node_ty(closure_hir_id);
+        let (closure_def_id, substs) = match ty.sty {
             ty::Closure(def_id, substs) => (def_id, UpvarSubsts::Closure(substs)),
             ty::Generator(def_id, substs, _) => (def_id, UpvarSubsts::Generator(substs)),
             ty::Error => {
                 // #51714: skip analysis when we have already encountered type errors
                 return;
             }
-            ref t => {
+            _ => {
                 span_bug!(
                     span,
                     "type of closure expr {:?} is not a closure {:?}",
                     closure_hir_id,
-                    t
+                    ty
                 );
             }
         };
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index fde940eb2c1..1f7e05de18b 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -68,7 +68,7 @@ pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: Def
 
     debug!("check_item_well_formed(it.hir_id={:?}, it.name={})",
            item.hir_id,
-           tcx.item_path_str(def_id));
+           tcx.def_path_str(def_id));
 
     match item.node {
         // Right now we check that every default trait implementation
@@ -618,7 +618,7 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>(
     span: Span,
     ty: Ty<'tcx>,
 ) -> Vec<ty::Predicate<'tcx>> {
-    trace!("check_existential_types: {:?}, {:?}", ty, ty.sty);
+    trace!("check_existential_types: {:?}", ty);
     let mut substituted_predicates = Vec::new();
     ty.fold_with(&mut ty::fold::BottomUpFolder {
         tcx: fcx.tcx,
@@ -976,7 +976,7 @@ fn report_bivariance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     if let Some(def_id) = suggested_marker_id {
         err.help(&format!("consider removing `{}` or using a marker such as `{}`",
                           param_name,
-                          tcx.item_path_str(def_id)));
+                          tcx.def_path_str(def_id)));
     }
     err.emit();
 }
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index d001545d1d9..4a3d4f31a24 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -472,7 +472,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
                 instantiated_ty.fold_with(&mut BottomUpFolder {
                     tcx: self.tcx().global_tcx(),
                     fldop: |ty| {
-                        trace!("checking type {:?}: {:#?}", ty, ty.sty);
+                        trace!("checking type {:?}", ty);
                         // find a type parameter
                         if let ty::Param(..) = ty.sty {
                             // look it up in the substitution list
diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs
index 5d86bc54095..a2b01e3843f 100644
--- a/src/librustc_typeck/coherence/builtin.rs
+++ b/src/librustc_typeck/coherence/builtin.rs
@@ -198,8 +198,8 @@ fn visit_implementation_of_dispatch_from_dyn<'a, 'tcx>(
                     if def_a.is_struct() && def_b.is_struct() =>
                 {
                     if def_a != def_b {
-                        let source_path = tcx.item_path_str(def_a.did);
-                        let target_path = tcx.item_path_str(def_b.did);
+                        let source_path = tcx.def_path_str(def_a.did);
+                        let target_path = tcx.def_path_str(def_b.did);
 
                         create_err(
                             &format!(
@@ -388,8 +388,8 @@ pub fn coerce_unsized_info<'a, 'gcx>(gcx: TyCtxt<'a, 'gcx, 'gcx>,
             (&ty::Adt(def_a, substs_a), &ty::Adt(def_b, substs_b)) if def_a.is_struct() &&
                                                                       def_b.is_struct() => {
                 if def_a != def_b {
-                    let source_path = gcx.item_path_str(def_a.did);
-                    let target_path = gcx.item_path_str(def_b.did);
+                    let source_path = gcx.def_path_str(def_a.did);
+                    let target_path = gcx.def_path_str(def_b.did);
                     span_err!(gcx.sess,
                               span,
                               E0377,
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index 39a2f5d37bd..a5452b4db2a 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -28,7 +28,7 @@ fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
     if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) {
         debug!("(checking implementation) adding impl for trait '{:?}', item '{}'",
                trait_ref,
-               tcx.item_path_str(impl_def_id));
+               tcx.def_path_str(impl_def_id));
 
         // Skip impls where one of the self type is an error type.
         // This occurs with e.g., resolve failures (#30589).
@@ -204,10 +204,10 @@ fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeI
                                      E0371,
                                      "the object type `{}` automatically implements the trait `{}`",
                                      trait_ref.self_ty(),
-                                     tcx.item_path_str(trait_def_id))
+                                     tcx.def_path_str(trait_def_id))
                         .span_label(sp, format!("`{}` automatically implements trait `{}`",
                                                 trait_ref.self_ty(),
-                                                tcx.item_path_str(trait_def_id)))
+                                                tcx.def_path_str(trait_def_id)))
                         .emit();
                 }
             }
diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs
index c875b856f3a..7e1c38e0515 100644
--- a/src/librustc_typeck/coherence/orphan.rs
+++ b/src/librustc_typeck/coherence/orphan.rs
@@ -121,7 +121,7 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> {
                                 format!("cross-crate traits with a default impl, like `{}`, \
                                          can only be implemented for a struct/enum type \
                                          defined in the current crate",
-                                        self.tcx.item_path_str(trait_def_id)),
+                                        self.tcx.def_path_str(trait_def_id)),
                                 "can't implement cross-crate trait for type in another crate"
                             ))
                         }
@@ -129,7 +129,7 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> {
                     _ => {
                         Some((format!("cross-crate traits with a default impl, like `{}`, can \
                                        only be implemented for a struct/enum type, not `{}`",
-                                      self.tcx.item_path_str(trait_def_id),
+                                      self.tcx.def_path_str(trait_def_id),
                                       self_ty),
                               "can't implement cross-crate trait with a default impl for \
                                non-struct/enum type"))
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index ebb617c23c6..cbed7d26a99 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -317,7 +317,7 @@ pub fn provide(providers: &mut Providers<'_>) {
 pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
                              -> Result<(), ErrorReported>
 {
-    tcx.sess.profiler(|p| p.start_activity(ProfileCategory::TypeChecking));
+    tcx.sess.profiler(|p| p.start_activity(ProfileCategory::TypeChecking, "type-check crate"));
 
     // this ensures that later parts of type checking can assume that items
     // have valid types and not error
@@ -368,7 +368,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
     check_unused::check_crate(tcx);
     check_for_entry_fn(tcx);
 
-    tcx.sess.profiler(|p| p.end_activity(ProfileCategory::TypeChecking));
+    tcx.sess.profiler(|p| p.end_activity(ProfileCategory::TypeChecking, "type-check crate"));
 
     if tcx.sess.err_count() == 0 {
         Ok(())
diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs
index 49d11150689..c18f9fd102f 100644
--- a/src/librustc_typeck/variance/constraints.rs
+++ b/src/librustc_typeck/variance/constraints.rs
@@ -131,7 +131,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
 
     fn build_constraints_for_item(&mut self, def_id: DefId) {
         let tcx = self.tcx();
-        debug!("build_constraints_for_item({})", tcx.item_path_str(def_id));
+        debug!("build_constraints_for_item({})", tcx.def_path_str(def_id));
 
         // Skip items with no generics - there's nothing to infer in them.
         if tcx.generics_of(def_id).count() == 0 {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index f2bf7ead561..c80fd8fcd81 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -20,8 +20,9 @@ use rustc::mir::interpret::GlobalId;
 use rustc::hir::{self, GenericArg, HirVec};
 use rustc::hir::def::{self, Def, CtorKind};
 use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
-use rustc::ty::subst::{InternalSubsts, SubstsRef};
-use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind};
+use rustc::hir::map::DisambiguatedDefPathData;
+use rustc::ty::subst::{Kind, InternalSubsts, SubstsRef};
+use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind};
 use rustc::ty::fold::TypeFolder;
 use rustc::ty::layout::VariantIdx;
 use rustc::util::nodemap::{FxHashMap, FxHashSet};
@@ -3971,7 +3972,7 @@ pub fn register_def(cx: &DocContext<'_>, def: Def) -> DefId {
         Def::ForeignTy(i) => (i, TypeKind::Foreign),
         Def::Const(i) => (i, TypeKind::Const),
         Def::Static(i, _) => (i, TypeKind::Static),
-        Def::Variant(i) => (cx.tcx.parent_def_id(i).expect("cannot get parent def id"),
+        Def::Variant(i) => (cx.tcx.parent(i).expect("cannot get parent def id"),
                             TypeKind::Enum),
         Def::Macro(i, mac_kind) => match mac_kind {
             MacroKind::Bang => (i, TypeKind::Macro),
@@ -4223,32 +4224,113 @@ pub fn path_to_def(tcx: &TyCtxt<'_, '_, '_>, path: &[&str]) -> Option<DefId> {
     }
 }
 
-pub fn get_path_for_type<F>(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, def_ctor: F) -> hir::Path
-where F: Fn(DefId) -> Def {
-    #[derive(Debug)]
-    struct AbsolutePathBuffer {
-        names: Vec<String>,
+pub fn get_path_for_type(
+    tcx: TyCtxt<'_, '_, '_>,
+    def_id: DefId,
+    def_ctor: impl Fn(DefId) -> Def,
+) -> hir::Path {
+    use rustc::ty::print::Printer;
+
+    struct AbsolutePathPrinter<'a, 'tcx> {
+        tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
 
-    impl ty::item_path::ItemPathBuffer for AbsolutePathBuffer {
-        fn root_mode(&self) -> &ty::item_path::RootMode {
-            const ABSOLUTE: &'static ty::item_path::RootMode = &ty::item_path::RootMode::Absolute;
-            ABSOLUTE
+    impl Printer<'tcx, 'tcx> for AbsolutePathPrinter<'_, 'tcx> {
+        type Error = !;
+
+        type Path = Vec<String>;
+        type Region = ();
+        type Type = ();
+        type DynExistential = ();
+
+        fn tcx(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
+            self.tcx
         }
 
-        fn push(&mut self, text: &str) {
-            self.names.push(text.to_owned());
+        fn print_region(
+            self,
+            _region: ty::Region<'_>,
+        ) -> Result<Self::Region, Self::Error> {
+            Ok(())
         }
-    }
 
-    let mut apb = AbsolutePathBuffer { names: vec![] };
+        fn print_type(
+            self,
+            _ty: Ty<'tcx>,
+        ) -> Result<Self::Type, Self::Error> {
+            Ok(())
+        }
+
+        fn print_dyn_existential(
+            self,
+            _predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
+        ) -> Result<Self::DynExistential, Self::Error> {
+            Ok(())
+        }
+
+        fn path_crate(
+            self,
+            cnum: CrateNum,
+        ) -> Result<Self::Path, Self::Error> {
+            Ok(vec![self.tcx.original_crate_name(cnum).to_string()])
+        }
+        fn path_qualified(
+            self,
+            self_ty: Ty<'tcx>,
+            trait_ref: Option<ty::TraitRef<'tcx>>,
+        ) -> Result<Self::Path, Self::Error> {
+            // This shouldn't ever be needed, but just in case:
+            Ok(vec![match trait_ref {
+                Some(trait_ref) => format!("{:?}", trait_ref),
+                None => format!("<{}>", self_ty),
+            }])
+        }
+
+        fn path_append_impl(
+            self,
+            print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
+            _disambiguated_data: &DisambiguatedDefPathData,
+            self_ty: Ty<'tcx>,
+            trait_ref: Option<ty::TraitRef<'tcx>>,
+        ) -> Result<Self::Path, Self::Error> {
+            let mut path = print_prefix(self)?;
+
+            // This shouldn't ever be needed, but just in case:
+            path.push(match trait_ref {
+                Some(trait_ref) => {
+                    format!("<impl {} for {}>", trait_ref, self_ty)
+                }
+                None => format!("<impl {}>", self_ty),
+            });
+
+            Ok(path)
+        }
+        fn path_append(
+            self,
+            print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
+            disambiguated_data: &DisambiguatedDefPathData,
+        ) -> Result<Self::Path, Self::Error> {
+            let mut path = print_prefix(self)?;
+            path.push(disambiguated_data.data.as_interned_str().to_string());
+            Ok(path)
+        }
+        fn path_generic_args(
+            self,
+            print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
+            _args: &[Kind<'tcx>],
+        ) -> Result<Self::Path, Self::Error> {
+            print_prefix(self)
+        }
+    }
 
-    tcx.push_item_path(&mut apb, def_id, false);
+    let names = AbsolutePathPrinter { tcx: tcx.global_tcx() }
+        .print_def_path(def_id, &[])
+        .unwrap();
 
     hir::Path {
         span: DUMMY_SP,
         def: def_ctor(def_id),
-        segments: hir::HirVec::from_vec(apb.names.iter().map(|s| hir::PathSegment {
+        segments: hir::HirVec::from_vec(names.iter().map(|s| hir::PathSegment {
             ident: ast::Ident::from_str(&s),
             hir_id: None,
             def: None,
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index d711e4514a0..5109e775ebf 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1117,11 +1117,7 @@ themePicker.onblur = handleThemeButtonsBlur;
     // with rustdoc running in parallel.
     all_indexes.sort();
     let mut w = try_err!(File::create(&dst), &dst);
-    if options.enable_minification {
-        try_err!(writeln!(&mut w, "var N=null,E=\"\",T=\"t\",U=\"u\",searchIndex={{}};"), &dst);
-    } else {
-        try_err!(writeln!(&mut w, "var searchIndex={{}};"), &dst);
-    }
+    try_err!(writeln!(&mut w, "var N=null,E=\"\",T=\"t\",U=\"u\",searchIndex={{}};"), &dst);
     try_err!(write_minify_replacer(&mut w,
                                    &format!("{}\n{}", variables.join(""), all_indexes.join("\n")),
                                    options.enable_minification),
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 1849e53d937..fef6910f40a 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -2077,16 +2077,22 @@ if (!DOMTokenList.prototype.remove) {
     }
 
     var toggle = createSimpleToggle(false);
+    var hideMethodDocs = getCurrentValue("rustdoc-method-docs") !== "false";
+    var pageId = getPageId();
 
     var func = function(e) {
         var next = e.nextElementSibling;
         if (!next) {
             return;
         }
-        if (hasClass(next, "docblock") ||
-            (hasClass(next, "stability") &&
-             hasClass(next.nextElementSibling, "docblock"))) {
-            insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]);
+        if (hasClass(next, "docblock") === true ||
+            (hasClass(next, "stability") === true &&
+             hasClass(next.nextElementSibling, "docblock") === true)) {
+            var newToggle = toggle.cloneNode(true);
+            insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]);
+            if (hideMethodDocs === true && hasClass(e, "method") === true) {
+                collapseDocs(newToggle, "hide", pageId);
+            }
         }
     };
 
@@ -2107,17 +2113,16 @@ if (!DOMTokenList.prototype.remove) {
     onEachLazy(document.getElementsByClassName("associatedconstant"), func);
     onEachLazy(document.getElementsByClassName("impl"), funcImpl);
     var impl_call = function() {};
-    if (getCurrentValue("rustdoc-method-docs") !== "false") {
+    if (hideMethodDocs === true) {
         impl_call = function(e, newToggle, pageId) {
             if (e.id.match(/^impl(?:-\d+)?$/) === null) {
                 // Automatically minimize all non-inherent impls
-                if (hasClass(e, "impl")) {
+                if (hasClass(e, "impl") === true) {
                     collapseDocs(newToggle, "hide", pageId);
                 }
             }
         };
     }
-    var pageId = getPageId();
     var newToggle = document.createElement("a");
     newToggle.href = "javascript:void(0)";
     newToggle.className = "collapse-toggle hidden-default collapsed";
@@ -2163,7 +2168,7 @@ if (!DOMTokenList.prototype.remove) {
             var inner_toggle = newToggle.cloneNode(true);
             inner_toggle.onclick = toggleClicked;
             e.insertBefore(inner_toggle, e.firstChild);
-            impl_call(e, inner_toggle, pageId);
+            impl_call(e.previousSibling, inner_toggle, pageId);
         }
     });
 
@@ -2265,30 +2270,6 @@ if (!DOMTokenList.prototype.remove) {
     onEachLazy(document.getElementsByClassName("docblock"), buildToggleWrapper);
     onEachLazy(document.getElementsByClassName("sub-variant"), buildToggleWrapper);
 
-    // In the search display, allows to switch between tabs.
-    function printTab(nb) {
-        if (nb === 0 || nb === 1 || nb === 2) {
-            currentTab = nb;
-        }
-        var nb_copy = nb;
-        onEachLazy(document.getElementById("titles").childNodes, function(elem) {
-            if (nb_copy === 0) {
-                addClass(elem, "selected");
-            } else {
-                removeClass(elem, "selected");
-            }
-            nb_copy -= 1;
-        });
-        onEachLazy(document.getElementById("results").childNodes, function(elem) {
-            if (nb === 0) {
-                elem.style.display = "";
-            } else {
-                elem.style.display = "none";
-            }
-            nb -= 1;
-        });
-    }
-
     function createToggleWrapper(tog) {
         var span = document.createElement("span");
         span.className = "toggle-label";
@@ -2374,6 +2355,30 @@ if (!DOMTokenList.prototype.remove) {
         };
     });
 
+    // In the search display, allows to switch between tabs.
+    function printTab(nb) {
+        if (nb === 0 || nb === 1 || nb === 2) {
+            currentTab = nb;
+        }
+        var nb_copy = nb;
+        onEachLazy(document.getElementById("titles").childNodes, function(elem) {
+            if (nb_copy === 0) {
+                addClass(elem, "selected");
+            } else {
+                removeClass(elem, "selected");
+            }
+            nb_copy -= 1;
+        });
+        onEachLazy(document.getElementById("results").childNodes, function(elem) {
+            if (nb === 0) {
+                elem.style.display = "";
+            } else {
+                elem.style.display = "none";
+            }
+            nb -= 1;
+        });
+    }
+
     function putBackSearch(search_input) {
         if (search_input.value !== "") {
             addClass(main, "hidden");
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index f11e268b909..fccf5a67ad4 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -5,8 +5,10 @@
 
 #![feature(bind_by_move_pattern_guards)]
 #![feature(rustc_private)]
+#![feature(arbitrary_self_types)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
+#![feature(in_band_lifetimes)]
 #![feature(nll)]
 #![feature(set_stdio)]
 #![feature(test)]
@@ -16,6 +18,7 @@
 #![feature(const_fn)]
 #![feature(drain_filter)]
 #![feature(inner_deref)]
+#![feature(never_type)]
 
 #![recursion_limit="256"]
 
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index fefff1f3a75..0f8e8894c04 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -288,6 +288,12 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
             if ori_link.contains('/') {
                 continue;
             }
+
+            // [] is mostly likely not supposed to be a link
+            if ori_link.is_empty() {
+                continue;
+            }
+
             let link = ori_link.replace("`", "");
             let (def, fragment) = {
                 let mut kind = PathKind::Unknown;
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 928de29b297..1d45df499d8 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -19,7 +19,7 @@ use super::table::{self, Bucket, EmptyBucket, Fallibility, FullBucket, FullBucke
 use super::table::BucketState::{Empty, Full};
 use super::table::Fallibility::{Fallible, Infallible};
 
-const MIN_NONZERO_RAW_CAPACITY: usize = 32;     // must be a power of two
+const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two
 
 /// The default behavior of HashMap implements a maximum load factor of 90.9%.
 #[derive(Clone)]
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index f2111f2d9e0..c026de35da6 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -8,7 +8,7 @@ use super::Recover;
 use super::map::{self, HashMap, Keys, RandomState};
 
 // Future Optimization (FIXME!)
-// =============================
+// ============================
 //
 // Iteration over zero sized values is a noop. There is no need
 // for `bucket.val` in the case of HashSet. I suppose we would need HKT
diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index f6cd9e82abd..a2b12d00a78 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -956,6 +956,27 @@ impl f32 {
     pub fn atanh(self) -> f32 {
         0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
     }
+    /// Returns max if self is greater than max, and min if self is less than min.
+    /// Otherwise this returns self.  Panics if min > max, min equals NaN, or max equals NaN.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(clamp)]
+    /// assert!((-3.0f32).clamp(-2.0f32, 1.0f32) == -2.0f32);
+    /// assert!((0.0f32).clamp(-2.0f32, 1.0f32) == 0.0f32);
+    /// assert!((2.0f32).clamp(-2.0f32, 1.0f32) == 1.0f32);
+    /// ```
+    #[unstable(feature = "clamp", issue = "44095")]
+    #[inline]
+    pub fn clamp(self, min: f32, max: f32) -> f32 {
+        assert!(min <= max);
+        let mut x = self;
+        if x < min { x = min; }
+        if x > max { x = max; }
+        x
+    }
+
 }
 
 #[cfg(test)]
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index 8ff97ab828a..be5cd92d416 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -878,6 +878,27 @@ impl f64 {
         0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
     }
 
+    /// Returns max if self is greater than max, and min if self is less than min.
+    /// Otherwise this returns self.  Panics if min > max, min equals NaN, or max equals NaN.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(clamp)]
+    /// assert!((-3.0f64).clamp(-2.0f64, 1.0f64) == -2.0f64);
+    /// assert!((0.0f64).clamp(-2.0f64, 1.0f64) == 0.0f64);
+    /// assert!((2.0f64).clamp(-2.0f64, 1.0f64) == 1.0f64);
+    /// ```
+    #[unstable(feature = "clamp", issue = "44095")]
+    #[inline]
+    pub fn clamp(self, min: f64, max: f64) -> f64 {
+        assert!(min <= max);
+        let mut x = self;
+        if x < min { x = min; }
+        if x > max { x = max; }
+        x
+    }
+
     // Solaris/Illumos requires a wrapper around log, log2, and log10 functions
     // because of their non-standard behavior (e.g., log(-n) returns -Inf instead
     // of expected NaN).
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index 25f2dd73504..8c3d0da0a7e 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -211,7 +211,7 @@ pub struct DirBuilder {
     recursive: bool,
 }
 
-/// How large a buffer to pre-allocate before reading the entire file.
+/// Indicates how large a buffer to pre-allocate before reading the entire file.
 fn initial_buffer_size(file: &File) -> usize {
     // Allocate one extra byte so the buffer doesn't need to grow before the
     // final `read` call at the end of the file.  Don't worry about `usize`
@@ -1581,7 +1581,8 @@ pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()>
 /// `O_CLOEXEC` is set for returned file descriptors.
 /// On Windows, this function currently corresponds to `CopyFileEx`. Alternate
 /// NTFS streams are copied but only the size of the main stream is returned by
-/// this function.
+/// this function. On MacOS, this function corresponds to `copyfile` with
+/// `COPYFILE_ALL`.
 /// Note that, this [may change in the future][changes].
 ///
 /// [changes]: ../io/index.html#platform-specific-behavior
@@ -2837,6 +2838,26 @@ mod tests {
     }
 
     #[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 };
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index e3e2754a7aa..1a2152a79af 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -390,6 +390,28 @@ fn read_to_end_with_reservation<R: Read + ?Sized>(r: &mut R,
     ret
 }
 
+pub(crate) fn default_read_vectored<F>(read: F, bufs: &mut [IoVecMut<'_>]) -> Result<usize>
+where
+    F: FnOnce(&mut [u8]) -> Result<usize>
+{
+    let buf = bufs
+        .iter_mut()
+        .find(|b| !b.is_empty())
+        .map_or(&mut [][..], |b| &mut **b);
+    read(buf)
+}
+
+pub(crate) fn default_write_vectored<F>(write: F, bufs: &[IoVec<'_>]) -> Result<usize>
+where
+    F: FnOnce(&[u8]) -> Result<usize>
+{
+    let buf = bufs
+        .iter()
+        .find(|b| !b.is_empty())
+        .map_or(&[][..], |b| &**b);
+    write(buf)
+}
+
 /// The `Read` trait allows for reading bytes from a source.
 ///
 /// Implementors of the `Read` trait are called 'readers'.
@@ -528,14 +550,11 @@ pub trait Read {
     /// written to possibly being only partially filled. This method must behave
     /// as a single call to `read` with the buffers concatenated would.
     ///
-    /// The default implementation simply passes the first nonempty buffer to
-    /// `read`.
+    /// The default implementation calls `read` with either the first nonempty
+    /// buffer provided, or an empty one if none exists.
     #[unstable(feature = "iovec", issue = "58452")]
     fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> Result<usize> {
-        match bufs.iter_mut().find(|b| !b.is_empty()) {
-            Some(buf) => self.read(buf),
-            None => Ok(0),
-        }
+        default_read_vectored(|b| self.read(b), bufs)
     }
 
     /// Determines if this `Read`er can work with buffers of uninitialized
@@ -1107,14 +1126,11 @@ pub trait Write {
     /// read from possibly being only partially consumed. This method must
     /// behave as a call to `write` with the buffers concatenated would.
     ///
-    /// The default implementation simply passes the first nonempty buffer to
-    /// `write`.
+    /// The default implementation calls `write` with either the first nonempty
+    /// buffer provided, or an empty one if none exists.
     #[unstable(feature = "iovec", issue = "58452")]
     fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> Result<usize> {
-        match bufs.iter().find(|b| !b.is_empty()) {
-            Some(buf) => self.write(buf),
-            None => Ok(0),
-        }
+        default_write_vectored(|b| self.write(b), bufs)
     }
 
     /// Flush this output stream, ensuring that all intermediately buffered
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index e31680f23f1..fc8ac9a0b3e 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -221,7 +221,7 @@
 
 #![cfg_attr(test, feature(print_internals, set_stdio, test, update_panic_count))]
 #![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"),
-            feature(global_asm, range_contains, slice_index_methods,
+            feature(global_asm, slice_index_methods,
                     decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))]
 
 // std is implemented with unstable features, many of which are internal
@@ -245,6 +245,7 @@
 #![feature(cfg_target_thread_local)]
 #![feature(char_error_internals)]
 #![feature(checked_duration_since)]
+#![feature(clamp)]
 #![feature(compiler_builtins_lib)]
 #![feature(concat_idents)]
 #![feature(const_cstr_unchecked)]
diff --git a/src/libstd/os/fortanix_sgx/mod.rs b/src/libstd/os/fortanix_sgx/mod.rs
index bca22e717d7..4e30b1edd15 100644
--- a/src/libstd/os/fortanix_sgx/mod.rs
+++ b/src/libstd/os/fortanix_sgx/mod.rs
@@ -43,3 +43,8 @@ pub mod mem {
 }
 
 pub use crate::sys::ext::{io, arch, ffi};
+
+/// Functions for querying thread-related information.
+pub mod thread {
+    pub use crate::sys::abi::thread::current;
+}
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index 56840009344..ad86acbb47d 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -8,7 +8,7 @@
 //!
 //! The [`Command`] struct is used to configure and spawn processes:
 //!
-//! ```
+//! ```no_run
 //! use std::process::Command;
 //!
 //! let output = Command::new("echo")
diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs
index 5ebb61754e1..c383f21dcd7 100644
--- a/src/libstd/sync/condvar.rs
+++ b/src/libstd/sync/condvar.rs
@@ -190,7 +190,7 @@ impl Condvar {
     /// // Wait for the thread to start up.
     /// let &(ref lock, ref cvar) = &*pair;
     /// let mut started = lock.lock().unwrap();
-    /// // As long as the value inside the `Mutex` is false, we wait.
+    /// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
     /// while !*started {
     ///     started = cvar.wait(started).unwrap();
     /// }
@@ -254,7 +254,7 @@ impl Condvar {
     ///
     /// // Wait for the thread to start up.
     /// let &(ref lock, ref cvar) = &*pair;
-    /// // As long as the value inside the `Mutex` is false, we wait.
+    /// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
     /// let _guard = cvar.wait_until(lock.lock().unwrap(), |started| { *started }).unwrap();
     /// ```
     #[unstable(feature = "wait_until", issue = "47960")]
@@ -311,7 +311,7 @@ impl Condvar {
     /// // Wait for the thread to start up.
     /// let &(ref lock, ref cvar) = &*pair;
     /// let mut started = lock.lock().unwrap();
-    /// // As long as the value inside the `Mutex` is false, we wait.
+    /// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
     /// loop {
     ///     let result = cvar.wait_timeout_ms(started, 10).unwrap();
     ///     // 10 milliseconds have passed, or maybe the value changed!
@@ -384,7 +384,7 @@ impl Condvar {
     /// // wait for the thread to start up
     /// let &(ref lock, ref cvar) = &*pair;
     /// let mut started = lock.lock().unwrap();
-    /// // as long as the value inside the `Mutex` is false, we wait
+    /// // as long as the value inside the `Mutex<bool>` is `false`, we wait
     /// loop {
     ///     let result = cvar.wait_timeout(started, Duration::from_millis(10)).unwrap();
     ///     // 10 milliseconds have passed, or maybe the value changed!
@@ -518,7 +518,7 @@ impl Condvar {
     /// // Wait for the thread to start up.
     /// let &(ref lock, ref cvar) = &*pair;
     /// let mut started = lock.lock().unwrap();
-    /// // As long as the value inside the `Mutex` is false, we wait.
+    /// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
     /// while !*started {
     ///     started = cvar.wait(started).unwrap();
     /// }
@@ -558,7 +558,7 @@ impl Condvar {
     /// // Wait for the thread to start up.
     /// let &(ref lock, ref cvar) = &*pair;
     /// let mut started = lock.lock().unwrap();
-    /// // As long as the value inside the `Mutex` is false, we wait.
+    /// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
     /// while !*started {
     ///     started = cvar.wait(started).unwrap();
     /// }
diff --git a/src/libstd/sys/redox/net/tcp.rs b/src/libstd/sys/redox/net/tcp.rs
index 5081c3de73c..3f2f6166a79 100644
--- a/src/libstd/sys/redox/net/tcp.rs
+++ b/src/libstd/sys/redox/net/tcp.rs
@@ -35,10 +35,7 @@ impl TcpStream {
     }
 
     pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
-        match bufs.iter_mut().find(|b| !b.is_empty()) {
-            Some(buf) => self.read(buf),
-            None => Ok(0),
-        }
+        io::default_read_vectored(|b| self.read(b), bufs)
     }
 
     pub fn write(&self, buf: &[u8]) -> Result<usize> {
@@ -46,10 +43,7 @@ impl TcpStream {
     }
 
     pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
-        match bufs.iter().find(|b| !b.is_empty()) {
-            Some(buf) => self.write(buf),
-            None => Ok(0),
-        }
+        io::default_write_vectored(|b| self.write(b), bufs)
     }
 
     pub fn take_error(&self) -> Result<Option<Error>> {
diff --git a/src/libstd/sys/sgx/abi/thread.rs b/src/libstd/sys/sgx/abi/thread.rs
index 86fe09d0035..c17fa2d0015 100644
--- a/src/libstd/sys/sgx/abi/thread.rs
+++ b/src/libstd/sys/sgx/abi/thread.rs
@@ -4,6 +4,7 @@ use fortanix_sgx_abi::Tcs;
 /// all currently running threads in the enclave, and it is guaranteed to be
 /// constant for the lifetime of the thread. More specifically for SGX, there
 /// is a one-to-one correspondence of the ID to the address of the TCS.
+#[unstable(feature = "sgx_platform", issue = "56975")]
 pub fn current() -> Tcs {
     extern "C" { fn get_tcs_addr() -> Tcs; }
     unsafe { get_tcs_addr() }
diff --git a/src/libstd/sys/sgx/net.rs b/src/libstd/sys/sgx/net.rs
index e5e42e3d0b0..e167e917957 100644
--- a/src/libstd/sys/sgx/net.rs
+++ b/src/libstd/sys/sgx/net.rs
@@ -103,24 +103,16 @@ impl TcpStream {
         self.inner.inner.read(buf)
     }
 
-    pub fn read_vectored(&self, buf: &mut [IoVecMut<'_>]) -> io::Result<usize> {
-        let buf = match buf.get_mut(0) {
-            Some(buf) => buf,
-            None => return Ok(0),
-        };
-        self.read(buf)
+    pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        io::default_read_vectored(|b| self.read(b), bufs)
     }
 
     pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
         self.inner.inner.write(buf)
     }
 
-    pub fn write_vectored(&self, buf: &[IoVec<'_>]) -> io::Result<usize> {
-        let buf = match buf.get(0) {
-            Some(buf) => buf,
-            None => return Ok(0),
-        };
-        self.write(buf)
+    pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        io::default_write_vectored(|b| self.write(b), bufs)
     }
 
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index 3b80b475a93..7ff098bc9e1 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -827,7 +827,10 @@ pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
     Ok(PathBuf::from(OsString::from_vec(buf)))
 }
 
-#[cfg(not(any(target_os = "linux", target_os = "android")))]
+#[cfg(not(any(target_os = "linux",
+              target_os = "android",
+              target_os = "macos",
+              target_os = "ios")))]
 pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
     use crate::fs::File;
     if !from.is_file() {
@@ -937,3 +940,85 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
     writer.set_permissions(perm)?;
     Ok(written)
 }
+
+#[cfg(any(target_os = "macos", target_os = "ios"))]
+pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
+    const COPYFILE_ACL: u32 = 1 << 0;
+    const COPYFILE_STAT: u32 = 1 << 1;
+    const COPYFILE_XATTR: u32 = 1 << 2;
+    const COPYFILE_DATA: u32 = 1 << 3;
+
+    const COPYFILE_SECURITY: u32 = COPYFILE_STAT | COPYFILE_ACL;
+    const COPYFILE_METADATA: u32 = COPYFILE_SECURITY | COPYFILE_XATTR;
+    const COPYFILE_ALL: u32 = COPYFILE_METADATA | COPYFILE_DATA;
+
+    const COPYFILE_STATE_COPIED: u32 = 8;
+
+    #[allow(non_camel_case_types)]
+    type copyfile_state_t = *mut libc::c_void;
+    #[allow(non_camel_case_types)]
+    type copyfile_flags_t = u32;
+
+    extern "C" {
+        fn copyfile(
+            from: *const libc::c_char,
+            to: *const libc::c_char,
+            state: copyfile_state_t,
+            flags: copyfile_flags_t,
+        ) -> libc::c_int;
+        fn copyfile_state_alloc() -> copyfile_state_t;
+        fn copyfile_state_free(state: copyfile_state_t) -> libc::c_int;
+        fn copyfile_state_get(
+            state: copyfile_state_t,
+            flag: u32,
+            dst: *mut libc::c_void,
+        ) -> libc::c_int;
+    }
+
+    struct FreeOnDrop(copyfile_state_t);
+    impl Drop for FreeOnDrop {
+        fn drop(&mut self) {
+            // The code below ensures that `FreeOnDrop` is never a null pointer
+            unsafe {
+                // `copyfile_state_free` returns -1 if the `to` or `from` files
+                // cannot be closed. However, this is not considerd this an
+                // error.
+                copyfile_state_free(self.0);
+            }
+        }
+    }
+
+    if !from.is_file() {
+        return Err(Error::new(ErrorKind::InvalidInput,
+                              "the source path is not an existing regular file"))
+    }
+
+    // We ensure that `FreeOnDrop` never contains a null pointer so it is
+    // always safe to call `copyfile_state_free`
+    let state = unsafe {
+        let state = copyfile_state_alloc();
+        if state.is_null() {
+            return Err(crate::io::Error::last_os_error());
+        }
+        FreeOnDrop(state)
+    };
+
+    cvt(unsafe {
+        copyfile(
+            cstr(from)?.as_ptr(),
+            cstr(to)?.as_ptr(),
+            state.0,
+            COPYFILE_ALL,
+        )
+    })?;
+
+    let mut bytes_copied: libc::off_t = 0;
+    cvt(unsafe {
+        copyfile_state_get(
+            state.0,
+            COPYFILE_STATE_COPIED,
+            &mut bytes_copied as *mut libc::off_t as *mut libc::c_void,
+        )
+    })?;
+    Ok(bytes_copied as u64)
+}
diff --git a/src/libstd/sys/wasm/alloc.rs b/src/libstd/sys/wasm/alloc.rs
index b9098548b9c..c1af6ec1262 100644
--- a/src/libstd/sys/wasm/alloc.rs
+++ b/src/libstd/sys/wasm/alloc.rs
@@ -49,7 +49,6 @@ unsafe impl GlobalAlloc for System {
 
 #[cfg(target_feature = "atomics")]
 mod lock {
-    use crate::arch::wasm32;
     use crate::sync::atomic::{AtomicI32, Ordering::SeqCst};
 
     static LOCKED: AtomicI32 = AtomicI32::new(0);
@@ -61,14 +60,76 @@ mod lock {
             if LOCKED.swap(1, SeqCst) == 0 {
                 return DropLock
             }
-            unsafe {
-                let r = wasm32::i32_atomic_wait(
-                    &LOCKED as *const AtomicI32 as *mut i32,
-                    1,  // expected value
-                    -1, // timeout
-                );
-                debug_assert!(r == 0 || r == 1);
-            }
+            // Ok so here's where things get a little depressing. At this point
+            // in time we need to synchronously acquire a lock, but we're
+            // contending with some other thread. Typically we'd execute some
+            // form of `i32.atomic.wait` like so:
+            //
+            //     unsafe {
+            //         let r = core::arch::wasm32::i32_atomic_wait(
+            //             &LOCKED as *const AtomicI32 as *mut i32,
+            //             1,  //     expected value
+            //             -1, //     timeout
+            //         );
+            //         debug_assert!(r == 0 || r == 1);
+            //     }
+            //
+            // Unfortunately though in doing so we would cause issues for the
+            // main thread. The main thread in a web browser *cannot ever
+            // block*, no exceptions. This means that the main thread can't
+            // actually execute the `i32.atomic.wait` instruction.
+            //
+            // As a result if we want to work within the context of browsers we
+            // need to figure out some sort of allocation scheme for the main
+            // thread where when there's contention on the global malloc lock we
+            // do... something.
+            //
+            // Possible ideas include:
+            //
+            // 1. Attempt to acquire the global lock. If it fails, fall back to
+            //    memory allocation via `memory.grow`. Later just ... somehow
+            //    ... inject this raw page back into the main allocator as it
+            //    gets sliced up over time. This strategy has the downside of
+            //    forcing allocation of a page to happen whenever the main
+            //    thread contents with other threads, which is unfortunate.
+            //
+            // 2. Maintain a form of "two level" allocator scheme where the main
+            //    thread has its own allocator. Somehow this allocator would
+            //    also be balanced with a global allocator, not only to have
+            //    allocations cross between threads but also to ensure that the
+            //    two allocators stay "balanced" in terms of free'd memory and
+            //    such. This, however, seems significantly complicated.
+            //
+            // Out of a lack of other ideas, the current strategy implemented
+            // here is to simply spin. Typical spin loop algorithms have some
+            // form of "hint" here to the CPU that it's what we're doing to
+            // ensure that the CPU doesn't get too hot, but wasm doesn't have
+            // such an instruction.
+            //
+            // To be clear, spinning here is not a great solution.
+            // Another thread with the lock may take quite a long time to wake
+            // up. For example it could be in `memory.grow` or it could be
+            // evicted from the CPU for a timeslice like 10ms. For these periods
+            // of time our thread will "helpfully" sit here and eat CPU time
+            // until it itself is evicted or the lock holder finishes. This
+            // means we're just burning and wasting CPU time to no one's
+            // benefit.
+            //
+            // Spinning does have the nice properties, though, of being
+            // semantically correct, being fair to all threads for memory
+            // allocation, and being simple enough to implement.
+            //
+            // This will surely (hopefully) be replaced in the future with a
+            // real memory allocator that can handle the restriction of the main
+            // thread.
+            //
+            //
+            // FIXME: We can also possibly add an optimization here to detect
+            // when a thread is the main thread or not and block on all
+            // non-main-thread threads. Currently, however, we have no way
+            // of knowing which wasm thread is on the browser main thread, but
+            // if we could figure out we could at least somewhat mitigate the
+            // cost of this spinning.
         }
     }
 
@@ -76,12 +137,16 @@ mod lock {
         fn drop(&mut self) {
             let r = LOCKED.swap(0, SeqCst);
             debug_assert_eq!(r, 1);
-            unsafe {
-                wasm32::atomic_notify(
-                    &LOCKED as *const AtomicI32 as *mut i32,
-                    1, // only one thread
-                );
-            }
+
+            // Note that due to the above logic we don't actually need to wake
+            // anyone up, but if we did it'd likely look something like this:
+            //
+            //     unsafe {
+            //         core::arch::wasm32::atomic_notify(
+            //             &LOCKED as *const AtomicI32 as *mut i32,
+            //             1, //     only one thread
+            //         );
+            //     }
         }
     }
 }
diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs
index 07f4f5f0e58..b38727830f3 100644
--- a/src/libstd/sys/windows/pipe.rs
+++ b/src/libstd/sys/windows/pipe.rs
@@ -37,9 +37,9 @@ pub struct Pipes {
 ///
 /// The ours/theirs pipes are *not* specifically readable or writable. Each
 /// one only supports a read or a write, but which is which depends on the
-/// boolean flag given. If `ours_readable` is true then `ours` is readable where
-/// `theirs` is writable. Conversely if `ours_readable` is false then `ours` is
-/// writable where `theirs` is readable.
+/// boolean flag given. If `ours_readable` is `true`, then `ours` is readable and
+/// `theirs` is writable. Conversely, if `ours_readable` is `false`, then `ours`
+/// is writable and `theirs` is readable.
 ///
 /// Also note that the `ours` pipe is always a handle opened up in overlapped
 /// mode. This means that technically speaking it should only ever be used
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index 6d7093ac33e..4c86f70ad87 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -712,13 +712,6 @@ mod tests {
         assert_almost_eq!(a - second + second, a);
         assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a);
 
-        // A difference of 80 and 800 years cannot fit inside a 32-bit time_t
-        if !(cfg!(unix) && crate::mem::size_of::<libc::time_t>() <= 4) {
-            let eighty_years = second * 60 * 60 * 24 * 365 * 80;
-            assert_almost_eq!(a - eighty_years + eighty_years, a);
-            assert_almost_eq!(a - (eighty_years * 10) + (eighty_years * 10), 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);
@@ -747,8 +740,8 @@ mod tests {
     #[test]
     fn since_epoch() {
         let ts = SystemTime::now();
-        let a = ts.duration_since(UNIX_EPOCH).unwrap();
-        let b = ts.duration_since(UNIX_EPOCH - Duration::new(1, 0)).unwrap();
+        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));
 
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 4e4432a3f33..2abb7e407eb 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -24,8 +24,8 @@ pub struct StripUnconfigured<'a> {
 }
 
 // `cfg_attr`-process the crate's attributes and compute the crate's features.
-pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition)
-                -> (ast::Crate, Features) {
+pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition,
+                allow_features: &Option<Vec<String>>) -> (ast::Crate, Features) {
     let features;
     {
         let mut strip_unconfigured = StripUnconfigured {
@@ -43,7 +43,7 @@ pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition)
             return (krate, Features::new());
         }
 
-        features = get_features(&sess.span_diagnostic, &krate.attrs, edition);
+        features = get_features(&sess.span_diagnostic, &krate.attrs, edition, allow_features);
 
         // Avoid reconfiguring malformed `cfg_attr`s
         if err_count == sess.span_diagnostic.err_count() {
diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs
index 2c367f1f402..ac24475cab8 100644
--- a/src/libsyntax/diagnostic_list.rs
+++ b/src/libsyntax/diagnostic_list.rs
@@ -378,6 +378,21 @@ Erroneous code example:
 
 "##,
 
+E0725: r##"
+A feature attribute named a feature that was disallowed in the compiler
+command line flags.
+
+Erroneous code example:
+
+```ignore (can't specify compiler flags from doctests)
+#![feature(never_type)] // error: the feature `never_type` is not in
+                        // the list of allowed features
+```
+
+Delete the offending feature attribute, or add it to the list of allowed
+features in the `-Z allow_features` flag.
+"##,
+
 }
 
 register_diagnostics! {
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 279e2089f5d..280b17da0be 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -1042,7 +1042,7 @@ pub const BUILTIN_ATTRIBUTES: &[(&str, AttributeType, AttributeTemplate, Attribu
                                              "rustc_attrs",
                                              "internal rustc attributes will never be stable",
                                              cfg_fn!(rustc_attrs))),
-    ("rustc_item_path", Whitelisted, template!(Word), Gated(Stability::Unstable,
+    ("rustc_def_path", Whitelisted, template!(Word), Gated(Stability::Unstable,
                                            "rustc_attrs",
                                            "internal rustc attributes will never be stable",
                                            cfg_fn!(rustc_attrs))),
@@ -2008,7 +2008,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
 }
 
 pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
-                    crate_edition: Edition) -> Features {
+                    crate_edition: Edition, allow_features: &Option<Vec<String>>) -> Features {
     fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
         let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed");
         if let Some(reason) = reason {
@@ -2127,6 +2127,15 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
             }
 
             if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) {
+                if let Some(allowed) = allow_features.as_ref() {
+                    if allowed.iter().find(|f| *f == name.as_str()).is_none() {
+                        span_err!(span_handler, mi.span, E0725,
+                                  "the feature `{}` is not in the list of allowed features",
+                                  name);
+                        continue;
+                    }
+                }
+
                 set(&mut features, mi.span);
                 features.declared_lang_features.push((name, mi.span, None));
                 continue
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index fe31311094b..22af7d47fd0 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -5116,12 +5116,8 @@ impl<'a> Parser<'a> {
 
                 let ident = self.parse_ident()?;
                 let (delim, tokens) = self.expect_delimited_token_tree()?;
-                if delim != MacDelimiter::Brace {
-                    if !self.eat(&token::Semi) {
-                        let msg = "macros that expand to items must either \
-                                   be surrounded with braces or followed by a semicolon";
-                        self.span_err(self.prev_span, msg);
-                    }
+                if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
+                    self.report_invalid_macro_expansion_item();
                 }
 
                 (ident, ast::MacroDef { tokens: tokens, legacy: true })
@@ -5264,13 +5260,8 @@ impl<'a> Parser<'a> {
                 // if it has a special ident, it's definitely an item
                 //
                 // Require a semicolon or braces.
-                if style != MacStmtStyle::Braces {
-                    if !self.eat(&token::Semi) {
-                        self.span_err(self.prev_span,
-                                      "macros that expand to items must \
-                                       either be surrounded with braces or \
-                                       followed by a semicolon");
-                    }
+                if style != MacStmtStyle::Braces && !self.eat(&token::Semi) {
+                    self.report_invalid_macro_expansion_item();
                 }
                 let span = lo.to(hi);
                 Stmt {
@@ -8360,13 +8351,8 @@ impl<'a> Parser<'a> {
             };
             // eat a matched-delimiter token tree:
             let (delim, tts) = self.expect_delimited_token_tree()?;
-            if delim != MacDelimiter::Brace {
-                if !self.eat(&token::Semi) {
-                    self.span_err(self.prev_span,
-                                  "macros that expand to items must either \
-                                   be surrounded with braces or followed by \
-                                   a semicolon");
-                }
+            if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
+                self.report_invalid_macro_expansion_item();
             }
 
             let hi = self.prev_span;
@@ -8597,6 +8583,25 @@ impl<'a> Parser<'a> {
             }
         }
     }
+
+    fn report_invalid_macro_expansion_item(&self) {
+        self.struct_span_err(
+            self.prev_span,
+            "macros that expand to items must be delimited with braces or followed by a semicolon",
+        ).multipart_suggestion(
+            "change the delimiters to curly braces",
+            vec![
+                (self.prev_span.with_hi(self.prev_span.lo() + BytePos(1)), String::from(" {")),
+                (self.prev_span.with_lo(self.prev_span.hi() - BytePos(1)), '}'.to_string()),
+            ],
+            Applicability::MaybeIncorrect,
+        ).span_suggestion(
+            self.sess.source_map.next_point(self.prev_span),
+            "add a semicolon",
+            ';'.to_string(),
+            Applicability::MaybeIncorrect,
+        ).emit();
+    }
 }
 
 pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedBrace>, handler: &errors::Handler) {
diff --git a/src/llvm-project b/src/llvm-project
-Subproject 38ad31bde8ff681d862dc0f96930a5dd9b7a472
+Subproject 4fc9fb8245abe24680192535870c4522644a421
diff --git a/src/test/debuginfo/auxiliary/issue13213aux.rs b/src/test/debuginfo/auxiliary/issue-13213-aux.rs
index bde98b44544..bde98b44544 100644
--- a/src/test/debuginfo/auxiliary/issue13213aux.rs
+++ b/src/test/debuginfo/auxiliary/issue-13213-aux.rs
diff --git a/src/test/debuginfo/issue-13213.rs b/src/test/debuginfo/issue-13213.rs
index 898ebe547b3..3c9a365fd4f 100644
--- a/src/test/debuginfo/issue-13213.rs
+++ b/src/test/debuginfo/issue-13213.rs
@@ -1,8 +1,8 @@
 // min-lldb-version: 310
 
-// aux-build:issue13213aux.rs
+// aux-build:issue-13213-aux.rs
 
-extern crate issue13213aux;
+extern crate issue_13213_aux;
 
 // compile-flags:-g
 
@@ -10,6 +10,6 @@ extern crate issue13213aux;
 // statics that are marked with AvailableExternallyLinkage in the importing crate, may actually not
 // be available because they have been optimized out from the exporting crate.
 fn main() {
-    let b: issue13213aux::S = issue13213aux::A;
+    let b: issue_13213_aux::S = issue_13213_aux::A;
     println!("Nothing to do here...");
 }
diff --git a/src/test/incremental/auxiliary/issue_49482_macro_def.rs b/src/test/incremental/auxiliary/issue-49482-macro-def.rs
index bfa7abb1a9d..bfa7abb1a9d 100644
--- a/src/test/incremental/auxiliary/issue_49482_macro_def.rs
+++ b/src/test/incremental/auxiliary/issue-49482-macro-def.rs
diff --git a/src/test/incremental/auxiliary/issue_49482_reexport.rs b/src/test/incremental/auxiliary/issue-49482-reexport.rs
index 39f19e3f15f..39f19e3f15f 100644
--- a/src/test/incremental/auxiliary/issue_49482_reexport.rs
+++ b/src/test/incremental/auxiliary/issue-49482-reexport.rs
diff --git a/src/test/incremental/auxiliary/issue_54059.rs b/src/test/incremental/auxiliary/issue-54059.rs
index fa2814a77f2..fa2814a77f2 100644
--- a/src/test/incremental/auxiliary/issue_54059.rs
+++ b/src/test/incremental/auxiliary/issue-54059.rs
diff --git a/src/test/incremental/issue-49482.rs b/src/test/incremental/issue-49482.rs
index 67d2c3876d7..042ecc0f279 100644
--- a/src/test/incremental/issue-49482.rs
+++ b/src/test/incremental/issue-49482.rs
@@ -1,5 +1,5 @@
-// aux-build:issue_49482_macro_def.rs
-// aux-build:issue_49482_reexport.rs
+// aux-build:issue-49482-macro-def.rs
+// aux-build:issue-49482-reexport.rs
 // revisions: rpass1
 
 extern crate issue_49482_reexport;
diff --git a/src/test/incremental/issue-49595/issue_49595.rs b/src/test/incremental/issue-49595/issue-49595.rs
index ada93f79b26..ada93f79b26 100644
--- a/src/test/incremental/issue-49595/issue_49595.rs
+++ b/src/test/incremental/issue-49595/issue-49595.rs
diff --git a/src/test/incremental/issue-54059.rs b/src/test/incremental/issue-54059.rs
index d78bbccf1bc..0a5a547509f 100644
--- a/src/test/incremental/issue-54059.rs
+++ b/src/test/incremental/issue-54059.rs
@@ -1,4 +1,4 @@
-// aux-build:issue_54059.rs
+// aux-build:issue-54059.rs
 // ignore-wasm32-bare no libc for ffi testing
 // ignore-windows - dealing with weird symbols issues on dylibs isn't worth it
 // revisions: rpass1
diff --git a/src/test/mir-opt/basic_assignment.rs b/src/test/mir-opt/basic_assignment.rs
index 1bbbe67a12c..3ce43cc4a22 100644
--- a/src/test/mir-opt/basic_assignment.rs
+++ b/src/test/mir-opt/basic_assignment.rs
@@ -35,7 +35,7 @@ fn main() {
 //        _2 = move _3;
 //        StorageDead(_3);
 //        StorageLive(_4);
-//        _4 = std::option::Option<std::boxed::Box<u32>>::None;
+//        _4 = std::option::Option::<std::boxed::Box<u32>>::None;
 //        FakeRead(ForLet, _4);
 //        AscribeUserType(_4, o, UserTypeProjection { base: UserType(1), projs: [] });
 //        StorageLive(_5);
diff --git a/src/test/mir-opt/issue-41697.rs b/src/test/mir-opt/issue-41697.rs
index 9db25b15f68..5a461d61482 100644
--- a/src/test/mir-opt/issue-41697.rs
+++ b/src/test/mir-opt/issue-41697.rs
@@ -1,7 +1,7 @@
 // Regression test for #41697. Using dump-mir was triggering
 // artificial cycles: during type-checking, we had to get the MIR for
 // the constant expressions in `[u8; 2]`, which in turn would trigger
-// an attempt to get the item-path, which in turn would request the
+// an attempt to get the def-path, which in turn would request the
 // types of the impl, which would trigger a cycle. We suppressed this
 // cycle now by forcing mir-dump to avoid asking for types of an impl.
 
diff --git a/src/test/mir-opt/match_false_edges.rs b/src/test/mir-opt/match_false_edges.rs
index ab6de71d289..9eeef8570a3 100644
--- a/src/test/mir-opt/match_false_edges.rs
+++ b/src/test/mir-opt/match_false_edges.rs
@@ -42,7 +42,7 @@ fn main() {
 // START rustc.full_tested_match.QualifyAndPromoteConstants.after.mir
 //  bb0: {
 //      ...
-//      _2 = std::option::Option<i32>::Some(const 42i32,);
+//      _2 = std::option::Option::<i32>::Some(const 42i32,);
 //      FakeRead(ForMatchedPlace, _2);
 //      _3 = discriminant(_2);
 //      switchInt(move _3) -> [0isize: bb4, 1isize: bb2, otherwise: bb7];
@@ -111,7 +111,7 @@ fn main() {
 // START rustc.full_tested_match2.QualifyAndPromoteConstants.before.mir
 //  bb0: {
 //      ...
-//      _2 = std::option::Option<i32>::Some(const 42i32,);
+//      _2 = std::option::Option::<i32>::Some(const 42i32,);
 //      FakeRead(ForMatchedPlace, _2);
 //      _3 = discriminant(_2);
 //      switchInt(move _3) -> [0isize: bb3, 1isize: bb2, otherwise: bb7];
@@ -180,7 +180,7 @@ fn main() {
 // START rustc.main.QualifyAndPromoteConstants.before.mir
 // bb0: {
 //     ...
-//      _2 = std::option::Option<i32>::Some(const 1i32,);
+//      _2 = std::option::Option::<i32>::Some(const 1i32,);
 //      FakeRead(ForMatchedPlace, _2);
 //      _3 = discriminant(_2);
 //      switchInt(move _3) -> [1isize: bb2, otherwise: bb3];
diff --git a/src/test/mir-opt/retag.rs b/src/test/mir-opt/retag.rs
index cdf63556737..3b333b5431c 100644
--- a/src/test/mir-opt/retag.rs
+++ b/src/test/mir-opt/retag.rs
@@ -98,7 +98,7 @@ fn main() {
 // }
 // END rustc.main.EraseRegions.after.mir
 // START rustc.main-{{closure}}.EraseRegions.after.mir
-// fn main::{{closure}}(_1: &[closure@HirId { owner: DefIndex(0:7), local_id: 70 }], _2: &i32) -> &i32 {
+// fn main::{{closure}}#0(_1: &[closure@HirId { owner: DefIndex(0:7), local_id: 70 }], _2: &i32) -> &i32 {
 //     ...
 //     bb0: {
 //         Retag([fn entry] _1);
diff --git a/src/test/mir-opt/storage_ranges.rs b/src/test/mir-opt/storage_ranges.rs
index a5d6ced2b17..9a22f57116e 100644
--- a/src/test/mir-opt/storage_ranges.rs
+++ b/src/test/mir-opt/storage_ranges.rs
@@ -18,7 +18,7 @@ fn main() {
 //         StorageLive(_4);
 //         StorageLive(_5);
 //         _5 = _1;
-//         _4 = std::option::Option<i32>::Some(move _5,);
+//         _4 = std::option::Option::<i32>::Some(move _5,);
 //         StorageDead(_5);
 //         _3 = &_4;
 //         FakeRead(ForLet, _3);
diff --git a/src/test/mir-opt/unusual-item-types.rs b/src/test/mir-opt/unusual-item-types.rs
index fe85baa048e..ced30381fda 100644
--- a/src/test/mir-opt/unusual-item-types.rs
+++ b/src/test/mir-opt/unusual-item-types.rs
@@ -7,11 +7,18 @@ impl A {
     const ASSOCIATED_CONSTANT: i32 = 2;
 }
 
+// See #59021
+enum Test {
+    X(usize),
+    Y { a: usize },
+}
+
 enum E {
     V = 5,
 }
 
 fn main() {
+    let f = Test::X as fn(usize) -> Test;
     let v = Vec::<i32>::new();
 }
 
@@ -64,3 +71,14 @@ fn main() {
 //     _3 = const std::ops::Drop::drop(move _2) -> [return: bb6, unwind: bb5];
 // }
 // END rustc.ptr-real_drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir
+
+// START rustc.Test-X.mir_map.0.mir
+// fn Test::X(_1: usize) -> Test {
+//     let mut _0: Test;
+//
+//     bb0: {
+//         _0 = Test::X(move _1,);
+//         return;
+//     }
+// }
+// END rustc.Test-X.mir_map.0.mir
diff --git a/src/test/pretty/issue_12590_a.rs b/src/test/pretty/issue-12590-a.rs
index 1ddd3c04263..1a9e85c42d8 100644
--- a/src/test/pretty/issue_12590_a.rs
+++ b/src/test/pretty/issue-12590-a.rs
@@ -2,6 +2,7 @@
 
 // The next line should not be expanded
 
+#[path = "issue-12590-b.rs"]
 mod issue_12590_b;
 
 fn main() { }
diff --git a/src/test/pretty/issue-12590-b.rs b/src/test/pretty/issue-12590-b.rs
new file mode 100644
index 00000000000..b14c7afa221
--- /dev/null
+++ b/src/test/pretty/issue-12590-b.rs
@@ -0,0 +1,5 @@
+// Second part of two-file test
+
+fn b() { }
+
+fn main() { }
diff --git a/src/test/pretty/issue_12590_c.pp b/src/test/pretty/issue-12590-c.pp
index 24182835303..1761c0653ce 100644
--- a/src/test/pretty/issue_12590_c.pp
+++ b/src/test/pretty/issue-12590-c.pp
@@ -6,10 +6,11 @@ use ::std::prelude::v1::*;
 extern crate std;
 // pretty-compare-only
 // pretty-mode:expanded
-// pp-exact:issue_12590_c.pp
+// pp-exact:issue-12590-c.pp
 
 // The next line should be expanded
 
+#[path = "issue-12590-b.rs"]
 mod issue_12590_b {
 
     fn b() { }
diff --git a/src/test/pretty/issue_12590_c.rs b/src/test/pretty/issue-12590-c.rs
index c0da36c2100..2cc444edda3 100644
--- a/src/test/pretty/issue_12590_c.rs
+++ b/src/test/pretty/issue-12590-c.rs
@@ -1,9 +1,10 @@
 // pretty-compare-only
 // pretty-mode:expanded
-// pp-exact:issue_12590_c.pp
+// pp-exact:issue-12590-c.pp
 
 // The next line should be expanded
 
+#[path = "issue-12590-b.rs"]
 mod issue_12590_b;
 
 fn main() { }
diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp
index b529beba783..ad663412e77 100644
--- a/src/test/pretty/issue-4264.pp
+++ b/src/test/pretty/issue-4264.pp
@@ -32,27 +32,27 @@ pub fn bar() ({
                   (($crate::fmt::format as
                        for<'r> fn(std::fmt::Arguments<'r>) -> std::string::String {std::fmt::format})(((<$crate::fmt::Arguments>::new_v1
                                                                                                            as
-                                                                                                           fn(&[&str], &[std::fmt::ArgumentV1<'_>]) -> std::fmt::Arguments<'_> {std::fmt::Arguments<'_>::new_v1})((&([("test"
+                                                                                                           fn(&[&str], &[std::fmt::ArgumentV1<'_>]) -> std::fmt::Arguments<'_> {std::fmt::Arguments::<'_>::new_v1})((&([("test"
+                                                                                                                                                                                                                            as
+                                                                                                                                                                                                                            &'static str)]
                                                                                                                                                                                                                           as
-                                                                                                                                                                                                                          &'static str)]
+                                                                                                                                                                                                                          [&str; 1])
                                                                                                                                                                                                                         as
-                                                                                                                                                                                                                        [&str; 1])
-                                                                                                                                                                                                                      as
-                                                                                                                                                                                                                      &[&str; 1]),
-                                                                                                                                                                                                                  (&(match (()
+                                                                                                                                                                                                                        &[&str; 1]),
+                                                                                                                                                                                                                    (&(match (()
+                                                                                                                                                                                                                                 as
+                                                                                                                                                                                                                                 ())
+                                                                                                                                                                                                                           {
+                                                                                                                                                                                                                           ()
+                                                                                                                                                                                                                           =>
+                                                                                                                                                                                                                           ([]
                                                                                                                                                                                                                                as
-                                                                                                                                                                                                                               ())
-                                                                                                                                                                                                                         {
-                                                                                                                                                                                                                         ()
-                                                                                                                                                                                                                         =>
-                                                                                                                                                                                                                         ([]
-                                                                                                                                                                                                                             as
-                                                                                                                                                                                                                             [std::fmt::ArgumentV1<'_>; 0]),
-                                                                                                                                                                                                                     }
+                                                                                                                                                                                                                               [std::fmt::ArgumentV1<'_>; 0]),
+                                                                                                                                                                                                                       }
+                                                                                                                                                                                                                          as
+                                                                                                                                                                                                                          [std::fmt::ArgumentV1<'_>; 0])
                                                                                                                                                                                                                         as
-                                                                                                                                                                                                                        [std::fmt::ArgumentV1<'_>; 0])
-                                                                                                                                                                                                                      as
-                                                                                                                                                                                                                      &[std::fmt::ArgumentV1<'_>; 0]))
+                                                                                                                                                                                                                        &[std::fmt::ArgumentV1<'_>; 0]))
                                                                                                           as
                                                                                                           std::fmt::Arguments<'_>))
                       as std::string::String);
diff --git a/src/test/pretty/issue_12590_b.rs b/src/test/pretty/issue_12590_b.rs
deleted file mode 100644
index f188f7bca69..00000000000
--- a/src/test/pretty/issue_12590_b.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-// Second part of two file test
-fn b() { }
-
-fn main() { }
diff --git a/src/test/run-pass-fulldeps/auxiliary/custom_derive_partial_eq.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-partial-eq.rs
index 4d6ff47a3ee..4d6ff47a3ee 100644
--- a/src/test/run-pass-fulldeps/auxiliary/custom_derive_partial_eq.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/custom-derive-partial-eq.rs
diff --git a/src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin_attr.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs
index 699972c9a85..699972c9a85 100644
--- a/src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin_attr.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs
diff --git a/src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin.rs
index 874a0ec7c13..874a0ec7c13 100644
--- a/src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin.rs
diff --git a/src/test/run-pass-fulldeps/auxiliary/issue_24106.rs b/src/test/run-pass-fulldeps/auxiliary/issue-24106.rs
index 2c6a6034806..2c6a6034806 100644
--- a/src/test/run-pass-fulldeps/auxiliary/issue_24106.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/issue-24106.rs
diff --git a/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs b/src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs
index f34e10218d4..f34e10218d4 100644
--- a/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs
diff --git a/src/test/run-pass-fulldeps/auxiliary/llvm_pass_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/llvm-pass-plugin.rs
index b5307446bca..b5307446bca 100644
--- a/src/test/run-pass-fulldeps/auxiliary/llvm_pass_plugin.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/llvm-pass-plugin.rs
diff --git a/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs b/src/test/run-pass-fulldeps/auxiliary/macro-crate-test.rs
index a2b1d6976d0..a2b1d6976d0 100644
--- a/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/macro-crate-test.rs
diff --git a/src/test/run-pass-fulldeps/auxiliary/plugin_args.rs b/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs
index 309acb25184..309acb25184 100644
--- a/src/test/run-pass-fulldeps/auxiliary/plugin_args.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs
diff --git a/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs b/src/test/run-pass-fulldeps/auxiliary/roman-numerals.rs
index 216c81ca34c..216c81ca34c 100644
--- a/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/roman-numerals.rs
diff --git a/src/test/run-pass-fulldeps/auxiliary/syntax_extension_with_dll_deps_1.rs b/src/test/run-pass-fulldeps/auxiliary/syntax-extension-with-dll-deps-1.rs
index 8b00fb81cd2..8b00fb81cd2 100644
--- a/src/test/run-pass-fulldeps/auxiliary/syntax_extension_with_dll_deps_1.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/syntax-extension-with-dll-deps-1.rs
diff --git a/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs b/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs
index 21b8ec7be98..ac8fff4f6bf 100644
--- a/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs
+++ b/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs
@@ -1,4 +1,4 @@
-// aux-build:custom_derive_partial_eq.rs
+// aux-build:custom-derive-partial-eq.rs
 // ignore-stage1
 #![feature(plugin)]
 #![plugin(custom_derive_partial_eq)]
diff --git a/src/test/run-pass-fulldeps/derive-totalsum-attr.rs b/src/test/run-pass-fulldeps/derive-totalsum-attr.rs
index 769861e7c94..38eaa71dd6a 100644
--- a/src/test/run-pass-fulldeps/derive-totalsum-attr.rs
+++ b/src/test/run-pass-fulldeps/derive-totalsum-attr.rs
@@ -1,4 +1,4 @@
-// aux-build:custom_derive_plugin_attr.rs
+// aux-build:custom-derive-plugin-attr.rs
 // ignore-stage1
 
 #![feature(plugin, rustc_attrs)]
diff --git a/src/test/run-pass-fulldeps/derive-totalsum.rs b/src/test/run-pass-fulldeps/derive-totalsum.rs
index be26943b6dc..2b0bb51d90a 100644
--- a/src/test/run-pass-fulldeps/derive-totalsum.rs
+++ b/src/test/run-pass-fulldeps/derive-totalsum.rs
@@ -1,4 +1,4 @@
-// aux-build:custom_derive_plugin.rs
+// aux-build:custom-derive-plugin.rs
 // ignore-stage1
 
 #![feature(plugin)]
diff --git a/src/test/run-pass-fulldeps/issue-15778-pass.rs b/src/test/run-pass-fulldeps/issue-15778-pass.rs
index 50e9b14b268..2add3ccbe36 100644
--- a/src/test/run-pass-fulldeps/issue-15778-pass.rs
+++ b/src/test/run-pass-fulldeps/issue-15778-pass.rs
@@ -1,4 +1,4 @@
-// aux-build:lint_for_crate.rs
+// aux-build:lint-for-crate.rs
 // ignore-stage1
 // compile-flags: -D crate-not-okay
 
diff --git a/src/test/run-pass-fulldeps/issue_24106.rs b/src/test/run-pass-fulldeps/issue-24106.rs
index a497d9f33ae..e8e85ff3377 100644
--- a/src/test/run-pass-fulldeps/issue_24106.rs
+++ b/src/test/run-pass-fulldeps/issue-24106.rs
@@ -1,4 +1,4 @@
-// aux-build:issue_24106.rs
+// aux-build:issue-24106.rs
 
 extern crate issue_24106;
 
diff --git a/src/test/run-pass-fulldeps/issue-40663.rs b/src/test/run-pass-fulldeps/issue-40663.rs
index cb01eddd7e4..133f6302bde 100644
--- a/src/test/run-pass-fulldeps/issue-40663.rs
+++ b/src/test/run-pass-fulldeps/issue-40663.rs
@@ -1,5 +1,5 @@
 #![allow(dead_code)]
-// aux-build:custom_derive_plugin.rs
+// aux-build:custom-derive-plugin.rs
 // ignore-stage1
 
 #![feature(plugin)]
diff --git a/src/test/run-pass-fulldeps/llvm-pass-plugin.rs b/src/test/run-pass-fulldeps/llvm-pass-plugin.rs
index 3aad40ecfe8..411631104a4 100644
--- a/src/test/run-pass-fulldeps/llvm-pass-plugin.rs
+++ b/src/test/run-pass-fulldeps/llvm-pass-plugin.rs
@@ -1,4 +1,4 @@
-// aux-build:llvm_pass_plugin.rs
+// aux-build:llvm-pass-plugin.rs
 // ignore-stage1
 
 #![feature(plugin)]
diff --git a/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs b/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs
index dcac160c4c9..573bfca3168 100644
--- a/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs
+++ b/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs
@@ -2,7 +2,7 @@
 #![allow(dead_code)]
 #![allow(unused_variables)]
 #![allow(unused_imports)]
-// aux-build:macro_crate_test.rs
+// aux-build:macro-crate-test.rs
 // ignore-stage1
 
 #![feature(rustc_attrs)]
diff --git a/src/test/run-pass-fulldeps/plugin-args-1.rs b/src/test/run-pass-fulldeps/plugin-args-1.rs
index 0111af1c768..1bdf004e305 100644
--- a/src/test/run-pass-fulldeps/plugin-args-1.rs
+++ b/src/test/run-pass-fulldeps/plugin-args-1.rs
@@ -1,4 +1,4 @@
-// aux-build:plugin_args.rs
+// aux-build:plugin-args.rs
 // ignore-stage1
 
 #![feature(plugin)]
diff --git a/src/test/run-pass-fulldeps/plugin-args-2.rs b/src/test/run-pass-fulldeps/plugin-args-2.rs
index e4a3dfab566..83091df0582 100644
--- a/src/test/run-pass-fulldeps/plugin-args-2.rs
+++ b/src/test/run-pass-fulldeps/plugin-args-2.rs
@@ -1,4 +1,4 @@
-// aux-build:plugin_args.rs
+// aux-build:plugin-args.rs
 // ignore-stage1
 
 #![feature(plugin)]
diff --git a/src/test/run-pass-fulldeps/plugin-args-3.rs b/src/test/run-pass-fulldeps/plugin-args-3.rs
index 4696233f281..9cd9bee5a0f 100644
--- a/src/test/run-pass-fulldeps/plugin-args-3.rs
+++ b/src/test/run-pass-fulldeps/plugin-args-3.rs
@@ -1,4 +1,4 @@
-// aux-build:plugin_args.rs
+// aux-build:plugin-args.rs
 // ignore-stage1
 
 #![feature(plugin)]
diff --git a/src/test/run-pass-fulldeps/roman-numerals-macro.rs b/src/test/run-pass-fulldeps/roman-numerals-macro.rs
index 59a2d132cdc..49c12e426fe 100644
--- a/src/test/run-pass-fulldeps/roman-numerals-macro.rs
+++ b/src/test/run-pass-fulldeps/roman-numerals-macro.rs
@@ -1,4 +1,4 @@
-// aux-build:roman_numerals.rs
+// aux-build:roman-numerals.rs
 // ignore-stage1
 
 #![feature(plugin)]
diff --git a/src/test/run-pass-fulldeps/undef_mask.rs b/src/test/run-pass-fulldeps/undef_mask.rs
new file mode 100644
index 00000000000..cf6e6f72316
--- /dev/null
+++ b/src/test/run-pass-fulldeps/undef_mask.rs
@@ -0,0 +1,26 @@
+// ignore-cross-compile
+// ignore-stage1
+
+#![feature(rustc_private)]
+
+extern crate rustc;
+
+use rustc::mir::interpret::UndefMask;
+use rustc::ty::layout::Size;
+
+fn main() {
+    let mut mask = UndefMask::new(Size::from_bytes(500), false);
+    assert!(!mask.get(Size::from_bytes(499)));
+    mask.set(Size::from_bytes(499), true);
+    assert!(mask.get(Size::from_bytes(499)));
+    mask.set_range_inbounds(Size::from_bytes(100), Size::from_bytes(256), true);
+    for i in 0..100 {
+        assert!(!mask.get(Size::from_bytes(i)));
+    }
+    for i in 100..256 {
+        assert!(mask.get(Size::from_bytes(i)));
+    }
+    for i in 256..499 {
+        assert!(!mask.get(Size::from_bytes(i)));
+    }
+}
diff --git a/src/test/run-pass/array-slice-vec/estr-slice.rs b/src/test/run-pass/array-slice-vec/estr-slice.rs
index 02b88f6a7ab..cd2c1722065 100644
--- a/src/test/run-pass/array-slice-vec/estr-slice.rs
+++ b/src/test/run-pass/array-slice-vec/estr-slice.rs
@@ -14,7 +14,7 @@ pub fn main() {
 
     let z : &str = "thing";
     assert_eq!(v, x);
-    assert!(x != z);
+    assert_ne!(x, z);
 
     let a = "aaaa";
     let b = "bbbb";
@@ -26,7 +26,7 @@ pub fn main() {
 
     assert!(a < b);
     assert!(a <= b);
-    assert!(a != b);
+    assert_ne!(a, b);
     assert!(b >= a);
     assert!(b > a);
 
@@ -34,7 +34,7 @@ pub fn main() {
 
     assert!(a < c);
     assert!(a <= c);
-    assert!(a != c);
+    assert_ne!(a, c);
     assert!(c >= a);
     assert!(c > a);
 
@@ -42,7 +42,7 @@ pub fn main() {
 
     assert!(c < cc);
     assert!(c <= cc);
-    assert!(c != cc);
+    assert_ne!(c, cc);
     assert!(cc >= c);
     assert!(cc > c);
 
diff --git a/src/test/run-pass/auxiliary/rmeta_rlib.rs b/src/test/run-pass/auxiliary/rmeta-rlib.rs
index f5e8c3d2a5c..f5e8c3d2a5c 100644
--- a/src/test/run-pass/auxiliary/rmeta_rlib.rs
+++ b/src/test/run-pass/auxiliary/rmeta-rlib.rs
diff --git a/src/test/run-pass/auxiliary/rmeta_rmeta.rs b/src/test/run-pass/auxiliary/rmeta-rmeta.rs
index 4a6d055a81f..4a6d055a81f 100644
--- a/src/test/run-pass/auxiliary/rmeta_rmeta.rs
+++ b/src/test/run-pass/auxiliary/rmeta-rmeta.rs
diff --git a/src/test/run-pass/issue-55809.rs b/src/test/run-pass/issue-55809.rs
new file mode 100644
index 00000000000..86b0977bebe
--- /dev/null
+++ b/src/test/run-pass/issue-55809.rs
@@ -0,0 +1,30 @@
+// edition:2018
+// run-pass
+
+#![feature(async_await, await_macro, futures_api)]
+
+trait Foo { }
+
+impl Foo for () { }
+
+impl<'a, T> Foo for &'a mut T where T: Foo { }
+
+async fn foo_async<T>(_v: T) -> u8 where T: Foo {
+    0
+}
+
+async fn bad<T>(v: T) -> u8 where T: Foo {
+    await!(foo_async(v))
+}
+
+async fn async_main() {
+    let mut v = ();
+
+    let _ = await!(bad(&mut v));
+    let _ = await!(foo_async(&mut v));
+    let _ = await!(bad(v));
+}
+
+fn main() {
+    let _ = async_main();
+}
diff --git a/src/test/run-pass/issues/auxiliary/issue_10031_aux.rs b/src/test/run-pass/issues/auxiliary/issue-10031-aux.rs
index e2abeb99ea8..e2abeb99ea8 100644
--- a/src/test/run-pass/issues/auxiliary/issue_10031_aux.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-10031-aux.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_12612_1.rs b/src/test/run-pass/issues/auxiliary/issue-12612-1.rs
index 01f5a784bb7..01f5a784bb7 100644
--- a/src/test/run-pass/issues/auxiliary/issue_12612_1.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-12612-1.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_12612_2.rs b/src/test/run-pass/issues/auxiliary/issue-12612-2.rs
index 2c724787193..2c724787193 100644
--- a/src/test/run-pass/issues/auxiliary/issue_12612_2.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-12612-2.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue13507.rs b/src/test/run-pass/issues/auxiliary/issue-13507.rs
index c91013043eb..c91013043eb 100644
--- a/src/test/run-pass/issues/auxiliary/issue13507.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-13507.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_19293.rs b/src/test/run-pass/issues/auxiliary/issue-19293.rs
index 31359e86559..31359e86559 100644
--- a/src/test/run-pass/issues/auxiliary/issue_19293.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-19293.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_20389.rs b/src/test/run-pass/issues/auxiliary/issue-20389.rs
index ae6d44eeb77..ae6d44eeb77 100644
--- a/src/test/run-pass/issues/auxiliary/issue_20389.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-20389.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue2170lib.rs b/src/test/run-pass/issues/auxiliary/issue-2170-lib.rs
index a99385a834d..a99385a834d 100644
--- a/src/test/run-pass/issues/auxiliary/issue2170lib.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-2170-lib.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_2316_a.rs b/src/test/run-pass/issues/auxiliary/issue-2316-a.rs
index 418ddc0b069..418ddc0b069 100644
--- a/src/test/run-pass/issues/auxiliary/issue_2316_a.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-2316-a.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_2316_b.rs b/src/test/run-pass/issues/auxiliary/issue-2316-b.rs
index 550c2d6eb22..550c2d6eb22 100644
--- a/src/test/run-pass/issues/auxiliary/issue_2316_b.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-2316-b.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_2472_b.rs b/src/test/run-pass/issues/auxiliary/issue-2472-b.rs
index 0d151520fe0..0d151520fe0 100644
--- a/src/test/run-pass/issues/auxiliary/issue_2472_b.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-2472-b.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_2723_a.rs b/src/test/run-pass/issues/auxiliary/issue-2723-a.rs
index 661b46d829d..661b46d829d 100644
--- a/src/test/run-pass/issues/auxiliary/issue_2723_a.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-2723-a.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_3136_a.rc b/src/test/run-pass/issues/auxiliary/issue-3136-a.rc
index 46da4132b82..cd5fd314505 100644
--- a/src/test/run-pass/issues/auxiliary/issue_3136_a.rc
+++ b/src/test/run-pass/issues/auxiliary/issue-3136-a.rc
@@ -1,3 +1,4 @@
 #![crate_type = "lib"]
 
+#[path = "issue-3136-a.rs"]
 pub mod issue_3136_a;
diff --git a/src/test/run-pass/issues/auxiliary/issue_3136_a.rs b/src/test/run-pass/issues/auxiliary/issue-3136-a.rs
index 9bb546ab393..9bb546ab393 100644
--- a/src/test/run-pass/issues/auxiliary/issue_3136_a.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-3136-a.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue34796aux.rs b/src/test/run-pass/issues/auxiliary/issue-34796-aux.rs
index 09c69b90329..09c69b90329 100644
--- a/src/test/run-pass/issues/auxiliary/issue34796aux.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-34796-aux.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_38190.rs b/src/test/run-pass/issues/auxiliary/issue-38190.rs
index 373e646ba2c..373e646ba2c 100644
--- a/src/test/run-pass/issues/auxiliary/issue_38190.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-38190.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_38226_aux.rs b/src/test/run-pass/issues/auxiliary/issue-38226-aux.rs
index f968017199f..f968017199f 100644
--- a/src/test/run-pass/issues/auxiliary/issue_38226_aux.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-38226-aux.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_38715-modern.rs b/src/test/run-pass/issues/auxiliary/issue-38715-modern.rs
index 15d072957cb..15d072957cb 100644
--- a/src/test/run-pass/issues/auxiliary/issue_38715-modern.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-38715-modern.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_38715.rs b/src/test/run-pass/issues/auxiliary/issue-38715.rs
index 5c15073f5a5..5c15073f5a5 100644
--- a/src/test/run-pass/issues/auxiliary/issue_38715.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-38715.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_3979_traits.rs b/src/test/run-pass/issues/auxiliary/issue-3979-traits.rs
index 5d03a0e9e99..5d03a0e9e99 100644
--- a/src/test/run-pass/issues/auxiliary/issue_3979_traits.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-3979-traits.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_39823.rs b/src/test/run-pass/issues/auxiliary/issue-39823.rs
index 3af9c68f233..3af9c68f233 100644
--- a/src/test/run-pass/issues/auxiliary/issue_39823.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-39823.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_40469.rs b/src/test/run-pass/issues/auxiliary/issue-40469.rs
index 4f2f41f2cde..4f2f41f2cde 100644
--- a/src/test/run-pass/issues/auxiliary/issue_40469.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-40469.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_41053.rs b/src/test/run-pass/issues/auxiliary/issue-41053.rs
index ae73c3e780f..ae73c3e780f 100644
--- a/src/test/run-pass/issues/auxiliary/issue_41053.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-41053.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_42007_s.rs b/src/test/run-pass/issues/auxiliary/issue-42007-s.rs
index 95119a589c9..95119a589c9 100644
--- a/src/test/run-pass/issues/auxiliary/issue_42007_s.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-42007-s.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_8401.rs b/src/test/run-pass/issues/auxiliary/issue-8401.rs
index e35dbbfabfc..e35dbbfabfc 100644
--- a/src/test/run-pass/issues/auxiliary/issue_8401.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-8401.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_9123.rs b/src/test/run-pass/issues/auxiliary/issue-9123.rs
index 60af53359e8..60af53359e8 100644
--- a/src/test/run-pass/issues/auxiliary/issue_9123.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-9123.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_9155.rs b/src/test/run-pass/issues/auxiliary/issue-9155.rs
index 049a96a655a..049a96a655a 100644
--- a/src/test/run-pass/issues/auxiliary/issue_9155.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-9155.rs
diff --git a/src/test/run-pass/issues/auxiliary/issue_9188.rs b/src/test/run-pass/issues/auxiliary/issue-9188.rs
index 3bc5697a1a6..3bc5697a1a6 100644
--- a/src/test/run-pass/issues/auxiliary/issue_9188.rs
+++ b/src/test/run-pass/issues/auxiliary/issue-9188.rs
diff --git a/src/test/run-pass/issues/issue-10031.rs b/src/test/run-pass/issues/issue-10031.rs
index ba1fbac4845..136df05c239 100644
--- a/src/test/run-pass/issues/issue-10031.rs
+++ b/src/test/run-pass/issues/issue-10031.rs
@@ -1,5 +1,5 @@
 // run-pass
-// aux-build:issue_10031_aux.rs
+// aux-build:issue-10031-aux.rs
 // pretty-expanded FIXME #23616
 
 extern crate issue_10031_aux;
diff --git a/src/test/run-pass/issues/issue-12612.rs b/src/test/run-pass/issues/issue-12612.rs
index 158c2aed137..d254f6941a3 100644
--- a/src/test/run-pass/issues/issue-12612.rs
+++ b/src/test/run-pass/issues/issue-12612.rs
@@ -1,7 +1,7 @@
 // run-pass
 #![allow(unused_imports)]
-// aux-build:issue_12612_1.rs
-// aux-build:issue_12612_2.rs
+// aux-build:issue-12612-1.rs
+// aux-build:issue-12612-2.rs
 
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/run-pass/issues/issue-13507-2.rs b/src/test/run-pass/issues/issue-13507-2.rs
index 4ea95149dc6..ce920a3ccab 100644
--- a/src/test/run-pass/issues/issue-13507-2.rs
+++ b/src/test/run-pass/issues/issue-13507-2.rs
@@ -1,14 +1,14 @@
 // run-pass
 #![allow(unused_imports)]
-// aux-build:issue13507.rs
+// aux-build:issue-13507.rs
 
-extern crate issue13507;
-use issue13507::testtypes;
+extern crate issue_13507;
+use issue_13507::testtypes;
 
 use std::any::TypeId;
 
 pub fn type_ids() -> Vec<TypeId> {
-    use issue13507::testtypes::*;
+    use issue_13507::testtypes::*;
     vec![
         TypeId::of::<FooBool>(),
         TypeId::of::<FooInt>(),
@@ -30,7 +30,7 @@ pub fn type_ids() -> Vec<TypeId> {
 }
 
 pub fn main() {
-    let othercrate = issue13507::testtypes::type_ids();
+    let othercrate = issue_13507::testtypes::type_ids();
     let thiscrate = type_ids();
     assert_eq!(thiscrate, othercrate);
 }
diff --git a/src/test/run-pass/issue-18952.rs b/src/test/run-pass/issues/issue-18952.rs
index 56378b59e36..56378b59e36 100644
--- a/src/test/run-pass/issue-18952.rs
+++ b/src/test/run-pass/issues/issue-18952.rs
diff --git a/src/test/run-pass/issues/issue-19293.rs b/src/test/run-pass/issues/issue-19293.rs
index 90f96566f38..b6e9e3d065a 100644
--- a/src/test/run-pass/issues/issue-19293.rs
+++ b/src/test/run-pass/issues/issue-19293.rs
@@ -1,5 +1,5 @@
 // run-pass
-// aux-build:issue_19293.rs
+// aux-build:issue-19293.rs
 // pretty-expanded FIXME #23616
 
 extern crate issue_19293;
diff --git a/src/test/run-pass/issues/issue-20389.rs b/src/test/run-pass/issues/issue-20389.rs
index 9c5a1844e29..9bc3efcc1c4 100644
--- a/src/test/run-pass/issues/issue-20389.rs
+++ b/src/test/run-pass/issues/issue-20389.rs
@@ -1,6 +1,6 @@
 // run-pass
 #![allow(dead_code)]
-// aux-build:issue_20389.rs
+// aux-build:issue-20389.rs
 
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/run-pass/issues/issue-2170-exe.rs b/src/test/run-pass/issues/issue-2170-exe.rs
new file mode 100644
index 00000000000..a89579706c8
--- /dev/null
+++ b/src/test/run-pass/issues/issue-2170-exe.rs
@@ -0,0 +1,9 @@
+// run-pass
+// aux-build:issue-2170-lib.rs
+// pretty-expanded FIXME #23616
+
+extern crate issue_2170_lib;
+
+pub fn main() {
+   // let _ = issue_2170_lib::rsrc(2);
+}
diff --git a/src/test/run-pass/issues/issue-2316-c.rs b/src/test/run-pass/issues/issue-2316-c.rs
index 6783f3fcfc6..d975aa695c8 100644
--- a/src/test/run-pass/issues/issue-2316-c.rs
+++ b/src/test/run-pass/issues/issue-2316-c.rs
@@ -1,6 +1,6 @@
 // run-pass
-// aux-build:issue_2316_a.rs
-// aux-build:issue_2316_b.rs
+// aux-build:issue-2316-a.rs
+// aux-build:issue-2316-b.rs
 
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/run-pass/issues/issue24687-embed-debuginfo/auxiliary/issue24687_lib.rs b/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs
index 3ae53baa82a..2275a8da696 100644
--- a/src/test/run-pass/issues/issue24687-embed-debuginfo/auxiliary/issue24687_lib.rs
+++ b/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs
@@ -4,7 +4,8 @@
 // that separate file has many multi-byte characters, to try to
 // encourage the compiler to trip on them.
 
-mod issue24687_mbcs_in_comments;
+#[path = "issue-24687-mbcs-in-comments.rs"]
+mod issue_24687_mbcs_in_comments;
 
-pub use issue24687_mbcs_in_comments::D;
+pub use issue_24687_mbcs_in_comments::D;
 
diff --git a/src/test/run-pass/issues/issue24687-embed-debuginfo/auxiliary/issue24687_mbcs_in_comments.rs b/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs
index 215145a64b1..215145a64b1 100644
--- a/src/test/run-pass/issues/issue24687-embed-debuginfo/auxiliary/issue24687_mbcs_in_comments.rs
+++ b/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs
diff --git a/src/test/run-pass/issues/issue24687-embed-debuginfo/main.rs b/src/test/run-pass/issues/issue-24687-embed-debuginfo/main.rs
index a0cda4fad26..773792c7a3f 100644
--- a/src/test/run-pass/issues/issue24687-embed-debuginfo/main.rs
+++ b/src/test/run-pass/issues/issue-24687-embed-debuginfo/main.rs
@@ -1,11 +1,11 @@
 // run-pass
-// aux-build:issue24687_lib.rs
+// aux-build:issue-24687-lib.rs
 // compile-flags:-g
 
-extern crate issue24687_lib as d;
+extern crate issue_24687_lib as d;
 
 fn main() {
-    // Create a d, which has a destructor whose body will be codegen'ed
+    // Create a `D`, which has a destructor whose body will be codegen'ed
     // into the generated code here, and thus the local debuginfo will
     // need references into the original source locations from
     // `importer` above.
diff --git a/src/test/run-pass/issues/issue-2472.rs b/src/test/run-pass/issues/issue-2472.rs
index cadd0151b4e..c790bc2d095 100644
--- a/src/test/run-pass/issues/issue-2472.rs
+++ b/src/test/run-pass/issues/issue-2472.rs
@@ -1,5 +1,5 @@
 // run-pass
-// aux-build:issue_2472_b.rs
+// aux-build:issue-2472-b.rs
 
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/run-pass/issues/issue-26873-multifile.rs b/src/test/run-pass/issues/issue-26873-multifile.rs
index 7b19713fcc6..da2acf6c9f7 100644
--- a/src/test/run-pass/issues/issue-26873-multifile.rs
+++ b/src/test/run-pass/issues/issue-26873-multifile.rs
@@ -5,6 +5,7 @@
 
 // ignore-pretty issue #37195
 
-mod issue_26873_multifile;
+#[path = "issue-26873-multifile/mod.rs"]
+mod multifile;
 
 fn main() {}
diff --git a/src/test/run-pass/issues/issue_26873_multifile/A/B.rs b/src/test/run-pass/issues/issue-26873-multifile/A/B.rs
index d1b802ff3cd..d1b802ff3cd 100644
--- a/src/test/run-pass/issues/issue_26873_multifile/A/B.rs
+++ b/src/test/run-pass/issues/issue-26873-multifile/A/B.rs
diff --git a/src/test/run-pass/issues/issue_26873_multifile/A/C.rs b/src/test/run-pass/issues/issue-26873-multifile/A/C.rs
index 88f3eb04afb..88f3eb04afb 100644
--- a/src/test/run-pass/issues/issue_26873_multifile/A/C.rs
+++ b/src/test/run-pass/issues/issue-26873-multifile/A/C.rs
diff --git a/src/test/run-pass/issues/issue_26873_multifile/A/mod.rs b/src/test/run-pass/issues/issue-26873-multifile/A/mod.rs
index 20f40a06782..20f40a06782 100644
--- a/src/test/run-pass/issues/issue_26873_multifile/A/mod.rs
+++ b/src/test/run-pass/issues/issue-26873-multifile/A/mod.rs
diff --git a/src/test/run-pass/issues/issue_26873_multifile/compiletest-ignore-dir b/src/test/run-pass/issues/issue-26873-multifile/compiletest-ignore-dir
index e69de29bb2d..e69de29bb2d 100644
--- a/src/test/run-pass/issues/issue_26873_multifile/compiletest-ignore-dir
+++ b/src/test/run-pass/issues/issue-26873-multifile/compiletest-ignore-dir
diff --git a/src/test/run-pass/issues/issue_26873_multifile/mod.rs b/src/test/run-pass/issues/issue-26873-multifile/mod.rs
index 52deea79a20..52deea79a20 100644
--- a/src/test/run-pass/issues/issue_26873_multifile/mod.rs
+++ b/src/test/run-pass/issues/issue-26873-multifile/mod.rs
diff --git a/src/test/run-pass/issues/issue-2723-b.rs b/src/test/run-pass/issues/issue-2723-b.rs
index 41f264b6dc0..1910561d0ba 100644
--- a/src/test/run-pass/issues/issue-2723-b.rs
+++ b/src/test/run-pass/issues/issue-2723-b.rs
@@ -1,5 +1,5 @@
 // run-pass
-// aux-build:issue_2723_a.rs
+// aux-build:issue-2723-a.rs
 
 extern crate issue_2723_a;
 use issue_2723_a::f;
diff --git a/src/test/run-pass/issues/issue28498-must-work-ex1.rs b/src/test/run-pass/issues/issue-28498-must-work-ex1.rs
index 4699d3352ad..4699d3352ad 100644
--- a/src/test/run-pass/issues/issue28498-must-work-ex1.rs
+++ b/src/test/run-pass/issues/issue-28498-must-work-ex1.rs
diff --git a/src/test/run-pass/issues/issue28498-must-work-ex2.rs b/src/test/run-pass/issues/issue-28498-must-work-ex2.rs
index 17111308555..17111308555 100644
--- a/src/test/run-pass/issues/issue28498-must-work-ex2.rs
+++ b/src/test/run-pass/issues/issue-28498-must-work-ex2.rs
diff --git a/src/test/run-pass/issues/issue28498-ugeh-ex1.rs b/src/test/run-pass/issues/issue-28498-ugeh-ex1.rs
index 65d5588871b..65d5588871b 100644
--- a/src/test/run-pass/issues/issue28498-ugeh-ex1.rs
+++ b/src/test/run-pass/issues/issue-28498-ugeh-ex1.rs
diff --git a/src/test/run-pass/issues/issue28498-ugeh-with-lifetime-param.rs b/src/test/run-pass/issues/issue-28498-ugeh-with-lifetime-param.rs
index 573ec8f6131..573ec8f6131 100644
--- a/src/test/run-pass/issues/issue28498-ugeh-with-lifetime-param.rs
+++ b/src/test/run-pass/issues/issue-28498-ugeh-with-lifetime-param.rs
diff --git a/src/test/run-pass/issues/issue28498-ugeh-with-passed-to-fn.rs b/src/test/run-pass/issues/issue-28498-ugeh-with-passed-to-fn.rs
index e0863fa9947..e0863fa9947 100644
--- a/src/test/run-pass/issues/issue28498-ugeh-with-passed-to-fn.rs
+++ b/src/test/run-pass/issues/issue-28498-ugeh-with-passed-to-fn.rs
diff --git a/src/test/run-pass/issues/issue28498-ugeh-with-trait-bound.rs b/src/test/run-pass/issues/issue-28498-ugeh-with-trait-bound.rs
index 01d884584f6..01d884584f6 100644
--- a/src/test/run-pass/issues/issue28498-ugeh-with-trait-bound.rs
+++ b/src/test/run-pass/issues/issue-28498-ugeh-with-trait-bound.rs
diff --git a/src/test/run-pass/issues/issue29927-1.rs b/src/test/run-pass/issues/issue-29927-1.rs
index a236e491375..a236e491375 100644
--- a/src/test/run-pass/issues/issue29927-1.rs
+++ b/src/test/run-pass/issues/issue-29927-1.rs
diff --git a/src/test/run-pass/issues/issue_3136_b.rs b/src/test/run-pass/issues/issue-3136-b.rs
index f0bdd2b5ec0..c4ca7236e76 100644
--- a/src/test/run-pass/issues/issue_3136_b.rs
+++ b/src/test/run-pass/issues/issue-3136-b.rs
@@ -1,7 +1,8 @@
 // run-pass
-// aux-build:issue_3136_a.rc
+// aux-build:issue-3136-a.rc
 
 // pretty-expanded FIXME #23616
 
 extern crate issue_3136_a;
+
 pub fn main() {}
diff --git a/src/test/run-pass/issues/issue-34796.rs b/src/test/run-pass/issues/issue-34796.rs
index a81040b8f4d..88d5c50a27d 100644
--- a/src/test/run-pass/issues/issue-34796.rs
+++ b/src/test/run-pass/issues/issue-34796.rs
@@ -8,8 +8,8 @@
 // the symbol name.
 // The fix was to make the order in which predicates get encoded stable.
 
-// aux-build:issue34796aux.rs
-extern crate issue34796aux;
+// aux-build:issue-34796-aux.rs
+extern crate issue_34796_aux;
 
 fn mk<T>() -> T { loop {} }
 
@@ -19,7 +19,7 @@ struct Data<T, E> {
 }
 
 fn main() {
-    issue34796aux::bar(|()| {
+    issue_34796_aux::bar(|()| {
         Data::<(), std::io::Error> {
             data: mk(),
             error: mk(),
diff --git a/src/test/run-pass/issues/issue-38190.rs b/src/test/run-pass/issues/issue-38190.rs
index 4f83dd26383..cfa0420c80d 100644
--- a/src/test/run-pass/issues/issue-38190.rs
+++ b/src/test/run-pass/issues/issue-38190.rs
@@ -1,12 +1,15 @@
 // run-pass
-// aux-build:issue_38190.rs
+// aux-build:issue-38190.rs
 // ignore-pretty issue #37195
 
 #[macro_use]
 extern crate issue_38190;
 
 mod auxiliary {
-    m!([mod issue_38190;]);
+    m!([
+        #[path = "issue-38190.rs"]
+        mod issue_38190;
+    ]);
 }
 
 fn main() {}
diff --git a/src/test/run-pass/issues/issue-38226.rs b/src/test/run-pass/issues/issue-38226.rs
index cd569c583f3..3213e3618a8 100644
--- a/src/test/run-pass/issues/issue-38226.rs
+++ b/src/test/run-pass/issues/issue-38226.rs
@@ -2,7 +2,7 @@
 // This test makes sure that we don't run into a linker error because of the
 // middle::reachable pass missing trait methods with default impls.
 
-// aux-build:issue_38226_aux.rs
+// aux-build:issue-38226-aux.rs
 
 // Need -Cno-prepopulate-passes to really disable inlining, otherwise the faulty
 // code gets optimized out:
diff --git a/src/test/run-pass/issues/issue-38715.rs b/src/test/run-pass/issues/issue-38715.rs
index 9d793147e24..e3c3a027f3c 100644
--- a/src/test/run-pass/issues/issue-38715.rs
+++ b/src/test/run-pass/issues/issue-38715.rs
@@ -1,6 +1,6 @@
 // run-pass
-// aux-build:issue_38715.rs
-// aux-build:issue_38715-modern.rs
+// aux-build:issue-38715.rs
+// aux-build:issue-38715-modern.rs
 
 // Test that `#[macro_export] macro_rules!` shadow earlier `#[macro_export] macro_rules!`
 
diff --git a/src/test/run-pass/issues/issue-3979-xcrate.rs b/src/test/run-pass/issues/issue-3979-xcrate.rs
index 0e47dee5b65..fcb1f55c32f 100644
--- a/src/test/run-pass/issues/issue-3979-xcrate.rs
+++ b/src/test/run-pass/issues/issue-3979-xcrate.rs
@@ -1,6 +1,6 @@
 // run-pass
 #![allow(dead_code)]
-// aux-build:issue_3979_traits.rs
+// aux-build:issue-3979-traits.rs
 
 extern crate issue_3979_traits;
 use issue_3979_traits::{Positioned, Movable};
diff --git a/src/test/run-pass/issues/issue-39823.rs b/src/test/run-pass/issues/issue-39823.rs
index 8a52399273b..0dfa8a75c4f 100644
--- a/src/test/run-pass/issues/issue-39823.rs
+++ b/src/test/run-pass/issues/issue-39823.rs
@@ -1,5 +1,5 @@
 // run-pass
-// aux-build:issue_39823.rs
+// aux-build:issue-39823.rs
 
 extern crate issue_39823;
 use issue_39823::{RemoteC, RemoteG};
diff --git a/src/test/run-pass/issues/issue-40469.rs b/src/test/run-pass/issues/issue-40469.rs
index 2e8247e032b..25e08ef85e9 100644
--- a/src/test/run-pass/issues/issue-40469.rs
+++ b/src/test/run-pass/issues/issue-40469.rs
@@ -3,7 +3,7 @@
 
 #![allow(dead_code)]
 
-include!("auxiliary/issue_40469.rs");
+include!("auxiliary/issue-40469.rs");
 fn f() { m!(); }
 
 fn main() {}
diff --git a/src/test/run-pass/issues/issue-41053.rs b/src/test/run-pass/issues/issue-41053.rs
index b9d8f00ff21..cd7a0a22623 100644
--- a/src/test/run-pass/issues/issue-41053.rs
+++ b/src/test/run-pass/issues/issue-41053.rs
@@ -1,5 +1,5 @@
 // run-pass
-// aux-build:issue_41053.rs
+// aux-build:issue-41053.rs
 
 pub trait Trait { fn foo(&self) {} }
 
diff --git a/src/test/run-pass/issues/issue-42007.rs b/src/test/run-pass/issues/issue-42007.rs
index de1367ec80f..a477e476eb9 100644
--- a/src/test/run-pass/issues/issue-42007.rs
+++ b/src/test/run-pass/issues/issue-42007.rs
@@ -1,6 +1,6 @@
 // run-pass
 #![allow(dead_code)]
-// aux-build:issue_42007_s.rs
+// aux-build:issue-42007-s.rs
 
 extern crate issue_42007_s;
 
diff --git a/src/test/run-pass/issue-45510.rs b/src/test/run-pass/issues/issue-45510.rs
index 9e104ce6c4f..9e104ce6c4f 100644
--- a/src/test/run-pass/issue-45510.rs
+++ b/src/test/run-pass/issues/issue-45510.rs
diff --git a/src/test/run-pass/issue-48006.rs b/src/test/run-pass/issues/issue-48006.rs
index 8e7105cf10c..8e7105cf10c 100644
--- a/src/test/run-pass/issue-48006.rs
+++ b/src/test/run-pass/issues/issue-48006.rs
diff --git a/src/test/run-pass/issue-53728.rs b/src/test/run-pass/issues/issue-53728.rs
index 00666972e25..00666972e25 100644
--- a/src/test/run-pass/issue-53728.rs
+++ b/src/test/run-pass/issues/issue-53728.rs
diff --git a/src/test/run-pass/issue-53843.rs b/src/test/run-pass/issues/issue-53843.rs
index 53728ec4d9f..53728ec4d9f 100644
--- a/src/test/run-pass/issue-53843.rs
+++ b/src/test/run-pass/issues/issue-53843.rs
diff --git a/src/test/run-pass/issue-54462-mutable-noalias-correctness.rs b/src/test/run-pass/issues/issue-54462-mutable-noalias-correctness.rs
index e7966b2978f..e7966b2978f 100644
--- a/src/test/run-pass/issue-54462-mutable-noalias-correctness.rs
+++ b/src/test/run-pass/issues/issue-54462-mutable-noalias-correctness.rs
diff --git a/src/test/run-pass/issue-54467.rs b/src/test/run-pass/issues/issue-54467.rs
index 52a9828b548..52a9828b548 100644
--- a/src/test/run-pass/issue-54467.rs
+++ b/src/test/run-pass/issues/issue-54467.rs
diff --git a/src/test/run-pass/issue-55376.rs b/src/test/run-pass/issues/issue-55376.rs
index fa92a85a445..fa92a85a445 100644
--- a/src/test/run-pass/issue-55376.rs
+++ b/src/test/run-pass/issues/issue-55376.rs
diff --git a/src/test/run-pass/issue-55380.rs b/src/test/run-pass/issues/issue-55380.rs
index 862218e2192..862218e2192 100644
--- a/src/test/run-pass/issue-55380.rs
+++ b/src/test/run-pass/issues/issue-55380.rs
diff --git a/src/test/run-pass/issue-56237.rs b/src/test/run-pass/issues/issue-56237.rs
index 87e10e83612..87e10e83612 100644
--- a/src/test/run-pass/issue-56237.rs
+++ b/src/test/run-pass/issues/issue-56237.rs
diff --git a/src/test/run-pass/issues/issue-57924.rs b/src/test/run-pass/issues/issue-57924.rs
new file mode 100644
index 00000000000..232596334b0
--- /dev/null
+++ b/src/test/run-pass/issues/issue-57924.rs
@@ -0,0 +1,9 @@
+pub struct Gcm<E>(E);
+
+impl<E> Gcm<E> {
+    pub fn crash(e: E) -> Self {
+        Self::<E>(e)
+    }
+}
+
+fn main() {}
diff --git a/src/test/run-pass/issues/issue-8401.rs b/src/test/run-pass/issues/issue-8401.rs
index 97d66c5e40f..1257bab6c0c 100644
--- a/src/test/run-pass/issues/issue-8401.rs
+++ b/src/test/run-pass/issues/issue-8401.rs
@@ -1,5 +1,5 @@
 // run-pass
-// aux-build:issue_8401.rs
+// aux-build:issue-8401.rs
 
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/run-pass/issues/issue-9123.rs b/src/test/run-pass/issues/issue-9123.rs
index 5072ca6ba53..8c21d06c477 100644
--- a/src/test/run-pass/issues/issue-9123.rs
+++ b/src/test/run-pass/issues/issue-9123.rs
@@ -1,5 +1,5 @@
 // run-pass
-// aux-build:issue_9123.rs
+// aux-build:issue-9123.rs
 
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/run-pass/issues/issue_9155.rs b/src/test/run-pass/issues/issue-9155.rs
index 87c453be142..4b5c451e853 100644
--- a/src/test/run-pass/issues/issue_9155.rs
+++ b/src/test/run-pass/issues/issue-9155.rs
@@ -1,5 +1,5 @@
 // run-pass
-// aux-build:issue_9155.rs
+// aux-build:issue-9155.rs
 
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/run-pass/issues/issue-9188.rs b/src/test/run-pass/issues/issue-9188.rs
index d7c39e9d505..34e61fdf68b 100644
--- a/src/test/run-pass/issues/issue-9188.rs
+++ b/src/test/run-pass/issues/issue-9188.rs
@@ -1,5 +1,5 @@
 // run-pass
-// aux-build:issue_9188.rs
+// aux-build:issue-9188.rs
 
 
 extern crate issue_9188;
diff --git a/src/test/run-pass/issues/issue2170exe.rs b/src/test/run-pass/issues/issue2170exe.rs
deleted file mode 100644
index 4169ddf9bb7..00000000000
--- a/src/test/run-pass/issues/issue2170exe.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// run-pass
-// aux-build:issue2170lib.rs
-// pretty-expanded FIXME #23616
-
-extern crate issue2170lib;
-
-pub fn main() {
-   // let _ = issue2170lib::rsrc(2);
-}
diff --git a/src/test/run-pass/rmeta.rs b/src/test/run-pass/rmeta.rs
index bd8125bbb56..cbbdd78dc20 100644
--- a/src/test/run-pass/rmeta.rs
+++ b/src/test/run-pass/rmeta.rs
@@ -1,8 +1,8 @@
 // Test that using rlibs and rmeta dep crates work together. Specifically, that
 // there can be both an rmeta and an rlib file and rustc will prefer the rlib.
 
-// aux-build:rmeta_rmeta.rs
-// aux-build:rmeta_rlib.rs
+// aux-build:rmeta-rmeta.rs
+// aux-build:rmeta-rlib.rs
 
 extern crate rmeta_aux;
 use rmeta_aux::Foo;
diff --git a/src/test/run-pass/simd/simd-size-align.rs b/src/test/run-pass/simd/simd-size-align.rs
index 0a537071a3c..556013788c3 100644
--- a/src/test/run-pass/simd/simd-size-align.rs
+++ b/src/test/run-pass/simd/simd-size-align.rs
@@ -37,6 +37,22 @@ fn main() {
     check::<f32x6>();
     check::<f32x7>();
     check::<f32x8>();
+
+    check::<usizex2>();
+    check::<usizex3>();
+    check::<usizex4>();
+    check::<usizex5>();
+    check::<usizex6>();
+    check::<usizex7>();
+    check::<usizex8>();
+
+    check::<isizex2>();
+    check::<isizex3>();
+    check::<isizex4>();
+    check::<isizex5>();
+    check::<isizex6>();
+    check::<isizex7>();
+    check::<isizex8>();
 }
 
 #[repr(simd)] struct u8x2(u8, u8);
@@ -62,3 +78,19 @@ fn main() {
 #[repr(simd)] struct f32x6(f32, f32, f32, f32, f32, f32);
 #[repr(simd)] struct f32x7(f32, f32, f32, f32, f32, f32, f32);
 #[repr(simd)] struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32);
+
+#[repr(simd)] struct usizex2(usize, usize);
+#[repr(simd)] struct usizex3(usize, usize, usize);
+#[repr(simd)] struct usizex4(usize, usize, usize, usize);
+#[repr(simd)] struct usizex5(usize, usize, usize, usize, usize);
+#[repr(simd)] struct usizex6(usize, usize, usize, usize, usize, usize);
+#[repr(simd)] struct usizex7(usize, usize, usize, usize, usize, usize, usize);
+#[repr(simd)] struct usizex8(usize, usize, usize, usize, usize, usize, usize, usize);
+
+#[repr(simd)] struct isizex2(isize, isize);
+#[repr(simd)] struct isizex3(isize, isize, isize);
+#[repr(simd)] struct isizex4(isize, isize, isize, isize);
+#[repr(simd)] struct isizex5(isize, isize, isize, isize, isize);
+#[repr(simd)] struct isizex6(isize, isize, isize, isize, isize, isize);
+#[repr(simd)] struct isizex7(isize, isize, isize, isize, isize, isize, isize);
+#[repr(simd)] struct isizex8(isize, isize, isize, isize, isize, isize, isize, isize);
diff --git a/src/test/rustdoc/auxiliary/enum_primitive.rs b/src/test/rustdoc/auxiliary/enum-primitive.rs
index ed1da253a97..ed1da253a97 100644
--- a/src/test/rustdoc/auxiliary/enum_primitive.rs
+++ b/src/test/rustdoc/auxiliary/enum-primitive.rs
diff --git a/src/test/rustdoc/auxiliary/reexp_stripped.rs b/src/test/rustdoc/auxiliary/reexp-stripped.rs
index ccc3dc11fd1..ccc3dc11fd1 100644
--- a/src/test/rustdoc/auxiliary/reexp_stripped.rs
+++ b/src/test/rustdoc/auxiliary/reexp-stripped.rs
diff --git a/src/test/rustdoc/no-stack-overflow-25295.rs b/src/test/rustdoc/no-stack-overflow-25295.rs
index 7e5c0279031..dd79f1e4baa 100644
--- a/src/test/rustdoc/no-stack-overflow-25295.rs
+++ b/src/test/rustdoc/no-stack-overflow-25295.rs
@@ -1,5 +1,5 @@
-// ensure this code doesn't stack overflow
-// aux-build:enum_primitive.rs
+// Ensure this code doesn't stack overflow.
+// aux-build:enum-primitive.rs
 
 #[macro_use] extern crate enum_primitive;
 
@@ -33,4 +33,3 @@ enum_from_primitive! {
         Z1,Z2,Z3,Z4,Z5,Z6,
     }
 }
-
diff --git a/src/test/rustdoc/redirect.rs b/src/test/rustdoc/redirect.rs
index 65c57ab65be..e3a14c7a74a 100644
--- a/src/test/rustdoc/redirect.rs
+++ b/src/test/rustdoc/redirect.rs
@@ -1,4 +1,4 @@
-// aux-build:reexp_stripped.rs
+// aux-build:reexp-stripped.rs
 // build-aux-docs
 // ignore-cross-compile
 
diff --git a/src/test/ui-fulldeps/auxiliary/attr_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/attr-plugin-test.rs
index c83e7bdb998..c83e7bdb998 100644
--- a/src/test/ui-fulldeps/auxiliary/attr_plugin_test.rs
+++ b/src/test/ui-fulldeps/auxiliary/attr-plugin-test.rs
diff --git a/src/test/ui-fulldeps/auxiliary/lint_for_crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs
index 82aa28b26b6..82aa28b26b6 100644
--- a/src/test/ui-fulldeps/auxiliary/lint_for_crate.rs
+++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs
diff --git a/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs
index 16630e2b312..16630e2b312 100644
--- a/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs
+++ b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs
diff --git a/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs
index 4e45189b424..4e45189b424 100644
--- a/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs
+++ b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs
diff --git a/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs
index d25a5ea3746..d25a5ea3746 100644
--- a/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs
+++ b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs
diff --git a/src/test/ui-fulldeps/auxiliary/rlib_crate_test.rs b/src/test/ui-fulldeps/auxiliary/rlib-crate-test.rs
index 3df40df7b33..3df40df7b33 100644
--- a/src/test/ui-fulldeps/auxiliary/rlib_crate_test.rs
+++ b/src/test/ui-fulldeps/auxiliary/rlib-crate-test.rs
diff --git a/src/test/ui-fulldeps/dropck_tarena_cycle_checked.rs b/src/test/ui-fulldeps/dropck-tarena-cycle-checked.rs
index a7e8131342f..a7e8131342f 100644
--- a/src/test/ui-fulldeps/dropck_tarena_cycle_checked.rs
+++ b/src/test/ui-fulldeps/dropck-tarena-cycle-checked.rs
diff --git a/src/test/ui-fulldeps/dropck_tarena_cycle_checked.stderr b/src/test/ui-fulldeps/dropck-tarena-cycle-checked.stderr
index 37d8b964c24..b6d5ee0cafe 100644
--- a/src/test/ui-fulldeps/dropck_tarena_cycle_checked.stderr
+++ b/src/test/ui-fulldeps/dropck-tarena-cycle-checked.stderr
@@ -1,5 +1,5 @@
 error[E0597]: `arena` does not live long enough
-  --> $DIR/dropck_tarena_cycle_checked.rs:116:8
+  --> $DIR/dropck-tarena-cycle-checked.rs:116:8
    |
 LL |     f(&arena);
    |        ^^^^^ borrowed value does not live long enough
diff --git a/src/test/ui-fulldeps/dropck_tarena_unsound_drop.rs b/src/test/ui-fulldeps/dropck-tarena-unsound-drop.rs
index 3103aef36cb..3103aef36cb 100644
--- a/src/test/ui-fulldeps/dropck_tarena_unsound_drop.rs
+++ b/src/test/ui-fulldeps/dropck-tarena-unsound-drop.rs
diff --git a/src/test/ui-fulldeps/dropck_tarena_unsound_drop.stderr b/src/test/ui-fulldeps/dropck-tarena-unsound-drop.stderr
index c791b8b451e..1e612f04983 100644
--- a/src/test/ui-fulldeps/dropck_tarena_unsound_drop.stderr
+++ b/src/test/ui-fulldeps/dropck-tarena-unsound-drop.stderr
@@ -1,5 +1,5 @@
 error[E0597]: `arena` does not live long enough
-  --> $DIR/dropck_tarena_unsound_drop.rs:41:8
+  --> $DIR/dropck-tarena-unsound-drop.rs:41:8
    |
 LL |     f(&arena);
    |        ^^^^^ borrowed value does not live long enough
diff --git a/src/test/ui-fulldeps/gated-plugin.rs b/src/test/ui-fulldeps/gated-plugin.rs
index a647585e621..be1ec061480 100644
--- a/src/test/ui-fulldeps/gated-plugin.rs
+++ b/src/test/ui-fulldeps/gated-plugin.rs
@@ -1,4 +1,4 @@
-// aux-build:attr_plugin_test.rs
+// aux-build:attr-plugin-test.rs
 
 #![plugin(attr_plugin_test)]
 //~^ ERROR compiler plugins are experimental and possibly buggy
diff --git a/src/test/ui-fulldeps/issue-15778-fail.rs b/src/test/ui-fulldeps/issue-15778-fail.rs
index 91c379673b3..75c52fdb4bd 100644
--- a/src/test/ui-fulldeps/issue-15778-fail.rs
+++ b/src/test/ui-fulldeps/issue-15778-fail.rs
@@ -1,4 +1,4 @@
-// aux-build:lint_for_crate.rs
+// aux-build:lint-for-crate.rs
 // ignore-stage1
 // compile-flags: -D crate-not-okay
 
diff --git a/src/test/ui-fulldeps/lint-group-plugin-deny-cmdline.rs b/src/test/ui-fulldeps/lint-group-plugin-deny-cmdline.rs
index 75e0a8fc31f..c9d8654a909 100644
--- a/src/test/ui-fulldeps/lint-group-plugin-deny-cmdline.rs
+++ b/src/test/ui-fulldeps/lint-group-plugin-deny-cmdline.rs
@@ -1,4 +1,4 @@
-// aux-build:lint_group_plugin_test.rs
+// aux-build:lint-group-plugin-test.rs
 // ignore-stage1
 // compile-flags: -D lint-me
 
diff --git a/src/test/ui-fulldeps/lint-group-plugin.rs b/src/test/ui-fulldeps/lint-group-plugin.rs
index 7a650afe5f8..55a880be0f9 100644
--- a/src/test/ui-fulldeps/lint-group-plugin.rs
+++ b/src/test/ui-fulldeps/lint-group-plugin.rs
@@ -1,5 +1,5 @@
 // run-pass
-// aux-build:lint_group_plugin_test.rs
+// aux-build:lint-group-plugin-test.rs
 // ignore-stage1
 
 #![feature(plugin)]
diff --git a/src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs b/src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs
index 21042c5e7d0..8017379ab3d 100644
--- a/src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs
+++ b/src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs
@@ -1,5 +1,5 @@
 // run-pass
-// aux-build:lint_plugin_test.rs
+// aux-build:lint-plugin-test.rs
 // ignore-stage1
 // compile-flags: -A test-lint
 
diff --git a/src/test/ui-fulldeps/lint-plugin-cmdline-load.rs b/src/test/ui-fulldeps/lint-plugin-cmdline-load.rs
index 0dca00040bf..fd681536b5b 100644
--- a/src/test/ui-fulldeps/lint-plugin-cmdline-load.rs
+++ b/src/test/ui-fulldeps/lint-plugin-cmdline-load.rs
@@ -1,5 +1,5 @@
 // run-pass
-// aux-build:lint_plugin_test.rs
+// aux-build:lint-plugin-test.rs
 // ignore-stage1
 // compile-flags: -Z extra-plugins=lint_plugin_test
 
diff --git a/src/test/ui-fulldeps/lint-plugin-deny-attr.rs b/src/test/ui-fulldeps/lint-plugin-deny-attr.rs
index 65a36236180..2d424af8707 100644
--- a/src/test/ui-fulldeps/lint-plugin-deny-attr.rs
+++ b/src/test/ui-fulldeps/lint-plugin-deny-attr.rs
@@ -1,4 +1,4 @@
-// aux-build:lint_plugin_test.rs
+// aux-build:lint-plugin-test.rs
 // ignore-stage1
 
 #![feature(plugin)]
diff --git a/src/test/ui-fulldeps/lint-plugin-deny-cmdline.rs b/src/test/ui-fulldeps/lint-plugin-deny-cmdline.rs
index b0c4dc0bce5..87324e85b3b 100644
--- a/src/test/ui-fulldeps/lint-plugin-deny-cmdline.rs
+++ b/src/test/ui-fulldeps/lint-plugin-deny-cmdline.rs
@@ -1,4 +1,4 @@
-// aux-build:lint_plugin_test.rs
+// aux-build:lint-plugin-test.rs
 // ignore-stage1
 // compile-flags: -D test-lint
 
diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs
index 964fed3b37d..c7f7f2be99e 100644
--- a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs
+++ b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs
@@ -1,4 +1,4 @@
-// aux-build:lint_plugin_test.rs
+// aux-build:lint-plugin-test.rs
 // ignore-stage1
 
 #![feature(plugin)]
diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs
index 07bd785ee71..91fe3b65be6 100644
--- a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs
+++ b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs
@@ -1,4 +1,4 @@
-// aux-build:lint_plugin_test.rs
+// aux-build:lint-plugin-test.rs
 // ignore-stage1
 // compile-flags: -F test-lint
 
diff --git a/src/test/ui-fulldeps/lint-plugin.rs b/src/test/ui-fulldeps/lint-plugin.rs
index 031f3b86b14..5f8bc16301a 100644
--- a/src/test/ui-fulldeps/lint-plugin.rs
+++ b/src/test/ui-fulldeps/lint-plugin.rs
@@ -1,5 +1,5 @@
 // run-pass
-// aux-build:lint_plugin_test.rs
+// aux-build:lint-plugin-test.rs
 // ignore-stage1
 #![feature(plugin)]
 #![plugin(lint_plugin_test)]
diff --git a/src/test/ui-fulldeps/lint_tool_cmdline_allow.rs b/src/test/ui-fulldeps/lint-tool-cmdline-allow.rs
index d60f41dd5a3..529f04c6fc4 100644
--- a/src/test/ui-fulldeps/lint_tool_cmdline_allow.rs
+++ b/src/test/ui-fulldeps/lint-tool-cmdline-allow.rs
@@ -1,5 +1,5 @@
 // run-pass
-// aux-build:lint_tool_test.rs
+// aux-build:lint-tool-test.rs
 // ignore-stage1
 // compile-flags: -A test-lint
 
@@ -7,7 +7,6 @@
 #![warn(unused)]
 #![plugin(lint_tool_test)]
 
-fn lintme() { }
+fn lintme() {}
 
-pub fn main() {
-}
+pub fn main() {}
diff --git a/src/test/ui-fulldeps/lint_tool_cmdline_allow.stderr b/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr
index 9634f1d572f..1d851013831 100644
--- a/src/test/ui-fulldeps/lint_tool_cmdline_allow.stderr
+++ b/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr
@@ -3,21 +3,21 @@ warning: lint name `test_lint` is deprecated and does not have an effect anymore
    = note: requested on the command line with `-A test_lint`
 
 warning: item is named 'lintme'
-  --> $DIR/lint_tool_cmdline_allow.rs:10:1
+  --> $DIR/lint-tool-cmdline-allow.rs:10:1
    |
-LL | fn lintme() { }
-   | ^^^^^^^^^^^^^^^
+LL | fn lintme() {}
+   | ^^^^^^^^^^^^^^
    |
    = note: #[warn(clippy::test_lint)] on by default
 
 warning: function is never used: `lintme`
-  --> $DIR/lint_tool_cmdline_allow.rs:10:1
+  --> $DIR/lint-tool-cmdline-allow.rs:10:1
    |
-LL | fn lintme() { }
+LL | fn lintme() {}
    | ^^^^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/lint_tool_cmdline_allow.rs:7:9
+  --> $DIR/lint-tool-cmdline-allow.rs:7:9
    |
 LL | #![warn(unused)]
    |         ^^^^^^
diff --git a/src/test/ui-fulldeps/lint_tool_test.rs b/src/test/ui-fulldeps/lint-tool-test.rs
index 04608b62f43..8bd06d1f1e3 100644
--- a/src/test/ui-fulldeps/lint_tool_test.rs
+++ b/src/test/ui-fulldeps/lint-tool-test.rs
@@ -1,4 +1,4 @@
-// aux-build:lint_tool_test.rs
+// aux-build:lint-tool-test.rs
 // ignore-stage1
 // compile-flags: --cfg foo
 
diff --git a/src/test/ui-fulldeps/lint_tool_test.stderr b/src/test/ui-fulldeps/lint-tool-test.stderr
index cec8800a25c..67e55e65c7e 100644
--- a/src/test/ui-fulldeps/lint_tool_test.stderr
+++ b/src/test/ui-fulldeps/lint-tool-test.stderr
@@ -1,5 +1,5 @@
 warning: lint name `test_lint` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore
-  --> $DIR/lint_tool_test.rs:8:23
+  --> $DIR/lint-tool-test.rs:8:23
    |
 LL | #![cfg_attr(foo, warn(test_lint))]
    |                       ^^^^^^^^^ help: change it to: `clippy::test_lint`
@@ -7,19 +7,19 @@ LL | #![cfg_attr(foo, warn(test_lint))]
    = note: #[warn(renamed_and_removed_lints)] on by default
 
 warning: lint name `clippy_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore
-  --> $DIR/lint_tool_test.rs:11:9
+  --> $DIR/lint-tool-test.rs:11:9
    |
 LL | #![deny(clippy_group)]
    |         ^^^^^^^^^^^^ help: change it to: `clippy::group`
 
 warning: lint name `test_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore
-  --> $DIR/lint_tool_test.rs:25:9
+  --> $DIR/lint-tool-test.rs:25:9
    |
 LL | #[allow(test_group)]
    |         ^^^^^^^^^^ help: change it to: `clippy::test_group`
 
 warning: unknown lint: `this_lint_does_not_exist`
-  --> $DIR/lint_tool_test.rs:27:8
+  --> $DIR/lint-tool-test.rs:27:8
    |
 LL | #[deny(this_lint_does_not_exist)]
    |        ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -27,32 +27,32 @@ LL | #[deny(this_lint_does_not_exist)]
    = note: #[warn(unknown_lints)] on by default
 
 warning: lint name `test_lint` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore
-  --> $DIR/lint_tool_test.rs:8:23
+  --> $DIR/lint-tool-test.rs:8:23
    |
 LL | #![cfg_attr(foo, warn(test_lint))]
    |                       ^^^^^^^^^ help: change it to: `clippy::test_lint`
 
 error: item is named 'lintme'
-  --> $DIR/lint_tool_test.rs:14:1
+  --> $DIR/lint-tool-test.rs:14:1
    |
 LL | fn lintme() { }
    | ^^^^^^^^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/lint_tool_test.rs:11:9
+  --> $DIR/lint-tool-test.rs:11:9
    |
 LL | #![deny(clippy_group)]
    |         ^^^^^^^^^^^^
    = note: #[deny(clippy::test_lint)] implied by #[deny(clippy::group)]
 
 error: item is named 'lintmetoo'
-  --> $DIR/lint_tool_test.rs:22:5
+  --> $DIR/lint-tool-test.rs:22:5
    |
 LL |     fn lintmetoo() { }
    |     ^^^^^^^^^^^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/lint_tool_test.rs:11:9
+  --> $DIR/lint-tool-test.rs:11:9
    |
 LL | #![deny(clippy_group)]
    |         ^^^^^^^^^^^^
diff --git a/src/test/ui-fulldeps/macro-crate-rlib.rs b/src/test/ui-fulldeps/macro-crate-rlib.rs
index 21e62171f0f..2962bb51fc4 100644
--- a/src/test/ui-fulldeps/macro-crate-rlib.rs
+++ b/src/test/ui-fulldeps/macro-crate-rlib.rs
@@ -1,4 +1,4 @@
-// aux-build:rlib_crate_test.rs
+// aux-build:rlib-crate-test.rs
 // ignore-tidy-linelength
 // ignore-cross-compile gives a different error message
 
diff --git a/src/test/ui-fulldeps/plugin-as-extern-crate.rs b/src/test/ui-fulldeps/plugin-as-extern-crate.rs
index 37ac8dfa391..c671ab581ef 100644
--- a/src/test/ui-fulldeps/plugin-as-extern-crate.rs
+++ b/src/test/ui-fulldeps/plugin-as-extern-crate.rs
@@ -1,4 +1,4 @@
-// aux-build:attr_plugin_test.rs
+// aux-build:attr-plugin-test.rs
 // ignore-cross-compile
 //
 // attr_plugin_test will not compile on a cross-compiled target because
diff --git a/src/test/ui-fulldeps/plugin-attr-register-deny.rs b/src/test/ui-fulldeps/plugin-attr-register-deny.rs
index f9922f7f606..8be73e330ab 100644
--- a/src/test/ui-fulldeps/plugin-attr-register-deny.rs
+++ b/src/test/ui-fulldeps/plugin-attr-register-deny.rs
@@ -1,4 +1,4 @@
-// aux-build:attr_plugin_test.rs
+// aux-build:attr-plugin-test.rs
 // ignore-stage1
 
 #![feature(plugin)]
diff --git a/src/test/ui/associated-types/associated-types-eq-3.stderr b/src/test/ui/associated-types/associated-types-eq-3.stderr
index c1a8e2002be..31d2c5f318e 100644
--- a/src/test/ui/associated-types/associated-types-eq-3.stderr
+++ b/src/test/ui/associated-types/associated-types-eq-3.stderr
@@ -29,7 +29,7 @@ LL |     baz(&a);
    |
    = note: expected type `usize`
               found type `Bar`
-   = note: required for the cast to the object type `dyn Foo<A=Bar>`
+   = note: required for the cast to the object type `dyn Foo<A = Bar>`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr b/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr
index 8c0e5570d19..ad0b6515490 100644
--- a/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr
+++ b/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr
@@ -6,7 +6,7 @@ LL |     let _: &I32Iterator<Item = u32> = &vec![42].into_iter();
    |
    = note: expected type `u32`
               found type `i32`
-   = note: required for the cast to the object type `dyn I32Iterator<Item=u32, Item=i32>`
+   = note: required for the cast to the object type `dyn I32Iterator<Item = u32, Item = i32>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/auxiliary/default_ty_param_cross_crate_crate.rs b/src/test/ui/auxiliary/default-ty-param-cross-crate-crate.rs
index 612f99dbcf8..612f99dbcf8 100644
--- a/src/test/ui/auxiliary/default_ty_param_cross_crate_crate.rs
+++ b/src/test/ui/auxiliary/default-ty-param-cross-crate-crate.rs
diff --git a/src/test/ui/auxiliary/define_macro.rs b/src/test/ui/auxiliary/define-macro.rs
index 4956907c55e..4956907c55e 100644
--- a/src/test/ui/auxiliary/define_macro.rs
+++ b/src/test/ui/auxiliary/define-macro.rs
diff --git a/src/test/ui/auxiliary/orphan_check_diagnostics.rs b/src/test/ui/auxiliary/orphan-check-diagnostics.rs
index 6b2c42b69b9..6b2c42b69b9 100644
--- a/src/test/ui/auxiliary/orphan_check_diagnostics.rs
+++ b/src/test/ui/auxiliary/orphan-check-diagnostics.rs
diff --git a/src/test/ui/auxiliary/pub_and_stability.rs b/src/test/ui/auxiliary/pub-and-stability.rs
index ee05a07dbb2..ee05a07dbb2 100644
--- a/src/test/ui/auxiliary/pub_and_stability.rs
+++ b/src/test/ui/auxiliary/pub-and-stability.rs
diff --git a/src/test/ui/auxiliary/rmeta_meta.rs b/src/test/ui/auxiliary/rmeta-meta.rs
index 6d8ed95bd38..6d8ed95bd38 100644
--- a/src/test/ui/auxiliary/rmeta_meta.rs
+++ b/src/test/ui/auxiliary/rmeta-meta.rs
diff --git a/src/test/ui/auxiliary/rmeta_rlib.rs b/src/test/ui/auxiliary/rmeta-rlib.rs
index 4a05710db66..4a05710db66 100644
--- a/src/test/ui/auxiliary/rmeta_rlib.rs
+++ b/src/test/ui/auxiliary/rmeta-rlib.rs
diff --git a/src/test/ui/auxiliary/stability_cfg2.rs b/src/test/ui/auxiliary/stability-cfg2.rs
index 8a2899584b9..8a2899584b9 100644
--- a/src/test/ui/auxiliary/stability_cfg2.rs
+++ b/src/test/ui/auxiliary/stability-cfg2.rs
diff --git a/src/test/ui/auxiliary/xc_private_method_lib.rs b/src/test/ui/auxiliary/xc-private-method-lib.rs
index 4d5ec6de392..4d5ec6de392 100644
--- a/src/test/ui/auxiliary/xc_private_method_lib.rs
+++ b/src/test/ui/auxiliary/xc-private-method-lib.rs
diff --git a/src/test/ui/bad/bad-sized.stderr b/src/test/ui/bad/bad-sized.stderr
index 9565888dcc0..51b84745552 100644
--- a/src/test/ui/bad/bad-sized.stderr
+++ b/src/test/ui/bad/bad-sized.stderr
@@ -22,7 +22,7 @@ LL |     let x: Vec<Trait + Sized> = Vec::new();
    |
    = help: the trait `std::marker::Sized` is not implemented for `dyn Trait`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
-   = note: required by `<std::vec::Vec<T>>::new`
+   = note: required by `std::vec::Vec::<T>::new`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/confuse-field-and-method/issue-2392.stderr b/src/test/ui/confuse-field-and-method/issue-2392.stderr
index 7cd1941d80e..456a4c18e2b 100644
--- a/src/test/ui/confuse-field-and-method/issue-2392.stderr
+++ b/src/test/ui/confuse-field-and-method/issue-2392.stderr
@@ -75,7 +75,7 @@ LL |     w.wrap.not_closure();
    |
    = help: did you mean to write `w.wrap.not_closure` instead of `w.wrap.not_closure(...)`?
 
-error[E0599]: no method named `closure` found for type `Obj<std::boxed::Box<(dyn std::boxed::FnBox<(), Output=u32> + 'static)>>` in the current scope
+error[E0599]: no method named `closure` found for type `Obj<std::boxed::Box<(dyn std::boxed::FnBox<(), Output = u32> + 'static)>>` in the current scope
   --> $DIR/issue-2392.rs:62:24
    |
 LL | struct Obj<F> where F: FnOnce() -> u32 {
diff --git a/src/test/ui/consts/const-size_of-cycle.stderr b/src/test/ui/consts/const-size_of-cycle.stderr
index 8f8eb38e938..3762f5e3d6a 100644
--- a/src/test/ui/consts/const-size_of-cycle.stderr
+++ b/src/test/ui/consts/const-size_of-cycle.stderr
@@ -1,22 +1,22 @@
-error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{constant}}`
+error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{constant}}#0`
   --> $DIR/const-size_of-cycle.rs:6:17
    |
 LL |     bytes: [u8; std::mem::size_of::<Foo>()]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: ...which requires const-evaluating `Foo::bytes::{{constant}}`...
+note: ...which requires const-evaluating `Foo::bytes::{{constant}}#0`...
   --> $SRC_DIR/libcore/mem.rs:LL:COL
    |
 LL |     intrinsics::size_of::<T>()
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...which requires computing layout of `Foo`...
    = note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`...
-note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}`...
+note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}#0`...
   --> $DIR/const-size_of-cycle.rs:6:17
    |
 LL |     bytes: [u8; std::mem::size_of::<Foo>()]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}`, completing the cycle
+   = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle
 note: cycle used when processing `Foo`
   --> $DIR/const-size_of-cycle.rs:5:1
    |
diff --git a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr
index 1fe3d33322f..7ede44c65b8 100644
--- a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr
+++ b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr
@@ -4,7 +4,7 @@ error[E0493]: destructors cannot be evaluated at compile-time
 LL |     const F: u32 = (U::X, 42).1;
    |                    ^^^^^^^^^^ constants cannot evaluate destructors
 
-error: `<std::vec::Vec<T>>::new` is not yet stable as a const fn
+error: `std::vec::Vec::<T>::new` is not yet stable as a const fn
   --> $DIR/feature-gate-unleash_the_miri_inside_of_you.rs:18:25
    |
 LL |     const X: Vec<u32> = Vec::new();
diff --git a/src/test/ui/consts/union_constant.rs b/src/test/ui/consts/union_constant.rs
new file mode 100644
index 00000000000..074014908ba
--- /dev/null
+++ b/src/test/ui/consts/union_constant.rs
@@ -0,0 +1,11 @@
+// compile-pass
+
+union Uninit {
+    _never_use: *const u8,
+    uninit: (),
+}
+
+const UNINIT: Uninit = Uninit { uninit: () };
+
+fn main() {}
+
diff --git a/src/test/ui/deprecation/deprecation-lint.rs b/src/test/ui/deprecation/deprecation-lint.rs
index 033d6eebbb2..26271395005 100644
--- a/src/test/ui/deprecation/deprecation-lint.rs
+++ b/src/test/ui/deprecation/deprecation-lint.rs
@@ -314,7 +314,7 @@ mod this_crate {
         let _ = || {
             #[deprecated]
             fn bar() { }
-            bar(); //~ ERROR use of deprecated item 'this_crate::test_fn_closure_body::{{closure}}::bar'
+            bar(); //~ ERROR use of deprecated item 'this_crate::test_fn_closure_body::{{closure}}#0::bar'
         };
     }
 
diff --git a/src/test/ui/deprecation/deprecation-lint.stderr b/src/test/ui/deprecation/deprecation-lint.stderr
index 50cbe3846bb..ffbcb259754 100644
--- a/src/test/ui/deprecation/deprecation-lint.stderr
+++ b/src/test/ui/deprecation/deprecation-lint.stderr
@@ -298,7 +298,7 @@ error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
 LL |         <Foo as Trait>::trait_deprecated_text(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::test_fn_closure_body::{{closure}}::bar'
+error: use of deprecated item 'this_crate::test_fn_closure_body::{{closure}}#0::bar'
   --> $DIR/deprecation-lint.rs:317:13
    |
 LL |             bar();
diff --git a/src/test/ui/e0119/auxiliary/issue_23563_a.rs b/src/test/ui/e0119/auxiliary/issue-23563-a.rs
index 4e85bcc4ba6..4e85bcc4ba6 100644
--- a/src/test/ui/e0119/auxiliary/issue_23563_a.rs
+++ b/src/test/ui/e0119/auxiliary/issue-23563-a.rs
diff --git a/src/test/ui/e0119/issue-23563.rs b/src/test/ui/e0119/issue-23563.rs
index a2804fcf1cc..f578560c552 100644
--- a/src/test/ui/e0119/issue-23563.rs
+++ b/src/test/ui/e0119/issue-23563.rs
@@ -1,4 +1,4 @@
-// aux-build:issue_23563_a.rs
+// aux-build:issue-23563-a.rs
 
 // Ref: https://github.com/rust-lang/rust/issues/23563#issuecomment-260751672
 
diff --git a/src/test/ui/enable-unstable-lib-feature.rs b/src/test/ui/enable-unstable-lib-feature.rs
index 2f248bf14c1..383c6868ce2 100644
--- a/src/test/ui/enable-unstable-lib-feature.rs
+++ b/src/test/ui/enable-unstable-lib-feature.rs
@@ -1,6 +1,6 @@
 // Test that enabling an unstable feature disables warnings
 
-// aux-build:stability_cfg2.rs
+// aux-build:stability-cfg2.rs
 
 #![feature(unstable_test_feature)]
 #![deny(non_snake_case)] // To trigger a hard error
diff --git a/src/test/ui/explore-issue-38412.rs b/src/test/ui/explore-issue-38412.rs
index cd0a69b0d8b..e7bcd7c6bfe 100644
--- a/src/test/ui/explore-issue-38412.rs
+++ b/src/test/ui/explore-issue-38412.rs
@@ -1,4 +1,4 @@
-// aux-build:pub_and_stability.rs
+// aux-build:pub-and-stability.rs
 
 #![feature(unused_feature)]
 
@@ -63,5 +63,4 @@ fn main() {
     t.pub_crate();                        //~ ERROR `pub_crate` is private
     t.pub_mod();                          //~ ERROR `pub_mod` is private
     t.private();                          //~ ERROR `private` is private
-
 }
diff --git a/src/test/ui/feature-gate/allow-features-empty.rs b/src/test/ui/feature-gate/allow-features-empty.rs
new file mode 100644
index 00000000000..83250052cb5
--- /dev/null
+++ b/src/test/ui/feature-gate/allow-features-empty.rs
@@ -0,0 +1,10 @@
+// compile-flags: -Z allow_features=
+// Note: This test uses rustc internal flags because they will never stabilize.
+
+#![feature(rustc_diagnostic_macros)] //~ ERROR
+
+#![feature(rustc_const_unstable)] //~ ERROR
+
+#![feature(lang_items)] //~ ERROR
+
+fn main() {}
diff --git a/src/test/ui/feature-gate/allow-features-empty.stderr b/src/test/ui/feature-gate/allow-features-empty.stderr
new file mode 100644
index 00000000000..cce2c4078c2
--- /dev/null
+++ b/src/test/ui/feature-gate/allow-features-empty.stderr
@@ -0,0 +1,21 @@
+error[E0725]: the feature `rustc_diagnostic_macros` is not in the list of allowed features
+  --> $DIR/allow-features-empty.rs:4:12
+   |
+LL | #![feature(rustc_diagnostic_macros)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features
+  --> $DIR/allow-features-empty.rs:6:12
+   |
+LL | #![feature(rustc_const_unstable)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+
+error[E0725]: the feature `lang_items` is not in the list of allowed features
+  --> $DIR/allow-features-empty.rs:8:12
+   |
+LL | #![feature(lang_items)]
+   |            ^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0725`.
diff --git a/src/test/ui/feature-gate/allow-features.rs b/src/test/ui/feature-gate/allow-features.rs
new file mode 100644
index 00000000000..1cebc8f34f2
--- /dev/null
+++ b/src/test/ui/feature-gate/allow-features.rs
@@ -0,0 +1,10 @@
+// compile-flags: -Z allow_features=rustc_diagnostic_macros,lang_items
+// Note: This test uses rustc internal flags because they will never stabilize.
+
+#![feature(rustc_diagnostic_macros)]
+
+#![feature(rustc_const_unstable)] //~ ERROR
+
+#![feature(lang_items)]
+
+fn main() {}
diff --git a/src/test/ui/feature-gate/allow-features.stderr b/src/test/ui/feature-gate/allow-features.stderr
new file mode 100644
index 00000000000..b13560fb81c
--- /dev/null
+++ b/src/test/ui/feature-gate/allow-features.stderr
@@ -0,0 +1,9 @@
+error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features
+  --> $DIR/allow-features.rs:6:12
+   |
+LL | #![feature(rustc_const_unstable)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0725`.
diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr
index b936fed85f4..4e79dfc3f7c 100644
--- a/src/test/ui/impl-trait/auto-trait-leak.stderr
+++ b/src/test/ui/impl-trait/auto-trait-leak.stderr
@@ -1,4 +1,4 @@
-error[E0391]: cycle detected when processing `cycle1::{{impl-Trait}}`
+error[E0391]: cycle detected when processing `cycle1::{{opaque}}#0`
   --> $DIR/auto-trait-leak.rs:14:16
    |
 LL | fn cycle1() -> impl Clone {
@@ -10,7 +10,7 @@ note: ...which requires processing `cycle1`...
 LL | fn cycle1() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`...
-note: ...which requires processing `cycle2::{{impl-Trait}}`...
+note: ...which requires processing `cycle2::{{opaque}}#0`...
   --> $DIR/auto-trait-leak.rs:23:16
    |
 LL | fn cycle2() -> impl Clone {
@@ -21,7 +21,7 @@ note: ...which requires processing `cycle2`...
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`...
-   = note: ...which again requires processing `cycle1::{{impl-Trait}}`, completing the cycle
+   = note: ...which again requires processing `cycle1::{{opaque}}#0`, completing the cycle
 note: cycle used when checking item types in top-level module
   --> $DIR/auto-trait-leak.rs:3:1
    |
@@ -34,7 +34,7 @@ LL | |     Rc::new(String::from("foo"))
 LL | | }
    | |_^
 
-error[E0391]: cycle detected when processing `cycle1::{{impl-Trait}}`
+error[E0391]: cycle detected when processing `cycle1::{{opaque}}#0`
   --> $DIR/auto-trait-leak.rs:14:16
    |
 LL | fn cycle1() -> impl Clone {
@@ -46,7 +46,7 @@ note: ...which requires processing `cycle1`...
 LL | fn cycle1() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`...
-note: ...which requires processing `cycle2::{{impl-Trait}}`...
+note: ...which requires processing `cycle2::{{opaque}}#0`...
   --> $DIR/auto-trait-leak.rs:23:16
    |
 LL | fn cycle2() -> impl Clone {
@@ -56,7 +56,7 @@ note: ...which requires processing `cycle2`...
    |
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: ...which again requires processing `cycle1::{{impl-Trait}}`, completing the cycle
+   = note: ...which again requires processing `cycle1::{{opaque}}#0`, completing the cycle
 note: cycle used when checking item types in top-level module
   --> $DIR/auto-trait-leak.rs:3:1
    |
diff --git a/src/test/ui/issues/issue-10536.rs b/src/test/ui/issues/issue-10536.rs
index 95c8c2b0585..ceb44ecf7f5 100644
--- a/src/test/ui/issues/issue-10536.rs
+++ b/src/test/ui/issues/issue-10536.rs
@@ -12,7 +12,7 @@ pub fn main() {
     foo!();
 
     assert!({one! two()});
-    //~^ ERROR macros that expand to items must either be surrounded with braces or followed by a
+    //~^ ERROR macros that expand to items
     //~| ERROR cannot find macro `one!` in this scope
     //~| ERROR mismatched types
 
diff --git a/src/test/ui/issues/issue-10536.stderr b/src/test/ui/issues/issue-10536.stderr
index d5caf777cd4..584cdf43a8f 100644
--- a/src/test/ui/issues/issue-10536.stderr
+++ b/src/test/ui/issues/issue-10536.stderr
@@ -1,8 +1,16 @@
-error: macros that expand to items must either be surrounded with braces or followed by a semicolon
+error: macros that expand to items must be delimited with braces or followed by a semicolon
   --> $DIR/issue-10536.rs:14:22
    |
 LL |     assert!({one! two()});
    |                      ^^
+help: change the delimiters to curly braces
+   |
+LL |     assert!({one! two {}});
+   |                       ^^
+help: add a semicolon
+   |
+LL |     assert!({one! two();});
+   |                        ^
 
 error: expected `(` or `{`, found `}`
   --> $DIR/issue-10536.rs:21:22
diff --git a/src/test/ui/issues/issue-17252.stderr b/src/test/ui/issues/issue-17252.stderr
index c993588f553..da3e2e763af 100644
--- a/src/test/ui/issues/issue-17252.stderr
+++ b/src/test/ui/issues/issue-17252.stderr
@@ -5,7 +5,7 @@ LL | const FOO: usize = FOO;
    |                    ^^^
    |
    = note: ...which again requires processing `FOO`, completing the cycle
-note: cycle used when processing `main::{{constant}}`
+note: cycle used when processing `main::{{constant}}#0`
   --> $DIR/issue-17252.rs:4:18
    |
 LL |     let _x: [u8; FOO]; // caused stack overflow prior to fix
diff --git a/src/test/ui/issues/issue-17651.stderr b/src/test/ui/issues/issue-17651.stderr
index 72c40ff4b3a..ce9af1524b0 100644
--- a/src/test/ui/issues/issue-17651.stderr
+++ b/src/test/ui/issues/issue-17651.stderr
@@ -6,7 +6,7 @@ LL |     (|| Box::new(*(&[0][..])))();
    |
    = help: the trait `std::marker::Sized` is not implemented for `[{integer}]`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
-   = note: required by `<std::boxed::Box<T>>::new`
+   = note: required by `std::boxed::Box::<T>::new`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-17905-2.stderr b/src/test/ui/issues/issue-17905-2.stderr
index f185f49b9b9..e3909e0c125 100644
--- a/src/test/ui/issues/issue-17905-2.stderr
+++ b/src/test/ui/issues/issue-17905-2.stderr
@@ -4,7 +4,7 @@ error[E0308]: mismatched method receiver
 LL |     fn say(self: &Pair<&str, isize>) {
    |                  ^^^^^^^^^^^^^^^^^^ lifetime mismatch
    |
-   = note: expected type `Pair<&'_ str, _>`
+   = note: expected type `Pair<&str, _>`
               found type `Pair<&str, _>`
 note: the anonymous lifetime #2 defined on the method body at 8:5...
   --> $DIR/issue-17905-2.rs:8:5
@@ -27,7 +27,7 @@ error[E0308]: mismatched method receiver
 LL |     fn say(self: &Pair<&str, isize>) {
    |                  ^^^^^^^^^^^^^^^^^^ lifetime mismatch
    |
-   = note: expected type `Pair<&'_ str, _>`
+   = note: expected type `Pair<&str, _>`
               found type `Pair<&str, _>`
 note: the lifetime '_ as defined on the impl at 5:5...
   --> $DIR/issue-17905-2.rs:5:5
diff --git a/src/test/ui/issues/issue-20605.stderr b/src/test/ui/issues/issue-20605.stderr
index f779fe51bf2..89df58dd2dc 100644
--- a/src/test/ui/issues/issue-20605.stderr
+++ b/src/test/ui/issues/issue-20605.stderr
@@ -1,10 +1,10 @@
-error[E0277]: the size for values of type `dyn std::iter::Iterator<Item=&mut u8>` cannot be known at compilation time
+error[E0277]: the size for values of type `dyn std::iter::Iterator<Item = &mut u8>` cannot be known at compilation time
   --> $DIR/issue-20605.rs:2:17
    |
 LL |     for item in *things { *item = 0 }
    |                 ^^^^^^^ doesn't have a size known at compile-time
    |
-   = help: the trait `std::marker::Sized` is not implemented for `dyn std::iter::Iterator<Item=&mut u8>`
+   = help: the trait `std::marker::Sized` is not implemented for `dyn std::iter::Iterator<Item = &mut u8>`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: required by `std::iter::IntoIterator::into_iter`
 
diff --git a/src/test/ui/issues/issue-20831-debruijn.stderr b/src/test/ui/issues/issue-20831-debruijn.stderr
index b2a05551837..e20869a6f3a 100644
--- a/src/test/ui/issues/issue-20831-debruijn.stderr
+++ b/src/test/ui/issues/issue-20831-debruijn.stderr
@@ -11,7 +11,7 @@ LL | |     }
    | |_____^ lifetime mismatch
    |
    = note: expected type `'a`
-              found type ``
+              found type `'_`
 note: the anonymous lifetime #2 defined on the method body at 28:5...
   --> $DIR/issue-20831-debruijn.rs:28:5
    |
@@ -42,7 +42,7 @@ LL | |     }
    | |_____^ lifetime mismatch
    |
    = note: expected type `'a`
-              found type ``
+              found type `'_`
 note: the lifetime 'a as defined on the impl at 26:6...
   --> $DIR/issue-20831-debruijn.rs:26:6
    |
diff --git a/src/test/ui/issues/issue-22312.stderr b/src/test/ui/issues/issue-22312.stderr
index d8987a37f7e..6a012b214c5 100644
--- a/src/test/ui/issues/issue-22312.stderr
+++ b/src/test/ui/issues/issue-22312.stderr
@@ -1,4 +1,4 @@
-error[E0605]: non-primitive cast: `Self` as `&dyn std::ops::Index<usize, Output=<Self as std::ops::Index<usize>>::Output>`
+error[E0605]: non-primitive cast: `Self` as `&dyn std::ops::Index<usize, Output = <Self as std::ops::Index<usize>>::Output>`
   --> $DIR/issue-22312.rs:11:24
    |
 LL |         let indexer = &(*self as &Index<usize, Output = <Self as Index<usize>>::Output>);
diff --git a/src/test/ui/issues/issue-22638.stderr b/src/test/ui/issues/issue-22638.stderr
index aff968f3618..b60e1c29ec0 100644
--- a/src/test/ui/issues/issue-22638.stderr
+++ b/src/test/ui/issues/issue-22638.stderr
@@ -8,7 +8,7 @@ LL | |         a.matches(f)
 LL | |     }
    | |_____^
    |
-   = note: consider adding a `#![type_length_limit="40000000"]` attribute to your crate
+   = note: consider adding a `#![type_length_limit="26214380"]` attribute to your crate
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-23302-1.stderr b/src/test/ui/issues/issue-23302-1.stderr
index 5fa82f8b786..43effc0b3b9 100644
--- a/src/test/ui/issues/issue-23302-1.stderr
+++ b/src/test/ui/issues/issue-23302-1.stderr
@@ -1,11 +1,11 @@
-error[E0391]: cycle detected when processing `X::A::{{constant}}`
+error[E0391]: cycle detected when processing `X::A::{{constant}}#0`
   --> $DIR/issue-23302-1.rs:4:9
    |
 LL |     A = X::A as isize,
    |         ^^^^^^^^^^^^^
    |
-   = note: ...which again requires processing `X::A::{{constant}}`, completing the cycle
-note: cycle used when const-evaluating `X::A::{{constant}}`
+   = note: ...which again requires processing `X::A::{{constant}}#0`, completing the cycle
+note: cycle used when const-evaluating `X::A::{{constant}}#0`
   --> $DIR/issue-23302-1.rs:4:9
    |
 LL |     A = X::A as isize,
diff --git a/src/test/ui/issues/issue-23302-2.stderr b/src/test/ui/issues/issue-23302-2.stderr
index 5b77baed73c..707d4fa7ed3 100644
--- a/src/test/ui/issues/issue-23302-2.stderr
+++ b/src/test/ui/issues/issue-23302-2.stderr
@@ -1,11 +1,11 @@
-error[E0391]: cycle detected when processing `Y::A::{{constant}}`
+error[E0391]: cycle detected when processing `Y::A::{{constant}}#0`
   --> $DIR/issue-23302-2.rs:4:9
    |
 LL |     A = Y::B as isize,
    |         ^^^^^^^^^^^^^
    |
-   = note: ...which again requires processing `Y::A::{{constant}}`, completing the cycle
-note: cycle used when const-evaluating `Y::A::{{constant}}`
+   = note: ...which again requires processing `Y::A::{{constant}}#0`, completing the cycle
+note: cycle used when const-evaluating `Y::A::{{constant}}#0`
   --> $DIR/issue-23302-2.rs:4:9
    |
 LL |     A = Y::B as isize,
diff --git a/src/test/ui/issues/issue-36163.stderr b/src/test/ui/issues/issue-36163.stderr
index 94de4c76927..4c3f726180d 100644
--- a/src/test/ui/issues/issue-36163.stderr
+++ b/src/test/ui/issues/issue-36163.stderr
@@ -1,4 +1,4 @@
-error[E0391]: cycle detected when processing `Foo::B::{{constant}}`
+error[E0391]: cycle detected when processing `Foo::B::{{constant}}#0`
   --> $DIR/issue-36163.rs:4:9
    |
 LL |     B = A,
@@ -9,8 +9,8 @@ note: ...which requires processing `A`...
    |
 LL | const A: isize = Foo::B as isize;
    |                  ^^^^^^^^^^^^^^^
-   = note: ...which again requires processing `Foo::B::{{constant}}`, completing the cycle
-note: cycle used when const-evaluating `Foo::B::{{constant}}`
+   = note: ...which again requires processing `Foo::B::{{constant}}#0`, completing the cycle
+note: cycle used when const-evaluating `Foo::B::{{constant}}#0`
   --> $DIR/issue-36163.rs:4:9
    |
 LL |     B = A,
diff --git a/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr b/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr
index 24b31f43a85..aead415d23f 100644
--- a/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr
+++ b/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr
@@ -1,4 +1,4 @@
-error: reached the type-length limit while instantiating `<T as Foo><(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(), &()), &(&()...`
+error: reached the type-length limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(...))))))))))))))) as Foo>::recurse`
   --> $DIR/issue-37311.rs:13:5
    |
 LL | /     fn recurse(&self) {
@@ -6,7 +6,7 @@ LL | |         (self, self).recurse();
 LL | |     }
    | |_____^
    |
-   = note: consider adding a `#![type_length_limit="2097152"]` attribute to your crate
+   = note: consider adding a `#![type_length_limit="2097149"]` attribute to your crate
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-42944.rs b/src/test/ui/issues/issue-42944.rs
index 9d746673f4d..9d746673f4d 100644
--- a/src/test/ui/issue-42944.rs
+++ b/src/test/ui/issues/issue-42944.rs
diff --git a/src/test/ui/issue-42944.stderr b/src/test/ui/issues/issue-42944.stderr
index 0613be0b3d0..0613be0b3d0 100644
--- a/src/test/ui/issue-42944.stderr
+++ b/src/test/ui/issues/issue-42944.stderr
diff --git a/src/test/ui/issues/issue-44415.stderr b/src/test/ui/issues/issue-44415.stderr
index 3f377fd27e7..df8e804c87a 100644
--- a/src/test/ui/issues/issue-44415.stderr
+++ b/src/test/ui/issues/issue-44415.stderr
@@ -1,22 +1,22 @@
-error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{constant}}`
+error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{constant}}#0`
   --> $DIR/issue-44415.rs:6:17
    |
 LL |     bytes: [u8; unsafe { intrinsics::size_of::<Foo>() }],
    |                 ^^^^^^
    |
-note: ...which requires const-evaluating `Foo::bytes::{{constant}}`...
+note: ...which requires const-evaluating `Foo::bytes::{{constant}}#0`...
   --> $DIR/issue-44415.rs:6:26
    |
 LL |     bytes: [u8; unsafe { intrinsics::size_of::<Foo>() }],
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...which requires computing layout of `Foo`...
    = note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`...
-note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}`...
+note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}#0`...
   --> $DIR/issue-44415.rs:6:17
    |
 LL |     bytes: [u8; unsafe { intrinsics::size_of::<Foo>() }],
    |                 ^^^^^^
-   = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}`, completing the cycle
+   = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle
 note: cycle used when processing `Foo`
   --> $DIR/issue-44415.rs:5:1
    |
diff --git a/src/test/ui/issue-53787-inline-assembler-macro.rs b/src/test/ui/issues/issue-53787-inline-assembler-macro.rs
index 937bce1b655..937bce1b655 100644
--- a/src/test/ui/issue-53787-inline-assembler-macro.rs
+++ b/src/test/ui/issues/issue-53787-inline-assembler-macro.rs
diff --git a/src/test/ui/issue-53787-inline-assembler-macro.stderr b/src/test/ui/issues/issue-53787-inline-assembler-macro.stderr
index 047ba341cfc..047ba341cfc 100644
--- a/src/test/ui/issue-53787-inline-assembler-macro.stderr
+++ b/src/test/ui/issues/issue-53787-inline-assembler-macro.stderr
diff --git a/src/test/ui/issue-54943-1.rs b/src/test/ui/issues/issue-54943-1.rs
index 7750e340361..7750e340361 100644
--- a/src/test/ui/issue-54943-1.rs
+++ b/src/test/ui/issues/issue-54943-1.rs
diff --git a/src/test/ui/issue-54943-2.rs b/src/test/ui/issues/issue-54943-2.rs
index f829c38c35d..f829c38c35d 100644
--- a/src/test/ui/issue-54943-2.rs
+++ b/src/test/ui/issues/issue-54943-2.rs
diff --git a/src/test/ui/issue-54943-3.rs b/src/test/ui/issues/issue-54943-3.rs
index 185077bd684..185077bd684 100644
--- a/src/test/ui/issue-54943-3.rs
+++ b/src/test/ui/issues/issue-54943-3.rs
diff --git a/src/test/ui/issue-54943.rs b/src/test/ui/issues/issue-54943.rs
index ce4e0106743..ce4e0106743 100644
--- a/src/test/ui/issue-54943.rs
+++ b/src/test/ui/issues/issue-54943.rs
diff --git a/src/test/ui/issue-54943.stderr b/src/test/ui/issues/issue-54943.stderr
index aa68177bcdb..aa68177bcdb 100644
--- a/src/test/ui/issue-54943.stderr
+++ b/src/test/ui/issues/issue-54943.stderr
diff --git a/src/test/ui/issue-55511.nll.stderr b/src/test/ui/issues/issue-55511.nll.stderr
index bf3e58e8cdb..bf3e58e8cdb 100644
--- a/src/test/ui/issue-55511.nll.stderr
+++ b/src/test/ui/issues/issue-55511.nll.stderr
diff --git a/src/test/ui/issue-55511.rs b/src/test/ui/issues/issue-55511.rs
index 4b9475ba627..4b9475ba627 100644
--- a/src/test/ui/issue-55511.rs
+++ b/src/test/ui/issues/issue-55511.rs
diff --git a/src/test/ui/issue-55511.stderr b/src/test/ui/issues/issue-55511.stderr
index 24668f04551..24668f04551 100644
--- a/src/test/ui/issue-55511.stderr
+++ b/src/test/ui/issues/issue-55511.stderr
diff --git a/src/test/ui/issues/issue-55796.stderr b/src/test/ui/issues/issue-55796.stderr
index c05f8b85d0e..7cf597d3a98 100644
--- a/src/test/ui/issues/issue-55796.stderr
+++ b/src/test/ui/issues/issue-55796.stderr
@@ -16,8 +16,8 @@ LL |         Box::new(self.out_edges(u).map(|e| e.target()))
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: but, the lifetime must be valid for the static lifetime...
    = note: ...so that the expression is assignable:
-           expected std::boxed::Box<(dyn std::iter::Iterator<Item=<Self as Graph<'a>>::Node> + 'static)>
-              found std::boxed::Box<dyn std::iter::Iterator<Item=<Self as Graph<'a>>::Node>>
+           expected std::boxed::Box<(dyn std::iter::Iterator<Item = <Self as Graph<'a>>::Node> + 'static)>
+              found std::boxed::Box<dyn std::iter::Iterator<Item = <Self as Graph<'a>>::Node>>
 
 error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
   --> $DIR/issue-55796.rs:21:9
@@ -37,8 +37,8 @@ LL |         Box::new(self.in_edges(u).map(|e| e.target()))
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: but, the lifetime must be valid for the static lifetime...
    = note: ...so that the expression is assignable:
-           expected std::boxed::Box<(dyn std::iter::Iterator<Item=<Self as Graph<'a>>::Node> + 'static)>
-              found std::boxed::Box<dyn std::iter::Iterator<Item=<Self as Graph<'a>>::Node>>
+           expected std::boxed::Box<(dyn std::iter::Iterator<Item = <Self as Graph<'a>>::Node> + 'static)>
+              found std::boxed::Box<dyn std::iter::Iterator<Item = <Self as Graph<'a>>::Node>>
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issue-55846.rs b/src/test/ui/issues/issue-55846.rs
index bd766752360..bd766752360 100644
--- a/src/test/ui/issue-55846.rs
+++ b/src/test/ui/issues/issue-55846.rs
diff --git a/src/test/ui/issues/issue_56411_aux.rs b/src/test/ui/issues/issue-56411-aux.rs
index bd689e913ab..bd689e913ab 100644
--- a/src/test/ui/issues/issue_56411_aux.rs
+++ b/src/test/ui/issues/issue-56411-aux.rs
diff --git a/src/test/ui/issues/issue-56411.rs b/src/test/ui/issues/issue-56411.rs
index 3561c21cc7e..163651a7ef6 100644
--- a/src/test/ui/issues/issue-56411.rs
+++ b/src/test/ui/issues/issue-56411.rs
@@ -1,6 +1,7 @@
 macro_rules! import {
-    ( $($name:ident),* ) => {
+    ( $(($path:expr, $name:ident)),* ) => {
         $(
+            #[path = $path]
             mod $name;
             pub use self::$name;
             //~^ ERROR the name `issue_56411_aux` is defined multiple times
@@ -10,7 +11,7 @@ macro_rules! import {
     }
 }
 
-import!(issue_56411_aux);
+import!(("issue-56411-aux.rs", issue_56411_aux));
 
 fn main() {
     println!("Hello, world!");
diff --git a/src/test/ui/issues/issue-56411.stderr b/src/test/ui/issues/issue-56411.stderr
index dd05852c091..7b23b3766be 100644
--- a/src/test/ui/issues/issue-56411.stderr
+++ b/src/test/ui/issues/issue-56411.stderr
@@ -1,5 +1,5 @@
 error[E0255]: the name `issue_56411_aux` is defined multiple times
-  --> $DIR/issue-56411.rs:5:21
+  --> $DIR/issue-56411.rs:6:21
    |
 LL |             mod $name;
    |             ---------- previous definition of the module `issue_56411_aux` here
@@ -9,19 +9,19 @@ LL |             pub use self::$name;
    |                     `issue_56411_aux` reimported here
    |                     you can use `as` to change the binding name of the import
 ...
-LL | import!(issue_56411_aux);
-   | ------------------------- in this macro invocation
+LL | import!(("issue-56411-aux.rs", issue_56411_aux));
+   | ------------------------------------------------- in this macro invocation
    |
    = note: `issue_56411_aux` must be defined only once in the type namespace of this module
 
 error[E0365]: `issue_56411_aux` is private, and cannot be re-exported
-  --> $DIR/issue-56411.rs:5:21
+  --> $DIR/issue-56411.rs:6:21
    |
 LL |             pub use self::$name;
    |                     ^^^^^^^^^^^ re-export of private `issue_56411_aux`
 ...
-LL | import!(issue_56411_aux);
-   | ------------------------- in this macro invocation
+LL | import!(("issue-56411-aux.rs", issue_56411_aux));
+   | ------------------------------------------------- in this macro invocation
    |
    = note: consider declaring type or module `issue_56411_aux` with `pub`
 
diff --git a/src/test/ui/issues/issue-59029-1.rs b/src/test/ui/issues/issue-59029-1.rs
new file mode 100644
index 00000000000..e98a4d0e491
--- /dev/null
+++ b/src/test/ui/issues/issue-59029-1.rs
@@ -0,0 +1,8 @@
+#![feature(trait_alias)]
+
+trait Svc<Req> { type Res; }
+
+trait MkSvc<Target, Req> = Svc<Target> where Self::Res: Svc<Req>;
+//~^ ERROR associated type `Res` not found for `Self`
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-59029-1.stderr b/src/test/ui/issues/issue-59029-1.stderr
new file mode 100644
index 00000000000..ed1d98c40d1
--- /dev/null
+++ b/src/test/ui/issues/issue-59029-1.stderr
@@ -0,0 +1,9 @@
+error[E0220]: associated type `Res` not found for `Self`
+  --> $DIR/issue-59029-1.rs:5:46
+   |
+LL | trait MkSvc<Target, Req> = Svc<Target> where Self::Res: Svc<Req>;
+   |                                              ^^^^^^^^^ associated type `Res` not found
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0220`.
diff --git a/src/test/ui/issues/issue-59029-2.rs b/src/test/ui/issues/issue-59029-2.rs
new file mode 100644
index 00000000000..2bdb128d8c4
--- /dev/null
+++ b/src/test/ui/issues/issue-59029-2.rs
@@ -0,0 +1,8 @@
+// run-pass
+#![feature(trait_alias)]
+
+trait Svc<Req> { type Res; }
+
+trait MkSvc<Target, Req> = Svc<Target> where <Self as Svc<Target>>::Res: Svc<Req>;
+
+fn main() {}
diff --git a/src/test/ui/lint/auxiliary/stability-cfg2.rs b/src/test/ui/lint/auxiliary/stability-cfg2.rs
new file mode 100644
index 00000000000..8a2899584b9
--- /dev/null
+++ b/src/test/ui/lint/auxiliary/stability-cfg2.rs
@@ -0,0 +1,5 @@
+// compile-flags:--cfg foo
+
+#![cfg_attr(foo, unstable(feature = "unstable_test_feature", issue = "0"))]
+#![cfg_attr(not(foo), stable(feature = "test_feature", since = "1.0.0"))]
+#![feature(staged_api)]
diff --git a/src/test/ui/lint/lint-stability-deprecated.rs b/src/test/ui/lint/lint-stability-deprecated.rs
index 8f6425bcc77..bf574d7144d 100644
--- a/src/test/ui/lint/lint-stability-deprecated.rs
+++ b/src/test/ui/lint/lint-stability-deprecated.rs
@@ -2,7 +2,7 @@
 // aux-build:lint_stability.rs
 // aux-build:inherited_stability.rs
 // aux-build:stability_cfg1.rs
-// aux-build:stability_cfg2.rs
+// aux-build:stability-cfg2.rs
 // ignore-tidy-linelength
 #![warn(deprecated)]
 #![allow(dead_code, unused_extern_crates)]
diff --git a/src/test/ui/lint/lint-stability.rs b/src/test/ui/lint/lint-stability.rs
index 6ff79083f46..3e4a3874d2c 100644
--- a/src/test/ui/lint/lint-stability.rs
+++ b/src/test/ui/lint/lint-stability.rs
@@ -1,7 +1,7 @@
 // aux-build:lint_stability.rs
 // aux-build:inherited_stability.rs
 // aux-build:stability_cfg1.rs
-// aux-build:stability_cfg2.rs
+// aux-build:stability-cfg2.rs
 
 #![allow(deprecated)]
 #![allow(dead_code)]
diff --git a/src/test/ui/namespace/namespace-mix.stderr b/src/test/ui/namespace/namespace-mix.stderr
index 22c871dd3c0..99fa3b96794 100644
--- a/src/test/ui/namespace/namespace-mix.stderr
+++ b/src/test/ui/namespace/namespace-mix.stderr
@@ -462,11 +462,11 @@ note: required by `check`
 LL | fn check<T: Impossible>(_: T) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0277]: the trait bound `fn() -> namespace_mix::c::E {namespace_mix::c::E::TV}: Impossible` is not satisfied
+error[E0277]: the trait bound `fn() -> namespace_mix::c::E {namespace_mix::xm7::TV}: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:128:5
    |
 LL |     check(xm9::TV);
-   |     ^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::E {namespace_mix::c::E::TV}`
+   |     ^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::E {namespace_mix::xm7::TV}`
    |
 note: required by `check`
   --> $DIR/namespace-mix.rs:21:1
diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
index 8e407070342..46de13dbbbd 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
@@ -16,7 +16,7 @@ LL |         let mut closure = expect_sig(|p, y| *p = y);
    |                                       -  -  ^^^^^^ assignment requires that `'1` must outlive `'2`
    |                                       |  |
    |                                       |  has type `&'1 i32`
-   |                                       has type `&mut &'2 i32`
+   |                                       has type `&'_#2r mut &'2 i32`
 
 note: No external requirements
   --> $DIR/escape-argument-callee.rs:20:1
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
index 067bd08220d..7eb4d96fc5f 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
@@ -20,9 +20,9 @@ error: lifetime may not live long enough
   --> $DIR/propagate-approximated-fail-no-postdom.rs:46:13
    |
 LL |         |_outlives1, _outlives2, _outlives3, x, y| {
-   |          ----------              ---------- has type `std::cell::Cell<&'2 &u32>`
+   |          ----------              ---------- has type `std::cell::Cell<&'2 &'_#3r u32>`
    |          |
-   |          has type `std::cell::Cell<&&'1 u32>`
+   |          has type `std::cell::Cell<&'_#1r &'1 u32>`
 ...
 LL |             demand_y(x, y, p)
    |             ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
index 5cf37bedb88..f8b6bfa003b 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
@@ -20,9 +20,9 @@ error: lifetime may not live long enough
   --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:37:9
    |
 LL |     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
-   |                                                ---------  - has type `&std::cell::Cell<&'1 u32>`
+   |                                                ---------  - has type `&'_#7r std::cell::Cell<&'1 u32>`
    |                                                |
-   |                                                has type `&std::cell::Cell<&'2 &u32>`
+   |                                                has type `&'_#5r std::cell::Cell<&'2 &'_#1r u32>`
 LL |         // Only works if 'x: 'y:
 LL |         demand_y(x, y, x.get())
    |         ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
index 671a8b9a935..7e7429405fa 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
@@ -20,9 +20,9 @@ error: lifetime may not live long enough
   --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:41:9
    |
 LL |     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-   |                                                ----------  ---------- has type `&std::cell::Cell<&'2 &u32>`
+   |                                                ----------  ---------- has type `&'_#8r std::cell::Cell<&'2 &'_#2r u32>`
    |                                                |
-   |                                                has type `&std::cell::Cell<&'1 &u32>`
+   |                                                has type `&'_#6r std::cell::Cell<&'1 &'_#1r u32>`
 LL |         // Only works if 'x: 'y:
 LL |         demand_y(x, y, x.get())
    |         ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
diff --git a/src/test/ui/orphan-check-diagnostics.rs b/src/test/ui/orphan-check-diagnostics.rs
index 9a29620ae65..c8803b9ae5d 100644
--- a/src/test/ui/orphan-check-diagnostics.rs
+++ b/src/test/ui/orphan-check-diagnostics.rs
@@ -1,5 +1,6 @@
-// aux-build:orphan_check_diagnostics.rs
-// see #22388
+// aux-build:orphan-check-diagnostics.rs
+
+// See issue #22388.
 
 extern crate orphan_check_diagnostics;
 
diff --git a/src/test/ui/orphan-check-diagnostics.stderr b/src/test/ui/orphan-check-diagnostics.stderr
index 4bd6aa2c154..3f868422c7f 100644
--- a/src/test/ui/orphan-check-diagnostics.stderr
+++ b/src/test/ui/orphan-check-diagnostics.stderr
@@ -1,5 +1,5 @@
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/orphan-check-diagnostics.rs:10:1
+  --> $DIR/orphan-check-diagnostics.rs:11:1
    |
 LL | impl<T> RemoteTrait for T where T: LocalTrait {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
diff --git a/src/test/ui/out-of-order-shadowing.rs b/src/test/ui/out-of-order-shadowing.rs
index b4cb6a23830..a0d1a973764 100644
--- a/src/test/ui/out-of-order-shadowing.rs
+++ b/src/test/ui/out-of-order-shadowing.rs
@@ -1,4 +1,4 @@
-// aux-build:define_macro.rs
+// aux-build:define-macro.rs
 
 macro_rules! bar { () => {} }
 define_macro!(bar);
diff --git a/src/test/ui/parser/macros-no-semicolon-items.rs b/src/test/ui/parser/macros-no-semicolon-items.rs
index a727cafcab0..3afc275d61a 100644
--- a/src/test/ui/parser/macros-no-semicolon-items.rs
+++ b/src/test/ui/parser/macros-no-semicolon-items.rs
@@ -1,4 +1,15 @@
 macro_rules! foo()  //~ ERROR semicolon
+                    //~| ERROR unexpected end of macro
+
+macro_rules! bar {
+    ($($tokens:tt)*) => {}
+}
+
+bar!( //~ ERROR semicolon
+    blah
+    blah
+    blah
+)
 
 fn main() {
 }
diff --git a/src/test/ui/parser/macros-no-semicolon-items.stderr b/src/test/ui/parser/macros-no-semicolon-items.stderr
index a869a53c1ee..5276aa6f5e9 100644
--- a/src/test/ui/parser/macros-no-semicolon-items.stderr
+++ b/src/test/ui/parser/macros-no-semicolon-items.stderr
@@ -1,8 +1,45 @@
-error: macros that expand to items must either be surrounded with braces or followed by a semicolon
+error: macros that expand to items must be delimited with braces or followed by a semicolon
   --> $DIR/macros-no-semicolon-items.rs:1:17
    |
 LL | macro_rules! foo()
    |                 ^^
+help: change the delimiters to curly braces
+   |
+LL | macro_rules! foo {}
+   |                  ^^
+help: add a semicolon
+   |
+LL | macro_rules! foo();
+   |                   ^
+
+error: macros that expand to items must be delimited with braces or followed by a semicolon
+  --> $DIR/macros-no-semicolon-items.rs:8:5
+   |
+LL |   bar!(
+   |  _____^
+LL | |     blah
+LL | |     blah
+LL | |     blah
+LL | | )
+   | |_^
+help: change the delimiters to curly braces
+   |
+LL | bar! {
+LL |     blah
+LL |     blah
+LL |     blah
+LL | }
+   |
+help: add a semicolon
+   |
+LL | );
+   |  ^
+
+error: unexpected end of macro invocation
+  --> $DIR/macros-no-semicolon-items.rs:1:1
+   |
+LL | macro_rules! foo()
+   | ^^^^^^^^^^^^^^^^^^ missing tokens in macro arguments
 
-error: aborting due to previous error
+error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/privacy/private-inferred-type-3.rs b/src/test/ui/privacy/private-inferred-type-3.rs
index d885407a1cd..39f2e5d4af2 100644
--- a/src/test/ui/privacy/private-inferred-type-3.rs
+++ b/src/test/ui/privacy/private-inferred-type-3.rs
@@ -6,7 +6,7 @@
 // error-pattern:type `fn() {<u8 as ext::PrivTrait>::method}` is private
 // error-pattern:type `fn(u8) -> ext::PrivTupleStruct {ext::PrivTupleStruct}` is private
 // error-pattern:type `fn(u8) -> ext::PubTupleStruct {ext::PubTupleStruct}` is private
-// error-pattern:type `for<'r> fn(&'r ext::Pub<u8>) {<ext::Pub<u8>>::priv_method}` is private
+// error-pattern:type `for<'r> fn(&'r ext::Pub<u8>) {ext::Pub::<u8>::priv_method}` is private
 
 #![feature(decl_macro)]
 
diff --git a/src/test/ui/privacy/private-inferred-type-3.stderr b/src/test/ui/privacy/private-inferred-type-3.stderr
index f8b757ea098..61cd8476297 100644
--- a/src/test/ui/privacy/private-inferred-type-3.stderr
+++ b/src/test/ui/privacy/private-inferred-type-3.stderr
@@ -46,7 +46,7 @@ LL |     ext::m!();
    |
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 
-error: type `for<'r> fn(&'r ext::Pub<u8>) {<ext::Pub<u8>>::priv_method}` is private
+error: type `for<'r> fn(&'r ext::Pub<u8>) {ext::Pub::<u8>::priv_method}` is private
   --> $DIR/private-inferred-type-3.rs:16:5
    |
 LL |     ext::m!();
diff --git a/src/test/ui/privacy/private-inferred-type.rs b/src/test/ui/privacy/private-inferred-type.rs
index d98cf5991ef..d9bb421b53f 100644
--- a/src/test/ui/privacy/private-inferred-type.rs
+++ b/src/test/ui/privacy/private-inferred-type.rs
@@ -47,7 +47,7 @@ mod m {
         PubTupleStruct;
         //~^ ERROR type `fn(u8) -> m::PubTupleStruct {m::PubTupleStruct}` is private
         Pub(0u8).priv_method();
-        //~^ ERROR type `for<'r> fn(&'r m::Pub<u8>) {<m::Pub<u8>>::priv_method}` is private
+        //~^ ERROR type `for<'r> fn(&'r m::Pub<u8>) {m::Pub::<u8>::priv_method}` is private
     }
 
     trait Trait {}
diff --git a/src/test/ui/privacy/private-inferred-type.stderr b/src/test/ui/privacy/private-inferred-type.stderr
index baa98292b67..4d40b6b7cab 100644
--- a/src/test/ui/privacy/private-inferred-type.stderr
+++ b/src/test/ui/privacy/private-inferred-type.stderr
@@ -151,7 +151,7 @@ LL |         PubTupleStruct;
 LL |     m::m!();
    |     -------- in this macro invocation
 
-error: type `for<'r> fn(&'r m::Pub<u8>) {<m::Pub<u8>>::priv_method}` is private
+error: type `for<'r> fn(&'r m::Pub<u8>) {m::Pub::<u8>::priv_method}` is private
   --> $DIR/private-inferred-type.rs:49:18
    |
 LL |         Pub(0u8).priv_method();
diff --git a/src/test/ui/proc-macro/auxiliary/issue_38586.rs b/src/test/ui/proc-macro/auxiliary/issue-38586.rs
index f3a19081c47..f3a19081c47 100644
--- a/src/test/ui/proc-macro/auxiliary/issue_38586.rs
+++ b/src/test/ui/proc-macro/auxiliary/issue-38586.rs
diff --git a/src/test/ui/proc-macro/auxiliary/issue_50493.rs b/src/test/ui/proc-macro/auxiliary/issue-50493.rs
index f72024948a9..f72024948a9 100644
--- a/src/test/ui/proc-macro/auxiliary/issue_50493.rs
+++ b/src/test/ui/proc-macro/auxiliary/issue-50493.rs
diff --git a/src/test/ui/proc-macro/issue-38586.rs b/src/test/ui/proc-macro/issue-38586.rs
index 4f291ba990a..24e88ed93ca 100644
--- a/src/test/ui/proc-macro/issue-38586.rs
+++ b/src/test/ui/proc-macro/issue-38586.rs
@@ -1,4 +1,4 @@
-// aux-build:issue_38586.rs
+// aux-build:issue-38586.rs
 
 #[macro_use]
 extern crate issue_38586;
diff --git a/src/test/ui/proc-macro/issue-50493.rs b/src/test/ui/proc-macro/issue-50493.rs
index f504dbdfce2..eeb08f5eebd 100644
--- a/src/test/ui/proc-macro/issue-50493.rs
+++ b/src/test/ui/proc-macro/issue-50493.rs
@@ -1,4 +1,4 @@
-// aux-build:issue_50493.rs
+// aux-build:issue-50493.rs
 
 #[macro_use]
 extern crate issue_50493;
diff --git a/src/test/ui/regions/regions-addr-of-upvar-self.stderr b/src/test/ui/regions/regions-addr-of-upvar-self.stderr
index 01b2631a537..ac5e5e9aabc 100644
--- a/src/test/ui/regions/regions-addr-of-upvar-self.stderr
+++ b/src/test/ui/regions/regions-addr-of-upvar-self.stderr
@@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to
 LL |             let p: &'static mut usize = &mut self.food;
    |                                         ^^^^^^^^^^^^^^
    |
-note: first, the lifetime cannot outlive the lifetime  as defined on the body at 9:18...
+note: first, the lifetime cannot outlive the lifetime '_ as defined on the body at 9:18...
   --> $DIR/regions-addr-of-upvar-self.rs:9:18
    |
 LL |         let _f = || {
diff --git a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr
index 9cf0b0ffabd..be441bc4808 100644
--- a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr
+++ b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr
@@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to
 LL |         let mut f = || &mut x;
    |                        ^^^^^^
    |
-note: first, the lifetime cannot outlive the lifetime  as defined on the body at 7:21...
+note: first, the lifetime cannot outlive the lifetime '_ as defined on the body at 7:21...
   --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:7:21
    |
 LL |         let mut f = || &mut x;
diff --git a/src/test/ui/resolve/auxiliary/issue_19452_aux.rs b/src/test/ui/resolve/auxiliary/issue-19452-aux.rs
index 9c7bcec51df..9c7bcec51df 100644
--- a/src/test/ui/resolve/auxiliary/issue_19452_aux.rs
+++ b/src/test/ui/resolve/auxiliary/issue-19452-aux.rs
diff --git a/src/test/ui/resolve/auxiliary/issue_3907.rs b/src/test/ui/resolve/auxiliary/issue-3907.rs
index 5dc502930ae..5dc502930ae 100644
--- a/src/test/ui/resolve/auxiliary/issue_3907.rs
+++ b/src/test/ui/resolve/auxiliary/issue-3907.rs
diff --git a/src/test/ui/resolve/issue-19452.rs b/src/test/ui/resolve/issue-19452.rs
index 5c58cabb3cd..1d3aa49eac6 100644
--- a/src/test/ui/resolve/issue-19452.rs
+++ b/src/test/ui/resolve/issue-19452.rs
@@ -1,4 +1,5 @@
-// aux-build:issue_19452_aux.rs
+// aux-build:issue-19452-aux.rs
+
 extern crate issue_19452_aux;
 
 enum Homura {
diff --git a/src/test/ui/resolve/issue-19452.stderr b/src/test/ui/resolve/issue-19452.stderr
index ef96fffee92..56a0e397b85 100644
--- a/src/test/ui/resolve/issue-19452.stderr
+++ b/src/test/ui/resolve/issue-19452.stderr
@@ -1,11 +1,11 @@
 error[E0423]: expected value, found struct variant `Homura::Madoka`
-  --> $DIR/issue-19452.rs:9:18
+  --> $DIR/issue-19452.rs:10:18
    |
 LL |     let homura = Homura::Madoka;
    |                  ^^^^^^^^^^^^^^ did you mean `Homura::Madoka { /* fields */ }`?
 
 error[E0423]: expected value, found struct variant `issue_19452_aux::Homura::Madoka`
-  --> $DIR/issue-19452.rs:12:18
+  --> $DIR/issue-19452.rs:13:18
    |
 LL |     let homura = issue_19452_aux::Homura::Madoka;
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ did you mean `issue_19452_aux::Homura::Madoka { /* fields */ }`?
diff --git a/src/test/ui/resolve/issue-3907-2.rs b/src/test/ui/resolve/issue-3907-2.rs
index 89e10ca4f2c..dc9624698df 100644
--- a/src/test/ui/resolve/issue-3907-2.rs
+++ b/src/test/ui/resolve/issue-3907-2.rs
@@ -1,4 +1,5 @@
-// aux-build:issue_3907.rs
+// aux-build:issue-3907.rs
+
 extern crate issue_3907;
 
 type Foo = issue_3907::Foo+'static;
diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr
index 4fce898dfa9..968c1f3e463 100644
--- a/src/test/ui/resolve/issue-3907-2.stderr
+++ b/src/test/ui/resolve/issue-3907-2.stderr
@@ -1,5 +1,5 @@
 error[E0038]: the trait `issue_3907::Foo` cannot be made into an object
-  --> $DIR/issue-3907-2.rs:10:1
+  --> $DIR/issue-3907-2.rs:11:1
    |
 LL | fn bar(_x: Foo) {}
    | ^^^^^^^^^^^^^^^ the trait `issue_3907::Foo` cannot be made into an object
diff --git a/src/test/ui/resolve/issue-3907.rs b/src/test/ui/resolve/issue-3907.rs
index a76c3134c0c..87e465489a4 100644
--- a/src/test/ui/resolve/issue-3907.rs
+++ b/src/test/ui/resolve/issue-3907.rs
@@ -1,4 +1,5 @@
-// aux-build:issue_3907.rs
+// aux-build:issue-3907.rs
+
 extern crate issue_3907;
 
 type Foo = issue_3907::Foo;
diff --git a/src/test/ui/resolve/issue-3907.stderr b/src/test/ui/resolve/issue-3907.stderr
index 49f7ae84491..384df571e2a 100644
--- a/src/test/ui/resolve/issue-3907.stderr
+++ b/src/test/ui/resolve/issue-3907.stderr
@@ -1,5 +1,5 @@
 error[E0404]: expected trait, found type alias `Foo`
-  --> $DIR/issue-3907.rs:10:6
+  --> $DIR/issue-3907.rs:11:6
    |
 LL | impl Foo for S {
    |      ^^^ type aliases cannot be used as traits
diff --git a/src/test/ui/retslot-cast.stderr b/src/test/ui/retslot-cast.stderr
index 3c58285bdb3..a1169910ae7 100644
--- a/src/test/ui/retslot-cast.stderr
+++ b/src/test/ui/retslot-cast.stderr
@@ -2,10 +2,10 @@ error[E0308]: mismatched types
   --> $DIR/retslot-cast.rs:13:5
    |
 LL |     inner(x)
-   |     ^^^^^^^^ expected trait `std::iter::Iterator<Item=()>`, found trait `std::iter::Iterator<Item=()> + std::marker::Send`
+   |     ^^^^^^^^ expected trait `std::iter::Iterator<Item = ()>`, found trait `std::iter::Iterator<Item = ()> + std::marker::Send`
    |
-   = note: expected type `std::option::Option<&dyn std::iter::Iterator<Item=()>>`
-              found type `std::option::Option<&dyn std::iter::Iterator<Item=()> + std::marker::Send>`
+   = note: expected type `std::option::Option<&dyn std::iter::Iterator<Item = ()>>`
+              found type `std::option::Option<&dyn std::iter::Iterator<Item = ()> + std::marker::Send>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rmeta-lib-pass.rs b/src/test/ui/rmeta-lib-pass.rs
index 6149b1685f5..4ab4117dd6c 100644
--- a/src/test/ui/rmeta-lib-pass.rs
+++ b/src/test/ui/rmeta-lib-pass.rs
@@ -1,5 +1,5 @@
 // compile-flags: --emit=metadata
-// aux-build:rmeta_rlib.rs
+// aux-build:rmeta-rlib.rs
 // no-prefer-dynamic
 // compile-pass
 
diff --git a/src/test/ui/rmeta-pass.rs b/src/test/ui/rmeta-pass.rs
index bcd40144f72..9c88de7a033 100644
--- a/src/test/ui/rmeta-pass.rs
+++ b/src/test/ui/rmeta-pass.rs
@@ -1,5 +1,5 @@
 // compile-flags: --emit=metadata
-// aux-build:rmeta_meta.rs
+// aux-build:rmeta-meta.rs
 // no-prefer-dynamic
 // compile-pass
 
diff --git a/src/test/ui/rmeta_lib.rs b/src/test/ui/rmeta_lib.rs
index 345b712e37e..6c74aec32e3 100644
--- a/src/test/ui/rmeta_lib.rs
+++ b/src/test/ui/rmeta_lib.rs
@@ -1,4 +1,4 @@
-// aux-build:rmeta_meta.rs
+// aux-build:rmeta-meta.rs
 // no-prefer-dynamic
 // error-pattern: crate `rmeta_meta` required to be available in rlib format, but was not found
 
diff --git a/src/test/ui/rmeta_meta_main.rs b/src/test/ui/rmeta_meta_main.rs
index df550775ee4..52cd0c2f53f 100644
--- a/src/test/ui/rmeta_meta_main.rs
+++ b/src/test/ui/rmeta_meta_main.rs
@@ -1,5 +1,5 @@
 // compile-flags: --emit=metadata
-// aux-build:rmeta_meta.rs
+// aux-build:rmeta-meta.rs
 // no-prefer-dynamic
 
 // Check that building a metadata crate finds an error with a dependent,
diff --git a/src/test/ui/simd-type.rs b/src/test/ui/simd-type.rs
index d1e2efa6a33..9e4b7e76560 100644
--- a/src/test/ui/simd-type.rs
+++ b/src/test/ui/simd-type.rs
@@ -7,7 +7,4 @@ struct empty; //~ ERROR SIMD vector cannot be empty
 #[repr(simd)]
 struct i64f64(i64, f64); //~ ERROR SIMD vector should be homogeneous
 
-#[repr(simd)]
-struct int4(isize, isize, isize, isize); //~ ERROR SIMD vector element type should be machine type
-
 fn main() {}
diff --git a/src/test/ui/simd-type.stderr b/src/test/ui/simd-type.stderr
index 027afcb981a..48b9916e89d 100644
--- a/src/test/ui/simd-type.stderr
+++ b/src/test/ui/simd-type.stderr
@@ -10,13 +10,7 @@ error[E0076]: SIMD vector should be homogeneous
 LL | struct i64f64(i64, f64);
    | ^^^^^^^^^^^^^^^^^^^^^^^^ SIMD elements must have the same type
 
-error[E0077]: SIMD vector element type should be machine type
-  --> $DIR/simd-type.rs:11:1
-   |
-LL | struct int4(isize, isize, isize, isize);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors occurred: E0075, E0076, E0077.
+Some errors occurred: E0075, E0076.
 For more information about an error, try `rustc --explain E0075`.
diff --git a/src/test/ui/substs-ppaux.rs b/src/test/ui/substs-ppaux.rs
index 7ad7ccb5444..129ebd43594 100644
--- a/src/test/ui/substs-ppaux.rs
+++ b/src/test/ui/substs-ppaux.rs
@@ -25,7 +25,7 @@ fn foo<'z>() where &'z (): Sized {
     let x: () = <i8 as Foo<'static, 'static,  u32>>::bar::<'static, char>;
     //[verbose]~^ ERROR mismatched types
     //[verbose]~| expected type `()`
-    //[verbose]~| found type `fn() {<i8 as Foo<ReStatic, ReStatic, u32>>::bar::<ReStatic, char>}`
+    //[verbose]~| found type `fn() {<i8 as Foo<ReStatic, ReStatic>>::bar::<ReStatic, char>}`
     //[normal]~^^^^ ERROR mismatched types
     //[normal]~| expected type `()`
     //[normal]~| found type `fn() {<i8 as Foo<'static, 'static>>::bar::<'static, char>}`
diff --git a/src/test/ui/substs-ppaux.verbose.stderr b/src/test/ui/substs-ppaux.verbose.stderr
index 9d8a555dffe..86936475f8c 100644
--- a/src/test/ui/substs-ppaux.verbose.stderr
+++ b/src/test/ui/substs-ppaux.verbose.stderr
@@ -14,7 +14,7 @@ LL |     let x: () = <i8 as Foo<'static, 'static,  u32>>::bar::<'static, char>;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item
    |
    = note: expected type `()`
-              found type `fn() {<i8 as Foo<ReStatic, ReStatic, u32>>::bar::<ReStatic, char>}`
+              found type `fn() {<i8 as Foo<ReStatic, ReStatic>>::bar::<ReStatic, char>}`
 
 error[E0308]: mismatched types
   --> $DIR/substs-ppaux.rs:33:17
diff --git a/src/test/ui/suggestions/return-without-lifetime.rs b/src/test/ui/suggestions/return-without-lifetime.rs
new file mode 100644
index 00000000000..9bfce11be9e
--- /dev/null
+++ b/src/test/ui/suggestions/return-without-lifetime.rs
@@ -0,0 +1,10 @@
+struct Thing<'a>(&'a ());
+struct Foo<'a>(&usize);
+//~^ ERROR missing lifetime specifier
+
+fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() }
+//~^ ERROR missing lifetime specifier
+fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() }
+//~^ ERROR missing lifetime specifier
+
+fn main() {}
diff --git a/src/test/ui/suggestions/return-without-lifetime.stderr b/src/test/ui/suggestions/return-without-lifetime.stderr
new file mode 100644
index 00000000000..7f5ff95938e
--- /dev/null
+++ b/src/test/ui/suggestions/return-without-lifetime.stderr
@@ -0,0 +1,25 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/return-without-lifetime.rs:2:16
+   |
+LL | struct Foo<'a>(&usize);
+   |                ^ help: consider using the named lifetime: `&'a`
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/return-without-lifetime.rs:5:34
+   |
+LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() }
+   |                                  ^ help: consider using the named lifetime: `&'a`
+   |
+   = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/return-without-lifetime.rs:7:35
+   |
+LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() }
+   |                                   ^ help: consider using the named lifetime: `&'a`
+   |
+   = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/symbol-names/basic.rs b/src/test/ui/symbol-names/basic.rs
index 2a051a5e144..086b903b973 100644
--- a/src/test/ui/symbol-names/basic.rs
+++ b/src/test/ui/symbol-names/basic.rs
@@ -1,6 +1,6 @@
 #![feature(rustc_attrs)]
 
 #[rustc_symbol_name] //~ ERROR _ZN5basic4main
-#[rustc_item_path] //~ ERROR item-path(main)
+#[rustc_def_path] //~ ERROR def-path(main)
 fn main() {
 }
diff --git a/src/test/ui/symbol-names/basic.stderr b/src/test/ui/symbol-names/basic.stderr
index e23a326d5f8..6ddd93d632e 100644
--- a/src/test/ui/symbol-names/basic.stderr
+++ b/src/test/ui/symbol-names/basic.stderr
@@ -4,11 +4,11 @@ error: symbol-name(_ZN5basic4main17h08bcaf310214ed52E)
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: item-path(main)
+error: def-path(main)
   --> $DIR/basic.rs:4:1
    |
-LL | #[rustc_item_path]
-   | ^^^^^^^^^^^^^^^^^^
+LL | #[rustc_def_path]
+   | ^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs
index 97169c33b8c..c712137e828 100644
--- a/src/test/ui/symbol-names/impl1.rs
+++ b/src/test/ui/symbol-names/impl1.rs
@@ -6,7 +6,7 @@ mod foo {
 
     impl Foo {
         #[rustc_symbol_name] //~ ERROR _ZN5impl13foo3Foo3bar
-        #[rustc_item_path] //~ ERROR item-path(foo::Foo::bar)
+        #[rustc_def_path] //~ ERROR def-path(foo::Foo::bar)
         fn bar() { }
     }
 }
@@ -16,7 +16,7 @@ mod bar {
 
     impl Foo {
         #[rustc_symbol_name] //~ ERROR _ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz
-        #[rustc_item_path] //~ ERROR item-path(bar::<impl foo::Foo>::baz)
+        #[rustc_def_path] //~ ERROR def-path(bar::<impl foo::Foo>::baz)
         fn baz() { }
     }
 }
diff --git a/src/test/ui/symbol-names/impl1.stderr b/src/test/ui/symbol-names/impl1.stderr
index e4fefeb601f..eda8646b5b4 100644
--- a/src/test/ui/symbol-names/impl1.stderr
+++ b/src/test/ui/symbol-names/impl1.stderr
@@ -4,11 +4,11 @@ error: symbol-name(_ZN5impl13foo3Foo3bar17hc487d6ec13fe9124E)
 LL |         #[rustc_symbol_name]
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error: item-path(foo::Foo::bar)
+error: def-path(foo::Foo::bar)
   --> $DIR/impl1.rs:9:9
    |
-LL |         #[rustc_item_path]
-   |         ^^^^^^^^^^^^^^^^^^
+LL |         #[rustc_def_path]
+   |         ^^^^^^^^^^^^^^^^^
 
 error: symbol-name(_ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz17h38577281258e1527E)
   --> $DIR/impl1.rs:18:9
@@ -16,11 +16,11 @@ error: symbol-name(_ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz17h385772
 LL |         #[rustc_symbol_name]
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error: item-path(bar::<impl foo::Foo>::baz)
+error: def-path(bar::<impl foo::Foo>::baz)
   --> $DIR/impl1.rs:19:9
    |
-LL |         #[rustc_item_path]
-   |         ^^^^^^^^^^^^^^^^^^
+LL |         #[rustc_def_path]
+   |         ^^^^^^^^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/type_length_limit.rs b/src/test/ui/type_length_limit.rs
index bb54669d37d..cd15f81a615 100644
--- a/src/test/ui/type_length_limit.rs
+++ b/src/test/ui/type_length_limit.rs
@@ -1,3 +1,5 @@
+// ignore-musl
+// ignore-x86
 // error-pattern: reached the type-length limit while instantiating
 
 // Test that the type length limit can be changed.
diff --git a/src/test/ui/type_length_limit.stderr b/src/test/ui/type_length_limit.stderr
index 910eca07594..9d07c86356b 100644
--- a/src/test/ui/type_length_limit.stderr
+++ b/src/test/ui/type_length_limit.stderr
@@ -1,6 +1,10 @@
-error: reached the type-length limit while instantiating `std::mem::drop::<std::option::Option<((((((G, G, G), (G, G, G), ...`
+error: reached the type-length limit while instantiating `std::mem::drop::<std::option::Op... G), (G, G, G), (G, G, G))))))>>`
+  --> $SRC_DIR/libcore/mem.rs:LL:COL
    |
-   = note: consider adding a `#![type_length_limit="512"]` attribute to your crate
+LL | pub fn drop<T>(_x: T) { }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: consider adding a `#![type_length_limit="1094"]` attribute to your crate
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr
index f1118709962..d41086186f8 100644
--- a/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr
+++ b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr
@@ -7,7 +7,7 @@ LL |     *x
    |     ^^ expected (), found trait std::iter::Iterator
    |
    = note: expected type `()`
-              found type `(dyn std::iter::Iterator<Item=()> + 'static)`
+              found type `(dyn std::iter::Iterator<Item = ()> + 'static)`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr
index 508c2f780b9..ce90f5b9d24 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr
@@ -1,8 +1,8 @@
-error[E0277]: the trait bound `dyn Foo<(isize,), isize, Output=()>: Eq<dyn Foo<(isize,), Output=()>>` is not satisfied
+error[E0277]: the trait bound `dyn Foo<(isize,), isize, Output = ()>: Eq<dyn Foo<(isize,), Output = ()>>` is not satisfied
   --> $DIR/unboxed-closure-sugar-default.rs:21:5
    |
 LL |     eq::< Foo<(isize,),isize,Output=()>,      Foo(isize)                      >();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Eq<dyn Foo<(isize,), Output=()>>` is not implemented for `dyn Foo<(isize,), isize, Output=()>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Eq<dyn Foo<(isize,), Output = ()>>` is not implemented for `dyn Foo<(isize,), isize, Output = ()>`
    |
 note: required by `eq`
   --> $DIR/unboxed-closure-sugar-default.rs:14:1
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr
index 071ba2792b0..857a32ca69e 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr
@@ -1,9 +1,9 @@
-error[E0277]: the trait bound `dyn Foo<(char,), Output=()>: Eq<dyn Foo<(), Output=()>>` is not satisfied
+error[E0277]: the trait bound `dyn Foo<(char,), Output = ()>: Eq<dyn Foo<(), Output = ()>>` is not satisfied
   --> $DIR/unboxed-closure-sugar-equiv.rs:43:5
    |
 LL | /     eq::< Foo<(),Output=()>,
 LL | |           Foo(char)                                               >();
-   | |___________________________________________________________________^ the trait `Eq<dyn Foo<(), Output=()>>` is not implemented for `dyn Foo<(char,), Output=()>`
+   | |___________________________________________________________________^ the trait `Eq<dyn Foo<(), Output = ()>>` is not implemented for `dyn Foo<(char,), Output = ()>`
    |
 note: required by `eq`
   --> $DIR/unboxed-closure-sugar-equiv.rs:16:1
diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
index 69a9fd7a60c..d0475bf08c3 100644
--- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
@@ -19,8 +19,8 @@ LL |     Box::new(items.iter())
    |              ^^^^^
    = note: but, the lifetime must be valid for the static lifetime...
    = note: ...so that the expression is assignable:
-           expected std::boxed::Box<(dyn std::iter::Iterator<Item=&T> + 'static)>
-              found std::boxed::Box<dyn std::iter::Iterator<Item=&T>>
+           expected std::boxed::Box<(dyn std::iter::Iterator<Item = &T> + 'static)>
+              found std::boxed::Box<dyn std::iter::Iterator<Item = &T>>
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/auxiliary/use_from_trait_xc.rs b/src/test/ui/use/auxiliary/use-from-trait-xc.rs
index 4abe11941b1..4abe11941b1 100644
--- a/src/test/ui/auxiliary/use_from_trait_xc.rs
+++ b/src/test/ui/use/auxiliary/use-from-trait-xc.rs
diff --git a/src/test/ui/use/auxiliary/use_from_trait_xc.rs b/src/test/ui/use/auxiliary/use_from_trait_xc.rs
deleted file mode 100644
index 4abe11941b1..00000000000
--- a/src/test/ui/use/auxiliary/use_from_trait_xc.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-pub use self::sub::{Bar, Baz};
-
-pub trait Trait {
-    fn foo(&self);
-    type Assoc;
-    const CONST: u32;
-}
-
-struct Foo;
-
-impl Foo {
-    pub fn new() {}
-
-    pub const C: u32 = 0;
-}
-
-mod sub {
-    pub struct Bar;
-
-    impl Bar {
-        pub fn new() {}
-    }
-
-    pub enum Baz {}
-
-    impl Baz {
-        pub fn new() {}
-    }
-}
diff --git a/src/test/ui/issue-18986.rs b/src/test/ui/use/issue-18986.rs
index 1c431a45ab2..f0b292f2911 100644
--- a/src/test/ui/issue-18986.rs
+++ b/src/test/ui/use/issue-18986.rs
@@ -1,4 +1,4 @@
-// aux-build:use_from_trait_xc.rs
+// aux-build:use-from-trait-xc.rs
 
 extern crate use_from_trait_xc;
 pub use use_from_trait_xc::Trait;
diff --git a/src/test/ui/issue-18986.stderr b/src/test/ui/use/issue-18986.stderr
index 6c23178c700..6c23178c700 100644
--- a/src/test/ui/issue-18986.stderr
+++ b/src/test/ui/use/issue-18986.stderr
diff --git a/src/test/ui/use/use-from-trait-xc.rs b/src/test/ui/use/use-from-trait-xc.rs
index e6f102f6269..695ed66a1c1 100644
--- a/src/test/ui/use/use-from-trait-xc.rs
+++ b/src/test/ui/use/use-from-trait-xc.rs
@@ -1,4 +1,4 @@
-// aux-build:use_from_trait_xc.rs
+// aux-build:use-from-trait-xc.rs
 
 extern crate use_from_trait_xc;
 
diff --git a/src/test/ui/useless_comment.rs b/src/test/ui/useless-comment.rs
index 7d2e5ab6f2b..7d2e5ab6f2b 100644
--- a/src/test/ui/useless_comment.rs
+++ b/src/test/ui/useless-comment.rs
diff --git a/src/test/ui/useless_comment.stderr b/src/test/ui/useless-comment.stderr
index 10d8ee60f99..925e3079636 100644
--- a/src/test/ui/useless_comment.stderr
+++ b/src/test/ui/useless-comment.stderr
@@ -1,5 +1,5 @@
 error: unused doc comment
-  --> $DIR/useless_comment.rs:9:1
+  --> $DIR/useless-comment.rs:9:1
    |
 LL | /// foo
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,14 +7,14 @@ LL | mac!();
    | ------- rustdoc does not generate documentation for macro expansions
    |
 note: lint level defined here
-  --> $DIR/useless_comment.rs:3:9
+  --> $DIR/useless-comment.rs:3:9
    |
 LL | #![deny(unused_doc_comments)]
    |         ^^^^^^^^^^^^^^^^^^^
    = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion
 
 error: unused doc comment
-  --> $DIR/useless_comment.rs:13:5
+  --> $DIR/useless-comment.rs:13:5
    |
 LL |     /// a
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -22,7 +22,7 @@ LL |     let x = 12;
    |     ----------- rustdoc does not generate documentation for statements
 
 error: unused doc comment
-  --> $DIR/useless_comment.rs:16:5
+  --> $DIR/useless-comment.rs:16:5
    |
 LL | /     /// multi-line
 LL | |     /// doc comment
@@ -36,7 +36,7 @@ LL | |     }
    | |_____- rustdoc does not generate documentation for expressions
 
 error: unused doc comment
-  --> $DIR/useless_comment.rs:20:9
+  --> $DIR/useless-comment.rs:20:9
    |
 LL |         /// c
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -44,7 +44,7 @@ LL |         1 => {},
    |         ------- rustdoc does not generate documentation for match arms
 
 error: unused doc comment
-  --> $DIR/useless_comment.rs:25:5
+  --> $DIR/useless-comment.rs:25:5
    |
 LL |     /// foo
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -52,7 +52,7 @@ LL |     unsafe {}
    |     --------- rustdoc does not generate documentation for expressions
 
 error: unused doc comment
-  --> $DIR/useless_comment.rs:28:5
+  --> $DIR/useless-comment.rs:28:5
    |
 LL |     #[doc = "foo"]
    |     ^^^^^^^^^^^^^^
@@ -61,7 +61,7 @@ LL |     3;
    |     - rustdoc does not generate documentation for expressions
 
 error: unused doc comment
-  --> $DIR/useless_comment.rs:29:5
+  --> $DIR/useless-comment.rs:29:5
    |
 LL |     #[doc = "bar"]
    |     ^^^^^^^^^^^^^^
@@ -69,7 +69,7 @@ LL |     3;
    |     - rustdoc does not generate documentation for expressions
 
 error: unused doc comment
-  --> $DIR/useless_comment.rs:32:5
+  --> $DIR/useless-comment.rs:32:5
    |
 LL |     /// bar
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -79,13 +79,13 @@ LL |     mac!();
    = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion
 
 error: unused doc comment
-  --> $DIR/useless_comment.rs:35:13
+  --> $DIR/useless-comment.rs:35:13
    |
 LL |     let x = /** comment */ 47;
    |             ^^^^^^^^^^^^^^ -- rustdoc does not generate documentation for expressions
 
 error: unused doc comment
-  --> $DIR/useless_comment.rs:37:5
+  --> $DIR/useless-comment.rs:37:5
    |
 LL |       /// dox
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/xc-private-method.rs b/src/test/ui/xc-private-method.rs
index 157249194a3..e95cab93d75 100644
--- a/src/test/ui/xc-private-method.rs
+++ b/src/test/ui/xc-private-method.rs
@@ -1,4 +1,4 @@
-// aux-build:xc_private_method_lib.rs
+// aux-build:xc-private-method-lib.rs
 
 extern crate xc_private_method_lib;
 
diff --git a/src/test/ui/xc-private-method2.rs b/src/test/ui/xc-private-method2.rs
index 6d73570318a..f11b251082b 100644
--- a/src/test/ui/xc-private-method2.rs
+++ b/src/test/ui/xc-private-method2.rs
@@ -1,4 +1,4 @@
-// aux-build:xc_private_method_lib.rs
+// aux-build:xc-private-method-lib.rs
 
 extern crate xc_private_method_lib;
 
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index d44a51a9635..058f2df624b 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -23,6 +23,10 @@ static HOSTS: &'static [&'static str] = &[
     "mips64-unknown-linux-gnuabi64",
     "mips64el-unknown-linux-gnuabi64",
     "mipsel-unknown-linux-gnu",
+    "mipsisa32r6-unknown-linux-gnu",
+    "mipsisa32r6el-unknown-linux-gnu",
+    "mipsisa64r6-unknown-linux-gnuabi64",
+    "mipsisa64r6el-unknown-linux-gnuabi64",
     "powerpc-unknown-linux-gnu",
     "powerpc64-unknown-linux-gnu",
     "powerpc64le-unknown-linux-gnu",
@@ -32,6 +36,7 @@ static HOSTS: &'static [&'static str] = &[
     "x86_64-pc-windows-msvc",
     "x86_64-unknown-freebsd",
     "x86_64-unknown-linux-gnu",
+    "x86_64-unknown-linux-musl",
     "x86_64-unknown-netbsd",
 ];
 
@@ -77,6 +82,10 @@ static TARGETS: &'static [&'static str] = &[
     "mips-unknown-linux-musl",
     "mips64-unknown-linux-gnuabi64",
     "mips64el-unknown-linux-gnuabi64",
+    "mipsisa32r6-unknown-linux-gnu",
+    "mipsisa32r6el-unknown-linux-gnu",
+    "mipsisa64r6-unknown-linux-gnuabi64",
+    "mipsisa64r6el-unknown-linux-gnuabi64",
     "mipsel-unknown-linux-gnu",
     "mipsel-unknown-linux-musl",
     "nvptx64-nvidia-cuda",
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 95b45eca19ac785263fed98ecefe540bb47337a
+Subproject 0e35bd8af0ec72d3225c4819b330b94628f0e9d
diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs
index c54035cdec5..50dce4b55ae 100644
--- a/src/tools/compiletest/src/util.rs
+++ b/src/tools/compiletest/src/util.rs
@@ -48,7 +48,15 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[
     ("mips", "mips"),
     ("mips64", "mips64"),
     ("mips64el", "mips64"),
+    ("mipsisa32r6", "mips"),
+    ("mipsisa32r6el", "mips"),
+    ("mipsisa64r6", "mips64"),
+    ("mipsisa64r6el", "mips64"),
     ("mipsel", "mips"),
+    ("mipsisa32r6", "mips"),
+    ("mipsisa32r6el", "mips"),
+    ("mipsisa64r6", "mips64"),
+    ("mipsisa64r6el", "mips64"),
     ("msp430", "msp430"),
     ("nvptx64", "nvptx64"),
     ("powerpc", "powerpc"),
diff --git a/src/tools/miri b/src/tools/miri
-Subproject e3527fdba7178120a6398e76aa4b3908b10ef85
+Subproject 72b4ee0381decf609204e5548c1f5e79bdfb18b